• 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 "GrBackendEffectFactory.h"
12 #include "GrBlend.h"
13 #include "GrColor.h"
14 #include "GrEffectStage.h"
15 #include "GrPaint.h"
16 #include "GrPoint.h"
17 #include "GrRenderTarget.h"
18 #include "GrStencil.h"
19 #include "GrTemplates.h"
20 #include "GrTexture.h"
21 #include "GrTypesPriv.h"
22 #include "effects/GrSimpleTextureEffect.h"
23 
24 #include "SkMatrix.h"
25 #include "SkTypes.h"
26 #include "SkXfermode.h"
27 
28 class GrDrawState : public SkRefCnt {
29 public:
SK_DECLARE_INST_COUNT(GrDrawState)30     SK_DECLARE_INST_COUNT(GrDrawState)
31 
32     GrDrawState() {
33         SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
34         this->reset();
35     }
36 
GrDrawState(const SkMatrix & initialViewMatrix)37     GrDrawState(const SkMatrix& initialViewMatrix) {
38         SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
39         this->reset(initialViewMatrix);
40     }
41 
42     /**
43      * Copies another draw state.
44      **/
GrDrawState(const GrDrawState & state)45     GrDrawState(const GrDrawState& state) : INHERITED() {
46         SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
47         *this = state;
48     }
49 
50     /**
51      * Copies another draw state with a preconcat to the view matrix.
52      **/
GrDrawState(const GrDrawState & state,const SkMatrix & preConcatMatrix)53     GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatrix) {
54         SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
55         *this = state;
56         if (!preConcatMatrix.isIdentity()) {
57             for (int i = 0; i < fColorStages.count(); ++i) {
58                 fColorStages[i].localCoordChange(preConcatMatrix);
59             }
60             for (int i = 0; i < fCoverageStages.count(); ++i) {
61                 fCoverageStages[i].localCoordChange(preConcatMatrix);
62             }
63         }
64     }
65 
~GrDrawState()66     virtual ~GrDrawState() { SkASSERT(0 == fBlockEffectRemovalCnt); }
67 
68     /**
69      * Resets to the default state. GrEffects will be removed from all stages.
70      */
reset()71     void reset() { this->onReset(NULL); }
72 
reset(const SkMatrix & initialViewMatrix)73     void reset(const SkMatrix& initialViewMatrix) { this->onReset(&initialViewMatrix); }
74 
75     /**
76      * Initializes the GrDrawState based on a GrPaint, view matrix and render target. Note that
77      * GrDrawState encompasses more than GrPaint. Aspects of GrDrawState that have no GrPaint
78      * equivalents are set to default values. Clipping will be enabled.
79      */
80     void setFromPaint(const GrPaint& , const SkMatrix& viewMatrix, GrRenderTarget*);
81 
82     ///////////////////////////////////////////////////////////////////////////
83     /// @name Vertex Attributes
84     ////
85 
86     enum {
87         kMaxVertexAttribCnt = kLast_GrVertexAttribBinding + 4,
88     };
89 
90    /**
91      * The format of vertices is represented as an array of GrVertexAttribs, with each representing
92      * the type of the attribute, its offset, and semantic binding (see GrVertexAttrib in
93      * GrTypesPriv.h).
94      *
95      * The mapping of attributes with kEffect bindings to GrEffect inputs is specified when
96      * setEffect is called.
97      */
98 
99     /**
100      *  Sets vertex attributes for next draw. The object driving the templatization
101      *  should be a global GrVertexAttrib array that is never changed.
102      */
setVertexAttribs(int count)103     template <const GrVertexAttrib A[]> void setVertexAttribs(int count) {
104         this->setVertexAttribs(A, count);
105     }
106 
getVertexAttribs()107     const GrVertexAttrib* getVertexAttribs() const { return fCommon.fVAPtr; }
getVertexAttribCount()108     int getVertexAttribCount() const { return fCommon.fVACount; }
109 
110     size_t getVertexSize() const;
111 
112     /**
113      *  Sets default vertex attributes for next draw. The default is a single attribute:
114      *  {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribType}
115      */
116     void setDefaultVertexAttribs();
117 
118     /**
119      * Getters for index into getVertexAttribs() for particular bindings. -1 is returned if the
120      * binding does not appear in the current attribs. These bindings should appear only once in
121      * the attrib array.
122      */
123 
positionAttributeIndex()124     int positionAttributeIndex() const {
125         return fCommon.fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding];
126     }
localCoordAttributeIndex()127     int localCoordAttributeIndex() const {
128         return fCommon.fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding];
129     }
colorVertexAttributeIndex()130     int colorVertexAttributeIndex() const {
131         return fCommon.fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding];
132     }
coverageVertexAttributeIndex()133     int coverageVertexAttributeIndex() const {
134         return fCommon.fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding];
135     }
136 
hasLocalCoordAttribute()137     bool hasLocalCoordAttribute() const {
138         return -1 != fCommon.fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding];
139     }
hasColorVertexAttribute()140     bool hasColorVertexAttribute() const {
141         return -1 != fCommon.fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding];
142     }
hasCoverageVertexAttribute()143     bool hasCoverageVertexAttribute() const {
144         return -1 != fCommon.fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding];
145     }
146 
147     bool validateVertexAttribs() const;
148 
149     /**
150      * Helper to save/restore vertex attribs
151      */
152      class AutoVertexAttribRestore {
153      public:
AutoVertexAttribRestore(GrDrawState * drawState)154          AutoVertexAttribRestore(GrDrawState* drawState) {
155              SkASSERT(NULL != drawState);
156              fDrawState = drawState;
157              fVAPtr = drawState->fCommon.fVAPtr;
158              fVACount = drawState->fCommon.fVACount;
159              fDrawState->setDefaultVertexAttribs();
160          }
161 
~AutoVertexAttribRestore()162          ~AutoVertexAttribRestore(){
163              fDrawState->setVertexAttribs(fVAPtr, fVACount);
164          }
165 
166      private:
167          GrDrawState*          fDrawState;
168          const GrVertexAttrib* fVAPtr;
169          int                   fVACount;
170      };
171 
172     /**
173      * Accessing positions, local coords, or colors, of a vertex within an array is a hassle
174      * involving casts and simple math. These helpers exist to keep GrDrawTarget clients' code a bit
175      * nicer looking.
176      */
177 
178     /**
179      * Gets a pointer to a GrPoint of a vertex's position or texture
180      * coordinate.
181      * @param vertices      the vertex array
182      * @param vertexIndex   the index of the vertex in the array
183      * @param vertexSize    the size of each vertex in the array
184      * @param offset        the offset in bytes of the vertex component.
185      *                      Defaults to zero (corresponding to vertex position)
186      * @return pointer to the vertex component as a GrPoint
187      */
188     static GrPoint* GetVertexPoint(void* vertices,
189                                    int vertexIndex,
190                                    int vertexSize,
191                                    int offset = 0) {
192         intptr_t start = GrTCast<intptr_t>(vertices);
193         return GrTCast<GrPoint*>(start + offset +
194                                  vertexIndex * vertexSize);
195     }
196     static const GrPoint* GetVertexPoint(const void* vertices,
197                                          int vertexIndex,
198                                          int vertexSize,
199                                          int offset = 0) {
200         intptr_t start = GrTCast<intptr_t>(vertices);
201         return GrTCast<const GrPoint*>(start + offset +
202                                        vertexIndex * vertexSize);
203     }
204 
205     /**
206      * Gets a pointer to a GrColor inside a vertex within a vertex array.
207      * @param vertices      the vetex array
208      * @param vertexIndex   the index of the vertex in the array
209      * @param vertexSize    the size of each vertex in the array
210      * @param offset        the offset in bytes of the vertex color
211      * @return pointer to the vertex component as a GrColor
212      */
GetVertexColor(void * vertices,int vertexIndex,int vertexSize,int offset)213     static GrColor* GetVertexColor(void* vertices,
214                                    int vertexIndex,
215                                    int vertexSize,
216                                    int offset) {
217         intptr_t start = GrTCast<intptr_t>(vertices);
218         return GrTCast<GrColor*>(start + offset +
219                                  vertexIndex * vertexSize);
220     }
GetVertexColor(const void * vertices,int vertexIndex,int vertexSize,int offset)221     static const GrColor* GetVertexColor(const void* vertices,
222                                          int vertexIndex,
223                                          int vertexSize,
224                                          int offset) {
225         const intptr_t start = GrTCast<intptr_t>(vertices);
226         return GrTCast<const GrColor*>(start + offset +
227                                        vertexIndex * vertexSize);
228     }
229 
230     /// @}
231 
232     /**
233      * Determines whether src alpha is guaranteed to be one for all src pixels
234      */
235     bool srcAlphaWillBeOne() const;
236 
237     /**
238      * Determines whether the output coverage is guaranteed to be one for all pixels hit by a draw.
239      */
240     bool hasSolidCoverage() const;
241 
242     /// @}
243 
244     ///////////////////////////////////////////////////////////////////////////
245     /// @name Color
246     ////
247 
248     /**
249      *  Sets color for next draw to a premultiplied-alpha color.
250      *
251      *  @param color    the color to set.
252      */
setColor(GrColor color)253     void setColor(GrColor color) { fCommon.fColor = color; }
254 
getColor()255     GrColor getColor() const { return fCommon.fColor; }
256 
257     /**
258      *  Sets the color to be used for the next draw to be
259      *  (r,g,b,a) = (alpha, alpha, alpha, alpha).
260      *
261      *  @param alpha The alpha value to set as the color.
262      */
setAlpha(uint8_t a)263     void setAlpha(uint8_t a) {
264         this->setColor((a << 24) | (a << 16) | (a << 8) | a);
265     }
266 
267     /**
268      * Constructor sets the color to be 'color' which is undone by the destructor.
269      */
270     class AutoColorRestore : public ::SkNoncopyable {
271     public:
AutoColorRestore()272         AutoColorRestore() : fDrawState(NULL), fOldColor(0) {}
273 
AutoColorRestore(GrDrawState * drawState,GrColor color)274         AutoColorRestore(GrDrawState* drawState, GrColor color) {
275             fDrawState = NULL;
276             this->set(drawState, color);
277         }
278 
reset()279         void reset() {
280             if (NULL != fDrawState) {
281                 fDrawState->setColor(fOldColor);
282                 fDrawState = NULL;
283             }
284         }
285 
set(GrDrawState * drawState,GrColor color)286         void set(GrDrawState* drawState, GrColor color) {
287             this->reset();
288             fDrawState = drawState;
289             fOldColor = fDrawState->getColor();
290             fDrawState->setColor(color);
291         }
292 
~AutoColorRestore()293         ~AutoColorRestore() { this->reset(); }
294     private:
295         GrDrawState*    fDrawState;
296         GrColor         fOldColor;
297     };
298 
299     /// @}
300 
301     ///////////////////////////////////////////////////////////////////////////
302     /// @name Coverage
303     ////
304 
305     /**
306      * Sets a constant fractional coverage to be applied to the draw. The
307      * initial value (after construction or reset()) is 0xff. The constant
308      * coverage is ignored when per-vertex coverage is provided.
309      */
setCoverage(uint8_t coverage)310     void setCoverage(uint8_t coverage) {
311         fCommon.fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage);
312     }
313 
getCoverage()314     uint8_t getCoverage() const {
315         return GrColorUnpackR(fCommon.fCoverage);
316     }
317 
getCoverageColor()318     GrColor getCoverageColor() const {
319         return fCommon.fCoverage;
320     }
321 
322     /// @}
323 
324     ///////////////////////////////////////////////////////////////////////////
325     /// @name Effect Stages
326     /// Each stage hosts a GrEffect. The effect produces an output color or coverage in the fragment
327     /// shader. Its inputs are the output from the previous stage as well as some variables
328     /// available to it in the fragment and vertex shader (e.g. the vertex position, the dst color,
329     /// the fragment position, local coordinates).
330     ///
331     /// The stages are divided into two sets, color-computing and coverage-computing. The final
332     /// color stage produces the final pixel color. The coverage-computing stages function exactly
333     /// as the color-computing but the output of the final coverage stage is treated as a fractional
334     /// pixel coverage rather than as input to the src/dst color blend step.
335     ///
336     /// The input color to the first color-stage is either the constant color or interpolated
337     /// per-vertex colors. The input to the first coverage stage is either a constant coverage
338     /// (usually full-coverage) or interpolated per-vertex coverage.
339     ///
340     /// See the documentation of kCoverageDrawing_StateBit for information about disabling the
341     /// the color / coverage distinction.
342     ////
343 
344     const GrEffectRef* addColorEffect(const GrEffectRef* effect, int attr0 = -1, int attr1 = -1) {
345         SkASSERT(NULL != effect);
346         SkNEW_APPEND_TO_TARRAY(&fColorStages, GrEffectStage, (effect, attr0, attr1));
347         return effect;
348     }
349 
350     const GrEffectRef* addCoverageEffect(const GrEffectRef* effect, int attr0 = -1, int attr1 = -1) {
351         SkASSERT(NULL != effect);
352         SkNEW_APPEND_TO_TARRAY(&fCoverageStages, GrEffectStage, (effect, attr0, attr1));
353         return effect;
354     }
355 
356     /**
357      * Creates a GrSimpleTextureEffect that uses local coords as texture coordinates.
358      */
addColorTextureEffect(GrTexture * texture,const SkMatrix & matrix)359     void addColorTextureEffect(GrTexture* texture, const SkMatrix& matrix) {
360         GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix);
361         this->addColorEffect(effect)->unref();
362     }
363 
addCoverageTextureEffect(GrTexture * texture,const SkMatrix & matrix)364     void addCoverageTextureEffect(GrTexture* texture, const SkMatrix& matrix) {
365         GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix);
366         this->addCoverageEffect(effect)->unref();
367     }
368 
addColorTextureEffect(GrTexture * texture,const SkMatrix & matrix,const GrTextureParams & params)369     void addColorTextureEffect(GrTexture* texture,
370                                const SkMatrix& matrix,
371                                const GrTextureParams& params) {
372         GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params);
373         this->addColorEffect(effect)->unref();
374     }
375 
addCoverageTextureEffect(GrTexture * texture,const SkMatrix & matrix,const GrTextureParams & params)376     void addCoverageTextureEffect(GrTexture* texture,
377                                   const SkMatrix& matrix,
378                                   const GrTextureParams& params) {
379         GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params);
380         this->addCoverageEffect(effect)->unref();
381     }
382 
383     /**
384      * When this object is destroyed it will remove any effects from the draw state that were added
385      * after its constructor.
386      */
387     class AutoRestoreEffects : public ::SkNoncopyable {
388     public:
AutoRestoreEffects()389         AutoRestoreEffects() : fDrawState(NULL), fColorEffectCnt(0), fCoverageEffectCnt(0) {}
390 
AutoRestoreEffects(GrDrawState * ds)391         AutoRestoreEffects(GrDrawState* ds) : fDrawState(NULL), fColorEffectCnt(0), fCoverageEffectCnt(0) {
392             this->set(ds);
393         }
394 
~AutoRestoreEffects()395         ~AutoRestoreEffects() { this->set(NULL); }
396 
set(GrDrawState * ds)397         void set(GrDrawState* ds) {
398             if (NULL != fDrawState) {
399                 int n = fDrawState->fColorStages.count() - fColorEffectCnt;
400                 SkASSERT(n >= 0);
401                 fDrawState->fColorStages.pop_back_n(n);
402                 n = fDrawState->fCoverageStages.count() - fCoverageEffectCnt;
403                 SkASSERT(n >= 0);
404                 fDrawState->fCoverageStages.pop_back_n(n);
405                 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;)
406             }
407             fDrawState = ds;
408             if (NULL != ds) {
409                 fColorEffectCnt = ds->fColorStages.count();
410                 fCoverageEffectCnt = ds->fCoverageStages.count();
411                 SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;)
412             }
413         }
414 
415     private:
416         GrDrawState* fDrawState;
417         int fColorEffectCnt;
418         int fCoverageEffectCnt;
419     };
420 
numColorStages()421     int numColorStages() const { return fColorStages.count(); }
numCoverageStages()422     int numCoverageStages() const { return fCoverageStages.count(); }
numTotalStages()423     int numTotalStages() const { return this->numColorStages() + this->numCoverageStages(); }
424 
getColorStage(int stageIdx)425     const GrEffectStage& getColorStage(int stageIdx) const { return fColorStages[stageIdx]; }
getCoverageStage(int stageIdx)426     const GrEffectStage& getCoverageStage(int stageIdx) const { return fCoverageStages[stageIdx]; }
427 
428     /**
429      * Checks whether any of the effects will read the dst pixel color.
430      */
431     bool willEffectReadDstColor() const;
432 
433     /// @}
434 
435     ///////////////////////////////////////////////////////////////////////////
436     /// @name Blending
437     ////
438 
439     /**
440      * Sets the blending function coefficients.
441      *
442      * The blend function will be:
443      *    D' = sat(S*srcCoef + D*dstCoef)
444      *
445      *   where D is the existing destination color, S is the incoming source
446      *   color, and D' is the new destination color that will be written. sat()
447      *   is the saturation function.
448      *
449      * @param srcCoef coefficient applied to the src color.
450      * @param dstCoef coefficient applied to the dst color.
451      */
setBlendFunc(GrBlendCoeff srcCoeff,GrBlendCoeff dstCoeff)452     void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
453         fCommon.fSrcBlend = srcCoeff;
454         fCommon.fDstBlend = dstCoeff;
455     #ifdef SK_DEBUG
456         if (GrBlendCoeffRefsDst(dstCoeff)) {
457             GrPrintf("Unexpected dst blend coeff. Won't work correctly with coverage stages.\n");
458         }
459         if (GrBlendCoeffRefsSrc(srcCoeff)) {
460             GrPrintf("Unexpected src blend coeff. Won't work correctly with coverage stages.\n");
461         }
462     #endif
463     }
464 
getSrcBlendCoeff()465     GrBlendCoeff getSrcBlendCoeff() const { return fCommon.fSrcBlend; }
getDstBlendCoeff()466     GrBlendCoeff getDstBlendCoeff() const { return fCommon.fDstBlend; }
467 
getDstBlendCoeff(GrBlendCoeff * srcBlendCoeff,GrBlendCoeff * dstBlendCoeff)468     void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff,
469                           GrBlendCoeff* dstBlendCoeff) const {
470         *srcBlendCoeff = fCommon.fSrcBlend;
471         *dstBlendCoeff = fCommon.fDstBlend;
472     }
473 
474     /**
475      * Sets the blending function constant referenced by the following blending
476      * coefficients:
477      *      kConstC_GrBlendCoeff
478      *      kIConstC_GrBlendCoeff
479      *      kConstA_GrBlendCoeff
480      *      kIConstA_GrBlendCoeff
481      *
482      * @param constant the constant to set
483      */
setBlendConstant(GrColor constant)484     void setBlendConstant(GrColor constant) { fCommon.fBlendConstant = constant; }
485 
486     /**
487      * Retrieves the last value set by setBlendConstant()
488      * @return the blending constant value
489      */
getBlendConstant()490     GrColor getBlendConstant() const { return fCommon.fBlendConstant; }
491 
492     /**
493      * Determines whether multiplying the computed per-pixel color by the pixel's fractional
494      * coverage before the blend will give the correct final destination color. In general it
495      * will not as coverage is applied after blending.
496      */
497     bool canTweakAlphaForCoverage() const;
498 
499     /**
500      * Optimizations for blending / coverage to that can be applied based on the current state.
501      */
502     enum BlendOptFlags {
503         /**
504          * No optimization
505          */
506         kNone_BlendOpt                  = 0,
507         /**
508          * Don't draw at all
509          */
510         kSkipDraw_BlendOptFlag          = 0x1,
511         /**
512          * Emit the src color, disable HW blending (replace dst with src)
513          */
514         kDisableBlend_BlendOptFlag      = 0x2,
515         /**
516          * The coverage value does not have to be computed separately from alpha, the the output
517          * color can be the modulation of the two.
518          */
519         kCoverageAsAlpha_BlendOptFlag   = 0x4,
520         /**
521          * Instead of emitting a src color, emit coverage in the alpha channel and r,g,b are
522          * "don't cares".
523          */
524         kEmitCoverage_BlendOptFlag      = 0x8,
525         /**
526          * Emit transparent black instead of the src color, no need to compute coverage.
527          */
528         kEmitTransBlack_BlendOptFlag    = 0x10,
529     };
530     GR_DECL_BITFIELD_OPS_FRIENDS(BlendOptFlags);
531 
532     /**
533      * Determines what optimizations can be applied based on the blend. The coefficients may have
534      * to be tweaked in order for the optimization to work. srcCoeff and dstCoeff are optional
535      * params that receive the tweaked coefficients. Normally the function looks at the current
536      * state to see if coverage is enabled. By setting forceCoverage the caller can speculatively
537      * determine the blend optimizations that would be used if there was partial pixel coverage.
538      *
539      * Subclasses of GrDrawTarget that actually draw (as opposed to those that just buffer for
540      * playback) must call this function and respect the flags that replace the output color.
541      */
542     BlendOptFlags getBlendOpts(bool forceCoverage = false,
543                                GrBlendCoeff* srcCoeff = NULL,
544                                GrBlendCoeff* dstCoeff = NULL) const;
545 
546     /// @}
547 
548     ///////////////////////////////////////////////////////////////////////////
549     /// @name View Matrix
550     ////
551 
552     /**
553      * Sets the view matrix to identity and updates any installed effects to compensate for the
554      * coord system change.
555      */
556     bool setIdentityViewMatrix();
557 
558     /**
559      * Retrieves the current view matrix
560      * @return the current view matrix.
561      */
getViewMatrix()562     const SkMatrix& getViewMatrix() const { return fCommon.fViewMatrix; }
563 
564     /**
565      *  Retrieves the inverse of the current view matrix.
566      *
567      *  If the current view matrix is invertible, return true, and if matrix
568      *  is non-null, copy the inverse into it. If the current view matrix is
569      *  non-invertible, return false and ignore the matrix parameter.
570      *
571      * @param matrix if not null, will receive a copy of the current inverse.
572      */
getViewInverse(SkMatrix * matrix)573     bool getViewInverse(SkMatrix* matrix) const {
574         // TODO: determine whether we really need to leave matrix unmodified
575         // at call sites when inversion fails.
576         SkMatrix inverse;
577         if (fCommon.fViewMatrix.invert(&inverse)) {
578             if (matrix) {
579                 *matrix = inverse;
580             }
581             return true;
582         }
583         return false;
584     }
585 
586     ////////////////////////////////////////////////////////////////////////////
587 
588     /**
589      * Preconcats the current view matrix and restores the previous view matrix in the destructor.
590      * Effect matrices are automatically adjusted to compensate and adjusted back in the destructor.
591      */
592     class AutoViewMatrixRestore : public ::SkNoncopyable {
593     public:
AutoViewMatrixRestore()594         AutoViewMatrixRestore() : fDrawState(NULL) {}
595 
AutoViewMatrixRestore(GrDrawState * ds,const SkMatrix & preconcatMatrix)596         AutoViewMatrixRestore(GrDrawState* ds, const SkMatrix& preconcatMatrix) {
597             fDrawState = NULL;
598             this->set(ds, preconcatMatrix);
599         }
600 
~AutoViewMatrixRestore()601         ~AutoViewMatrixRestore() { this->restore(); }
602 
603         /**
604          * Can be called prior to destructor to restore the original matrix.
605          */
606         void restore();
607 
608         void set(GrDrawState* drawState, const SkMatrix& preconcatMatrix);
609 
610         /** Sets the draw state's matrix to identity. This can fail because the current view matrix
611             is not invertible. */
612         bool setIdentity(GrDrawState* drawState);
613 
614     private:
615         void doEffectCoordChanges(const SkMatrix& coordChangeMatrix);
616 
617         GrDrawState*                                        fDrawState;
618         SkMatrix                                            fViewMatrix;
619         int                                                 fNumColorStages;
620         SkAutoSTArray<8, GrEffectStage::SavedCoordChange>   fSavedCoordChanges;
621     };
622 
623     /// @}
624 
625     ///////////////////////////////////////////////////////////////////////////
626     /// @name Render Target
627     ////
628 
629     /**
630      * Sets the render-target used at the next drawing call
631      *
632      * @param target  The render target to set.
633      */
setRenderTarget(GrRenderTarget * target)634     void setRenderTarget(GrRenderTarget* target) {
635         fRenderTarget.reset(SkSafeRef(target));
636     }
637 
638     /**
639      * Retrieves the currently set render-target.
640      *
641      * @return    The currently set render target.
642      */
getRenderTarget()643     const GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
getRenderTarget()644     GrRenderTarget* getRenderTarget() { return fRenderTarget.get(); }
645 
646     class AutoRenderTargetRestore : public ::SkNoncopyable {
647     public:
AutoRenderTargetRestore()648         AutoRenderTargetRestore() : fDrawState(NULL), fSavedTarget(NULL) {}
AutoRenderTargetRestore(GrDrawState * ds,GrRenderTarget * newTarget)649         AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) {
650             fDrawState = NULL;
651             fSavedTarget = NULL;
652             this->set(ds, newTarget);
653         }
~AutoRenderTargetRestore()654         ~AutoRenderTargetRestore() { this->restore(); }
655 
restore()656         void restore() {
657             if (NULL != fDrawState) {
658                 fDrawState->setRenderTarget(fSavedTarget);
659                 fDrawState = NULL;
660             }
661             SkSafeSetNull(fSavedTarget);
662         }
663 
set(GrDrawState * ds,GrRenderTarget * newTarget)664         void set(GrDrawState* ds, GrRenderTarget* newTarget) {
665             this->restore();
666 
667             if (NULL != ds) {
668                 SkASSERT(NULL == fSavedTarget);
669                 fSavedTarget = ds->getRenderTarget();
670                 SkSafeRef(fSavedTarget);
671                 ds->setRenderTarget(newTarget);
672                 fDrawState = ds;
673             }
674         }
675     private:
676         GrDrawState* fDrawState;
677         GrRenderTarget* fSavedTarget;
678     };
679 
680     /// @}
681 
682     ///////////////////////////////////////////////////////////////////////////
683     /// @name Stencil
684     ////
685 
686     /**
687      * Sets the stencil settings to use for the next draw.
688      * Changing the clip has the side-effect of possibly zeroing
689      * out the client settable stencil bits. So multipass algorithms
690      * using stencil should not change the clip between passes.
691      * @param settings  the stencil settings to use.
692      */
setStencil(const GrStencilSettings & settings)693     void setStencil(const GrStencilSettings& settings) {
694         fCommon.fStencilSettings = settings;
695     }
696 
697     /**
698      * Shortcut to disable stencil testing and ops.
699      */
disableStencil()700     void disableStencil() {
701         fCommon.fStencilSettings.setDisabled();
702     }
703 
getStencil()704     const GrStencilSettings& getStencil() const { return fCommon.fStencilSettings; }
705 
stencil()706     GrStencilSettings* stencil() { return &fCommon.fStencilSettings; }
707 
708     /// @}
709 
710     ///////////////////////////////////////////////////////////////////////////
711     /// @name State Flags
712     ////
713 
714     /**
715      *  Flags that affect rendering. Controlled using enable/disableState(). All
716      *  default to disabled.
717      */
718     enum StateBits {
719         /**
720          * Perform dithering. TODO: Re-evaluate whether we need this bit
721          */
722         kDither_StateBit        = 0x01,
723         /**
724          * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
725          * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
726          * the 3D API.
727          */
728         kHWAntialias_StateBit   = 0x02,
729         /**
730          * Draws will respect the clip, otherwise the clip is ignored.
731          */
732         kClip_StateBit          = 0x04,
733         /**
734          * Disables writing to the color buffer. Useful when performing stencil
735          * operations.
736          */
737         kNoColorWrites_StateBit = 0x08,
738 
739         /**
740          * Usually coverage is applied after color blending. The color is blended using the coeffs
741          * specified by setBlendFunc(). The blended color is then combined with dst using coeffs
742          * of src_coverage, 1-src_coverage. Sometimes we are explicitly drawing a coverage mask. In
743          * this case there is no distinction between coverage and color and the caller needs direct
744          * control over the blend coeffs. When set, there will be a single blend step controlled by
745          * setBlendFunc() which will use coverage*color as the src color.
746          */
747          kCoverageDrawing_StateBit = 0x10,
748 
749         // Users of the class may add additional bits to the vector
750         kDummyStateBit,
751         kLastPublicStateBit = kDummyStateBit-1,
752     };
753 
resetStateFlags()754     void resetStateFlags() {
755         fCommon.fFlagBits = 0;
756     }
757 
758     /**
759      * Enable render state settings.
760      *
761      * @param stateBits bitfield of StateBits specifying the states to enable
762      */
enableState(uint32_t stateBits)763     void enableState(uint32_t stateBits) {
764         fCommon.fFlagBits |= stateBits;
765     }
766 
767     /**
768      * Disable render state settings.
769      *
770      * @param stateBits bitfield of StateBits specifying the states to disable
771      */
disableState(uint32_t stateBits)772     void disableState(uint32_t stateBits) {
773         fCommon.fFlagBits &= ~(stateBits);
774     }
775 
776     /**
777      * Enable or disable stateBits based on a boolean.
778      *
779      * @param stateBits bitfield of StateBits to enable or disable
780      * @param enable    if true enable stateBits, otherwise disable
781      */
setState(uint32_t stateBits,bool enable)782     void setState(uint32_t stateBits, bool enable) {
783         if (enable) {
784             this->enableState(stateBits);
785         } else {
786             this->disableState(stateBits);
787         }
788     }
789 
isDitherState()790     bool isDitherState() const {
791         return 0 != (fCommon.fFlagBits & kDither_StateBit);
792     }
793 
isHWAntialiasState()794     bool isHWAntialiasState() const {
795         return 0 != (fCommon.fFlagBits & kHWAntialias_StateBit);
796     }
797 
isClipState()798     bool isClipState() const {
799         return 0 != (fCommon.fFlagBits & kClip_StateBit);
800     }
801 
isColorWriteDisabled()802     bool isColorWriteDisabled() const {
803         return 0 != (fCommon.fFlagBits & kNoColorWrites_StateBit);
804     }
805 
isCoverageDrawing()806     bool isCoverageDrawing() const {
807         return 0 != (fCommon.fFlagBits & kCoverageDrawing_StateBit);
808     }
809 
isStateFlagEnabled(uint32_t stateBit)810     bool isStateFlagEnabled(uint32_t stateBit) const {
811         return 0 != (stateBit & fCommon.fFlagBits);
812     }
813 
814     /// @}
815 
816     ///////////////////////////////////////////////////////////////////////////
817     /// @name Face Culling
818     ////
819 
820     enum DrawFace {
821         kInvalid_DrawFace = -1,
822 
823         kBoth_DrawFace,
824         kCCW_DrawFace,
825         kCW_DrawFace,
826     };
827 
828     /**
829      * Controls whether clockwise, counterclockwise, or both faces are drawn.
830      * @param face  the face(s) to draw.
831      */
setDrawFace(DrawFace face)832     void setDrawFace(DrawFace face) {
833         SkASSERT(kInvalid_DrawFace != face);
834         fCommon.fDrawFace = face;
835     }
836 
837     /**
838      * Gets whether the target is drawing clockwise, counterclockwise,
839      * or both faces.
840      * @return the current draw face(s).
841      */
getDrawFace()842     DrawFace getDrawFace() const { return fCommon.fDrawFace; }
843 
844     /// @}
845 
846     ///////////////////////////////////////////////////////////////////////////
847 
848     bool operator ==(const GrDrawState& s) const {
849         if (fRenderTarget.get() != s.fRenderTarget.get() ||
850             fColorStages.count() != s.fColorStages.count() ||
851             fCoverageStages.count() != s.fCoverageStages.count() ||
852             fCommon != s.fCommon) {
853             return false;
854         }
855         for (int i = 0; i < fColorStages.count(); i++) {
856             if (fColorStages[i] != s.fColorStages[i]) {
857                 return false;
858             }
859         }
860         for (int i = 0; i < fCoverageStages.count(); i++) {
861             if (fCoverageStages[i] != s.fCoverageStages[i]) {
862                 return false;
863             }
864         }
865         return true;
866     }
867     bool operator !=(const GrDrawState& s) const { return !(*this == s); }
868 
869     GrDrawState& operator= (const GrDrawState& s) {
870         SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages());
871         this->setRenderTarget(s.fRenderTarget.get());
872         fCommon = s.fCommon;
873         fColorStages = s.fColorStages;
874         fCoverageStages = s.fCoverageStages;
875         return *this;
876     }
877 
878 private:
879 
onReset(const SkMatrix * initialViewMatrix)880     void onReset(const SkMatrix* initialViewMatrix) {
881         SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages());
882         fColorStages.reset();
883         fCoverageStages.reset();
884 
885         fRenderTarget.reset(NULL);
886 
887         this->setDefaultVertexAttribs();
888 
889         fCommon.fColor = 0xffffffff;
890         if (NULL == initialViewMatrix) {
891             fCommon.fViewMatrix.reset();
892         } else {
893             fCommon.fViewMatrix = *initialViewMatrix;
894         }
895         fCommon.fSrcBlend = kOne_GrBlendCoeff;
896         fCommon.fDstBlend = kZero_GrBlendCoeff;
897         fCommon.fBlendConstant = 0x0;
898         fCommon.fFlagBits = 0x0;
899         fCommon.fStencilSettings.setDisabled();
900         fCommon.fCoverage = 0xffffffff;
901         fCommon.fDrawFace = kBoth_DrawFace;
902     }
903 
904     /** Fields that are identical in GrDrawState and GrDrawState::DeferredState. */
905     struct CommonState {
906         // These fields are roughly sorted by decreasing likelihood of being different in op==
907         GrColor               fColor;
908         SkMatrix              fViewMatrix;
909         GrBlendCoeff          fSrcBlend;
910         GrBlendCoeff          fDstBlend;
911         GrColor               fBlendConstant;
912         uint32_t              fFlagBits;
913         const GrVertexAttrib* fVAPtr;
914         int                   fVACount;
915         GrStencilSettings     fStencilSettings;
916         GrColor               fCoverage;
917         DrawFace              fDrawFace;
918 
919         // This is simply a different representation of info in fVertexAttribs and thus does
920         // not need to be compared in op==.
921         int fFixedFunctionVertexAttribIndices[kGrFixedFunctionVertexAttribBindingCnt];
922 
923         bool operator== (const CommonState& other) const {
924             bool result = fColor == other.fColor &&
925                           fViewMatrix.cheapEqualTo(other.fViewMatrix) &&
926                           fSrcBlend == other.fSrcBlend &&
927                           fDstBlend == other.fDstBlend &&
928                           fBlendConstant == other.fBlendConstant &&
929                           fFlagBits == other.fFlagBits &&
930                           fVACount == other.fVACount &&
931                           !memcmp(fVAPtr, other.fVAPtr, fVACount * sizeof(GrVertexAttrib)) &&
932                           fStencilSettings == other.fStencilSettings &&
933                           fCoverage == other.fCoverage &&
934                           fDrawFace == other.fDrawFace;
935             SkASSERT(!result || 0 == memcmp(fFixedFunctionVertexAttribIndices,
936                                             other.fFixedFunctionVertexAttribIndices,
937                                             sizeof(fFixedFunctionVertexAttribIndices)));
938             return result;
939         }
940         bool operator!= (const CommonState& other) const { return !(*this == other); }
941     };
942 
943     /** GrDrawState uses GrEffectStages to hold stage state which holds a ref on GrEffectRef.
944         DeferredState must directly reference GrEffects, however. */
945     struct SavedEffectStage {
SavedEffectStageSavedEffectStage946         SavedEffectStage() : fEffect(NULL) {}
947         const GrEffect*                    fEffect;
948         GrEffectStage::SavedCoordChange    fCoordChange;
949     };
950 
951 public:
952     /**
953      * DeferredState contains all of the data of a GrDrawState but does not hold refs on GrResource
954      * objects. Resources are allowed to hit zero ref count while in DeferredStates. Their internal
955      * dispose mechanism returns them to the cache. This allows recycling resources through the
956      * the cache while they are in a deferred draw queue.
957      */
958     class DeferredState {
959     public:
DeferredState()960         DeferredState() : fRenderTarget(NULL) {
961             SkDEBUGCODE(fInitialized = false;)
962         }
963         // TODO: Remove this when DeferredState no longer holds a ref to the RT
~DeferredState()964         ~DeferredState() { SkSafeUnref(fRenderTarget); }
965 
saveFrom(const GrDrawState & drawState)966         void saveFrom(const GrDrawState& drawState) {
967             fCommon = drawState.fCommon;
968             // TODO: Here we will copy the GrRenderTarget pointer without taking a ref.
969             fRenderTarget = drawState.fRenderTarget.get();
970             SkSafeRef(fRenderTarget);
971             // Here we ref the effects directly rather than the effect-refs. TODO: When the effect-
972             // ref gets fully unref'ed it will cause the underlying effect to unref its resources
973             // and recycle them to the cache (if no one else is holding a ref to the resources).
974             fStages.reset(drawState.fColorStages.count() + drawState.fCoverageStages.count());
975             fColorStageCnt = drawState.fColorStages.count();
976             for (int i = 0; i < fColorStageCnt; ++i) {
977                 fStages[i].saveFrom(drawState.fColorStages[i]);
978             }
979             for (int i = 0; i < drawState.fCoverageStages.count(); ++i) {
980                 fStages[i + fColorStageCnt].saveFrom(drawState.fCoverageStages[i]);
981             }
982             SkDEBUGCODE(fInitialized = true;)
983         }
984 
restoreTo(GrDrawState * drawState)985         void restoreTo(GrDrawState* drawState) {
986             SkASSERT(fInitialized);
987             drawState->fCommon = fCommon;
988             drawState->setRenderTarget(fRenderTarget);
989             // reinflate color/cov stage arrays.
990             drawState->fColorStages.reset();
991             for (int i = 0; i < fColorStageCnt; ++i) {
992                 SkNEW_APPEND_TO_TARRAY(&drawState->fColorStages, GrEffectStage, (fStages[i]));
993             }
994             int coverageStageCnt = fStages.count() - fColorStageCnt;
995             drawState->fCoverageStages.reset();
996             for (int i = 0; i < coverageStageCnt; ++i) {
997                 SkNEW_APPEND_TO_TARRAY(&drawState->fCoverageStages,
998                                         GrEffectStage, (fStages[i + fColorStageCnt]));
999             }
1000         }
1001 
isEqual(const GrDrawState & state)1002         bool isEqual(const GrDrawState& state) const {
1003             int numCoverageStages = fStages.count() - fColorStageCnt;
1004             if (fRenderTarget != state.fRenderTarget.get() ||
1005                 fColorStageCnt != state.fColorStages.count() ||
1006                 numCoverageStages != state.fCoverageStages.count() ||
1007                 fCommon != state.fCommon) {
1008                 return false;
1009             }
1010             bool explicitLocalCoords = state.hasLocalCoordAttribute();
1011             for (int i = 0; i < fColorStageCnt; ++i) {
1012                 if (!fStages[i].isEqual(state.fColorStages[i], explicitLocalCoords)) {
1013                     return false;
1014                 }
1015             }
1016             for (int i = 0; i < numCoverageStages; ++i) {
1017                 int s = fColorStageCnt + i;
1018                 if (!fStages[s].isEqual(state.fCoverageStages[i], explicitLocalCoords)) {
1019                     return false;
1020                 }
1021             }
1022             return true;
1023         }
1024 
1025     private:
1026         typedef SkAutoSTArray<8, GrEffectStage::DeferredStage> DeferredStageArray;
1027 
1028         GrRenderTarget*                       fRenderTarget;
1029         CommonState                           fCommon;
1030         int                                   fColorStageCnt;
1031         DeferredStageArray                    fStages;
1032 
1033         SkDEBUGCODE(bool fInitialized;)
1034     };
1035 
1036 private:
1037 
1038     SkAutoTUnref<GrRenderTarget>        fRenderTarget;
1039     CommonState                         fCommon;
1040 
1041     typedef SkSTArray<4, GrEffectStage> EffectStageArray;
1042     EffectStageArray                    fColorStages;
1043     EffectStageArray                    fCoverageStages;
1044 
1045     // Some of the auto restore objects assume that no effects are removed during their lifetime.
1046     // This is used to assert that this condition holds.
1047     SkDEBUGCODE(int fBlockEffectRemovalCnt;)
1048 
1049     /**
1050      *  Sets vertex attributes for next draw.
1051      *
1052      *  @param attribs    the array of vertex attributes to set.
1053      *  @param count      the number of attributes being set, limited to kMaxVertexAttribCnt.
1054      */
1055     void setVertexAttribs(const GrVertexAttrib attribs[], int count);
1056 
1057     typedef SkRefCnt INHERITED;
1058 };
1059 
1060 GR_MAKE_BITFIELD_OPS(GrDrawState::BlendOptFlags);
1061 
1062 #endif
1063