GrDrawState.h revision 4647f9059825c062169d4d454c12640d82ae16c0
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"
1968b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com#include "effects/GrSimpleTextureEffect.h"
209381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
21cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com#include "SkMatrix.h"
229381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#include "SkXfermode.h"
239381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
24af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.comclass GrPaint;
259381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
269b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com/**
279b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com * Types used to describe format of vertices in arrays
289b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com  */
299b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.comenum GrVertexAttribType {
309b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    kFloat_GrVertexAttribType = 0,
319b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    kVec2f_GrVertexAttribType,
329b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    kVec3f_GrVertexAttribType,
339b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    kVec4f_GrVertexAttribType,
349b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    kVec4ub_GrVertexAttribType,   // vector of 4 unsigned bytes, e.g. colors
359b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
369b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    kLast_GrVertexAttribType = kVec4ub_GrVertexAttribType
379b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com};
389b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.comstatic const int kGrVertexAttribTypeCount = kLast_GrVertexAttribType + 1;
399b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
409b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.comstruct GrVertexAttrib {
41f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com    inline void set(GrVertexAttribType type, size_t offset) {
423b0d631cdfe2dcf59e7b7ea60d92566eade7bfc0jvanverth@google.com        fType = type; fOffset = offset;
433b0d631cdfe2dcf59e7b7ea60d92566eade7bfc0jvanverth@google.com    }
449b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    bool operator==(const GrVertexAttrib& other) const {
459b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        return fType == other.fType && fOffset == other.fOffset;
469b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    };
479b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    bool operator!=(const GrVertexAttrib& other) const { return !(*this == other); }
489b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
499b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    GrVertexAttribType fType;
509b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    size_t             fOffset;
519b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com};
529b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
539b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.comtemplate <int N>
549b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.comclass GrVertexAttribArray : public SkSTArray<N, GrVertexAttrib, true> {};
559b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
569b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com/**
579b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com * Type used to describe how attributes bind to program usage
589b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com */
599b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.comtypedef int GrAttribBindings;
609b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
612e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.comclass GrDrawState : public GrRefCnt {
622e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.compublic:
63fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com    SK_DECLARE_INST_COUNT(GrDrawState)
64d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
659381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    /**
661322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * Total number of effect stages. Each stage can host a GrEffect. A stage is enabled if it has a
671322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * GrEffect. The effect produces an output color in the fragment shader. It's inputs are the
681322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * output from the previous enabled stage and a position. The position is either derived from
691322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * the interpolated vertex positions or explicit per-vertex coords, depending upon the
709b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     * GrAttribBindings used to draw.
71bf5cad4e9c5808493b35cb9b0000a2d36b7f9b78robertphillips@google.com     *
721322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * The stages are divided into two sets, color-computing and coverage-computing. The final color
731322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * stage produces the final pixel color. The coverage-computing stages function exactly as the
741322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * color-computing but the output of the final coverage stage is treated as a fractional pixel
751322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * coverage rather than as input to the src/dst color blend step.
761322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     *
771322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * The input color to the first enabled color-stage is either the constant color or interpolated
789b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     * per-vertex colors, depending upon GrAttribBindings. The input to the first coverage stage is
794647f9059825c062169d4d454c12640d82ae16c0bsalomon@google.com     * either a constant coverage (usually full-coverage) or interpolated per-vertex coverage.
801322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     *
81cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com     * See the documentation of kCoverageDrawing_StateBit for information about disabling the
82cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com     * the color / coverage distinction.
83cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com     *
841322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * Stages 0 through GrPaint::kTotalStages-1 are reserved for stages copied from the client's
851322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * GrPaint. Stages GrPaint::kTotalStages through kNumStages-2 are earmarked for use by
861322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * GrTextContext and GrPathRenderer-derived classes. kNumStages-1 is earmarked for clipping
87dfdb7e5240276493077b7c6e1f3cc8b8a0e195babsalomon@google.com     * by GrClipMaskManager.
889381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     */
899381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    enum {
90580711694654b8edc70028d09c4211445b661466twiz@google.com        kNumStages = 5,
919381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    };
929381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
93ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    GrDrawState() {
9475847199c25121c9989e8dba103ac6002d2132d6reed@google.com#if GR_DEBUG
959b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        VertexAttributesUnitTest();
9675847199c25121c9989e8dba103ac6002d2132d6reed@google.com#endif
9752a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        this->reset();
9852a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    }
9946f7afb9867200b568c21736da8a8bbb56b20e30bsalomon@google.com
100ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    GrDrawState(const GrDrawState& state) {
10146f7afb9867200b568c21736da8a8bbb56b20e30bsalomon@google.com        *this = state;
10246f7afb9867200b568c21736da8a8bbb56b20e30bsalomon@google.com    }
10346f7afb9867200b568c21736da8a8bbb56b20e30bsalomon@google.com
1049ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com    virtual ~GrDrawState() {
1057d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        this->disableStages();
1069ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com    }
1079ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
10852a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    /**
1097d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com     * Resets to the default state.
11008283afc265f1153834256fc1012519813ba6b73bsalomon@google.com     * GrEffects will be removed from all stages.
111d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     */
11252a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    void reset() {
1139ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
1147d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        this->disableStages();
11552a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com
116ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fRenderTarget.reset(NULL);
117ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com
1189b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        this->setDefaultVertexAttribs();
1199b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
120ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fColor = 0xffffffff;
121ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fViewMatrix.reset();
122ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fSrcBlend = kOne_GrBlendCoeff;
123ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fDstBlend = kZero_GrBlendCoeff;
124ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fBlendConstant = 0x0;
125ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fFlagBits = 0x0;
126ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fStencilSettings.setDisabled();
127ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fFirstCoverageStage = kNumStages;
128ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fCoverage = 0xffffffff;
129ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fColorFilterMode = SkXfermode::kDst_Mode;
130ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fColorFilterColor = 0x0;
131ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fDrawFace = kBoth_DrawFace;
132af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com    }
133af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com
134af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com    /**
135af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com     * Initializes the GrDrawState based on a GrPaint. Note that GrDrawState
1361e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * encompasses more than GrPaint. Aspects of GrDrawState that have no
137af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com     * GrPaint equivalents are not modified. GrPaint has fewer stages than
138af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com     * GrDrawState. The extra GrDrawState stages are disabled.
139af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com     */
140af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com    void setFromPaint(const GrPaint& paint);
1418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
1439b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    /// @name Vertex Attributes
144cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    ////
145cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com
1469b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    enum {
1479b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        kVertexAttribCnt = 6,
148af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com    };
149cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com
1509b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com   /**
151f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com     * The format of vertices is represented as an array of vertex attribute
152f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com     * pair, with each pair representing the type of the attribute and the
153f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com     * offset in the vertex structure (see GrVertexAttrib, above).
154cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     *
1559b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     * This will only set up the vertex geometry. To bind the attributes in
156f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com     * the shaders, attribute indices and attribute bindings need to be set
1579b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     * as well.
158cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     */
159af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com
160af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com    /**
161f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com     *  Sets vertex attributes for next draw.
162af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com     *
163f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com     *  @param attribs    the array of vertex attributes to set.
1649b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     *  @param count      the number of attributes being set.
165f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com     *                    limited to a count of kVertexAttribCnt.
166af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com     */
1679b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    void setVertexAttribs(const GrVertexAttrib attribs[], int count);
168af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com
1699b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    const GrVertexAttrib* getVertexAttribs() const { return fVertexAttribs.begin(); }
1709b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    int getVertexAttribCount() const { return fVertexAttribs.count(); }
1719b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
1729b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    size_t getVertexSize() const;
173af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com
174af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com    /**
175f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com     *  Sets default vertex attributes for next draw.
176af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com     *
1779b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     *  This will also set default vertex attribute indices and bindings
178af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com     */
1799b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    void setDefaultVertexAttribs();
180af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com
181ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org    bool validateVertexAttribs() const;
182ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org
1839b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    ////////////////////////////////////////////////////////////////////////////
1849b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    // Helpers for picking apart vertex attributes
185af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com
1869b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    // helper array to let us check the expected so we know what bound attrib indices
1879b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    // we care about
1889b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    static const size_t kVertexAttribSizes[kGrVertexAttribTypeCount];
189cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com
190cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    /**
191cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * Accessing positions, texture coords, or colors, of a vertex within an
192cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * array is a hassle involving casts and simple math. These helpers exist
193cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * to keep GrDrawTarget clients' code a bit nicer looking.
194cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     */
195cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com
196cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    /**
197cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * Gets a pointer to a GrPoint of a vertex's position or texture
198cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * coordinate.
1999b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     * @param vertices      the vertex array
200cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * @param vertexIndex   the index of the vertex in the array
201cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * @param vertexSize    the size of each vertex in the array
202cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * @param offset        the offset in bytes of the vertex component.
203cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     *                      Defaults to zero (corresponding to vertex position)
204cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * @return pointer to the vertex component as a GrPoint
205cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     */
206cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    static GrPoint* GetVertexPoint(void* vertices,
207cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                   int vertexIndex,
208cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                   int vertexSize,
209cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                   int offset = 0) {
210cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com        intptr_t start = GrTCast<intptr_t>(vertices);
211cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com        return GrTCast<GrPoint*>(start + offset +
212cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                 vertexIndex * vertexSize);
213cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    }
214cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    static const GrPoint* GetVertexPoint(const void* vertices,
215cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                         int vertexIndex,
216cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                         int vertexSize,
217cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                         int offset = 0) {
218cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com        intptr_t start = GrTCast<intptr_t>(vertices);
219cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com        return GrTCast<const GrPoint*>(start + offset +
220cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                       vertexIndex * vertexSize);
221cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    }
222cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com
223cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    /**
224cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * Gets a pointer to a GrColor inside a vertex within a vertex array.
225cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * @param vertices      the vetex array
226cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * @param vertexIndex   the index of the vertex in the array
227cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * @param vertexSize    the size of each vertex in the array
228cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * @param offset        the offset in bytes of the vertex color
229cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * @return pointer to the vertex component as a GrColor
230cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     */
231cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    static GrColor* GetVertexColor(void* vertices,
232cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                   int vertexIndex,
233cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                   int vertexSize,
234cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                   int offset) {
235cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com        intptr_t start = GrTCast<intptr_t>(vertices);
236cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com        return GrTCast<GrColor*>(start + offset +
237cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                 vertexIndex * vertexSize);
238cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    }
239cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    static const GrColor* GetVertexColor(const void* vertices,
240cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                         int vertexIndex,
241cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                         int vertexSize,
242cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                         int offset) {
243cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com        const intptr_t start = GrTCast<intptr_t>(vertices);
244cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com        return GrTCast<const GrColor*>(start + offset +
245cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                       vertexIndex * vertexSize);
246cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    }
247cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com
2489b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    /// @}
2499b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
2509b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    ///////////////////////////////////////////////////////////////////////////
2519b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    /// @name Attribute Bindings
2529b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    ////
2539b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
2549b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    /**
255f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com     * The vertex data used by the current program is represented as a bitfield
256f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com     * of flags. Programs always use positions and may also use texture
257c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com     * coordinates, per-vertex colors, per-vertex coverage and edge data. The
258c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com     * local coords accessible by effects may either come from positions or
259c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com     * be specified explicitly.
2609b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     */
2619b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
2629b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    /**
2639b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     * Additional Bits that can be specified in GrAttribBindings.
2649b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     */
2659b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    enum AttribBindingsBits {
266c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        /** explicit local coords are provided (instead of using pre-view-matrix positions) */
267c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        kLocalCoords_AttribBindingsBit        = 0x1,
2689b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        /* program uses colors (GrColor) */
269c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        kColor_AttribBindingsBit              = 0x2,
2709b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        /* program uses coverage (GrColor)
2719b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com         */
272c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        kCoverage_AttribBindingsBit           = 0x4,
2739b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        // for below assert
2749b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        kDummyAttribBindingsBit,
2759b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        kHighAttribBindingsBit = kDummyAttribBindingsBit - 1
2769b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    };
2779b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    // make sure we haven't exceeded the number of bits in GrAttribBindings.
2789b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    GR_STATIC_ASSERT(kHighAttribBindingsBit < ((uint64_t)1 << 8*sizeof(GrAttribBindings)));
2799b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
2809b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    enum AttribBindings {
2819b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        kDefault_AttribBindings = 0
2829b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    };
2839b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
2849b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    /**
2859b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     *  Sets attribute bindings for next draw.
2869b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     *
2879b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     *  @param bindings    the attribute bindings to set.
2889b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     */
2899b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    void setAttribBindings(GrAttribBindings bindings) { fCommon.fAttribBindings = bindings; }
2909b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
2919b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    GrAttribBindings getAttribBindings() const { return fCommon.fAttribBindings; }
2929b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
2939b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    ////////////////////////////////////////////////////////////////////////////
2949b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    // Helpers for picking apart attribute bindings
2959b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
2969b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    /**
2979b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     * Determines whether src alpha is guaranteed to be one for all src pixels
2989b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     */
2999b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    bool srcAlphaWillBeOne(GrAttribBindings) const;
3009b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
3019b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    /**
3029b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     * Determines whether the output coverage is guaranteed to be one for all pixels hit by a draw.
3039b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     */
3049b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    bool hasSolidCoverage(GrAttribBindings) const;
3059b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
3069b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    static void VertexAttributesUnitTest();
30791274b99722d9be62e077ab979c630c23cdd04b1skia.committer@gmail.com
3089b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    /// @}
3099b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
3109b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    ///////////////////////////////////////////////////////////////////////////
3119b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    /// @name Vertex Attribute Indices
3129b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    ////
3139b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
3149b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    /**
3159b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     * Vertex attribute indices map the data set in the vertex attribute array
3169b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     * to the bindings specified in the attribute bindings. Each binding type
317f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com     * has an associated index in the attribute array. This index is used to
318f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com     * look up the vertex attribute data from the array, and potentially as the
3199b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     * attribute index if we're binding attributes in GL.
320f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com     *
3219b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     * Indices which do not have active attribute bindings will be ignored.
3229b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     */
3239b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
3249b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    enum AttribIndex {
3259b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        kPosition_AttribIndex = 0,
3269b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        kColor_AttribIndex,
3279b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        kCoverage_AttribIndex,
328c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        kLocalCoords_AttribIndex,
3299b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
330c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        kLast_AttribIndex = kLocalCoords_AttribIndex
3319b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    };
3329b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    static const int kAttribIndexCount = kLast_AttribIndex + 1;
3339b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
3349b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    // these are used when vertex color and coverage isn't set
3359b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    enum {
3369b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        kColorOverrideAttribIndexValue = GrDrawState::kVertexAttribCnt,
3379b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        kCoverageOverrideAttribIndexValue = GrDrawState::kVertexAttribCnt+1,
3389b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    };
3399b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
3409b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    ////////////////////////////////////////////////////////////////////////////
341f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com    // Helpers to set attribute indices. These should match the index in the
342f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com    // current attribute index array.
3439b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
3449b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    /**
345f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com     *  Sets index for next draw. This is used to look up the offset
3469b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     *  from the current vertex attribute array and to bind the attributes.
3479b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     *
3489b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     *  @param index      the attribute index we're setting
3499b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     *  @param value      the value of the index
3509b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     */
3519b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    void setAttribIndex(AttribIndex index, int value) { fAttribIndices[index] = value; }
3529b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
3539b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    int getAttribIndex(AttribIndex index) const       { return fAttribIndices[index]; }
354cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com
355cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    /// @}
356cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com
357cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    ///////////////////////////////////////////////////////////////////////////
3588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Color
3598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
3608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Sets color for next draw to a premultiplied-alpha color.
3638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param color    the color to set.
3658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
366ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    void setColor(GrColor color) { fCommon.fColor = color; }
3678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
368ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    GrColor getColor() const { return fCommon.fColor; }
3698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Sets the color to be used for the next draw to be
3728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  (r,g,b,a) = (alpha, alpha, alpha, alpha).
3738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param alpha The alpha value to set as the color.
3758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setAlpha(uint8_t a) {
3778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        this->setColor((a << 24) | (a << 16) | (a << 8) | a);
3788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
3798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Add a color filter that can be represented by a color and a mode. Applied
382c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com     * after color-computing effect stages.
3838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setColorFilter(GrColor c, SkXfermode::Mode mode) {
385ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fColorFilterColor = c;
386ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fColorFilterMode = mode;
3878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
3888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
389ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    GrColor getColorFilterColor() const { return fCommon.fColorFilterColor; }
390ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    SkXfermode::Mode getColorFilterMode() const { return fCommon.fColorFilterMode; }
3918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3925b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    /**
3935b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com     * Constructor sets the color to be 'color' which is undone by the destructor.
3945b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com     */
3955b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    class AutoColorRestore : public ::GrNoncopyable {
3965b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    public:
39766a58aca8379a33ccc7572a31c74a3334d08b47csugoi@google.com        AutoColorRestore() : fDrawState(NULL), fOldColor(0) {}
398d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
3995b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        AutoColorRestore(GrDrawState* drawState, GrColor color) {
400d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            fDrawState = NULL;
401d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            this->set(drawState, color);
402d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        }
403d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
404d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        void reset() {
405d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            if (NULL != fDrawState) {
406d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                fDrawState->setColor(fOldColor);
407d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                fDrawState = NULL;
408d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            }
409d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        }
410d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
411d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        void set(GrDrawState* drawState, GrColor color) {
412d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            this->reset();
4135b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com            fDrawState = drawState;
4145b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com            fOldColor = fDrawState->getColor();
4155b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com            fDrawState->setColor(color);
4165b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        }
417d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
418d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        ~AutoColorRestore() { this->reset(); }
4195b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    private:
4205b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        GrDrawState*    fDrawState;
4215b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        GrColor         fOldColor;
4225b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    };
4235b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com
4248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
4258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
4272401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    /// @name Coverage
4282401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    ////
4292401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com
4302401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    /**
431d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     * Sets a constant fractional coverage to be applied to the draw. The
4322401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     * initial value (after construction or reset()) is 0xff. The constant
4332401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     * coverage is ignored when per-vertex coverage is provided.
4342401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     */
4352401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    void setCoverage(uint8_t coverage) {
436ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage);
4372401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    }
4382401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com
4392401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    /**
4402401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     * Version of above that specifies 4 channel per-vertex color. The value
4412401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     * should be premultiplied.
4422401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     */
4432401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    void setCoverage4(GrColor coverage) {
444ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fCoverage = coverage;
4452401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    }
4462401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com
4472401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    GrColor getCoverage() const {
448ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        return fCommon.fCoverage;
4492401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    }
4502401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com
4512401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    /// @}
4522401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com
4532401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
454adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com    /// @name Effect Stages
4558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
4568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
45765eb4d5a210884cc92c43a8582cbd1ccbddcab57jvanverth@google.com    const GrEffectRef* setEffect(int stageIdx, const GrEffectRef* effect) {
45865eb4d5a210884cc92c43a8582cbd1ccbddcab57jvanverth@google.com        fStages[stageIdx].setEffect(effect);
45965eb4d5a210884cc92c43a8582cbd1ccbddcab57jvanverth@google.com        return effect;
46065eb4d5a210884cc92c43a8582cbd1ccbddcab57jvanverth@google.com    }
46101c34ee59906f729f6ca7d35f0c0e5e2f5e693feskia.committer@gmail.com
46291274b99722d9be62e077ab979c630c23cdd04b1skia.committer@gmail.com    const GrEffectRef* setEffect(int stageIdx, const GrEffectRef* effect,
46365eb4d5a210884cc92c43a8582cbd1ccbddcab57jvanverth@google.com                                 int attr0, int attr1 = -1) {
46465eb4d5a210884cc92c43a8582cbd1ccbddcab57jvanverth@google.com        fStages[stageIdx].setEffect(effect, attr0, attr1);
465adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com        return effect;
466adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com    }
467adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com
4688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
469c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com     * Creates a GrSimpleTextureEffect that uses local coords as texture coordinates.
4701e8f016305805d4d8cad74aba3a21b78486f9d6ftomhudson@google.com     */
471b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com    void createTextureEffect(int stageIdx, GrTexture* texture, const SkMatrix& matrix) {
47208283afc265f1153834256fc1012519813ba6b73bsalomon@google.com        GrAssert(!this->getStage(stageIdx).getEffect());
47368b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com        GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix);
474adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com        this->setEffect(stageIdx, effect)->unref();
475dfdb7e5240276493077b7c6e1f3cc8b8a0e195babsalomon@google.com    }
47608283afc265f1153834256fc1012519813ba6b73bsalomon@google.com    void createTextureEffect(int stageIdx,
47708283afc265f1153834256fc1012519813ba6b73bsalomon@google.com                             GrTexture* texture,
478b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com                             const SkMatrix& matrix,
479dfdb7e5240276493077b7c6e1f3cc8b8a0e195babsalomon@google.com                             const GrTextureParams& params) {
48008283afc265f1153834256fc1012519813ba6b73bsalomon@google.com        GrAssert(!this->getStage(stageIdx).getEffect());
48168b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com        GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params);
482adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com        this->setEffect(stageIdx, effect)->unref();
4831ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com    }
4841ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com
4857d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com    bool stagesDisabled() {
4867d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        for (int i = 0; i < kNumStages; ++i) {
48708283afc265f1153834256fc1012519813ba6b73bsalomon@google.com            if (NULL != fStages[i].getEffect()) {
4887d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com                return false;
4897d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com            }
4907d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        }
4913eee8fbe0f280bc1dea59dc0b0ebd8021b51137ftomhudson@google.com        return true;
4927d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com    }
493676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com
49491274b99722d9be62e077ab979c630c23cdd04b1skia.committer@gmail.com    void disableStage(int stageIdx) {
49565eb4d5a210884cc92c43a8582cbd1ccbddcab57jvanverth@google.com        this->setEffect(stageIdx, NULL);
496ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org    }
497676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com
498972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    /**
499f271cc7183fe48ac64d2d9a454eb013c91b42d53bsalomon@google.com     * Release all the GrEffects referred to by this draw state.
500972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com     */
5017d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com    void disableStages() {
502972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com        for (int i = 0; i < kNumStages; ++i) {
503676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com            this->disableStage(i);
504972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com        }
505972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    }
506972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com
5077d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com    class AutoStageDisable : public ::GrNoncopyable {
508972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    public:
5097d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        AutoStageDisable(GrDrawState* ds) : fDrawState(ds) {}
5107d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        ~AutoStageDisable() {
511972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com            if (NULL != fDrawState) {
5127d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com                fDrawState->disableStages();
513972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com            }
514972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com        }
515972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    private:
516972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com        GrDrawState* fDrawState;
517972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    };
518972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com
5198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
52008283afc265f1153834256fc1012519813ba6b73bsalomon@google.com     * Returns the current stage by index.
5218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
52208283afc265f1153834256fc1012519813ba6b73bsalomon@google.com    const GrEffectStage& getStage(int stageIdx) const {
52308283afc265f1153834256fc1012519813ba6b73bsalomon@google.com        GrAssert((unsigned)stageIdx < kNumStages);
52408283afc265f1153834256fc1012519813ba6b73bsalomon@google.com        return fStages[stageIdx];
5258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
5268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
528c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com     * Called when the source coord system is changing. This ensures that effects will see the
529c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com     * correct local coordinates. oldToNew gives the transformation from the old coord system in
530c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com     * which the geometry was specified to the new coordinate system from which it will be rendered.
5318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
532c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com    void localCoordChange(const SkMatrix& oldToNew) {
533e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        for (int i = 0; i < kNumStages; ++i) {
534e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com            if (this->isStageEnabled(i)) {
535c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com                fStages[i].localCoordChange(oldToNew);
536e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com            }
537e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        }
538e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com    }
539e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com
5408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
5418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
5438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Coverage / Color Stages
5448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
5458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
5478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * A common pattern is to compute a color with the initial stages and then
5488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * modulate that color by a coverage value in later stage(s) (AA, mask-
549d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     * filters, glyph mask, etc). Color-filters, xfermodes, etc should be
550d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     * computed based on the pre-coverage-modulated color. The division of
551d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     * stages between color-computing and coverage-computing is specified by
5528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * this method. Initially this is kNumStages (all stages
5538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * are color-computing).
5548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
5558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setFirstCoverageStage(int firstCoverageStage) {
5568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((unsigned)firstCoverageStage <= kNumStages);
557ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fFirstCoverageStage = firstCoverageStage;
5588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
5598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
5618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Gets the index of the first coverage-computing stage.
5628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
5638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    int getFirstCoverageStage() const {
564ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        return fCommon.fFirstCoverageStage;
5658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
5668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///@}
5688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
5708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Blending
5718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
5728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
5741e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * Sets the blending function coefficients.
5758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
5768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * The blend function will be:
5778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *    D' = sat(S*srcCoef + D*dstCoef)
5788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
5798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *   where D is the existing destination color, S is the incoming source
5808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *   color, and D' is the new destination color that will be written. sat()
5818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *   is the saturation function.
5828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
5831e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * @param srcCoef coefficient applied to the src color.
5841e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * @param dstCoef coefficient applied to the dst color.
5858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
5868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
587ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fSrcBlend = srcCoeff;
588ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fDstBlend = dstCoeff;
5898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    #if GR_DEBUG
5908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        switch (dstCoeff) {
59147059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kDC_GrBlendCoeff:
59247059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kIDC_GrBlendCoeff:
59347059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kDA_GrBlendCoeff:
59447059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kIDA_GrBlendCoeff:
5958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
5968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                     "coverage stages.\n");
5978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
5988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        default:
5998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
6008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
6018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        switch (srcCoeff) {
60247059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kSC_GrBlendCoeff:
60347059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kISC_GrBlendCoeff:
60447059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kSA_GrBlendCoeff:
60547059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kISA_GrBlendCoeff:
6068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            GrPrintf("Unexpected src blend coeff. Won't work correctly with"
6078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                     "coverage stages.\n");
6088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
6098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        default:
6108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
6118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
6128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    #endif
6138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
615ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    GrBlendCoeff getSrcBlendCoeff() const { return fCommon.fSrcBlend; }
616ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    GrBlendCoeff getDstBlendCoeff() const { return fCommon.fDstBlend; }
6178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff,
6198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                          GrBlendCoeff* dstBlendCoeff) const {
620ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        *srcBlendCoeff = fCommon.fSrcBlend;
621ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        *dstBlendCoeff = fCommon.fDstBlend;
6228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
6258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the blending function constant referenced by the following blending
6261e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * coefficients:
62747059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com     *      kConstC_GrBlendCoeff
62847059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com     *      kIConstC_GrBlendCoeff
62947059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com     *      kConstA_GrBlendCoeff
63047059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com     *      kIConstA_GrBlendCoeff
6318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
6328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param constant the constant to set
6338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
634ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    void setBlendConstant(GrColor constant) { fCommon.fBlendConstant = constant; }
6358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
6378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Retrieves the last value set by setBlendConstant()
6388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return the blending constant value
6398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
640ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    GrColor getBlendConstant() const { return fCommon.fBlendConstant; }
6418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6422b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com    /**
6432b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * Determines whether multiplying the computed per-pixel color by the pixel's fractional
6442b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * coverage before the blend will give the correct final destination color. In general it
6452b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * will not as coverage is applied after blending.
6462b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     */
6472b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com    bool canTweakAlphaForCoverage() const;
6482b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com
6492b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com    /**
6502b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * Optimizations for blending / coverage to that can be applied based on the current state.
6512b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     */
6522b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com    enum BlendOptFlags {
6532b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        /**
6542b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         * No optimization
6552b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         */
6562b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        kNone_BlendOpt                  = 0,
6572b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        /**
6582b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         * Don't draw at all
6592b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         */
6602b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        kSkipDraw_BlendOptFlag          = 0x1,
6612b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        /**
6622b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         * Emit the src color, disable HW blending (replace dst with src)
6632b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         */
6642b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        kDisableBlend_BlendOptFlag      = 0x2,
6652b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        /**
6662b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         * The coverage value does not have to be computed separately from alpha, the the output
6672b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         * color can be the modulation of the two.
6682b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         */
6692b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        kCoverageAsAlpha_BlendOptFlag   = 0x4,
6702b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        /**
6712b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         * Instead of emitting a src color, emit coverage in the alpha channel and r,g,b are
6722b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         * "don't cares".
6732b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         */
6742b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        kEmitCoverage_BlendOptFlag      = 0x8,
6752b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        /**
6762b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         * Emit transparent black instead of the src color, no need to compute coverage.
6772b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         */
6782b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        kEmitTransBlack_BlendOptFlag    = 0x10,
6792b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com    };
6802b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com    GR_DECL_BITFIELD_OPS_FRIENDS(BlendOptFlags);
6812b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com
6822b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com    /**
6832b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * Determines what optimizations can be applied based on the blend. The coefficients may have
6842b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * to be tweaked in order for the optimization to work. srcCoeff and dstCoeff are optional
6852b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * params that receive the tweaked coefficients. Normally the function looks at the current
6862b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * state to see if coverage is enabled. By setting forceCoverage the caller can speculatively
6872b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * determine the blend optimizations that would be used if there was partial pixel coverage.
6882b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     *
6892b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * Subclasses of GrDrawTarget that actually draw (as opposed to those that just buffer for
6902b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * playback) must call this function and respect the flags that replace the output color.
6912b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     */
6922b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com    BlendOptFlags getBlendOpts(bool forceCoverage = false,
6932b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com                               GrBlendCoeff* srcCoeff = NULL,
6942b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com                               GrBlendCoeff* dstCoeff = NULL) const;
6952b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com
6968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
6978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
6998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name View Matrix
7008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
7018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
703a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com     * Sets the matrix applied to vertex positions.
7048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
7058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * In the post-view-matrix space the rectangle [0,w]x[0,h]
7068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * fully covers the render target. (w and h are the width and height of the
707ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com     * the render-target.)
7088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
709ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    void setViewMatrix(const SkMatrix& m) { fCommon.fViewMatrix = m; }
7108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
7128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Gets a writable pointer to the view matrix.
7138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
714ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    SkMatrix* viewMatrix() { return &fCommon.fViewMatrix; }
7158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
7178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Multiplies the current view matrix by a matrix
7188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
7198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  After this call V' = V*m where V is the old view matrix,
7208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  m is the parameter to this function, and V' is the new view matrix.
7218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  (We consider positions to be column vectors so position vector p is
7228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  transformed by matrix X as p' = X*p.)
7238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
7248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param m the matrix used to modify the view matrix.
7258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
726ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    void preConcatViewMatrix(const SkMatrix& m) { fCommon.fViewMatrix.preConcat(m); }
7278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
7298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Multiplies the current view matrix by a matrix
7308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
7318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  After this call V' = m*V where V is the old view matrix,
7328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  m is the parameter to this function, and V' is the new view matrix.
7338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  (We consider positions to be column vectors so position vector p is
7348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  transformed by matrix X as p' = X*p.)
7358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
7368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param m the matrix used to modify the view matrix.
7378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
738ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    void postConcatViewMatrix(const SkMatrix& m) { fCommon.fViewMatrix.postConcat(m); }
7398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
7418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Retrieves the current view matrix
7428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return the current view matrix.
7438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
744ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    const SkMatrix& getViewMatrix() const { return fCommon.fViewMatrix; }
7458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
7478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Retrieves the inverse of the current view matrix.
7488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
7498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  If the current view matrix is invertible, return true, and if matrix
7508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  is non-null, copy the inverse into it. If the current view matrix is
7518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  non-invertible, return false and ignore the matrix parameter.
7528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
7538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param matrix if not null, will receive a copy of the current inverse.
7548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
755b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com    bool getViewInverse(SkMatrix* matrix) const {
7568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // TODO: determine whether we really need to leave matrix unmodified
7578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // at call sites when inversion fails.
758b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com        SkMatrix inverse;
759ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        if (fCommon.fViewMatrix.invert(&inverse)) {
7608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (matrix) {
7618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                *matrix = inverse;
7628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
7638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            return true;
7648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
7658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return false;
7668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
7678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7685b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    ////////////////////////////////////////////////////////////////////////////
7695b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com
7705b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    /**
7712fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com     * Preconcats the current view matrix and restores the previous view matrix in the destructor.
772c196b522d06919885c6bbe28b7b06d2e5b2cb9bfbsalomon@google.com     * Effect matrices are automatically adjusted to compensate.
7735b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com     */
7748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    class AutoViewMatrixRestore : public ::GrNoncopyable {
7758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    public:
7768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        AutoViewMatrixRestore() : fDrawState(NULL) {}
7772fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
778c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        AutoViewMatrixRestore(GrDrawState* ds, const SkMatrix& preconcatMatrix) {
7798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            fDrawState = NULL;
780c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com            this->set(ds, preconcatMatrix);
7818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
7822fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
7832fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        ~AutoViewMatrixRestore() { this->restore(); }
7842fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
785a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        /**
786a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * Can be called prior to destructor to restore the original matrix.
787a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         */
7882fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        void restore();
789f467ce7bc33af5f496e0619387551aedec6d2517skia.committer@gmail.com
790c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        void set(GrDrawState* drawState, const SkMatrix& preconcatMatrix);
7912fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
792ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com        bool isSet() const { return NULL != fDrawState; }
7932fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
7948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    private:
795288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com        GrDrawState*                        fDrawState;
796b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com        SkMatrix                            fViewMatrix;
79708283afc265f1153834256fc1012519813ba6b73bsalomon@google.com        GrEffectStage::SavedCoordChange     fSavedCoordChanges[GrDrawState::kNumStages];
798288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com        uint32_t                            fRestoreMask;
7999381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    };
8009381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
8015b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    ////////////////////////////////////////////////////////////////////////////
8025b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com
8035b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    /**
8042fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com     * This sets the view matrix to identity and adjusts stage matrices to compensate. The
8052fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com     * destructor undoes the changes, restoring the view matrix that was set before the
8062fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com     * constructor. It is similar to passing the inverse of the current view matrix to
8072fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com     * AutoViewMatrixRestore, but lazily computes the inverse only if necessary.
8085b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com     */
8095b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    class AutoDeviceCoordDraw : ::GrNoncopyable {
8105b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    public:
8112fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        AutoDeviceCoordDraw() : fDrawState(NULL) {}
8125b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        /**
8132fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com         * If a stage's texture matrix is applied to explicit per-vertex coords, rather than to
8142fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com         * positions, then we don't want to modify its matrix. The explicitCoordStageMask is used
8152fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com         * to specify such stages.
8165b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com         */
817c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        AutoDeviceCoordDraw(GrDrawState* drawState) {
8182fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com            fDrawState = NULL;
819c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com            this->set(drawState);
8202fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        }
8212fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
822a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        ~AutoDeviceCoordDraw() { this->restore(); }
823a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com
824c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        bool set(GrDrawState* drawState);
8252fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
826a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        /**
827a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * Returns true if this object was successfully initialized on to a GrDrawState. It may
828a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * return false because a non-default constructor or set() were never called or because
829a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * the view matrix was not invertible.
830a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         */
8315b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        bool succeeded() const { return NULL != fDrawState; }
8322fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
833a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        /**
834a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * Returns the matrix that was set previously set on the drawState. This is only valid
835a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * if succeeded returns true.
836a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         */
837b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com        const SkMatrix& getOriginalMatrix() const {
838a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com            GrAssert(this->succeeded());
839a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com            return fViewMatrix;
840a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        }
8412fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
842a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        /**
843a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * Can be called prior to destructor to restore the original matrix.
844a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         */
845a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        void restore();
8462fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
8475b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    private:
848288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com        GrDrawState*                        fDrawState;
849b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com        SkMatrix                            fViewMatrix;
85008283afc265f1153834256fc1012519813ba6b73bsalomon@google.com        GrEffectStage::SavedCoordChange     fSavedCoordChanges[GrDrawState::kNumStages];
851288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com        uint32_t                            fRestoreMask;
8525b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    };
8535b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com
8548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
8558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
8578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Render Target
8588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
8598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
861ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com     * Sets the render-target used at the next drawing call
8628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
8638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param target  The render target to set.
8648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
865d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    void setRenderTarget(GrRenderTarget* target) {
866ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fRenderTarget.reset(SkSafeRef(target));
8679ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com    }
8688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
870ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com     * Retrieves the currently set render-target.
8718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
8728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return    The currently set render target.
8738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
874ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    const GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
875ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    GrRenderTarget* getRenderTarget() { return fRenderTarget.get(); }
8768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    class AutoRenderTargetRestore : public ::GrNoncopyable {
8788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    public:
879cadbcb8e536f89babb4e165bfdca18384e97d582bsalomon@google.com        AutoRenderTargetRestore() : fDrawState(NULL), fSavedTarget(NULL) {}
8808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) {
8818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            fDrawState = NULL;
8827460b378d68217167013ca889a4cdcae742908e7robertphillips@google.com            fSavedTarget = NULL;
8838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            this->set(ds, newTarget);
8848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
8859ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        ~AutoRenderTargetRestore() { this->restore(); }
8869ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
8879ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        void restore() {
8888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (NULL != fDrawState) {
8898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fDrawState->setRenderTarget(fSavedTarget);
8909ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com                fDrawState = NULL;
8918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
8929ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com            GrSafeSetNull(fSavedTarget);
8939ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        }
8949ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
8959ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        void set(GrDrawState* ds, GrRenderTarget* newTarget) {
8969ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com            this->restore();
8979ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
8988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (NULL != ds) {
8999ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com                GrAssert(NULL == fSavedTarget);
9008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fSavedTarget = ds->getRenderTarget();
9019ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com                SkSafeRef(fSavedTarget);
9028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                ds->setRenderTarget(newTarget);
9039ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com                fDrawState = ds;
9048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
9058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
9068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    private:
9078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrDrawState* fDrawState;
9088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrRenderTarget* fSavedTarget;
9098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    };
9108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
9118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
9128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
9138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
9148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Stencil
9158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
9168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
9178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
9188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the stencil settings to use for the next draw.
9198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Changing the clip has the side-effect of possibly zeroing
9208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * out the client settable stencil bits. So multipass algorithms
9218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * using stencil should not change the clip between passes.
9228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param settings  the stencil settings to use.
9238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
9248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setStencil(const GrStencilSettings& settings) {
925ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fStencilSettings = settings;
9268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
9278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
9288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
9298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Shortcut to disable stencil testing and ops.
9308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
9318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void disableStencil() {
932ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fStencilSettings.setDisabled();
9338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
9348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
935ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    const GrStencilSettings& getStencil() const { return fCommon.fStencilSettings; }
9368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
937ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    GrStencilSettings* stencil() { return &fCommon.fStencilSettings; }
9388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
9398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
9408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
9418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
9428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name State Flags
9438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
9448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
9458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
9468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Flags that affect rendering. Controlled using enable/disableState(). All
9478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  default to disabled.
9488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
9498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    enum StateBits {
9508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
9518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Perform dithering. TODO: Re-evaluate whether we need this bit
9528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
9538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kDither_StateBit        = 0x01,
9548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
955cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
956cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
957cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * the 3D API.
9588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
9598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kHWAntialias_StateBit   = 0x02,
9608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
9618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Draws will respect the clip, otherwise the clip is ignored.
9628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
9638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kClip_StateBit          = 0x04,
9648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
9658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Disables writing to the color buffer. Useful when performing stencil
9668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * operations.
9678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
9688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kNoColorWrites_StateBit = 0x08,
9690342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com
970cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com        /**
971cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * Usually coverage is applied after color blending. The color is blended using the coeffs
972cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * specified by setBlendFunc(). The blended color is then combined with dst using coeffs
973cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * of src_coverage, 1-src_coverage. Sometimes we are explicitly drawing a coverage mask. In
974cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * this case there is no distinction between coverage and color and the caller needs direct
975cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * control over the blend coeffs. When set, there will be a single blend step controlled by
976cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * setBlendFunc() which will use coverage*color as the src color.
977cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         */
978cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         kCoverageDrawing_StateBit = 0x10,
979cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com
9808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // Users of the class may add additional bits to the vector
9818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kDummyStateBit,
9828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kLastPublicStateBit = kDummyStateBit-1,
9838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    };
9848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
9858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void resetStateFlags() {
986ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fFlagBits = 0;
9870fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
9880fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
9898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
9908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Enable render state settings.
9918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
9921e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * @param stateBits bitfield of StateBits specifying the states to enable
9938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
9948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void enableState(uint32_t stateBits) {
995ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fFlagBits |= stateBits;
9968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
9970fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
9988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
9998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Disable render state settings.
10008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
10011e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * @param stateBits bitfield of StateBits specifying the states to disable
10028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
10038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void disableState(uint32_t stateBits) {
1004ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fFlagBits &= ~(stateBits);
10058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
10060fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
1007d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com    /**
1008d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com     * Enable or disable stateBits based on a boolean.
1009d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com     *
10101e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * @param stateBits bitfield of StateBits to enable or disable
1011d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com     * @param enable    if true enable stateBits, otherwise disable
1012d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com     */
1013d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com    void setState(uint32_t stateBits, bool enable) {
1014d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com        if (enable) {
1015d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com            this->enableState(stateBits);
1016d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com        } else {
1017d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com            this->disableState(stateBits);
1018d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com        }
1019d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com    }
1020d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com
10218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isDitherState() const {
1022ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        return 0 != (fCommon.fFlagBits & kDither_StateBit);
10238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
10240fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
10258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isHWAntialiasState() const {
1026ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        return 0 != (fCommon.fFlagBits & kHWAntialias_StateBit);
10278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
10280fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
10298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isClipState() const {
1030ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        return 0 != (fCommon.fFlagBits & kClip_StateBit);
10318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
10320fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
10338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isColorWriteDisabled() const {
1034ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        return 0 != (fCommon.fFlagBits & kNoColorWrites_StateBit);
10358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
10368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1037cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com    bool isCoverageDrawing() const {
1038ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        return 0 != (fCommon.fFlagBits & kCoverageDrawing_StateBit);
1039cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com    }
1040cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com
10418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isStateFlagEnabled(uint32_t stateBit) const {
1042ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        return 0 != (stateBit & fCommon.fFlagBits);
10438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
10448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
10458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
10468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
10478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
10488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Face Culling
10498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
10508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
10518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    enum DrawFace {
1052978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com        kInvalid_DrawFace = -1,
1053978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com
10548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kBoth_DrawFace,
10558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kCCW_DrawFace,
10568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kCW_DrawFace,
10578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    };
10588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
10598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
10608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Controls whether clockwise, counterclockwise, or both faces are drawn.
10618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param face  the face(s) to draw.
10628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
10638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setDrawFace(DrawFace face) {
1064978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com        GrAssert(kInvalid_DrawFace != face);
1065ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fDrawFace = face;
10668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
10678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
10688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
10698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Gets whether the target is drawing clockwise, counterclockwise,
10708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * or both faces.
10718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return the current draw face(s).
10728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
1073ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    DrawFace getDrawFace() const { return fCommon.fDrawFace; }
1074d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
10758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
10768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
10778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
107862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
1079f13f58804659175925042a291304d483a4fd9278tomhudson@google.com    bool isStageEnabled(int s) const {
1080f13f58804659175925042a291304d483a4fd9278tomhudson@google.com        GrAssert((unsigned)s < kNumStages);
108108283afc265f1153834256fc1012519813ba6b73bsalomon@google.com        return (NULL != fStages[s].getEffect());
1082f13f58804659175925042a291304d483a4fd9278tomhudson@google.com    }
1083f13f58804659175925042a291304d483a4fd9278tomhudson@google.com
10849381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    bool operator ==(const GrDrawState& s) const {
1085ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        if (fRenderTarget.get() != s.fRenderTarget.get() || fCommon != s.fCommon) {
10868fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com            return false;
10878fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com        }
1088ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org        if (fVertexAttribs != s.fVertexAttribs) {
10899b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com            return false;
10909b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        }
10919b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        for (int i = 0; i < kAttribIndexCount; ++i) {
1092c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com            if ((i == kPosition_AttribIndex || s.fCommon.fAttribBindings & (1 << i)) &&
10939b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com                fAttribIndices[i] != s.fAttribIndices[i]) {
10949b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com                return false;
10959b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com            }
10969b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        }
109762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        for (int i = 0; i < kNumStages; i++) {
1098f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com            bool enabled = this->isStageEnabled(i);
1099f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com            if (enabled != s.isStageEnabled(i)) {
1100f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com                return false;
1101f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com            }
110208283afc265f1153834256fc1012519813ba6b73bsalomon@google.com            if (enabled && this->fStages[i] != s.fStages[i]) {
110362b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com                return false;
110462b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com            }
110562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        }
110662b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        return true;
11079381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    }
11089381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    bool operator !=(const GrDrawState& s) const { return !(*this == s); }
110962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
1110ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    GrDrawState& operator= (const GrDrawState& s) {
1111ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        this->setRenderTarget(s.fRenderTarget.get());
1112ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon = s.fCommon;
11139b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        fVertexAttribs = s.fVertexAttribs;
11149b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        for (int i = 0; i < kAttribIndexCount; i++) {
11159b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com            fAttribIndices[i] = s.fAttribIndices[i];
11169b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        }
111762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        for (int i = 0; i < kNumStages; i++) {
1118e742bf0ab19659145325ac894f7e0b78c8efbd89tomhudson@google.com            if (s.isStageEnabled(i)) {
111908283afc265f1153834256fc1012519813ba6b73bsalomon@google.com                this->fStages[i] = s.fStages[i];
112062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com            }
112162b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        }
112262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        return *this;
112362b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    }
112462b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
112562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.comprivate:
11262e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com
1127ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    /** Fields that are identical in GrDrawState and GrDrawState::DeferredState. */
1128ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    struct CommonState {
1129ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        // These fields are roughly sorted by decreasing likelihood of being different in op==
1130ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        GrColor                         fColor;
11319b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        GrAttribBindings                fAttribBindings;
1132ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        SkMatrix                        fViewMatrix;
1133ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        GrBlendCoeff                    fSrcBlend;
1134ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        GrBlendCoeff                    fDstBlend;
1135ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        GrColor                         fBlendConstant;
1136ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        uint32_t                        fFlagBits;
1137ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        GrStencilSettings               fStencilSettings;
1138ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        int                             fFirstCoverageStage;
1139ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        GrColor                         fCoverage;
1140ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        SkXfermode::Mode                fColorFilterMode;
1141ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        GrColor                         fColorFilterColor;
1142ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        DrawFace                        fDrawFace;
1143ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        bool operator== (const CommonState& other) const {
1144ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            return fColor == other.fColor &&
11459b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com                   fAttribBindings == other.fAttribBindings &&
1146ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                   fViewMatrix.cheapEqualTo(other.fViewMatrix) &&
1147ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                   fSrcBlend == other.fSrcBlend &&
1148ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                   fDstBlend == other.fDstBlend &&
1149ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                   fBlendConstant == other.fBlendConstant &&
1150ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                   fFlagBits == other.fFlagBits &&
1151ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                   fStencilSettings == other.fStencilSettings &&
1152ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                   fFirstCoverageStage == other.fFirstCoverageStage &&
1153ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                   fCoverage == other.fCoverage &&
1154ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                   fColorFilterMode == other.fColorFilterMode &&
1155ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                   fColorFilterColor == other.fColorFilterColor &&
1156ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                   fDrawFace == other.fDrawFace;
1157ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        }
1158ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        bool operator!= (const CommonState& other) const { return !(*this == other); }
1159ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    };
1160ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com
1161ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    /** GrDrawState uses GrEffectStages to hold stage state which holds a ref on GrEffectRef.
1162ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        DeferredState must directly reference GrEffects, however. */
1163ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    struct SavedEffectStage {
1164ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        SavedEffectStage() : fEffect(NULL) {}
1165ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        const GrEffect*                    fEffect;
1166ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        GrEffectStage::SavedCoordChange    fCoordChange;
1167ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    };
1168ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com
1169ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.compublic:
1170ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    /**
1171ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com     * DeferredState contains all of the data of a GrDrawState but does not hold refs on GrResource
1172ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com     * objects. Resources are allowed to hit zero ref count while in DeferredStates. Their internal
1173ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com     * dispose mechanism returns them to the cache. This allows recycling resources through the
1174ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com     * the cache while they are in a deferred draw queue.
1175ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com     */
1176ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    class DeferredState {
1177ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    public:
1178ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        DeferredState() : fRenderTarget(NULL) {
1179ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            GR_DEBUGCODE(fInitialized = false;)
1180ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        }
1181ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        // TODO: Remove this when DeferredState no longer holds a ref to the RT
1182ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        ~DeferredState() { SkSafeUnref(fRenderTarget); }
1183ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com
1184ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        void saveFrom(const GrDrawState& drawState) {
1185ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            fCommon = drawState.fCommon;
1186ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            // TODO: Here we will copy the GrRenderTarget pointer without taking a ref.
1187ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            fRenderTarget = drawState.fRenderTarget.get();
1188ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            SkSafeRef(fRenderTarget);
11899b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com            fVertexAttribs = drawState.fVertexAttribs;
11909b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com            for (int i = 0; i < kAttribIndexCount; i++) {
11919b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com                fAttribIndices[i] = drawState.fAttribIndices[i];
11929b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com            }
1193ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            // Here we ref the effects directly rather than the effect-refs. TODO: When the effect-
1194ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            // ref gets fully unref'ed it will cause the underlying effect to unref its resources
1195ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            // and recycle them to the cache (if no one else is holding a ref to the resources).
1196ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            for (int i = 0; i < kNumStages; ++i) {
1197ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                fStages[i].saveFrom(drawState.fStages[i]);
1198ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            }
1199ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            GR_DEBUGCODE(fInitialized = true;)
1200ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        }
1201ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com
1202ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        void restoreTo(GrDrawState* drawState) {
1203ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            GrAssert(fInitialized);
1204ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            drawState->fCommon = fCommon;
1205ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            drawState->setRenderTarget(fRenderTarget);
12069b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com            drawState->fVertexAttribs = fVertexAttribs;
12079b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com            for (int i = 0; i < kAttribIndexCount; i++) {
12089b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com                drawState->fAttribIndices[i] = fAttribIndices[i];
12099b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com            }
1210ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            for (int i = 0; i < kNumStages; ++i) {
1211ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                fStages[i].restoreTo(&drawState->fStages[i]);
1212ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            }
1213ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        }
1214ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com
1215ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        bool isEqual(const GrDrawState& state) const {
1216ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            if (fRenderTarget != state.fRenderTarget.get() || fCommon != state.fCommon) {
1217ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                return false;
1218ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            }
12199b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com            for (int i = 0; i < kAttribIndexCount; ++i) {
1220f140f18878215d6b4f21a94485cd1d2dbce8e976skia.committer@gmail.com                if ((i == kPosition_AttribIndex ||
12219b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com                     state.fCommon.fAttribBindings & kAttribIndexMasks[i]) &&
12229b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com                    fAttribIndices[i] != state.fAttribIndices[i]) {
12239b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com                    return false;
12249b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com                }
12259b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com            }
1226ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org            if (fVertexAttribs != state.fVertexAttribs) {
12279b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com                return false;
12289b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com            }
1229ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            for (int i = 0; i < kNumStages; ++i) {
1230dcd69bfca1d8e85ef5abc4e54f1e4b820d38e428bsalomon@google.com                if (!fStages[i].isEqual(state.fStages[i])) {
1231ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                    return false;
1232ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                }
1233ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            }
1234ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            return true;
1235ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        }
1236ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com
1237ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    private:
12389b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        GrRenderTarget*                       fRenderTarget;
12399b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        CommonState                           fCommon;
12409b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        int                                   fAttribIndices[kAttribIndexCount];
12419b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        GrVertexAttribArray<kVertexAttribCnt> fVertexAttribs;
12429b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        GrEffectStage::DeferredStage          fStages[kNumStages];
1243ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com
1244ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        GR_DEBUGCODE(bool fInitialized;)
1245ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    };
1246ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com
1247ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.comprivate:
12489b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    // helper array to let us check the current bindings so we know what bound attrib indices
12499b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    // we care about
12509b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    static const GrAttribBindings kAttribIndexMasks[kAttribIndexCount];
12519b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
12529b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    SkAutoTUnref<GrRenderTarget>           fRenderTarget;
12539b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    CommonState                            fCommon;
12549b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    int                                    fAttribIndices[kAttribIndexCount];
12559b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    GrVertexAttribArray<kVertexAttribCnt>  fVertexAttribs;
12569b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    GrEffectStage                          fStages[kNumStages];
12578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1258fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com    typedef GrRefCnt INHERITED;
12599381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com};
12609381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
12612b446734cfa8201e5478648988de86b646cb9544bsalomon@google.comGR_MAKE_BITFIELD_OPS(GrDrawState::BlendOptFlags);
12622b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com
12639381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#endif
1264