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