blob: c736f1e3dfb35b1c67536781dd33ee0978af3a96 [file] [log] [blame]
tomhudson@google.com93813632011-10-27 20:21:16 +00001/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef GrDrawState_DEFINED
9#define GrDrawState_DEFINED
10
11#include "GrColor.h"
12#include "GrMatrix.h"
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +000013#include "GrNoncopyable.h"
tomhudson@google.com93813632011-10-27 20:21:16 +000014#include "GrSamplerState.h"
15#include "GrStencil.h"
16
17#include "SkXfermode.h"
18
19class GrRenderTarget;
20class GrTexture;
21
22struct GrDrawState {
23
24 /**
25 * Number of texture stages. Each stage takes as input a color and
26 * 2D texture coordinates. The color input to the first enabled stage is the
27 * per-vertex color or the constant color (setColor/setAlpha) if there are
28 * no per-vertex colors. For subsequent stages the input color is the output
29 * color from the previous enabled stage. The output color of each stage is
30 * the input color modulated with the result of a texture lookup. Texture
31 * lookups are specified by a texture a sampler (setSamplerState). Texture
32 * coordinates for each stage come from the vertices based on a
33 * GrVertexLayout bitfield. The output fragment color is the output color of
34 * the last enabled stage. The presence or absence of texture coordinates
35 * for each stage in the vertex layout indicates whether a stage is enabled
36 * or not.
37 */
38 enum {
39 kNumStages = 3,
40 kMaxTexCoords = kNumStages
41 };
42
bsalomon@google.com39ee0ff2011-12-06 15:32:52 +000043 /**
44 * Bitfield used to indicate a set of stages.
45 */
46 typedef uint32_t StageMask;
47 GR_STATIC_ASSERT(sizeof(StageMask)*8 >= GrDrawState::kNumStages);
48
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +000049 GrDrawState() {
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +000050 this->reset();
51 }
52
53 /**
54 * Resets to the default state. Sampler states will not be modified.
55 */
56 void reset() {
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +000057 // make sure any pad is zero for memcmp
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +000058 // all GrDrawState members should default to something valid by the
59 // the memset except those initialized individually below. There should
60 // be no padding between the individually initialized members.
61 static const size_t kMemsetSize =
62 reinterpret_cast<intptr_t>(&fColor) -
63 reinterpret_cast<intptr_t>(this);
64 memset(this, 0, kMemsetSize);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +000065 // pedantic assertion that our ptrs will
66 // be NULL (0 ptr is mem addr 0)
67 GrAssert((intptr_t)(void*)NULL == 0LL);
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +000068 GR_STATIC_ASSERT(0 == kBoth_DrawFace);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +000069 GrAssert(fStencilSettings.isDisabled());
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +000070
71 // memset exceptions
72 fColor = 0xffffffff;
bsalomon@google.com2401ae82012-01-17 21:03:05 +000073 fCoverage = 0xffffffff;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +000074 fFirstCoverageStage = kNumStages;
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +000075 fColorFilterMode = SkXfermode::kDst_Mode;
76 fSrcBlend = kOne_BlendCoeff;
77 fDstBlend = kZero_BlendCoeff;
78 fViewMatrix.reset();
79
80 // ensure values that will be memcmp'ed in == but not memset in reset()
81 // are tightly packed
bsalomon@google.com2401ae82012-01-17 21:03:05 +000082 GrAssert(kMemsetSize + sizeof(fColor) + sizeof(fCoverage) +
83 sizeof(fFirstCoverageStage) + sizeof(fColorFilterMode) +
84 sizeof(fSrcBlend) + sizeof(fDstBlend) + sizeof(GrMatrix) ==
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +000085 reinterpret_cast<intptr_t>(&fEdgeAANumEdges) -
86 reinterpret_cast<intptr_t>(this));
87
88 fEdgeAANumEdges = 0;
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +000089 }
90
91 ///////////////////////////////////////////////////////////////////////////
92 /// @name Color
93 ////
94
95 /**
96 * Sets color for next draw to a premultiplied-alpha color.
97 *
98 * @param color the color to set.
99 */
100 void setColor(GrColor color) { fColor = color; }
101
102 GrColor getColor() const { return fColor; }
103
104 /**
105 * Sets the color to be used for the next draw to be
106 * (r,g,b,a) = (alpha, alpha, alpha, alpha).
107 *
108 * @param alpha The alpha value to set as the color.
109 */
110 void setAlpha(uint8_t a) {
111 this->setColor((a << 24) | (a << 16) | (a << 8) | a);
112 }
113
114 /**
115 * Add a color filter that can be represented by a color and a mode. Applied
116 * after color-computing texture stages.
117 */
118 void setColorFilter(GrColor c, SkXfermode::Mode mode) {
119 fColorFilterColor = c;
120 fColorFilterMode = mode;
121 }
122
123 GrColor getColorFilterColor() const { return fColorFilterColor; }
124 SkXfermode::Mode getColorFilterMode() const { return fColorFilterMode; }
125
126 /// @}
127
128 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000129 /// @name Coverage
130 ////
131
132 /**
133 * Sets a constant fractional coverage to be applied to the draw. The
134 * initial value (after construction or reset()) is 0xff. The constant
135 * coverage is ignored when per-vertex coverage is provided.
136 */
137 void setCoverage(uint8_t coverage) {
138 fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage);
139 }
140
141 /**
142 * Version of above that specifies 4 channel per-vertex color. The value
143 * should be premultiplied.
144 */
145 void setCoverage4(GrColor coverage) {
146 fCoverage = coverage;
147 }
148
149 GrColor getCoverage() const {
150 return fCoverage;
151 }
152
153 /// @}
154
155 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000156 /// @name Textures
157 ////
158
159 /**
160 * Sets the texture used at the next drawing call
161 *
162 * @param stage The texture stage for which the texture will be set
163 *
164 * @param texture The texture to set. Can be NULL though there is no
165 * advantage to settings a NULL texture if doing non-textured drawing
166 */
167 void setTexture(int stage, GrTexture* texture) {
168 GrAssert((unsigned)stage < kNumStages);
169 fTextures[stage] = texture;
170 }
171
172 /**
173 * Retrieves the currently set texture.
174 *
175 * @return The currently set texture. The return value will be NULL if no
176 * texture has been set, NULL was most recently passed to
177 * setTexture, or the last setTexture was destroyed.
178 */
179 const GrTexture* getTexture(int stage) const {
180 GrAssert((unsigned)stage < kNumStages);
181 return fTextures[stage];
182 }
183 GrTexture* getTexture(int stage) {
184 GrAssert((unsigned)stage < kNumStages);
185 return fTextures[stage];
186 }
187
188 /// @}
189
190 ///////////////////////////////////////////////////////////////////////////
191 /// @name Samplers
192 ////
193
194 /**
195 * Returns the current sampler for a stage.
196 */
197 const GrSamplerState& getSampler(int stage) const {
198 GrAssert((unsigned)stage < kNumStages);
199 return fSamplerStates[stage];
200 }
201
202 /**
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000203 * Writable pointer to a stage's sampler.
204 */
205 GrSamplerState* sampler(int stage) {
206 GrAssert((unsigned)stage < kNumStages);
207 return fSamplerStates + stage;
208 }
209
210 /**
211 * Preconcats the matrix of all samplers in the mask with the same matrix.
212 */
213 void preConcatSamplerMatrices(StageMask stageMask, const GrMatrix& matrix) {
214 GrAssert(!(stageMask & kIllegalStageMaskBits));
215 for (int i = 0; i < kNumStages; ++i) {
216 if ((1 << i) & stageMask) {
217 fSamplerStates[i].preConcatMatrix(matrix);
218 }
219 }
220 }
221
222 /// @}
223
224 ///////////////////////////////////////////////////////////////////////////
225 /// @name Coverage / Color Stages
226 ////
227
228 /**
229 * A common pattern is to compute a color with the initial stages and then
230 * modulate that color by a coverage value in later stage(s) (AA, mask-
231 * filters, glyph mask, etc). Color-filters, xfermodes, etc should be
232 * computed based on the pre-coverage-modulated color. The division of
233 * stages between color-computing and coverage-computing is specified by
234 * this method. Initially this is kNumStages (all stages
235 * are color-computing).
236 */
237 void setFirstCoverageStage(int firstCoverageStage) {
238 GrAssert((unsigned)firstCoverageStage <= kNumStages);
239 fFirstCoverageStage = firstCoverageStage;
240 }
241
242 /**
243 * Gets the index of the first coverage-computing stage.
244 */
245 int getFirstCoverageStage() const {
246 return fFirstCoverageStage;
247 }
248
249 ///@}
250
251 ///////////////////////////////////////////////////////////////////////////
252 /// @name Blending
253 ////
254
255 /**
256 * Sets the blending function coeffecients.
257 *
258 * The blend function will be:
259 * D' = sat(S*srcCoef + D*dstCoef)
260 *
261 * where D is the existing destination color, S is the incoming source
262 * color, and D' is the new destination color that will be written. sat()
263 * is the saturation function.
264 *
265 * @param srcCoef coeffecient applied to the src color.
266 * @param dstCoef coeffecient applied to the dst color.
267 */
268 void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
269 fSrcBlend = srcCoeff;
270 fDstBlend = dstCoeff;
271 #if GR_DEBUG
272 switch (dstCoeff) {
273 case kDC_BlendCoeff:
274 case kIDC_BlendCoeff:
275 case kDA_BlendCoeff:
276 case kIDA_BlendCoeff:
277 GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
278 "coverage stages.\n");
279 break;
280 default:
281 break;
282 }
283 switch (srcCoeff) {
284 case kSC_BlendCoeff:
285 case kISC_BlendCoeff:
286 case kSA_BlendCoeff:
287 case kISA_BlendCoeff:
288 GrPrintf("Unexpected src blend coeff. Won't work correctly with"
289 "coverage stages.\n");
290 break;
291 default:
292 break;
293 }
294 #endif
295 }
296
297 GrBlendCoeff getSrcBlendCoeff() const { return fSrcBlend; }
298 GrBlendCoeff getDstBlendCoeff() const { return fDstBlend; }
299
300 void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff,
301 GrBlendCoeff* dstBlendCoeff) const {
302 *srcBlendCoeff = fSrcBlend;
303 *dstBlendCoeff = fDstBlend;
304 }
305
306 /**
307 * Sets the blending function constant referenced by the following blending
308 * coeffecients:
309 * kConstC_BlendCoeff
310 * kIConstC_BlendCoeff
311 * kConstA_BlendCoeff
312 * kIConstA_BlendCoeff
313 *
314 * @param constant the constant to set
315 */
316 void setBlendConstant(GrColor constant) { fBlendConstant = constant; }
317
318 /**
319 * Retrieves the last value set by setBlendConstant()
320 * @return the blending constant value
321 */
322 GrColor getBlendConstant() const { return fBlendConstant; }
323
324 /// @}
325
326 ///////////////////////////////////////////////////////////////////////////
327 /// @name View Matrix
328 ////
329
330 /**
331 * Sets the matrix applied to veretx positions.
332 *
333 * In the post-view-matrix space the rectangle [0,w]x[0,h]
334 * fully covers the render target. (w and h are the width and height of the
335 * the rendertarget.)
336 */
337 void setViewMatrix(const GrMatrix& m) { fViewMatrix = m; }
338
339 /**
340 * Gets a writable pointer to the view matrix.
341 */
342 GrMatrix* viewMatrix() { return &fViewMatrix; }
343
344 /**
345 * Multiplies the current view matrix by a matrix
346 *
347 * After this call V' = V*m where V is the old view matrix,
348 * m is the parameter to this function, and V' is the new view matrix.
349 * (We consider positions to be column vectors so position vector p is
350 * transformed by matrix X as p' = X*p.)
351 *
352 * @param m the matrix used to modify the view matrix.
353 */
354 void preConcatViewMatrix(const GrMatrix& m) { fViewMatrix.preConcat(m); }
355
356 /**
357 * Multiplies the current view matrix by a matrix
358 *
359 * After this call V' = m*V where V is the old view matrix,
360 * m is the parameter to this function, and V' is the new view matrix.
361 * (We consider positions to be column vectors so position vector p is
362 * transformed by matrix X as p' = X*p.)
363 *
364 * @param m the matrix used to modify the view matrix.
365 */
366 void postConcatViewMatrix(const GrMatrix& m) { fViewMatrix.postConcat(m); }
367
368 /**
369 * Retrieves the current view matrix
370 * @return the current view matrix.
371 */
372 const GrMatrix& getViewMatrix() const { return fViewMatrix; }
373
374 /**
375 * Retrieves the inverse of the current view matrix.
376 *
377 * If the current view matrix is invertible, return true, and if matrix
378 * is non-null, copy the inverse into it. If the current view matrix is
379 * non-invertible, return false and ignore the matrix parameter.
380 *
381 * @param matrix if not null, will receive a copy of the current inverse.
382 */
383 bool getViewInverse(GrMatrix* matrix) const {
384 // TODO: determine whether we really need to leave matrix unmodified
385 // at call sites when inversion fails.
386 GrMatrix inverse;
387 if (fViewMatrix.invert(&inverse)) {
388 if (matrix) {
389 *matrix = inverse;
390 }
391 return true;
392 }
393 return false;
394 }
395
396 class AutoViewMatrixRestore : public ::GrNoncopyable {
397 public:
398 AutoViewMatrixRestore() : fDrawState(NULL) {}
399 AutoViewMatrixRestore(GrDrawState* ds, const GrMatrix& newMatrix) {
400 fDrawState = NULL;
401 this->set(ds, newMatrix);
402 }
403 AutoViewMatrixRestore(GrDrawState* ds) {
404 fDrawState = NULL;
405 this->set(ds);
406 }
407 ~AutoViewMatrixRestore() {
408 this->set(NULL, GrMatrix::I());
409 }
410 void set(GrDrawState* ds, const GrMatrix& newMatrix) {
411 if (NULL != fDrawState) {
412 fDrawState->setViewMatrix(fSavedMatrix);
413 }
414 if (NULL != ds) {
415 fSavedMatrix = ds->getViewMatrix();
416 ds->setViewMatrix(newMatrix);
417 }
418 fDrawState = ds;
419 }
420 void set(GrDrawState* ds) {
421 if (NULL != fDrawState) {
422 fDrawState->setViewMatrix(fSavedMatrix);
423 }
424 if (NULL != ds) {
425 fSavedMatrix = ds->getViewMatrix();
426 }
427 fDrawState = ds;
428 }
429 private:
430 GrDrawState* fDrawState;
431 GrMatrix fSavedMatrix;
tomhudson@google.com93813632011-10-27 20:21:16 +0000432 };
433
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000434 /// @}
435
436 ///////////////////////////////////////////////////////////////////////////
437 /// @name Render Target
438 ////
439
440 /**
441 * Sets the rendertarget used at the next drawing call
442 *
443 * @param target The render target to set.
444 */
445 void setRenderTarget(GrRenderTarget* target) { fRenderTarget = target; }
446
447 /**
448 * Retrieves the currently set rendertarget.
449 *
450 * @return The currently set render target.
451 */
452 const GrRenderTarget* getRenderTarget() const { return fRenderTarget; }
453 GrRenderTarget* getRenderTarget() { return fRenderTarget; }
454
455 class AutoRenderTargetRestore : public ::GrNoncopyable {
456 public:
bsalomon@google.comcadbcb82012-01-06 19:22:11 +0000457 AutoRenderTargetRestore() : fDrawState(NULL), fSavedTarget(NULL) {}
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000458 AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) {
459 fDrawState = NULL;
460 this->set(ds, newTarget);
461 }
462 ~AutoRenderTargetRestore() { this->set(NULL, NULL); }
463 void set(GrDrawState* ds, GrRenderTarget* newTarget) {
464 if (NULL != fDrawState) {
465 fDrawState->setRenderTarget(fSavedTarget);
466 }
467 if (NULL != ds) {
468 fSavedTarget = ds->getRenderTarget();
469 ds->setRenderTarget(newTarget);
470 }
471 fDrawState = ds;
472 }
473 private:
474 GrDrawState* fDrawState;
475 GrRenderTarget* fSavedTarget;
476 };
477
478 /// @}
479
480 ///////////////////////////////////////////////////////////////////////////
481 /// @name Stencil
482 ////
483
484 /**
485 * Sets the stencil settings to use for the next draw.
486 * Changing the clip has the side-effect of possibly zeroing
487 * out the client settable stencil bits. So multipass algorithms
488 * using stencil should not change the clip between passes.
489 * @param settings the stencil settings to use.
490 */
491 void setStencil(const GrStencilSettings& settings) {
492 fStencilSettings = settings;
493 }
494
495 /**
496 * Shortcut to disable stencil testing and ops.
497 */
498 void disableStencil() {
499 fStencilSettings.setDisabled();
500 }
501
502 const GrStencilSettings& getStencil() const { return fStencilSettings; }
503
504 GrStencilSettings* stencil() { return &fStencilSettings; }
505
506 /// @}
507
508 ///////////////////////////////////////////////////////////////////////////
senorblanco@chromium.org50bdad82012-01-03 20:51:57 +0000509 /// @name Color Matrix
510 ////
511
512 /**
513 * Sets the color matrix to use for the next draw.
514 * @param matrix the 5x4 matrix to apply to the incoming color
515 */
516 void setColorMatrix(const float matrix[20]) {
517 memcpy(fColorMatrix, matrix, sizeof(fColorMatrix));
518 }
519
520 const float* getColorMatrix() const { return fColorMatrix; }
521
522 /// @}
523
524 ///////////////////////////////////////////////////////////////////////////
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000525 // @name Edge AA
526 // There are two ways to perform antialiasing using edge equations. One
527 // is to specify an (linear or quadratic) edge eq per-vertex. This requires
528 // splitting vertices shared by primitives.
529 //
530 // The other is via setEdgeAAData which sets a set of edges and each
531 // is tested against all the edges.
532 ////
533
534 /**
tomhudson@google.com93813632011-10-27 20:21:16 +0000535 * When specifying edges as vertex data this enum specifies what type of
536 * edges are in use. The edges are always 4 GrScalars in memory, even when
537 * the edge type requires fewer than 4.
538 */
539 enum VertexEdgeType {
540 /* 1-pixel wide line
541 2D implicit line eq (a*x + b*y +c = 0). 4th component unused */
542 kHairLine_EdgeType,
bsalomon@google.com69cc6ad2012-01-17 14:25:10 +0000543 /* Quadratic specified by u^2-v canonical coords (only 2
544 components used). Coverage based on signed distance with negative
545 being inside, positive outside.*/
546 kQuad_EdgeType,
547 /* Same as above but for hairline quadratics. Uses unsigned distance.
548 Coverage is min(0, 1-distance). */
549 kHairQuad_EdgeType,
550
551 kVertexEdgeTypeCnt
tomhudson@google.com93813632011-10-27 20:21:16 +0000552 };
553
554 /**
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000555 * Determines the interpretation per-vertex edge data when the
556 * kEdge_VertexLayoutBit is set (see GrDrawTarget). When per-vertex edges
557 * are not specified the value of this setting has no effect.
558 */
559 void setVertexEdgeType(VertexEdgeType type) {
bsalomon@google.com69cc6ad2012-01-17 14:25:10 +0000560 GrAssert(type >=0 && type < kVertexEdgeTypeCnt);
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000561 fVertexEdgeType = type;
562 }
563
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +0000564 VertexEdgeType getVertexEdgeType() const { return fVertexEdgeType; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000565
566 /**
tomhudson@google.com93813632011-10-27 20:21:16 +0000567 * The absolute maximum number of edges that may be specified for
568 * a single draw call when performing edge antialiasing. This is used for
569 * the size of several static buffers, so implementations of getMaxEdges()
570 * (below) should clamp to this value.
571 */
572 enum {
tomhudson@google.com62b09682011-11-09 16:39:17 +0000573 // TODO: this should be 32 when GrTesselatedPathRenderer is used
574 // Visual Studio 2010 does not permit a member array of size 0.
575 kMaxEdges = 1
tomhudson@google.com93813632011-10-27 20:21:16 +0000576 };
577
578 class Edge {
579 public:
580 Edge() {}
581 Edge(float x, float y, float z) : fX(x), fY(y), fZ(z) {}
582 GrPoint intersect(const Edge& other) {
583 return GrPoint::Make(
bsalomon@google.com72e49b82011-10-27 21:47:03 +0000584 SkFloatToScalar((fY * other.fZ - other.fY * fZ) /
585 (fX * other.fY - other.fX * fY)),
586 SkFloatToScalar((fX * other.fZ - other.fX * fZ) /
587 (other.fX * fY - fX * other.fY)));
tomhudson@google.com93813632011-10-27 20:21:16 +0000588 }
589 float fX, fY, fZ;
590 };
591
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000592 /**
593 * Sets the edge data required for edge antialiasing.
594 *
595 * @param edges 3 * numEdges float values, representing the edge
596 * equations in Ax + By + C form
597 */
598 void setEdgeAAData(const Edge* edges, int numEdges) {
599 GrAssert(numEdges <= GrDrawState::kMaxEdges);
600 memcpy(fEdgeAAEdges, edges, numEdges * sizeof(GrDrawState::Edge));
601 fEdgeAANumEdges = numEdges;
tomhudson@google.com93813632011-10-27 20:21:16 +0000602 }
603
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000604 int getNumAAEdges() const { return fEdgeAANumEdges; }
tomhudson@google.com93813632011-10-27 20:21:16 +0000605
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000606 const Edge* getAAEdges() const { return fEdgeAAEdges; }
tomhudson@google.com62b09682011-11-09 16:39:17 +0000607
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000608 /// @}
tomhudson@google.com62b09682011-11-09 16:39:17 +0000609
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000610 ///////////////////////////////////////////////////////////////////////////
611 /// @name State Flags
612 ////
tomhudson@google.com62b09682011-11-09 16:39:17 +0000613
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000614 /**
615 * Flags that affect rendering. Controlled using enable/disableState(). All
616 * default to disabled.
617 */
618 enum StateBits {
619 /**
620 * Perform dithering. TODO: Re-evaluate whether we need this bit
621 */
622 kDither_StateBit = 0x01,
623 /**
624 * Perform HW anti-aliasing. This means either HW FSAA, if supported
625 * by the render target, or smooth-line rendering if a line primitive
626 * is drawn and line smoothing is supported by the 3D API.
627 */
628 kHWAntialias_StateBit = 0x02,
629 /**
630 * Draws will respect the clip, otherwise the clip is ignored.
631 */
632 kClip_StateBit = 0x04,
633 /**
634 * Disables writing to the color buffer. Useful when performing stencil
635 * operations.
636 */
637 kNoColorWrites_StateBit = 0x08,
638 /**
639 * Modifies the behavior of edge AA specified by setEdgeAA. If set,
640 * will test edge pairs for convexity when rasterizing. Set this if the
641 * source polygon is non-convex.
642 */
643 kEdgeAAConcave_StateBit = 0x10,
senorblanco@chromium.org50bdad82012-01-03 20:51:57 +0000644 /**
645 * Draws will apply the color matrix, otherwise the color matrix is
646 * ignored.
647 */
648 kColorMatrix_StateBit = 0x20,
tomhudson@google.com62b09682011-11-09 16:39:17 +0000649
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000650 // Users of the class may add additional bits to the vector
651 kDummyStateBit,
652 kLastPublicStateBit = kDummyStateBit-1,
653 };
654
655 void resetStateFlags() {
656 fFlagBits = 0;
657 }
658
659 /**
660 * Enable render state settings.
661 *
662 * @param flags bitfield of StateBits specifing the states to enable
663 */
664 void enableState(uint32_t stateBits) {
665 fFlagBits |= stateBits;
666 }
667
668 /**
669 * Disable render state settings.
670 *
671 * @param flags bitfield of StateBits specifing the states to disable
672 */
673 void disableState(uint32_t stateBits) {
674 fFlagBits &= ~(stateBits);
675 }
676
677 bool isDitherState() const {
678 return 0 != (fFlagBits & kDither_StateBit);
679 }
680
681 bool isHWAntialiasState() const {
682 return 0 != (fFlagBits & kHWAntialias_StateBit);
683 }
684
685 bool isClipState() const {
686 return 0 != (fFlagBits & kClip_StateBit);
687 }
688
689 bool isColorWriteDisabled() const {
690 return 0 != (fFlagBits & kNoColorWrites_StateBit);
691 }
692
693 bool isConcaveEdgeAAState() const {
694 return 0 != (fFlagBits & kEdgeAAConcave_StateBit);
695 }
696
697 bool isStateFlagEnabled(uint32_t stateBit) const {
698 return 0 != (stateBit & fFlagBits);
699 }
700
701 void copyStateFlags(const GrDrawState& ds) {
702 fFlagBits = ds.fFlagBits;
703 }
704
705 /// @}
706
707 ///////////////////////////////////////////////////////////////////////////
708 /// @name Face Culling
709 ////
710
711 enum DrawFace {
712 kBoth_DrawFace,
713 kCCW_DrawFace,
714 kCW_DrawFace,
715 };
716
717 /**
718 * Controls whether clockwise, counterclockwise, or both faces are drawn.
719 * @param face the face(s) to draw.
720 */
721 void setDrawFace(DrawFace face) {
722 fDrawFace = face;
723 }
724
725 /**
726 * Gets whether the target is drawing clockwise, counterclockwise,
727 * or both faces.
728 * @return the current draw face(s).
729 */
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +0000730 DrawFace getDrawFace() const { return fDrawFace; }
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000731
732 /// @}
733
734 ///////////////////////////////////////////////////////////////////////////
tomhudson@google.com62b09682011-11-09 16:39:17 +0000735
bsalomon@google.com3d0835b2011-12-08 16:12:03 +0000736 // Most stages are usually not used, so conditionals here
737 // reduce the expected number of bytes touched by 50%.
738 bool operator ==(const GrDrawState& s) const {
739 if (memcmp(this, &s, this->leadingBytes())) return false;
740
741 for (int i = 0; i < kNumStages; i++) {
742 if (fTextures[i] &&
743 memcmp(&this->fSamplerStates[i], &s.fSamplerStates[i],
744 sizeof(GrSamplerState))) {
745 return false;
746 }
747 }
748
749 return true;
750 }
751 bool operator !=(const GrDrawState& s) const { return !(*this == s); }
752
753 // Most stages are usually not used, so conditionals here
754 // reduce the expected number of bytes touched by 50%.
755 GrDrawState& operator =(const GrDrawState& s) {
756 memcpy(this, &s, this->leadingBytes());
757
758 for (int i = 0; i < kNumStages; i++) {
759 if (s.fTextures[i]) {
760 memcpy(&this->fSamplerStates[i], &s.fSamplerStates[i],
761 sizeof(GrSamplerState));
762 }
763 }
764
765 return *this;
766 }
767
768private:
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000769 static const StageMask kIllegalStageMaskBits = ~((1 << kNumStages)-1);
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +0000770 // @{ these fields can be initialized with memset to 0
771 GrColor fBlendConstant;
772 GrTexture* fTextures[kNumStages];
773 GrColor fColorFilterColor;
774 uint32_t fFlagBits;
775 DrawFace fDrawFace;
776 VertexEdgeType fVertexEdgeType;
777 GrStencilSettings fStencilSettings;
778 float fColorMatrix[20]; // 5 x 4 matrix
779 GrRenderTarget* fRenderTarget;
780 // @}
781
782 // @{ Initialized to values other than zero
783 GrColor fColor;
bsalomon@google.com2401ae82012-01-17 21:03:05 +0000784 GrColor fCoverage;
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +0000785 int fFirstCoverageStage;
786 SkXfermode::Mode fColorFilterMode;
787 GrBlendCoeff fSrcBlend;
788 GrBlendCoeff fDstBlend;
789 GrMatrix fViewMatrix;
790 // @}
791
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000792 // @{ Data for GrTesselatedPathRenderer
793 // TODO: currently ignored in copying & comparison for performance.
794 // Must be considered if GrTesselatedPathRenderer is being used.
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +0000795 int fEdgeAANumEdges;
796 Edge fEdgeAAEdges[kMaxEdges];
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000797 // @}
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +0000798
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000799 // This field must be last; it will not be copied or compared
800 // if the corresponding fTexture[] is NULL.
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +0000801 GrSamplerState fSamplerStates[kNumStages];
bsalomon@google.com8f9cbd62011-12-09 15:55:34 +0000802
tomhudson@google.com62b09682011-11-09 16:39:17 +0000803 size_t leadingBytes() const {
804 // Can't use offsetof() with non-POD types, so stuck with pointer math.
805 // TODO: ignores GrTesselatedPathRenderer data structures. We don't
806 // have a compile-time flag that lets us know if it's being used, and
807 // checking at runtime seems to cost 5% performance.
808 return (size_t) ((unsigned char*)&fEdgeAANumEdges -
bsalomon@google.com52a5dcb2012-01-17 16:01:37 +0000809 (unsigned char*)&fBlendConstant);
tomhudson@google.com62b09682011-11-09 16:39:17 +0000810 }
811
tomhudson@google.com93813632011-10-27 20:21:16 +0000812};
813
814#endif