GrDrawState.h revision 31ec7985f2b52a0cab4aa714a613b918cf663c08
19381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com/*
29381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * Copyright 2011 Google Inc.
39381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com *
49381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * Use of this source code is governed by a BSD-style license that can be
59381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * found in the LICENSE file.
69381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com */
79381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
89381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#ifndef GrDrawState_DEFINED
99381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#define GrDrawState_DEFINED
109381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
112eaaefd7e6a58339b3f93333f1e9cc92252cc303bsalomon@google.com#include "GrBackendEffectFactory.h"
129381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#include "GrColor.h"
1308283afc265f1153834256fc1012519813ba6b73bsalomon@google.com#include "GrEffectStage.h"
14cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com#include "GrRefCnt.h"
15cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com#include "GrRenderTarget.h"
169381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#include "GrStencil.h"
17cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com#include "GrTemplates.h"
1864aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com#include "GrTexture.h"
1931ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com#include "GrTypesPriv.h"
2068b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com#include "effects/GrSimpleTextureEffect.h"
219381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
22cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com#include "SkMatrix.h"
239381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#include "SkXfermode.h"
249381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
25af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.comclass GrPaint;
269381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
279b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com/**
289b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com * Type used to describe how attributes bind to program usage
299b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com */
309b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.comtypedef int GrAttribBindings;
319b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
322e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.comclass GrDrawState : public GrRefCnt {
332e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.compublic:
34fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com    SK_DECLARE_INST_COUNT(GrDrawState)
35d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
369381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    /**
371322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * Total number of effect stages. Each stage can host a GrEffect. A stage is enabled if it has a
381322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * GrEffect. The effect produces an output color in the fragment shader. It's inputs are the
391322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * output from the previous enabled stage and a position. The position is either derived from
401322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * the interpolated vertex positions or explicit per-vertex coords, depending upon the
419b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     * GrAttribBindings used to draw.
42bf5cad4e9c5808493b35cb9b0000a2d36b7f9b78robertphillips@google.com     *
431322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * The stages are divided into two sets, color-computing and coverage-computing. The final color
441322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * stage produces the final pixel color. The coverage-computing stages function exactly as the
451322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * color-computing but the output of the final coverage stage is treated as a fractional pixel
461322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * coverage rather than as input to the src/dst color blend step.
471322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     *
481322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * The input color to the first enabled color-stage is either the constant color or interpolated
499b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     * per-vertex colors, depending upon GrAttribBindings. The input to the first coverage stage is
504647f9059825c062169d4d454c12640d82ae16c0bsalomon@google.com     * either a constant coverage (usually full-coverage) or interpolated per-vertex coverage.
511322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     *
52cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com     * See the documentation of kCoverageDrawing_StateBit for information about disabling the
53cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com     * the color / coverage distinction.
54cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com     *
551322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * Stages 0 through GrPaint::kTotalStages-1 are reserved for stages copied from the client's
561322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * GrPaint. Stages GrPaint::kTotalStages through kNumStages-2 are earmarked for use by
571322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * GrTextContext and GrPathRenderer-derived classes. kNumStages-1 is earmarked for clipping
58dfdb7e5240276493077b7c6e1f3cc8b8a0e195babsalomon@google.com     * by GrClipMaskManager.
599381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     */
609381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    enum {
61580711694654b8edc70028d09c4211445b661466twiz@google.com        kNumStages = 5,
629381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    };
639381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
64ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    GrDrawState() {
6575847199c25121c9989e8dba103ac6002d2132d6reed@google.com#if GR_DEBUG
669b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        VertexAttributesUnitTest();
6775847199c25121c9989e8dba103ac6002d2132d6reed@google.com#endif
6852a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        this->reset();
6952a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    }
7046f7afb9867200b568c21736da8a8bbb56b20e30bsalomon@google.com
71ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    GrDrawState(const GrDrawState& state) {
7246f7afb9867200b568c21736da8a8bbb56b20e30bsalomon@google.com        *this = state;
7346f7afb9867200b568c21736da8a8bbb56b20e30bsalomon@google.com    }
7446f7afb9867200b568c21736da8a8bbb56b20e30bsalomon@google.com
759ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com    virtual ~GrDrawState() {
767d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        this->disableStages();
779ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com    }
789ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
7952a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    /**
807d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com     * Resets to the default state.
8108283afc265f1153834256fc1012519813ba6b73bsalomon@google.com     * GrEffects will be removed from all stages.
82d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     */
8352a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    void reset() {
849ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
857d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        this->disableStages();
8652a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com
87ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fRenderTarget.reset(NULL);
88ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com
899b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        this->setDefaultVertexAttribs();
909b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
91ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fColor = 0xffffffff;
92ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fViewMatrix.reset();
93ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fSrcBlend = kOne_GrBlendCoeff;
94ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fDstBlend = kZero_GrBlendCoeff;
95ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fBlendConstant = 0x0;
96ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fFlagBits = 0x0;
97ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fStencilSettings.setDisabled();
98ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fFirstCoverageStage = kNumStages;
99ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fCoverage = 0xffffffff;
100ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fColorFilterMode = SkXfermode::kDst_Mode;
101ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fColorFilterColor = 0x0;
102ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fDrawFace = kBoth_DrawFace;
103af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com    }
104af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com
105af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com    /**
106af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com     * Initializes the GrDrawState based on a GrPaint. Note that GrDrawState
1071e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * encompasses more than GrPaint. Aspects of GrDrawState that have no
108af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com     * GrPaint equivalents are not modified. GrPaint has fewer stages than
109af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com     * GrDrawState. The extra GrDrawState stages are disabled.
110af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com     */
111af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com    void setFromPaint(const GrPaint& paint);
1128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
1149b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    /// @name Vertex Attributes
115cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    ////
116cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com
1179b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    enum {
1189b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        kVertexAttribCnt = 6,
119af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com    };
120cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com
1219b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com   /**
122f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com     * The format of vertices is represented as an array of vertex attribute
123f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com     * pair, with each pair representing the type of the attribute and the
124f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com     * offset in the vertex structure (see GrVertexAttrib, above).
125cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     *
1269b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     * This will only set up the vertex geometry. To bind the attributes in
127f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com     * the shaders, attribute indices and attribute bindings need to be set
1289b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     * as well.
129cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     */
130af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com
131af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com    /**
132f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com     *  Sets vertex attributes for next draw.
133af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com     *
134f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com     *  @param attribs    the array of vertex attributes to set.
1359b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     *  @param count      the number of attributes being set.
136f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com     *                    limited to a count of kVertexAttribCnt.
137af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com     */
1389b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    void setVertexAttribs(const GrVertexAttrib attribs[], int count);
139af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com
1409b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    const GrVertexAttrib* getVertexAttribs() const { return fVertexAttribs.begin(); }
1419b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    int getVertexAttribCount() const { return fVertexAttribs.count(); }
1429b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
1439b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    size_t getVertexSize() const;
144af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com
145af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com    /**
146f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com     *  Sets default vertex attributes for next draw.
147af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com     *
1489b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     *  This will also set default vertex attribute indices and bindings
149af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com     */
1509b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    void setDefaultVertexAttribs();
151af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com
152ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org    bool validateVertexAttribs() const;
153ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org
1549b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    ////////////////////////////////////////////////////////////////////////////
1559b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    // Helpers for picking apart vertex attributes
156af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com
1579b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    // helper array to let us check the expected so we know what bound attrib indices
1589b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    // we care about
1599b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    static const size_t kVertexAttribSizes[kGrVertexAttribTypeCount];
160cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com
161cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    /**
162cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * Accessing positions, texture coords, or colors, of a vertex within an
163cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * array is a hassle involving casts and simple math. These helpers exist
164cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * to keep GrDrawTarget clients' code a bit nicer looking.
165cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     */
166cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com
167cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    /**
168cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * Gets a pointer to a GrPoint of a vertex's position or texture
169cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * coordinate.
1709b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     * @param vertices      the vertex array
171cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * @param vertexIndex   the index of the vertex in the array
172cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * @param vertexSize    the size of each vertex in the array
173cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * @param offset        the offset in bytes of the vertex component.
174cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     *                      Defaults to zero (corresponding to vertex position)
175cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * @return pointer to the vertex component as a GrPoint
176cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     */
177cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    static GrPoint* GetVertexPoint(void* vertices,
178cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                   int vertexIndex,
179cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                   int vertexSize,
180cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                   int offset = 0) {
181cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com        intptr_t start = GrTCast<intptr_t>(vertices);
182cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com        return GrTCast<GrPoint*>(start + offset +
183cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                 vertexIndex * vertexSize);
184cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    }
185cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    static const GrPoint* GetVertexPoint(const void* vertices,
186cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                         int vertexIndex,
187cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                         int vertexSize,
188cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                         int offset = 0) {
189cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com        intptr_t start = GrTCast<intptr_t>(vertices);
190cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com        return GrTCast<const GrPoint*>(start + offset +
191cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                       vertexIndex * vertexSize);
192cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    }
193cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com
194cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    /**
195cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * Gets a pointer to a GrColor inside a vertex within a vertex array.
196cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * @param vertices      the vetex array
197cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * @param vertexIndex   the index of the vertex in the array
198cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * @param vertexSize    the size of each vertex in the array
199cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * @param offset        the offset in bytes of the vertex color
200cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * @return pointer to the vertex component as a GrColor
201cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     */
202cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    static GrColor* GetVertexColor(void* vertices,
203cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                   int vertexIndex,
204cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                   int vertexSize,
205cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                   int offset) {
206cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com        intptr_t start = GrTCast<intptr_t>(vertices);
207cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com        return GrTCast<GrColor*>(start + offset +
208cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                 vertexIndex * vertexSize);
209cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    }
210cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    static const GrColor* GetVertexColor(const void* vertices,
211cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                         int vertexIndex,
212cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                         int vertexSize,
213cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                         int offset) {
214cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com        const intptr_t start = GrTCast<intptr_t>(vertices);
215cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com        return GrTCast<const GrColor*>(start + offset +
216cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                       vertexIndex * vertexSize);
217cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    }
218cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com
2199b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    /// @}
2209b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
2219b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    ///////////////////////////////////////////////////////////////////////////
2229b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    /// @name Attribute Bindings
2239b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    ////
2249b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
2259b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    /**
226f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com     * The vertex data used by the current program is represented as a bitfield
227f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com     * of flags. Programs always use positions and may also use texture
228c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com     * coordinates, per-vertex colors, per-vertex coverage and edge data. The
229c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com     * local coords accessible by effects may either come from positions or
230c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com     * be specified explicitly.
2319b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     */
2329b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
2339b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    /**
2349b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     * Additional Bits that can be specified in GrAttribBindings.
2359b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     */
2369b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    enum AttribBindingsBits {
237c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        /** explicit local coords are provided (instead of using pre-view-matrix positions) */
238c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        kLocalCoords_AttribBindingsBit        = 0x1,
2399b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        /* program uses colors (GrColor) */
240c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        kColor_AttribBindingsBit              = 0x2,
2419b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        /* program uses coverage (GrColor)
2429b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com         */
243c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        kCoverage_AttribBindingsBit           = 0x4,
2449b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        // for below assert
2459b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        kDummyAttribBindingsBit,
2469b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        kHighAttribBindingsBit = kDummyAttribBindingsBit - 1
2479b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    };
2489b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    // make sure we haven't exceeded the number of bits in GrAttribBindings.
2499b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    GR_STATIC_ASSERT(kHighAttribBindingsBit < ((uint64_t)1 << 8*sizeof(GrAttribBindings)));
2509b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
2519b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    enum AttribBindings {
2529b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        kDefault_AttribBindings = 0
2539b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    };
2549b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
2559b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    /**
2569b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     *  Sets attribute bindings for next draw.
2579b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     *
2589b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     *  @param bindings    the attribute bindings to set.
2599b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     */
2609b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    void setAttribBindings(GrAttribBindings bindings) { fCommon.fAttribBindings = bindings; }
2619b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
2629b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    GrAttribBindings getAttribBindings() const { return fCommon.fAttribBindings; }
2639b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
2649b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    ////////////////////////////////////////////////////////////////////////////
2659b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    // Helpers for picking apart attribute bindings
2669b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
2679b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    /**
2689b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     * Determines whether src alpha is guaranteed to be one for all src pixels
2699b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     */
2709b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    bool srcAlphaWillBeOne(GrAttribBindings) const;
2719b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
2729b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    /**
2739b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     * Determines whether the output coverage is guaranteed to be one for all pixels hit by a draw.
2749b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     */
2759b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    bool hasSolidCoverage(GrAttribBindings) const;
2769b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
2779b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    static void VertexAttributesUnitTest();
27891274b99722d9be62e077ab979c630c23cdd04b1skia.committer@gmail.com
2799b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    /// @}
2809b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
2819b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    ///////////////////////////////////////////////////////////////////////////
2829b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    /// @name Vertex Attribute Indices
2839b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    ////
2849b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
2859b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    /**
2869b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     * Vertex attribute indices map the data set in the vertex attribute array
2879b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     * to the bindings specified in the attribute bindings. Each binding type
288f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com     * has an associated index in the attribute array. This index is used to
289f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com     * look up the vertex attribute data from the array, and potentially as the
2909b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     * attribute index if we're binding attributes in GL.
291f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com     *
2929b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     * Indices which do not have active attribute bindings will be ignored.
2939b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     */
2949b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
2959b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    enum AttribIndex {
2969b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        kPosition_AttribIndex = 0,
2979b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        kColor_AttribIndex,
2989b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        kCoverage_AttribIndex,
299c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        kLocalCoords_AttribIndex,
3009b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
301c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        kLast_AttribIndex = kLocalCoords_AttribIndex
3029b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    };
3039b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    static const int kAttribIndexCount = kLast_AttribIndex + 1;
3049b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
3059b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    // these are used when vertex color and coverage isn't set
3069b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    enum {
3079b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        kColorOverrideAttribIndexValue = GrDrawState::kVertexAttribCnt,
3089b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        kCoverageOverrideAttribIndexValue = GrDrawState::kVertexAttribCnt+1,
3099b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    };
3109b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
3119b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    ////////////////////////////////////////////////////////////////////////////
312f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com    // Helpers to set attribute indices. These should match the index in the
313f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com    // current attribute index array.
3149b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
3159b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    /**
316f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com     *  Sets index for next draw. This is used to look up the offset
3179b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     *  from the current vertex attribute array and to bind the attributes.
3189b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     *
3199b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     *  @param index      the attribute index we're setting
3209b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     *  @param value      the value of the index
3219b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     */
3229b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    void setAttribIndex(AttribIndex index, int value) { fAttribIndices[index] = value; }
3239b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
3249b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    int getAttribIndex(AttribIndex index) const       { return fAttribIndices[index]; }
325cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com
326cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    /// @}
327cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com
328cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    ///////////////////////////////////////////////////////////////////////////
3298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Color
3308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
3318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Sets color for next draw to a premultiplied-alpha color.
3348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param color    the color to set.
3368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
337ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    void setColor(GrColor color) { fCommon.fColor = color; }
3388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
339ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    GrColor getColor() const { return fCommon.fColor; }
3408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Sets the color to be used for the next draw to be
3438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  (r,g,b,a) = (alpha, alpha, alpha, alpha).
3448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param alpha The alpha value to set as the color.
3468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setAlpha(uint8_t a) {
3488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        this->setColor((a << 24) | (a << 16) | (a << 8) | a);
3498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
3508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Add a color filter that can be represented by a color and a mode. Applied
353c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com     * after color-computing effect stages.
3548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setColorFilter(GrColor c, SkXfermode::Mode mode) {
356ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fColorFilterColor = c;
357ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fColorFilterMode = mode;
3588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
3598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
360ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    GrColor getColorFilterColor() const { return fCommon.fColorFilterColor; }
361ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    SkXfermode::Mode getColorFilterMode() const { return fCommon.fColorFilterMode; }
3628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3635b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    /**
3645b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com     * Constructor sets the color to be 'color' which is undone by the destructor.
3655b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com     */
3665b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    class AutoColorRestore : public ::GrNoncopyable {
3675b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    public:
36866a58aca8379a33ccc7572a31c74a3334d08b47csugoi@google.com        AutoColorRestore() : fDrawState(NULL), fOldColor(0) {}
369d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
3705b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        AutoColorRestore(GrDrawState* drawState, GrColor color) {
371d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            fDrawState = NULL;
372d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            this->set(drawState, color);
373d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        }
374d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
375d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        void reset() {
376d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            if (NULL != fDrawState) {
377d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                fDrawState->setColor(fOldColor);
378d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                fDrawState = NULL;
379d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            }
380d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        }
381d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
382d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        void set(GrDrawState* drawState, GrColor color) {
383d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            this->reset();
3845b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com            fDrawState = drawState;
3855b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com            fOldColor = fDrawState->getColor();
3865b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com            fDrawState->setColor(color);
3875b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        }
388d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
389d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        ~AutoColorRestore() { this->reset(); }
3905b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    private:
3915b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        GrDrawState*    fDrawState;
3925b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        GrColor         fOldColor;
3935b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    };
3945b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com
3958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
3968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
3982401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    /// @name Coverage
3992401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    ////
4002401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com
4012401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    /**
402d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     * Sets a constant fractional coverage to be applied to the draw. The
4032401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     * initial value (after construction or reset()) is 0xff. The constant
4042401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     * coverage is ignored when per-vertex coverage is provided.
4052401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     */
4062401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    void setCoverage(uint8_t coverage) {
407ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage);
4082401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    }
4092401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com
4102401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    /**
4112401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     * Version of above that specifies 4 channel per-vertex color. The value
4122401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     * should be premultiplied.
4132401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     */
4142401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    void setCoverage4(GrColor coverage) {
415ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fCoverage = coverage;
4162401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    }
4172401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com
4182401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    GrColor getCoverage() const {
419ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        return fCommon.fCoverage;
4202401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    }
4212401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com
4222401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    /// @}
4232401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com
4242401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
425adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com    /// @name Effect Stages
4268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
4278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
42865eb4d5a210884cc92c43a8582cbd1ccbddcab57jvanverth@google.com    const GrEffectRef* setEffect(int stageIdx, const GrEffectRef* effect) {
42965eb4d5a210884cc92c43a8582cbd1ccbddcab57jvanverth@google.com        fStages[stageIdx].setEffect(effect);
43065eb4d5a210884cc92c43a8582cbd1ccbddcab57jvanverth@google.com        return effect;
43165eb4d5a210884cc92c43a8582cbd1ccbddcab57jvanverth@google.com    }
43201c34ee59906f729f6ca7d35f0c0e5e2f5e693feskia.committer@gmail.com
43391274b99722d9be62e077ab979c630c23cdd04b1skia.committer@gmail.com    const GrEffectRef* setEffect(int stageIdx, const GrEffectRef* effect,
43465eb4d5a210884cc92c43a8582cbd1ccbddcab57jvanverth@google.com                                 int attr0, int attr1 = -1) {
43565eb4d5a210884cc92c43a8582cbd1ccbddcab57jvanverth@google.com        fStages[stageIdx].setEffect(effect, attr0, attr1);
436adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com        return effect;
437adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com    }
438adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com
4398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
440c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com     * Creates a GrSimpleTextureEffect that uses local coords as texture coordinates.
4411e8f016305805d4d8cad74aba3a21b78486f9d6ftomhudson@google.com     */
442b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com    void createTextureEffect(int stageIdx, GrTexture* texture, const SkMatrix& matrix) {
44308283afc265f1153834256fc1012519813ba6b73bsalomon@google.com        GrAssert(!this->getStage(stageIdx).getEffect());
44468b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com        GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix);
445adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com        this->setEffect(stageIdx, effect)->unref();
446dfdb7e5240276493077b7c6e1f3cc8b8a0e195babsalomon@google.com    }
44708283afc265f1153834256fc1012519813ba6b73bsalomon@google.com    void createTextureEffect(int stageIdx,
44808283afc265f1153834256fc1012519813ba6b73bsalomon@google.com                             GrTexture* texture,
449b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com                             const SkMatrix& matrix,
450dfdb7e5240276493077b7c6e1f3cc8b8a0e195babsalomon@google.com                             const GrTextureParams& params) {
45108283afc265f1153834256fc1012519813ba6b73bsalomon@google.com        GrAssert(!this->getStage(stageIdx).getEffect());
45268b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com        GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params);
453adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com        this->setEffect(stageIdx, effect)->unref();
4541ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com    }
4551ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com
4567d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com    bool stagesDisabled() {
4577d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        for (int i = 0; i < kNumStages; ++i) {
45808283afc265f1153834256fc1012519813ba6b73bsalomon@google.com            if (NULL != fStages[i].getEffect()) {
4597d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com                return false;
4607d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com            }
4617d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        }
4623eee8fbe0f280bc1dea59dc0b0ebd8021b51137ftomhudson@google.com        return true;
4637d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com    }
464676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com
46591274b99722d9be62e077ab979c630c23cdd04b1skia.committer@gmail.com    void disableStage(int stageIdx) {
46665eb4d5a210884cc92c43a8582cbd1ccbddcab57jvanverth@google.com        this->setEffect(stageIdx, NULL);
467ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org    }
468676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com
469972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    /**
470f271cc7183fe48ac64d2d9a454eb013c91b42d53bsalomon@google.com     * Release all the GrEffects referred to by this draw state.
471972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com     */
4727d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com    void disableStages() {
473972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com        for (int i = 0; i < kNumStages; ++i) {
474676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com            this->disableStage(i);
475972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com        }
476972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    }
477972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com
4787d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com    class AutoStageDisable : public ::GrNoncopyable {
479972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    public:
4807d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        AutoStageDisable(GrDrawState* ds) : fDrawState(ds) {}
4817d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        ~AutoStageDisable() {
482972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com            if (NULL != fDrawState) {
4837d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com                fDrawState->disableStages();
484972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com            }
485972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com        }
486972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    private:
487972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com        GrDrawState* fDrawState;
488972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    };
489972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com
4908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
49108283afc265f1153834256fc1012519813ba6b73bsalomon@google.com     * Returns the current stage by index.
4928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
49308283afc265f1153834256fc1012519813ba6b73bsalomon@google.com    const GrEffectStage& getStage(int stageIdx) const {
49408283afc265f1153834256fc1012519813ba6b73bsalomon@google.com        GrAssert((unsigned)stageIdx < kNumStages);
49508283afc265f1153834256fc1012519813ba6b73bsalomon@google.com        return fStages[stageIdx];
4968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
4978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
499c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com     * Called when the source coord system is changing. This ensures that effects will see the
500c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com     * correct local coordinates. oldToNew gives the transformation from the old coord system in
501c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com     * which the geometry was specified to the new coordinate system from which it will be rendered.
5028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
503c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    void localCoordChange(const SkMatrix& oldToNew) {
504e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        for (int i = 0; i < kNumStages; ++i) {
505e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com            if (this->isStageEnabled(i)) {
506c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com                fStages[i].localCoordChange(oldToNew);
507e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com            }
508e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        }
509e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com    }
510e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com
5118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
5128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
5148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Coverage / Color Stages
5158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
5168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
5188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * A common pattern is to compute a color with the initial stages and then
5198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * modulate that color by a coverage value in later stage(s) (AA, mask-
520d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     * filters, glyph mask, etc). Color-filters, xfermodes, etc should be
521d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     * computed based on the pre-coverage-modulated color. The division of
522d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     * stages between color-computing and coverage-computing is specified by
5238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * this method. Initially this is kNumStages (all stages
5248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * are color-computing).
5258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
5268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setFirstCoverageStage(int firstCoverageStage) {
5278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((unsigned)firstCoverageStage <= kNumStages);
528ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fFirstCoverageStage = firstCoverageStage;
5298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
5308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
5328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Gets the index of the first coverage-computing stage.
5338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
5348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    int getFirstCoverageStage() const {
535ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        return fCommon.fFirstCoverageStage;
5368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
5378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///@}
5398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
5418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Blending
5428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
5438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
5451e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * Sets the blending function coefficients.
5468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
5478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * The blend function will be:
5488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *    D' = sat(S*srcCoef + D*dstCoef)
5498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
5508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *   where D is the existing destination color, S is the incoming source
5518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *   color, and D' is the new destination color that will be written. sat()
5528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *   is the saturation function.
5538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
5541e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * @param srcCoef coefficient applied to the src color.
5551e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * @param dstCoef coefficient applied to the dst color.
5568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
5578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
558ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fSrcBlend = srcCoeff;
559ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fDstBlend = dstCoeff;
5608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    #if GR_DEBUG
5618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        switch (dstCoeff) {
56247059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kDC_GrBlendCoeff:
56347059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kIDC_GrBlendCoeff:
56447059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kDA_GrBlendCoeff:
56547059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kIDA_GrBlendCoeff:
5668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
5678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                     "coverage stages.\n");
5688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
5698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        default:
5708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
5718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
5728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        switch (srcCoeff) {
57347059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kSC_GrBlendCoeff:
57447059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kISC_GrBlendCoeff:
57547059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kSA_GrBlendCoeff:
57647059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kISA_GrBlendCoeff:
5778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            GrPrintf("Unexpected src blend coeff. Won't work correctly with"
5788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                     "coverage stages.\n");
5798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
5808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        default:
5818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
5828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
5838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    #endif
5848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
5858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
586ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    GrBlendCoeff getSrcBlendCoeff() const { return fCommon.fSrcBlend; }
587ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    GrBlendCoeff getDstBlendCoeff() const { return fCommon.fDstBlend; }
5888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff,
5908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                          GrBlendCoeff* dstBlendCoeff) const {
591ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        *srcBlendCoeff = fCommon.fSrcBlend;
592ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        *dstBlendCoeff = fCommon.fDstBlend;
5938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
5948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
5968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the blending function constant referenced by the following blending
5971e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * coefficients:
59847059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com     *      kConstC_GrBlendCoeff
59947059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com     *      kIConstC_GrBlendCoeff
60047059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com     *      kConstA_GrBlendCoeff
60147059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com     *      kIConstA_GrBlendCoeff
6028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
6038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param constant the constant to set
6048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
605ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    void setBlendConstant(GrColor constant) { fCommon.fBlendConstant = constant; }
6068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
6088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Retrieves the last value set by setBlendConstant()
6098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return the blending constant value
6108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
611ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    GrColor getBlendConstant() const { return fCommon.fBlendConstant; }
6128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6132b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com    /**
6142b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * Determines whether multiplying the computed per-pixel color by the pixel's fractional
6152b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * coverage before the blend will give the correct final destination color. In general it
6162b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * will not as coverage is applied after blending.
6172b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     */
6182b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com    bool canTweakAlphaForCoverage() const;
6192b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com
6202b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com    /**
6212b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * Optimizations for blending / coverage to that can be applied based on the current state.
6222b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     */
6232b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com    enum BlendOptFlags {
6242b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        /**
6252b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         * No optimization
6262b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         */
6272b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        kNone_BlendOpt                  = 0,
6282b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        /**
6292b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         * Don't draw at all
6302b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         */
6312b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        kSkipDraw_BlendOptFlag          = 0x1,
6322b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        /**
6332b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         * Emit the src color, disable HW blending (replace dst with src)
6342b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         */
6352b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        kDisableBlend_BlendOptFlag      = 0x2,
6362b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        /**
6372b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         * The coverage value does not have to be computed separately from alpha, the the output
6382b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         * color can be the modulation of the two.
6392b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         */
6402b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        kCoverageAsAlpha_BlendOptFlag   = 0x4,
6412b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        /**
6422b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         * Instead of emitting a src color, emit coverage in the alpha channel and r,g,b are
6432b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         * "don't cares".
6442b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         */
6452b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        kEmitCoverage_BlendOptFlag      = 0x8,
6462b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        /**
6472b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         * Emit transparent black instead of the src color, no need to compute coverage.
6482b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         */
6492b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        kEmitTransBlack_BlendOptFlag    = 0x10,
6502b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com    };
6512b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com    GR_DECL_BITFIELD_OPS_FRIENDS(BlendOptFlags);
6522b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com
6532b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com    /**
6542b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * Determines what optimizations can be applied based on the blend. The coefficients may have
6552b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * to be tweaked in order for the optimization to work. srcCoeff and dstCoeff are optional
6562b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * params that receive the tweaked coefficients. Normally the function looks at the current
6572b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * state to see if coverage is enabled. By setting forceCoverage the caller can speculatively
6582b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * determine the blend optimizations that would be used if there was partial pixel coverage.
6592b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     *
6602b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * Subclasses of GrDrawTarget that actually draw (as opposed to those that just buffer for
6612b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * playback) must call this function and respect the flags that replace the output color.
6622b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     */
6632b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com    BlendOptFlags getBlendOpts(bool forceCoverage = false,
6642b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com                               GrBlendCoeff* srcCoeff = NULL,
6652b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com                               GrBlendCoeff* dstCoeff = NULL) const;
6662b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com
6678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
6688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
6708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name View Matrix
6718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
6728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
674a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com     * Sets the matrix applied to vertex positions.
6758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
6768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * In the post-view-matrix space the rectangle [0,w]x[0,h]
6778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * fully covers the render target. (w and h are the width and height of the
678ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com     * the render-target.)
6798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
680ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    void setViewMatrix(const SkMatrix& m) { fCommon.fViewMatrix = m; }
6818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
6838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Gets a writable pointer to the view matrix.
6848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
685ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    SkMatrix* viewMatrix() { return &fCommon.fViewMatrix; }
6868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
6888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Multiplies the current view matrix by a matrix
6898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
6908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  After this call V' = V*m where V is the old view matrix,
6918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  m is the parameter to this function, and V' is the new view matrix.
6928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  (We consider positions to be column vectors so position vector p is
6938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  transformed by matrix X as p' = X*p.)
6948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
6958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param m the matrix used to modify the view matrix.
6968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
697ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    void preConcatViewMatrix(const SkMatrix& m) { fCommon.fViewMatrix.preConcat(m); }
6988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
7008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Multiplies the current view matrix by a matrix
7018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
7028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  After this call V' = m*V where V is the old view matrix,
7038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  m is the parameter to this function, and V' is the new view matrix.
7048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  (We consider positions to be column vectors so position vector p is
7058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  transformed by matrix X as p' = X*p.)
7068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
7078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param m the matrix used to modify the view matrix.
7088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
709ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    void postConcatViewMatrix(const SkMatrix& m) { fCommon.fViewMatrix.postConcat(m); }
7108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
7128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Retrieves the current view matrix
7138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return the current view matrix.
7148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
715ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    const SkMatrix& getViewMatrix() const { return fCommon.fViewMatrix; }
7168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
7188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Retrieves the inverse of the current view matrix.
7198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
7208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  If the current view matrix is invertible, return true, and if matrix
7218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  is non-null, copy the inverse into it. If the current view matrix is
7228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  non-invertible, return false and ignore the matrix parameter.
7238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
7248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param matrix if not null, will receive a copy of the current inverse.
7258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
726b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com    bool getViewInverse(SkMatrix* matrix) const {
7278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // TODO: determine whether we really need to leave matrix unmodified
7288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // at call sites when inversion fails.
729b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com        SkMatrix inverse;
730ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        if (fCommon.fViewMatrix.invert(&inverse)) {
7318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (matrix) {
7328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                *matrix = inverse;
7338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
7348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            return true;
7358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
7368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return false;
7378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
7388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7395b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    ////////////////////////////////////////////////////////////////////////////
7405b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com
7415b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    /**
7422fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com     * Preconcats the current view matrix and restores the previous view matrix in the destructor.
743c196b522d06919885c6bbe28b7b06d2e5b2cb9bfbsalomon@google.com     * Effect matrices are automatically adjusted to compensate.
7445b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com     */
7458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    class AutoViewMatrixRestore : public ::GrNoncopyable {
7468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    public:
7478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        AutoViewMatrixRestore() : fDrawState(NULL) {}
7482fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
749c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        AutoViewMatrixRestore(GrDrawState* ds, const SkMatrix& preconcatMatrix) {
7508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            fDrawState = NULL;
751c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com            this->set(ds, preconcatMatrix);
7528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
7532fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
7542fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        ~AutoViewMatrixRestore() { this->restore(); }
7552fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
756a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        /**
757a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * Can be called prior to destructor to restore the original matrix.
758a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         */
7592fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        void restore();
760f467ce7bc33af5f496e0619387551aedec6d2517skia.committer@gmail.com
761c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        void set(GrDrawState* drawState, const SkMatrix& preconcatMatrix);
7622fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
763ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com        bool isSet() const { return NULL != fDrawState; }
7642fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
7658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    private:
766288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com        GrDrawState*                        fDrawState;
767b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com        SkMatrix                            fViewMatrix;
76808283afc265f1153834256fc1012519813ba6b73bsalomon@google.com        GrEffectStage::SavedCoordChange     fSavedCoordChanges[GrDrawState::kNumStages];
769288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com        uint32_t                            fRestoreMask;
7709381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    };
7719381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
7725b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    ////////////////////////////////////////////////////////////////////////////
7735b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com
7745b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    /**
7752fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com     * This sets the view matrix to identity and adjusts stage matrices to compensate. The
7762fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com     * destructor undoes the changes, restoring the view matrix that was set before the
7772fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com     * constructor. It is similar to passing the inverse of the current view matrix to
7782fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com     * AutoViewMatrixRestore, but lazily computes the inverse only if necessary.
7795b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com     */
7805b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    class AutoDeviceCoordDraw : ::GrNoncopyable {
7815b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    public:
7822fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        AutoDeviceCoordDraw() : fDrawState(NULL) {}
7835b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        /**
7842fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com         * If a stage's texture matrix is applied to explicit per-vertex coords, rather than to
7852fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com         * positions, then we don't want to modify its matrix. The explicitCoordStageMask is used
7862fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com         * to specify such stages.
7875b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com         */
788c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        AutoDeviceCoordDraw(GrDrawState* drawState) {
7892fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com            fDrawState = NULL;
790c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com            this->set(drawState);
7912fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        }
7922fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
793a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        ~AutoDeviceCoordDraw() { this->restore(); }
794a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com
795c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        bool set(GrDrawState* drawState);
7962fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
797a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        /**
798a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * Returns true if this object was successfully initialized on to a GrDrawState. It may
799a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * return false because a non-default constructor or set() were never called or because
800a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * the view matrix was not invertible.
801a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         */
8025b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        bool succeeded() const { return NULL != fDrawState; }
8032fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
804a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        /**
805a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * Returns the matrix that was set previously set on the drawState. This is only valid
806a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * if succeeded returns true.
807a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         */
808b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com        const SkMatrix& getOriginalMatrix() const {
809a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com            GrAssert(this->succeeded());
810a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com            return fViewMatrix;
811a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        }
8122fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
813a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        /**
814a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * Can be called prior to destructor to restore the original matrix.
815a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         */
816a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        void restore();
8172fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
8185b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    private:
819288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com        GrDrawState*                        fDrawState;
820b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com        SkMatrix                            fViewMatrix;
82108283afc265f1153834256fc1012519813ba6b73bsalomon@google.com        GrEffectStage::SavedCoordChange     fSavedCoordChanges[GrDrawState::kNumStages];
822288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com        uint32_t                            fRestoreMask;
8235b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    };
8245b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com
8258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
8268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
8288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Render Target
8298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
8308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
832ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com     * Sets the render-target used at the next drawing call
8338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
8348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param target  The render target to set.
8358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
836d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    void setRenderTarget(GrRenderTarget* target) {
837ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fRenderTarget.reset(SkSafeRef(target));
8389ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com    }
8398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
841ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com     * Retrieves the currently set render-target.
8428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
8438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return    The currently set render target.
8448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
845ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    const GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
846ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    GrRenderTarget* getRenderTarget() { return fRenderTarget.get(); }
8478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    class AutoRenderTargetRestore : public ::GrNoncopyable {
8498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    public:
850cadbcb8e536f89babb4e165bfdca18384e97d582bsalomon@google.com        AutoRenderTargetRestore() : fDrawState(NULL), fSavedTarget(NULL) {}
8518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) {
8528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            fDrawState = NULL;
8537460b378d68217167013ca889a4cdcae742908e7robertphillips@google.com            fSavedTarget = NULL;
8548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            this->set(ds, newTarget);
8558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
8569ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        ~AutoRenderTargetRestore() { this->restore(); }
8579ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
8589ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        void restore() {
8598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (NULL != fDrawState) {
8608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fDrawState->setRenderTarget(fSavedTarget);
8619ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com                fDrawState = NULL;
8628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
8639ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com            GrSafeSetNull(fSavedTarget);
8649ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        }
8659ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
8669ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        void set(GrDrawState* ds, GrRenderTarget* newTarget) {
8679ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com            this->restore();
8689ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
8698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (NULL != ds) {
8709ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com                GrAssert(NULL == fSavedTarget);
8718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fSavedTarget = ds->getRenderTarget();
8729ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com                SkSafeRef(fSavedTarget);
8738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                ds->setRenderTarget(newTarget);
8749ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com                fDrawState = ds;
8758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
8768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
8778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    private:
8788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrDrawState* fDrawState;
8798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrRenderTarget* fSavedTarget;
8808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    };
8818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
8838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
8858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Stencil
8868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
8878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
8898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the stencil settings to use for the next draw.
8908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Changing the clip has the side-effect of possibly zeroing
8918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * out the client settable stencil bits. So multipass algorithms
8928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * using stencil should not change the clip between passes.
8938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param settings  the stencil settings to use.
8948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
8958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setStencil(const GrStencilSettings& settings) {
896ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fStencilSettings = settings;
8978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
8988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
9008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Shortcut to disable stencil testing and ops.
9018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
9028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void disableStencil() {
903ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fStencilSettings.setDisabled();
9048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
9058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
906ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    const GrStencilSettings& getStencil() const { return fCommon.fStencilSettings; }
9078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
908ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    GrStencilSettings* stencil() { return &fCommon.fStencilSettings; }
9098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
9108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
9118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
9128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
9138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name State Flags
9148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
9158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
9168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
9178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Flags that affect rendering. Controlled using enable/disableState(). All
9188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  default to disabled.
9198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
9208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    enum StateBits {
9218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
9228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Perform dithering. TODO: Re-evaluate whether we need this bit
9238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
9248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kDither_StateBit        = 0x01,
9258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
926cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
927cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
928cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * the 3D API.
9298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
9308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kHWAntialias_StateBit   = 0x02,
9318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
9328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Draws will respect the clip, otherwise the clip is ignored.
9338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
9348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kClip_StateBit          = 0x04,
9358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
9368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Disables writing to the color buffer. Useful when performing stencil
9378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * operations.
9388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
9398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kNoColorWrites_StateBit = 0x08,
9400342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com
941cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com        /**
942cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * Usually coverage is applied after color blending. The color is blended using the coeffs
943cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * specified by setBlendFunc(). The blended color is then combined with dst using coeffs
944cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * of src_coverage, 1-src_coverage. Sometimes we are explicitly drawing a coverage mask. In
945cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * this case there is no distinction between coverage and color and the caller needs direct
946cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * control over the blend coeffs. When set, there will be a single blend step controlled by
947cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * setBlendFunc() which will use coverage*color as the src color.
948cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         */
949cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         kCoverageDrawing_StateBit = 0x10,
950cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com
9518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // Users of the class may add additional bits to the vector
9528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kDummyStateBit,
9538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kLastPublicStateBit = kDummyStateBit-1,
9548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    };
9558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
9568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void resetStateFlags() {
957ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fFlagBits = 0;
9580fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
9590fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
9608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
9618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Enable render state settings.
9628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
9631e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * @param stateBits bitfield of StateBits specifying the states to enable
9648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
9658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void enableState(uint32_t stateBits) {
966ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fFlagBits |= stateBits;
9678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
9680fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
9698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
9708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Disable render state settings.
9718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
9721e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * @param stateBits bitfield of StateBits specifying the states to disable
9738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
9748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void disableState(uint32_t stateBits) {
975ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fFlagBits &= ~(stateBits);
9768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
9770fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
978d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com    /**
979d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com     * Enable or disable stateBits based on a boolean.
980d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com     *
9811e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * @param stateBits bitfield of StateBits to enable or disable
982d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com     * @param enable    if true enable stateBits, otherwise disable
983d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com     */
984d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com    void setState(uint32_t stateBits, bool enable) {
985d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com        if (enable) {
986d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com            this->enableState(stateBits);
987d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com        } else {
988d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com            this->disableState(stateBits);
989d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com        }
990d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com    }
991d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com
9928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isDitherState() const {
993ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        return 0 != (fCommon.fFlagBits & kDither_StateBit);
9948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
9950fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
9968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isHWAntialiasState() const {
997ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        return 0 != (fCommon.fFlagBits & kHWAntialias_StateBit);
9988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
9990fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
10008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isClipState() const {
1001ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        return 0 != (fCommon.fFlagBits & kClip_StateBit);
10028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
10030fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
10048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isColorWriteDisabled() const {
1005ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        return 0 != (fCommon.fFlagBits & kNoColorWrites_StateBit);
10068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
10078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1008cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com    bool isCoverageDrawing() const {
1009ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        return 0 != (fCommon.fFlagBits & kCoverageDrawing_StateBit);
1010cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com    }
1011cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com
10128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isStateFlagEnabled(uint32_t stateBit) const {
1013ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        return 0 != (stateBit & fCommon.fFlagBits);
10148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
10158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
10168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
10178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
10188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
10198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Face Culling
10208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
10218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
10228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    enum DrawFace {
1023978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com        kInvalid_DrawFace = -1,
1024978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com
10258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kBoth_DrawFace,
10268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kCCW_DrawFace,
10278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kCW_DrawFace,
10288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    };
10298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
10308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
10318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Controls whether clockwise, counterclockwise, or both faces are drawn.
10328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param face  the face(s) to draw.
10338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
10348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setDrawFace(DrawFace face) {
1035978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com        GrAssert(kInvalid_DrawFace != face);
1036ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fDrawFace = face;
10378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
10388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
10398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
10408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Gets whether the target is drawing clockwise, counterclockwise,
10418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * or both faces.
10428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return the current draw face(s).
10438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
1044ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    DrawFace getDrawFace() const { return fCommon.fDrawFace; }
1045d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
10468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
10478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
10488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
104962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
1050f13f58804659175925042a291304d483a4fd9278tomhudson@google.com    bool isStageEnabled(int s) const {
1051f13f58804659175925042a291304d483a4fd9278tomhudson@google.com        GrAssert((unsigned)s < kNumStages);
105208283afc265f1153834256fc1012519813ba6b73bsalomon@google.com        return (NULL != fStages[s].getEffect());
1053f13f58804659175925042a291304d483a4fd9278tomhudson@google.com    }
1054f13f58804659175925042a291304d483a4fd9278tomhudson@google.com
10559381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    bool operator ==(const GrDrawState& s) const {
1056ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        if (fRenderTarget.get() != s.fRenderTarget.get() || fCommon != s.fCommon) {
10578fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com            return false;
10588fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com        }
1059ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org        if (fVertexAttribs != s.fVertexAttribs) {
10609b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com            return false;
10619b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        }
10629b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        for (int i = 0; i < kAttribIndexCount; ++i) {
1063c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com            if ((i == kPosition_AttribIndex || s.fCommon.fAttribBindings & (1 << i)) &&
10649b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com                fAttribIndices[i] != s.fAttribIndices[i]) {
10659b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com                return false;
10669b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com            }
10679b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        }
106862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        for (int i = 0; i < kNumStages; i++) {
1069f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com            bool enabled = this->isStageEnabled(i);
1070f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com            if (enabled != s.isStageEnabled(i)) {
1071f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com                return false;
1072f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com            }
107308283afc265f1153834256fc1012519813ba6b73bsalomon@google.com            if (enabled && this->fStages[i] != s.fStages[i]) {
107462b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com                return false;
107562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com            }
107662b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        }
107762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        return true;
10789381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    }
10799381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    bool operator !=(const GrDrawState& s) const { return !(*this == s); }
108062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
1081ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    GrDrawState& operator= (const GrDrawState& s) {
1082ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        this->setRenderTarget(s.fRenderTarget.get());
1083ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon = s.fCommon;
10849b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        fVertexAttribs = s.fVertexAttribs;
10859b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        for (int i = 0; i < kAttribIndexCount; i++) {
10869b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com            fAttribIndices[i] = s.fAttribIndices[i];
10879b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        }
108862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        for (int i = 0; i < kNumStages; i++) {
1089e742bf0ab19659145325ac894f7e0b78c8efbd89tomhudson@google.com            if (s.isStageEnabled(i)) {
109008283afc265f1153834256fc1012519813ba6b73bsalomon@google.com                this->fStages[i] = s.fStages[i];
109162b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com            }
109262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        }
109362b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        return *this;
109462b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    }
109562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
109662b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.comprivate:
10972e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com
1098ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    /** Fields that are identical in GrDrawState and GrDrawState::DeferredState. */
1099ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    struct CommonState {
1100ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        // These fields are roughly sorted by decreasing likelihood of being different in op==
1101ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        GrColor                         fColor;
11029b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        GrAttribBindings                fAttribBindings;
1103ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        SkMatrix                        fViewMatrix;
1104ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        GrBlendCoeff                    fSrcBlend;
1105ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        GrBlendCoeff                    fDstBlend;
1106ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        GrColor                         fBlendConstant;
1107ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        uint32_t                        fFlagBits;
1108ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        GrStencilSettings               fStencilSettings;
1109ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        int                             fFirstCoverageStage;
1110ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        GrColor                         fCoverage;
1111ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        SkXfermode::Mode                fColorFilterMode;
1112ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        GrColor                         fColorFilterColor;
1113ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        DrawFace                        fDrawFace;
1114ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        bool operator== (const CommonState& other) const {
1115ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            return fColor == other.fColor &&
11169b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com                   fAttribBindings == other.fAttribBindings &&
1117ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                   fViewMatrix.cheapEqualTo(other.fViewMatrix) &&
1118ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                   fSrcBlend == other.fSrcBlend &&
1119ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                   fDstBlend == other.fDstBlend &&
1120ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                   fBlendConstant == other.fBlendConstant &&
1121ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                   fFlagBits == other.fFlagBits &&
1122ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                   fStencilSettings == other.fStencilSettings &&
1123ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                   fFirstCoverageStage == other.fFirstCoverageStage &&
1124ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                   fCoverage == other.fCoverage &&
1125ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                   fColorFilterMode == other.fColorFilterMode &&
1126ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                   fColorFilterColor == other.fColorFilterColor &&
1127ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                   fDrawFace == other.fDrawFace;
1128ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        }
1129ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        bool operator!= (const CommonState& other) const { return !(*this == other); }
1130ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    };
1131ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com
1132ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    /** GrDrawState uses GrEffectStages to hold stage state which holds a ref on GrEffectRef.
1133ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        DeferredState must directly reference GrEffects, however. */
1134ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    struct SavedEffectStage {
1135ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        SavedEffectStage() : fEffect(NULL) {}
1136ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        const GrEffect*                    fEffect;
1137ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        GrEffectStage::SavedCoordChange    fCoordChange;
1138ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    };
1139ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com
1140ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.compublic:
1141ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    /**
1142ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com     * DeferredState contains all of the data of a GrDrawState but does not hold refs on GrResource
1143ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com     * objects. Resources are allowed to hit zero ref count while in DeferredStates. Their internal
1144ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com     * dispose mechanism returns them to the cache. This allows recycling resources through the
1145ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com     * the cache while they are in a deferred draw queue.
1146ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com     */
1147ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    class DeferredState {
1148ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    public:
1149ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        DeferredState() : fRenderTarget(NULL) {
1150ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            GR_DEBUGCODE(fInitialized = false;)
1151ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        }
1152ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        // TODO: Remove this when DeferredState no longer holds a ref to the RT
1153ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        ~DeferredState() { SkSafeUnref(fRenderTarget); }
1154ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com
1155ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        void saveFrom(const GrDrawState& drawState) {
1156ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            fCommon = drawState.fCommon;
1157ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            // TODO: Here we will copy the GrRenderTarget pointer without taking a ref.
1158ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            fRenderTarget = drawState.fRenderTarget.get();
1159ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            SkSafeRef(fRenderTarget);
11609b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com            fVertexAttribs = drawState.fVertexAttribs;
11619b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com            for (int i = 0; i < kAttribIndexCount; i++) {
11629b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com                fAttribIndices[i] = drawState.fAttribIndices[i];
11639b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com            }
1164ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            // Here we ref the effects directly rather than the effect-refs. TODO: When the effect-
1165ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            // ref gets fully unref'ed it will cause the underlying effect to unref its resources
1166ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            // and recycle them to the cache (if no one else is holding a ref to the resources).
1167ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            for (int i = 0; i < kNumStages; ++i) {
1168ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                fStages[i].saveFrom(drawState.fStages[i]);
1169ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            }
1170ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            GR_DEBUGCODE(fInitialized = true;)
1171ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        }
1172ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com
1173ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        void restoreTo(GrDrawState* drawState) {
1174ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            GrAssert(fInitialized);
1175ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            drawState->fCommon = fCommon;
1176ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            drawState->setRenderTarget(fRenderTarget);
11779b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com            drawState->fVertexAttribs = fVertexAttribs;
11789b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com            for (int i = 0; i < kAttribIndexCount; i++) {
11799b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com                drawState->fAttribIndices[i] = fAttribIndices[i];
11809b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com            }
1181ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            for (int i = 0; i < kNumStages; ++i) {
1182ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                fStages[i].restoreTo(&drawState->fStages[i]);
1183ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            }
1184ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        }
1185ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com
1186ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        bool isEqual(const GrDrawState& state) const {
1187ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            if (fRenderTarget != state.fRenderTarget.get() || fCommon != state.fCommon) {
1188ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                return false;
1189ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            }
11909b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com            for (int i = 0; i < kAttribIndexCount; ++i) {
1191f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com                if ((i == kPosition_AttribIndex ||
11929b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com                     state.fCommon.fAttribBindings & kAttribIndexMasks[i]) &&
11939b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com                    fAttribIndices[i] != state.fAttribIndices[i]) {
11949b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com                    return false;
11959b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com                }
11969b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com            }
1197ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org            if (fVertexAttribs != state.fVertexAttribs) {
11989b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com                return false;
11999b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com            }
1200ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            for (int i = 0; i < kNumStages; ++i) {
1201dcd69bfca1d8e85ef5abc4e54f1e4b820d38e428bsalomon@google.com                if (!fStages[i].isEqual(state.fStages[i])) {
1202ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                    return false;
1203ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                }
1204ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            }
1205ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            return true;
1206ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        }
1207ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com
1208ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    private:
12099b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        GrRenderTarget*                       fRenderTarget;
12109b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        CommonState                           fCommon;
12119b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        int                                   fAttribIndices[kAttribIndexCount];
12129b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        GrVertexAttribArray<kVertexAttribCnt> fVertexAttribs;
12139b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        GrEffectStage::DeferredStage          fStages[kNumStages];
1214ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com
1215ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        GR_DEBUGCODE(bool fInitialized;)
1216ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    };
1217ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com
1218ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.comprivate:
12199b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    // helper array to let us check the current bindings so we know what bound attrib indices
12209b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    // we care about
12219b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    static const GrAttribBindings kAttribIndexMasks[kAttribIndexCount];
12229b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
12239b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    SkAutoTUnref<GrRenderTarget>           fRenderTarget;
12249b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    CommonState                            fCommon;
12259b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    int                                    fAttribIndices[kAttribIndexCount];
12269b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    GrVertexAttribArray<kVertexAttribCnt>  fVertexAttribs;
12279b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    GrEffectStage                          fStages[kNumStages];
12288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1229fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com    typedef GrRefCnt INHERITED;
12309381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com};
12319381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
12322b446734cfa8201e5478648988de86b646cb9544bsalomon@google.comGR_MAKE_BITFIELD_OPS(GrDrawState::BlendOptFlags);
12332b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com
12349381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#endif
1235