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
27class GrDrawState : public SkRefCnt {
28public:
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
879private:
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
952public:
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
1037private:
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
1061GR_MAKE_BITFIELD_OPS(GrDrawState::BlendOptFlags);
1062
1063#endif
1064