• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
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"
13 #include "GrNoncopyable.h"
14 #include "GrSamplerState.h"
15 #include "GrStencil.h"
16 
17 #include "SkXfermode.h"
18 
19 class GrRenderTarget;
20 class GrTexture;
21 
22 struct 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 
43     /**
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 
GrDrawStateGrDrawState49     GrDrawState() {
50         this->reset();
51     }
52 
GrDrawStateGrDrawState53     GrDrawState(const GrDrawState& state) {
54         *this = state;
55     }
56 
57     /**
58      * Resets to the default state. Sampler states will not be modified.
59      */
resetGrDrawState60     void reset() {
61         // make sure any pad is zero for memcmp
62         // all GrDrawState members should default to something valid by the
63         // the memset except those initialized individually below. There should
64         // be no padding between the individually initialized members.
65         static const size_t kMemsetSize =
66             reinterpret_cast<intptr_t>(&fColor) -
67             reinterpret_cast<intptr_t>(this);
68         memset(this, 0, kMemsetSize);
69         // pedantic assertion that our ptrs will
70         // be NULL (0 ptr is mem addr 0)
71         GrAssert((intptr_t)(void*)NULL == 0LL);
72         GR_STATIC_ASSERT(0 == kBoth_DrawFace);
73         GrAssert(fStencilSettings.isDisabled());
74 
75         // memset exceptions
76         fColor = 0xffffffff;
77         fCoverage = 0xffffffff;
78         fFirstCoverageStage = kNumStages;
79         fColorFilterMode = SkXfermode::kDst_Mode;
80         fSrcBlend = kOne_BlendCoeff;
81         fDstBlend = kZero_BlendCoeff;
82         fViewMatrix.reset();
83 
84         // ensure values that will be memcmp'ed in == but not memset in reset()
85         // are tightly packed
86         GrAssert(kMemsetSize +  sizeof(fColor) + sizeof(fCoverage) +
87                  sizeof(fFirstCoverageStage) + sizeof(fColorFilterMode) +
88                  sizeof(fSrcBlend) + sizeof(fDstBlend) + sizeof(GrMatrix) ==
89                  reinterpret_cast<intptr_t>(&fEdgeAANumEdges) -
90                  reinterpret_cast<intptr_t>(this));
91 
92         fEdgeAANumEdges = 0;
93     }
94 
95     ///////////////////////////////////////////////////////////////////////////
96     /// @name Color
97     ////
98 
99     /**
100      *  Sets color for next draw to a premultiplied-alpha color.
101      *
102      *  @param color    the color to set.
103      */
setColorGrDrawState104     void setColor(GrColor color) { fColor = color; }
105 
getColorGrDrawState106     GrColor getColor() const { return fColor; }
107 
108     /**
109      *  Sets the color to be used for the next draw to be
110      *  (r,g,b,a) = (alpha, alpha, alpha, alpha).
111      *
112      *  @param alpha The alpha value to set as the color.
113      */
setAlphaGrDrawState114     void setAlpha(uint8_t a) {
115         this->setColor((a << 24) | (a << 16) | (a << 8) | a);
116     }
117 
118     /**
119      * Add a color filter that can be represented by a color and a mode. Applied
120      * after color-computing texture stages.
121      */
setColorFilterGrDrawState122     void setColorFilter(GrColor c, SkXfermode::Mode mode) {
123         fColorFilterColor = c;
124         fColorFilterMode = mode;
125     }
126 
getColorFilterColorGrDrawState127     GrColor getColorFilterColor() const { return fColorFilterColor; }
getColorFilterModeGrDrawState128     SkXfermode::Mode getColorFilterMode() const { return fColorFilterMode; }
129 
130     /// @}
131 
132     ///////////////////////////////////////////////////////////////////////////
133     /// @name Coverage
134     ////
135 
136     /**
137      * Sets a constant fractional coverage to be applied to the draw. The
138      * initial value (after construction or reset()) is 0xff. The constant
139      * coverage is ignored when per-vertex coverage is provided.
140      */
setCoverageGrDrawState141     void setCoverage(uint8_t coverage) {
142         fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage);
143     }
144 
145     /**
146      * Version of above that specifies 4 channel per-vertex color. The value
147      * should be premultiplied.
148      */
setCoverage4GrDrawState149     void setCoverage4(GrColor coverage) {
150         fCoverage = coverage;
151     }
152 
getCoverageGrDrawState153     GrColor getCoverage() const {
154         return fCoverage;
155     }
156 
157     /// @}
158 
159     ///////////////////////////////////////////////////////////////////////////
160     /// @name Textures
161     ////
162 
163     /**
164      * Sets the texture used at the next drawing call
165      *
166      * @param stage The texture stage for which the texture will be set
167      *
168      * @param texture The texture to set. Can be NULL though there is no
169      * advantage to settings a NULL texture if doing non-textured drawing
170      */
setTextureGrDrawState171     void setTexture(int stage, GrTexture* texture) {
172         GrAssert((unsigned)stage < kNumStages);
173         fTextures[stage] = texture;
174     }
175 
176     /**
177      * Retrieves the currently set texture.
178      *
179      * @return    The currently set texture. The return value will be NULL if no
180      *            texture has been set, NULL was most recently passed to
181      *            setTexture, or the last setTexture was destroyed.
182      */
getTextureGrDrawState183     const GrTexture* getTexture(int stage) const {
184         GrAssert((unsigned)stage < kNumStages);
185         return fTextures[stage];
186     }
getTextureGrDrawState187     GrTexture* getTexture(int stage) {
188         GrAssert((unsigned)stage < kNumStages);
189         return fTextures[stage];
190     }
191 
192     /// @}
193 
194     ///////////////////////////////////////////////////////////////////////////
195     /// @name Samplers
196     ////
197 
198     /**
199      * Returns the current sampler for a stage.
200      */
getSamplerGrDrawState201     const GrSamplerState& getSampler(int stage) const {
202         GrAssert((unsigned)stage < kNumStages);
203         return fSamplerStates[stage];
204     }
205 
206     /**
207      * Writable pointer to a stage's sampler.
208      */
samplerGrDrawState209     GrSamplerState* sampler(int stage) {
210         GrAssert((unsigned)stage < kNumStages);
211         return fSamplerStates + stage;
212     }
213 
214     /**
215      * Preconcats the matrix of all samplers in the mask with the same matrix.
216      */
preConcatSamplerMatricesGrDrawState217     void preConcatSamplerMatrices(StageMask stageMask, const GrMatrix& matrix) {
218         GrAssert(!(stageMask & kIllegalStageMaskBits));
219         for (int i = 0; i < kNumStages; ++i) {
220             if ((1 << i) & stageMask) {
221                 fSamplerStates[i].preConcatMatrix(matrix);
222             }
223         }
224     }
225 
226     /// @}
227 
228     ///////////////////////////////////////////////////////////////////////////
229     /// @name Coverage / Color Stages
230     ////
231 
232     /**
233      * A common pattern is to compute a color with the initial stages and then
234      * modulate that color by a coverage value in later stage(s) (AA, mask-
235      * filters, glyph mask, etc). Color-filters, xfermodes, etc should be
236      * computed based on the pre-coverage-modulated color. The division of
237      * stages between color-computing and coverage-computing is specified by
238      * this method. Initially this is kNumStages (all stages
239      * are color-computing).
240      */
setFirstCoverageStageGrDrawState241     void setFirstCoverageStage(int firstCoverageStage) {
242         GrAssert((unsigned)firstCoverageStage <= kNumStages);
243         fFirstCoverageStage = firstCoverageStage;
244     }
245 
246     /**
247      * Gets the index of the first coverage-computing stage.
248      */
getFirstCoverageStageGrDrawState249     int getFirstCoverageStage() const {
250         return fFirstCoverageStage;
251     }
252 
253     ///@}
254 
255     ///////////////////////////////////////////////////////////////////////////
256     /// @name Blending
257     ////
258 
259     /**
260      * Sets the blending function coeffecients.
261      *
262      * The blend function will be:
263      *    D' = sat(S*srcCoef + D*dstCoef)
264      *
265      *   where D is the existing destination color, S is the incoming source
266      *   color, and D' is the new destination color that will be written. sat()
267      *   is the saturation function.
268      *
269      * @param srcCoef coeffecient applied to the src color.
270      * @param dstCoef coeffecient applied to the dst color.
271      */
setBlendFuncGrDrawState272     void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
273         fSrcBlend = srcCoeff;
274         fDstBlend = dstCoeff;
275     #if GR_DEBUG
276         switch (dstCoeff) {
277         case kDC_BlendCoeff:
278         case kIDC_BlendCoeff:
279         case kDA_BlendCoeff:
280         case kIDA_BlendCoeff:
281             GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
282                      "coverage stages.\n");
283             break;
284         default:
285             break;
286         }
287         switch (srcCoeff) {
288         case kSC_BlendCoeff:
289         case kISC_BlendCoeff:
290         case kSA_BlendCoeff:
291         case kISA_BlendCoeff:
292             GrPrintf("Unexpected src blend coeff. Won't work correctly with"
293                      "coverage stages.\n");
294             break;
295         default:
296             break;
297         }
298     #endif
299     }
300 
getSrcBlendCoeffGrDrawState301     GrBlendCoeff getSrcBlendCoeff() const { return fSrcBlend; }
getDstBlendCoeffGrDrawState302     GrBlendCoeff getDstBlendCoeff() const { return fDstBlend; }
303 
getDstBlendCoeffGrDrawState304     void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff,
305                           GrBlendCoeff* dstBlendCoeff) const {
306         *srcBlendCoeff = fSrcBlend;
307         *dstBlendCoeff = fDstBlend;
308     }
309 
310     /**
311      * Sets the blending function constant referenced by the following blending
312      * coeffecients:
313      *      kConstC_BlendCoeff
314      *      kIConstC_BlendCoeff
315      *      kConstA_BlendCoeff
316      *      kIConstA_BlendCoeff
317      *
318      * @param constant the constant to set
319      */
setBlendConstantGrDrawState320     void setBlendConstant(GrColor constant) { fBlendConstant = constant; }
321 
322     /**
323      * Retrieves the last value set by setBlendConstant()
324      * @return the blending constant value
325      */
getBlendConstantGrDrawState326     GrColor getBlendConstant() const { return fBlendConstant; }
327 
328     /// @}
329 
330     ///////////////////////////////////////////////////////////////////////////
331     /// @name View Matrix
332     ////
333 
334     /**
335      * Sets the matrix applied to veretx positions.
336      *
337      * In the post-view-matrix space the rectangle [0,w]x[0,h]
338      * fully covers the render target. (w and h are the width and height of the
339      * the rendertarget.)
340      */
setViewMatrixGrDrawState341     void setViewMatrix(const GrMatrix& m) { fViewMatrix = m; }
342 
343     /**
344      * Gets a writable pointer to the view matrix.
345      */
viewMatrixGrDrawState346     GrMatrix* viewMatrix() { return &fViewMatrix; }
347 
348     /**
349      *  Multiplies the current view matrix by a matrix
350      *
351      *  After this call V' = V*m where V is the old view matrix,
352      *  m is the parameter to this function, and V' is the new view matrix.
353      *  (We consider positions to be column vectors so position vector p is
354      *  transformed by matrix X as p' = X*p.)
355      *
356      *  @param m the matrix used to modify the view matrix.
357      */
preConcatViewMatrixGrDrawState358     void preConcatViewMatrix(const GrMatrix& m) { fViewMatrix.preConcat(m); }
359 
360     /**
361      *  Multiplies the current view matrix by a matrix
362      *
363      *  After this call V' = m*V where V is the old view matrix,
364      *  m is the parameter to this function, and V' is the new view matrix.
365      *  (We consider positions to be column vectors so position vector p is
366      *  transformed by matrix X as p' = X*p.)
367      *
368      *  @param m the matrix used to modify the view matrix.
369      */
postConcatViewMatrixGrDrawState370     void postConcatViewMatrix(const GrMatrix& m) { fViewMatrix.postConcat(m); }
371 
372     /**
373      * Retrieves the current view matrix
374      * @return the current view matrix.
375      */
getViewMatrixGrDrawState376     const GrMatrix& getViewMatrix() const { return fViewMatrix; }
377 
378     /**
379      *  Retrieves the inverse of the current view matrix.
380      *
381      *  If the current view matrix is invertible, return true, and if matrix
382      *  is non-null, copy the inverse into it. If the current view matrix is
383      *  non-invertible, return false and ignore the matrix parameter.
384      *
385      * @param matrix if not null, will receive a copy of the current inverse.
386      */
getViewInverseGrDrawState387     bool getViewInverse(GrMatrix* matrix) const {
388         // TODO: determine whether we really need to leave matrix unmodified
389         // at call sites when inversion fails.
390         GrMatrix inverse;
391         if (fViewMatrix.invert(&inverse)) {
392             if (matrix) {
393                 *matrix = inverse;
394             }
395             return true;
396         }
397         return false;
398     }
399 
400     class AutoViewMatrixRestore : public ::GrNoncopyable {
401     public:
AutoViewMatrixRestoreGrDrawState402         AutoViewMatrixRestore() : fDrawState(NULL) {}
AutoViewMatrixRestoreGrDrawState403         AutoViewMatrixRestore(GrDrawState* ds, const GrMatrix& newMatrix) {
404             fDrawState = NULL;
405             this->set(ds, newMatrix);
406         }
AutoViewMatrixRestoreGrDrawState407         AutoViewMatrixRestore(GrDrawState* ds) {
408             fDrawState = NULL;
409             this->set(ds);
410         }
~AutoViewMatrixRestoreGrDrawState411         ~AutoViewMatrixRestore() {
412             this->set(NULL, GrMatrix::I());
413         }
setGrDrawState414         void set(GrDrawState* ds, const GrMatrix& newMatrix) {
415             if (NULL != fDrawState) {
416                 fDrawState->setViewMatrix(fSavedMatrix);
417             }
418             if (NULL != ds) {
419                 fSavedMatrix = ds->getViewMatrix();
420                 ds->setViewMatrix(newMatrix);
421             }
422             fDrawState = ds;
423         }
setGrDrawState424         void set(GrDrawState* ds) {
425             if (NULL != fDrawState) {
426                 fDrawState->setViewMatrix(fSavedMatrix);
427             }
428             if (NULL != ds) {
429                 fSavedMatrix = ds->getViewMatrix();
430             }
431             fDrawState = ds;
432         }
433     private:
434         GrDrawState* fDrawState;
435         GrMatrix fSavedMatrix;
436     };
437 
438     /// @}
439 
440     ///////////////////////////////////////////////////////////////////////////
441     /// @name Render Target
442     ////
443 
444     /**
445      * Sets the rendertarget used at the next drawing call
446      *
447      * @param target  The render target to set.
448      */
setRenderTargetGrDrawState449     void setRenderTarget(GrRenderTarget* target) { fRenderTarget = target; }
450 
451     /**
452      * Retrieves the currently set rendertarget.
453      *
454      * @return    The currently set render target.
455      */
getRenderTargetGrDrawState456     const GrRenderTarget* getRenderTarget() const { return fRenderTarget; }
getRenderTargetGrDrawState457     GrRenderTarget* getRenderTarget() { return fRenderTarget; }
458 
459     class AutoRenderTargetRestore : public ::GrNoncopyable {
460     public:
AutoRenderTargetRestoreGrDrawState461         AutoRenderTargetRestore() : fDrawState(NULL), fSavedTarget(NULL) {}
AutoRenderTargetRestoreGrDrawState462         AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) {
463             fDrawState = NULL;
464             this->set(ds, newTarget);
465         }
~AutoRenderTargetRestoreGrDrawState466         ~AutoRenderTargetRestore() { this->set(NULL, NULL); }
setGrDrawState467         void set(GrDrawState* ds, GrRenderTarget* newTarget) {
468             if (NULL != fDrawState) {
469                 fDrawState->setRenderTarget(fSavedTarget);
470             }
471             if (NULL != ds) {
472                 fSavedTarget = ds->getRenderTarget();
473                 ds->setRenderTarget(newTarget);
474             }
475             fDrawState = ds;
476         }
477     private:
478         GrDrawState* fDrawState;
479         GrRenderTarget* fSavedTarget;
480     };
481 
482     /// @}
483 
484     ///////////////////////////////////////////////////////////////////////////
485     /// @name Stencil
486     ////
487 
488     /**
489      * Sets the stencil settings to use for the next draw.
490      * Changing the clip has the side-effect of possibly zeroing
491      * out the client settable stencil bits. So multipass algorithms
492      * using stencil should not change the clip between passes.
493      * @param settings  the stencil settings to use.
494      */
setStencilGrDrawState495     void setStencil(const GrStencilSettings& settings) {
496         fStencilSettings = settings;
497     }
498 
499     /**
500      * Shortcut to disable stencil testing and ops.
501      */
disableStencilGrDrawState502     void disableStencil() {
503         fStencilSettings.setDisabled();
504     }
505 
getStencilGrDrawState506     const GrStencilSettings& getStencil() const { return fStencilSettings; }
507 
stencilGrDrawState508     GrStencilSettings* stencil() { return &fStencilSettings; }
509 
510     /// @}
511 
512     ///////////////////////////////////////////////////////////////////////////
513     /// @name Color Matrix
514     ////
515 
516     /**
517      * Sets the color matrix to use for the next draw.
518      * @param matrix  the 5x4 matrix to apply to the incoming color
519      */
setColorMatrixGrDrawState520     void setColorMatrix(const float matrix[20]) {
521         memcpy(fColorMatrix, matrix, sizeof(fColorMatrix));
522     }
523 
getColorMatrixGrDrawState524     const float* getColorMatrix() const { return fColorMatrix; }
525 
526     /// @}
527 
528     ///////////////////////////////////////////////////////////////////////////
529     // @name Edge AA
530     // There are two ways to perform antialiasing using edge equations. One
531     // is to specify an (linear or quadratic) edge eq per-vertex. This requires
532     // splitting vertices shared by primitives.
533     //
534     // The other is via setEdgeAAData which sets a set of edges and each
535     // is tested against all the edges.
536     ////
537 
538     /**
539      * When specifying edges as vertex data this enum specifies what type of
540      * edges are in use. The edges are always 4 GrScalars in memory, even when
541      * the edge type requires fewer than 4.
542      */
543     enum VertexEdgeType {
544         /* 1-pixel wide line
545            2D implicit line eq (a*x + b*y +c = 0). 4th component unused */
546         kHairLine_EdgeType,
547         /* Quadratic specified by u^2-v canonical coords (only 2
548            components used). Coverage based on signed distance with negative
549            being inside, positive outside.*/
550         kQuad_EdgeType,
551         /* Same as above but for hairline quadratics. Uses unsigned distance.
552            Coverage is min(0, 1-distance). */
553         kHairQuad_EdgeType,
554 
555         kVertexEdgeTypeCnt
556     };
557 
558     /**
559      * Determines the interpretation per-vertex edge data when the
560      * kEdge_VertexLayoutBit is set (see GrDrawTarget). When per-vertex edges
561      * are not specified the value of this setting has no effect.
562      */
setVertexEdgeTypeGrDrawState563     void setVertexEdgeType(VertexEdgeType type) {
564         GrAssert(type >=0 && type < kVertexEdgeTypeCnt);
565         fVertexEdgeType = type;
566     }
567 
getVertexEdgeTypeGrDrawState568     VertexEdgeType getVertexEdgeType() const { return fVertexEdgeType; }
569 
570     /**
571      * The absolute maximum number of edges that may be specified for
572      * a single draw call when performing edge antialiasing.  This is used for
573      * the size of several static buffers, so implementations of getMaxEdges()
574      * (below) should clamp to this value.
575      */
576     enum {
577         // TODO: this should be 32 when GrTesselatedPathRenderer is used
578         // Visual Studio 2010 does not permit a member array of size 0.
579         kMaxEdges = 1
580     };
581 
582     class Edge {
583       public:
EdgeGrDrawState584         Edge() {}
EdgeGrDrawState585         Edge(float x, float y, float z) : fX(x), fY(y), fZ(z) {}
intersectGrDrawState586         GrPoint intersect(const Edge& other) {
587             return GrPoint::Make(
588                 SkFloatToScalar((fY * other.fZ - other.fY * fZ) /
589                                 (fX * other.fY - other.fX * fY)),
590                 SkFloatToScalar((fX * other.fZ - other.fX * fZ) /
591                                 (other.fX * fY - fX * other.fY)));
592         }
593         float fX, fY, fZ;
594     };
595 
596     /**
597      * Sets the edge data required for edge antialiasing.
598      *
599      * @param edges       3 * numEdges float values, representing the edge
600      *                    equations in Ax + By + C form
601      */
setEdgeAADataGrDrawState602     void setEdgeAAData(const Edge* edges, int numEdges) {
603         GrAssert(numEdges <= GrDrawState::kMaxEdges);
604         memcpy(fEdgeAAEdges, edges, numEdges * sizeof(GrDrawState::Edge));
605         fEdgeAANumEdges = numEdges;
606     }
607 
getNumAAEdgesGrDrawState608     int getNumAAEdges() const { return fEdgeAANumEdges; }
609 
getAAEdgesGrDrawState610     const Edge* getAAEdges() const { return fEdgeAAEdges; }
611 
612     /// @}
613 
614     ///////////////////////////////////////////////////////////////////////////
615     /// @name State Flags
616     ////
617 
618     /**
619      *  Flags that affect rendering. Controlled using enable/disableState(). All
620      *  default to disabled.
621      */
622     enum StateBits {
623         /**
624          * Perform dithering. TODO: Re-evaluate whether we need this bit
625          */
626         kDither_StateBit        = 0x01,
627         /**
628          * Perform HW anti-aliasing. This means either HW FSAA, if supported
629          * by the render target, or smooth-line rendering if a line primitive
630          * is drawn and line smoothing is supported by the 3D API.
631          */
632         kHWAntialias_StateBit   = 0x02,
633         /**
634          * Draws will respect the clip, otherwise the clip is ignored.
635          */
636         kClip_StateBit          = 0x04,
637         /**
638          * Disables writing to the color buffer. Useful when performing stencil
639          * operations.
640          */
641         kNoColorWrites_StateBit = 0x08,
642         /**
643          * Modifies the behavior of edge AA specified by setEdgeAA. If set,
644          * will test edge pairs for convexity when rasterizing. Set this if the
645          * source polygon is non-convex.
646          */
647         kEdgeAAConcave_StateBit = 0x10,
648         /**
649          * Draws will apply the color matrix, otherwise the color matrix is
650          * ignored.
651          */
652         kColorMatrix_StateBit   = 0x20,
653 
654         // Users of the class may add additional bits to the vector
655         kDummyStateBit,
656         kLastPublicStateBit = kDummyStateBit-1,
657     };
658 
resetStateFlagsGrDrawState659     void resetStateFlags() {
660         fFlagBits = 0;
661     }
662 
663     /**
664      * Enable render state settings.
665      *
666      * @param flags   bitfield of StateBits specifing the states to enable
667      */
enableStateGrDrawState668     void enableState(uint32_t stateBits) {
669         fFlagBits |= stateBits;
670     }
671 
672     /**
673      * Disable render state settings.
674      *
675      * @param flags   bitfield of StateBits specifing the states to disable
676      */
disableStateGrDrawState677     void disableState(uint32_t stateBits) {
678         fFlagBits &= ~(stateBits);
679     }
680 
isDitherStateGrDrawState681     bool isDitherState() const {
682         return 0 != (fFlagBits & kDither_StateBit);
683     }
684 
isHWAntialiasStateGrDrawState685     bool isHWAntialiasState() const {
686         return 0 != (fFlagBits & kHWAntialias_StateBit);
687     }
688 
isClipStateGrDrawState689     bool isClipState() const {
690         return 0 != (fFlagBits & kClip_StateBit);
691     }
692 
isColorWriteDisabledGrDrawState693     bool isColorWriteDisabled() const {
694         return 0 != (fFlagBits & kNoColorWrites_StateBit);
695     }
696 
isConcaveEdgeAAStateGrDrawState697     bool isConcaveEdgeAAState() const {
698         return 0 != (fFlagBits & kEdgeAAConcave_StateBit);
699     }
700 
isStateFlagEnabledGrDrawState701     bool isStateFlagEnabled(uint32_t stateBit) const {
702         return 0 != (stateBit & fFlagBits);
703     }
704 
copyStateFlagsGrDrawState705     void copyStateFlags(const GrDrawState& ds) {
706         fFlagBits = ds.fFlagBits;
707     }
708 
709     /// @}
710 
711     ///////////////////////////////////////////////////////////////////////////
712     /// @name Face Culling
713     ////
714 
715     enum DrawFace {
716         kBoth_DrawFace,
717         kCCW_DrawFace,
718         kCW_DrawFace,
719     };
720 
721     /**
722      * Controls whether clockwise, counterclockwise, or both faces are drawn.
723      * @param face  the face(s) to draw.
724      */
setDrawFaceGrDrawState725     void setDrawFace(DrawFace face) {
726         fDrawFace = face;
727     }
728 
729     /**
730      * Gets whether the target is drawing clockwise, counterclockwise,
731      * or both faces.
732      * @return the current draw face(s).
733      */
getDrawFaceGrDrawState734     DrawFace getDrawFace() const { return fDrawFace; }
735 
736     /// @}
737 
738     ///////////////////////////////////////////////////////////////////////////
739 
740     // Most stages are usually not used, so conditionals here
741     // reduce the expected number of bytes touched by 50%.
742     bool operator ==(const GrDrawState& s) const {
743         if (memcmp(this, &s, this->leadingBytes())) return false;
744 
745         for (int i = 0; i < kNumStages; i++) {
746             if (fTextures[i] &&
747                 memcmp(&this->fSamplerStates[i], &s.fSamplerStates[i],
748                        sizeof(GrSamplerState))) {
749                 return false;
750             }
751         }
752 
753         return true;
754     }
755     bool operator !=(const GrDrawState& s) const { return !(*this == s); }
756 
757     // Most stages are usually not used, so conditionals here
758     // reduce the expected number of bytes touched by 50%.
759     GrDrawState& operator =(const GrDrawState& s) {
760         memcpy(this, &s, this->leadingBytes());
761 
762         for (int i = 0; i < kNumStages; i++) {
763             if (s.fTextures[i]) {
764                 memcpy(&this->fSamplerStates[i], &s.fSamplerStates[i],
765                        sizeof(GrSamplerState));
766             }
767         }
768 
769         return *this;
770     }
771 
772 private:
773     static const StageMask kIllegalStageMaskBits = ~((1 << kNumStages)-1);
774     // @{ these fields can be initialized with memset to 0
775     GrColor             fBlendConstant;
776     GrTexture*          fTextures[kNumStages];
777     GrColor             fColorFilterColor;
778     uint32_t            fFlagBits;
779     DrawFace            fDrawFace;
780     VertexEdgeType      fVertexEdgeType;
781     GrStencilSettings   fStencilSettings;
782     float               fColorMatrix[20];       // 5 x 4 matrix
783     GrRenderTarget*     fRenderTarget;
784     // @}
785 
786     // @{ Initialized to values other than zero
787     GrColor             fColor;
788     GrColor             fCoverage;
789     int                 fFirstCoverageStage;
790     SkXfermode::Mode    fColorFilterMode;
791     GrBlendCoeff        fSrcBlend;
792     GrBlendCoeff        fDstBlend;
793     GrMatrix            fViewMatrix;
794     // @}
795 
796     // @{ Data for GrTesselatedPathRenderer
797     // TODO: currently ignored in copying & comparison for performance.
798     // Must be considered if GrTesselatedPathRenderer is being used.
799     int                 fEdgeAANumEdges;
800     Edge                fEdgeAAEdges[kMaxEdges];
801     // @}
802 
803     // This field must be last; it will not be copied or compared
804     // if the corresponding fTexture[] is NULL.
805     GrSamplerState      fSamplerStates[kNumStages];
806 
leadingBytesGrDrawState807     size_t leadingBytes() const {
808         // Can't use offsetof() with non-POD types, so stuck with pointer math.
809         // TODO: ignores GrTesselatedPathRenderer data structures. We don't
810         // have a compile-time flag that lets us know if it's being used, and
811         // checking at runtime seems to cost 5% performance.
812         return (size_t) ((unsigned char*)&fEdgeAANumEdges -
813                          (unsigned char*)&fBlendConstant);
814     }
815 
816 };
817 
818 #endif
819