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"
1224ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org#include "GrBlend.h"
139381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#include "GrColor.h"
1408283afc265f1153834256fc1012519813ba6b73bsalomon@google.com#include "GrEffectStage.h"
1573818dce9340c9d7be372d44e8bba305c915c89absalomon@google.com#include "GrPaint.h"
16cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com#include "GrRenderTarget.h"
179381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#include "GrStencil.h"
18cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com#include "GrTemplates.h"
1964aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com#include "GrTexture.h"
2031ec7985f2b52a0cab4aa714a613b918cf663c08bsalomon@google.com#include "GrTypesPriv.h"
2168b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com#include "effects/GrSimpleTextureEffect.h"
229381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
23cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com#include "SkMatrix.h"
24a0b40280a49a8a43af7929ead3b3489951c58501commit-bot@chromium.org#include "SkTypes.h"
259381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#include "SkXfermode.h"
269381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
27a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.orgclass GrDrawState : public SkRefCnt {
282e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.compublic:
29fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com    SK_DECLARE_INST_COUNT(GrDrawState)
30d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
31eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    GrDrawState() {
321acc3d7cc28c5631b5300578ab13439bdefd4e33commit-bot@chromium.org        SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
33eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        this->reset();
34eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    }
35137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com
36eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    GrDrawState(const SkMatrix& initialViewMatrix) {
371acc3d7cc28c5631b5300578ab13439bdefd4e33commit-bot@chromium.org        SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
38eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        this->reset(initialViewMatrix);
39eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    }
4046f7afb9867200b568c21736da8a8bbb56b20e30bsalomon@google.com
41137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com    /**
42137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com     * Copies another draw state.
43137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com     **/
44faa5ae456d184202993a5dbe782a3a95acc25326commit-bot@chromium.org    GrDrawState(const GrDrawState& state) : INHERITED() {
451acc3d7cc28c5631b5300578ab13439bdefd4e33commit-bot@chromium.org        SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
4646f7afb9867200b568c21736da8a8bbb56b20e30bsalomon@google.com        *this = state;
4746f7afb9867200b568c21736da8a8bbb56b20e30bsalomon@google.com    }
4846f7afb9867200b568c21736da8a8bbb56b20e30bsalomon@google.com
49137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com    /**
50137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com     * Copies another draw state with a preconcat to the view matrix.
51137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com     **/
52137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com    GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatrix) {
531acc3d7cc28c5631b5300578ab13439bdefd4e33commit-bot@chromium.org        SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
54137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com        *this = state;
55137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com        if (!preConcatMatrix.isIdentity()) {
56eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com            for (int i = 0; i < fColorStages.count(); ++i) {
57eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com                fColorStages[i].localCoordChange(preConcatMatrix);
58eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com            }
59eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com            for (int i = 0; i < fCoverageStages.count(); ++i) {
60eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com                fCoverageStages[i].localCoordChange(preConcatMatrix);
61137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com            }
62137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com        }
639ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com    }
649ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
65f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org    virtual ~GrDrawState() { SkASSERT(0 == fBlockEffectRemovalCnt); }
66137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com
6752a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    /**
68137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com     * Resets to the default state. GrEffects will be removed from all stages.
69d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     */
70137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com    void reset() { this->onReset(NULL); }
71ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com
72137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com    void reset(const SkMatrix& initialViewMatrix) { this->onReset(&initialViewMatrix); }
73af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com
74af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com    /**
75bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org     * Initializes the GrDrawState based on a GrPaint, view matrix and render target. Note that
76bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org     * GrDrawState encompasses more than GrPaint. Aspects of GrDrawState that have no GrPaint
77eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com     * equivalents are set to default values. Clipping will be enabled.
78af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com     */
79bb6a3178c3e79c8549b332e4ce84c64b59964f1ecommit-bot@chromium.org    void setFromPaint(const GrPaint& , const SkMatrix& viewMatrix, GrRenderTarget*);
808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
829b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    /// @name Vertex Attributes
83cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    ////
84cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com
859b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    enum {
86054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com        kMaxVertexAttribCnt = kLast_GrVertexAttribBinding + 4,
87af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com    };
88cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com
899b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com   /**
90054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com     * The format of vertices is represented as an array of GrVertexAttribs, with each representing
91054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com     * the type of the attribute, its offset, and semantic binding (see GrVertexAttrib in
92054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com     * GrTypesPriv.h).
93cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     *
94054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com     * The mapping of attributes with kEffect bindings to GrEffect inputs is specified when
95054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com     * setEffect is called.
96cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     */
97af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com
98af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com    /**
99429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com     *  Sets vertex attributes for next draw. The object driving the templatization
100429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com     *  should be a global GrVertexAttrib array that is never changed.
101af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com     */
102429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com    template <const GrVertexAttrib A[]> void setVertexAttribs(int count) {
103429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com        this->setVertexAttribs(A, count);
104429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com    }
105af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com
106429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com    const GrVertexAttrib* getVertexAttribs() const { return fCommon.fVAPtr; }
107429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com    int getVertexAttribCount() const { return fCommon.fVACount; }
1089b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
1099b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    size_t getVertexSize() const;
110af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com
111af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com    /**
112054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com     *  Sets default vertex attributes for next draw. The default is a single attribute:
113054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com     *  {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribType}
114af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com     */
1159b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    void setDefaultVertexAttribs();
116af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com
117054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com    /**
118054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com     * Getters for index into getVertexAttribs() for particular bindings. -1 is returned if the
119054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com     * binding does not appear in the current attribs. These bindings should appear only once in
120054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com     * the attrib array.
121054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com     */
122af3a3b9fb1f3be46082013a2d1977d12faf1f61crobertphillips@google.com
123054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com    int positionAttributeIndex() const {
124054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com        return fCommon.fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding];
125054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com    }
126054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com    int localCoordAttributeIndex() const {
127054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com        return fCommon.fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding];
128054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com    }
129054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com    int colorVertexAttributeIndex() const {
130054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com        return fCommon.fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding];
131054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com    }
132054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com    int coverageVertexAttributeIndex() const {
133054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com        return fCommon.fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding];
134054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com    }
135fb495b537f5ddd6966f02cfe38f6b106a4869934commit-bot@chromium.org
136054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com    bool hasLocalCoordAttribute() const {
137054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com        return -1 != fCommon.fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding];
138054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com    }
139054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com    bool hasColorVertexAttribute() const {
140054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com        return -1 != fCommon.fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding];
141054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com    }
142054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com    bool hasCoverageVertexAttribute() const {
143054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com        return -1 != fCommon.fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding];
144054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com    }
145054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com
146054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com    bool validateVertexAttribs() const;
147cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com
148cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    /**
1490406b9e1faee06c6ecb2732a1bcf3b0e53104e07bsalomon@google.com     * Helper to save/restore vertex attribs
1500406b9e1faee06c6ecb2732a1bcf3b0e53104e07bsalomon@google.com     */
1510406b9e1faee06c6ecb2732a1bcf3b0e53104e07bsalomon@google.com     class AutoVertexAttribRestore {
1520406b9e1faee06c6ecb2732a1bcf3b0e53104e07bsalomon@google.com     public:
1530406b9e1faee06c6ecb2732a1bcf3b0e53104e07bsalomon@google.com         AutoVertexAttribRestore(GrDrawState* drawState) {
154f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org             SkASSERT(NULL != drawState);
1550406b9e1faee06c6ecb2732a1bcf3b0e53104e07bsalomon@google.com             fDrawState = drawState;
156429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com             fVAPtr = drawState->fCommon.fVAPtr;
157429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com             fVACount = drawState->fCommon.fVACount;
1580406b9e1faee06c6ecb2732a1bcf3b0e53104e07bsalomon@google.com             fDrawState->setDefaultVertexAttribs();
1590406b9e1faee06c6ecb2732a1bcf3b0e53104e07bsalomon@google.com         }
1600406b9e1faee06c6ecb2732a1bcf3b0e53104e07bsalomon@google.com
1610406b9e1faee06c6ecb2732a1bcf3b0e53104e07bsalomon@google.com         ~AutoVertexAttribRestore(){
162fe070ba6d82a4c77b02d33a46db21acf01050383commit-bot@chromium.org             fDrawState->setVertexAttribs(fVAPtr, fVACount);
1630406b9e1faee06c6ecb2732a1bcf3b0e53104e07bsalomon@google.com         }
1640406b9e1faee06c6ecb2732a1bcf3b0e53104e07bsalomon@google.com
1650406b9e1faee06c6ecb2732a1bcf3b0e53104e07bsalomon@google.com     private:
166429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com         GrDrawState*          fDrawState;
167429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com         const GrVertexAttrib* fVAPtr;
168429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com         int                   fVACount;
1690406b9e1faee06c6ecb2732a1bcf3b0e53104e07bsalomon@google.com     };
1700406b9e1faee06c6ecb2732a1bcf3b0e53104e07bsalomon@google.com
1710406b9e1faee06c6ecb2732a1bcf3b0e53104e07bsalomon@google.com    /**
172054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com     * Accessing positions, local coords, or colors, of a vertex within an array is a hassle
173054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com     * involving casts and simple math. These helpers exist to keep GrDrawTarget clients' code a bit
174054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com     * nicer looking.
175cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     */
176cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com
177cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    /**
178cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * Gets a pointer to a GrPoint of a vertex's position or texture
179cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * coordinate.
1809b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     * @param vertices      the vertex array
181cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * @param vertexIndex   the index of the vertex in the array
182cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * @param vertexSize    the size of each vertex in the array
183cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * @param offset        the offset in bytes of the vertex component.
184cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     *                      Defaults to zero (corresponding to vertex position)
185cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * @return pointer to the vertex component as a GrPoint
186cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     */
187972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org    static SkPoint* GetVertexPoint(void* vertices,
188cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                   int vertexIndex,
189cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                   int vertexSize,
190cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                   int offset = 0) {
191cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com        intptr_t start = GrTCast<intptr_t>(vertices);
192972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org        return GrTCast<SkPoint*>(start + offset +
193cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                 vertexIndex * vertexSize);
194cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    }
195972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org    static const SkPoint* GetVertexPoint(const void* vertices,
196cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                         int vertexIndex,
197cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                         int vertexSize,
198cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                         int offset = 0) {
199cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com        intptr_t start = GrTCast<intptr_t>(vertices);
200972f9cd7a063d0544f8c919fd12b9a3adbd12b24commit-bot@chromium.org        return GrTCast<const SkPoint*>(start + offset +
201cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                       vertexIndex * vertexSize);
202cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    }
203cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com
204cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    /**
205cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * Gets a pointer to a GrColor inside a vertex within a vertex array.
206cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * @param vertices      the vetex array
207cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * @param vertexIndex   the index of the vertex in the array
208cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * @param vertexSize    the size of each vertex in the array
209cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * @param offset        the offset in bytes of the vertex color
210cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     * @return pointer to the vertex component as a GrColor
211cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com     */
212cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    static GrColor* GetVertexColor(void* vertices,
213cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                   int vertexIndex,
214cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                   int vertexSize,
215cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                   int offset) {
216cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com        intptr_t start = GrTCast<intptr_t>(vertices);
217cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com        return GrTCast<GrColor*>(start + offset +
218cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                 vertexIndex * vertexSize);
219cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    }
220cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    static const GrColor* GetVertexColor(const void* vertices,
221cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                         int vertexIndex,
222cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                         int vertexSize,
223cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                         int offset) {
224cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com        const intptr_t start = GrTCast<intptr_t>(vertices);
225cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com        return GrTCast<const GrColor*>(start + offset +
226cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com                                       vertexIndex * vertexSize);
227cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    }
228cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com
2299b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    /// @}
2309b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
2319b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    /**
2329b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     * Determines whether src alpha is guaranteed to be one for all src pixels
2339b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     */
234054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com    bool srcAlphaWillBeOne() const;
2359b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
2369b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com    /**
2379b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     * Determines whether the output coverage is guaranteed to be one for all pixels hit by a draw.
2389b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com     */
239054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com    bool hasSolidCoverage() const;
240cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com
241cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    /// @}
242cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com
243cc78238f0b6aa1a7b3fc767758d9eeef4c1bffa9jvanverth@google.com    ///////////////////////////////////////////////////////////////////////////
2448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Color
2458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
2468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
2488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Sets color for next draw to a premultiplied-alpha color.
2498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
2508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param color    the color to set.
2518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
252ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    void setColor(GrColor color) { fCommon.fColor = color; }
2538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
254ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    GrColor getColor() const { return fCommon.fColor; }
2558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
2578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Sets the color to be used for the next draw to be
2588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  (r,g,b,a) = (alpha, alpha, alpha, alpha).
2598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
2608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param alpha The alpha value to set as the color.
2618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
2628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setAlpha(uint8_t a) {
2638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        this->setColor((a << 24) | (a << 16) | (a << 8) | a);
2648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
2658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
2675b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com     * Constructor sets the color to be 'color' which is undone by the destructor.
2685b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com     */
269a0b40280a49a8a43af7929ead3b3489951c58501commit-bot@chromium.org    class AutoColorRestore : public ::SkNoncopyable {
2705b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    public:
27166a58aca8379a33ccc7572a31c74a3334d08b47csugoi@google.com        AutoColorRestore() : fDrawState(NULL), fOldColor(0) {}
272d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
2735b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        AutoColorRestore(GrDrawState* drawState, GrColor color) {
274d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            fDrawState = NULL;
275d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            this->set(drawState, color);
276d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        }
277d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
278d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        void reset() {
279d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            if (NULL != fDrawState) {
280d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                fDrawState->setColor(fOldColor);
281d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com                fDrawState = NULL;
282d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            }
283d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        }
284d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
285d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        void set(GrDrawState* drawState, GrColor color) {
286d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com            this->reset();
2875b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com            fDrawState = drawState;
2885b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com            fOldColor = fDrawState->getColor();
2895b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com            fDrawState->setColor(color);
2905b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        }
291d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com
292d62e88e5af39347a8fc2a5abdf5feb67d7ea256dbsalomon@google.com        ~AutoColorRestore() { this->reset(); }
2935b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    private:
2945b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        GrDrawState*    fDrawState;
2955b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        GrColor         fOldColor;
2965b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    };
2975b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com
2988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
2998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
3012401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    /// @name Coverage
3022401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    ////
3032401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com
3042401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    /**
305d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     * Sets a constant fractional coverage to be applied to the draw. The
3062401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     * initial value (after construction or reset()) is 0xff. The constant
3072401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     * coverage is ignored when per-vertex coverage is provided.
3082401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     */
3092401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    void setCoverage(uint8_t coverage) {
310ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage);
3112401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    }
3122401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com
313e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org    uint8_t getCoverage() const {
314e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org        return GrColorUnpackR(fCommon.fCoverage);
3152401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    }
3162401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com
317e0a868c84ebc34c5a16b5faa1546016abb9ca0accommit-bot@chromium.org    GrColor getCoverageColor() const {
318ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        return fCommon.fCoverage;
3192401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    }
3202401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com
3212401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    /// @}
3222401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com
3232401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
324adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com    /// @name Effect Stages
325eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    /// Each stage hosts a GrEffect. The effect produces an output color or coverage in the fragment
326eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    /// shader. Its inputs are the output from the previous stage as well as some variables
327eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    /// available to it in the fragment and vertex shader (e.g. the vertex position, the dst color,
328eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    /// the fragment position, local coordinates).
329eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    ///
330eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    /// The stages are divided into two sets, color-computing and coverage-computing. The final
331eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    /// color stage produces the final pixel color. The coverage-computing stages function exactly
332eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    /// as the color-computing but the output of the final coverage stage is treated as a fractional
333eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    /// pixel coverage rather than as input to the src/dst color blend step.
334eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    ///
335eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    /// The input color to the first color-stage is either the constant color or interpolated
336eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    /// per-vertex colors. The input to the first coverage stage is either a constant coverage
337eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    /// (usually full-coverage) or interpolated per-vertex coverage.
338eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    ///
339eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    /// See the documentation of kCoverageDrawing_StateBit for information about disabling the
340eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    /// the color / coverage distinction.
3418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
3428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
343eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    const GrEffectRef* addColorEffect(const GrEffectRef* effect, int attr0 = -1, int attr1 = -1) {
344f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(NULL != effect);
345eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        SkNEW_APPEND_TO_TARRAY(&fColorStages, GrEffectStage, (effect, attr0, attr1));
34665eb4d5a210884cc92c43a8582cbd1ccbddcab57jvanverth@google.com        return effect;
34765eb4d5a210884cc92c43a8582cbd1ccbddcab57jvanverth@google.com    }
34801c34ee59906f729f6ca7d35f0c0e5e2f5e693feskia.committer@gmail.com
349eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    const GrEffectRef* addCoverageEffect(const GrEffectRef* effect, int attr0 = -1, int attr1 = -1) {
350f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(NULL != effect);
351eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        SkNEW_APPEND_TO_TARRAY(&fCoverageStages, GrEffectStage, (effect, attr0, attr1));
352adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com        return effect;
353adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com    }
354adc6536fe5baff2216fb76ecda6cc81c61109d5cbsalomon@google.com
3558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
356c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com     * Creates a GrSimpleTextureEffect that uses local coords as texture coordinates.
3571e8f016305805d4d8cad74aba3a21b78486f9d6ftomhudson@google.com     */
358eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    void addColorTextureEffect(GrTexture* texture, const SkMatrix& matrix) {
35968b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com        GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix);
360eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        this->addColorEffect(effect)->unref();
361dfdb7e5240276493077b7c6e1f3cc8b8a0e195babsalomon@google.com    }
362eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com
363eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    void addCoverageTextureEffect(GrTexture* texture, const SkMatrix& matrix) {
364eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix);
365eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        this->addCoverageEffect(effect)->unref();
3661ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com    }
3671ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com
368eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    void addColorTextureEffect(GrTexture* texture,
369eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com                               const SkMatrix& matrix,
370eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com                               const GrTextureParams& params) {
371eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params);
372eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        this->addColorEffect(effect)->unref();
3737d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com    }
374676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com
375eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    void addCoverageTextureEffect(GrTexture* texture,
376eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com                                  const SkMatrix& matrix,
377eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com                                  const GrTextureParams& params) {
378eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params);
379eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        this->addCoverageEffect(effect)->unref();
380ff6ea2663f76aa85ec55ddd0f00ca7906f1bc4e3commit-bot@chromium.org    }
381676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com
382972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    /**
383eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com     * When this object is destroyed it will remove any effects from the draw state that were added
384eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com     * after its constructor.
385972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com     */
386a0b40280a49a8a43af7929ead3b3489951c58501commit-bot@chromium.org    class AutoRestoreEffects : public ::SkNoncopyable {
387972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    public:
3882fad5a8da92b0c1b8455c04690ecaa28de8db50fbsalomon@google.com        AutoRestoreEffects() : fDrawState(NULL), fColorEffectCnt(0), fCoverageEffectCnt(0) {}
389eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com
3905c493d5b3dc753fccba47c8250fb38713bac3cb8skia.committer@gmail.com        AutoRestoreEffects(GrDrawState* ds) : fDrawState(NULL), fColorEffectCnt(0), fCoverageEffectCnt(0) {
3915c493d5b3dc753fccba47c8250fb38713bac3cb8skia.committer@gmail.com            this->set(ds);
392f09b87dda39df1315f26afb663aeaf8048330725robertphillips@google.com        }
393eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com
394eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        ~AutoRestoreEffects() { this->set(NULL); }
395eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com
396eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        void set(GrDrawState* ds) {
397972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com            if (NULL != fDrawState) {
398eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com                int n = fDrawState->fColorStages.count() - fColorEffectCnt;
399f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org                SkASSERT(n >= 0);
400eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com                fDrawState->fColorStages.pop_back_n(n);
401eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com                n = fDrawState->fCoverageStages.count() - fCoverageEffectCnt;
402f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org                SkASSERT(n >= 0);
403eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com                fDrawState->fCoverageStages.pop_back_n(n);
4041acc3d7cc28c5631b5300578ab13439bdefd4e33commit-bot@chromium.org                SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;)
405eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com            }
406eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com            fDrawState = ds;
407eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com            if (NULL != ds) {
408eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com                fColorEffectCnt = ds->fColorStages.count();
409eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com                fCoverageEffectCnt = ds->fCoverageStages.count();
4101acc3d7cc28c5631b5300578ab13439bdefd4e33commit-bot@chromium.org                SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;)
411972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com            }
412972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com        }
413eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com
4148af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon        bool isSet() const { return NULL != fDrawState; }
4158af0523b38f25993c8b1ba3a3562b9f9ac87162dbsalomon
416972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    private:
417972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com        GrDrawState* fDrawState;
418eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        int fColorEffectCnt;
419eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        int fCoverageEffectCnt;
420972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    };
421972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com
422eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    int numColorStages() const { return fColorStages.count(); }
423eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    int numCoverageStages() const { return fCoverageStages.count(); }
424eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    int numTotalStages() const { return this->numColorStages() + this->numCoverageStages(); }
4258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
426eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    const GrEffectStage& getColorStage(int stageIdx) const { return fColorStages[stageIdx]; }
427eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    const GrEffectStage& getCoverageStage(int stageIdx) const { return fCoverageStages[stageIdx]; }
42805a2ee052c9ef4c781b7b590b00b3d2da3b3449askia.committer@gmail.com
429bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org    /**
430bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org     * Checks whether any of the effects will read the dst pixel color.
431bb5c46591c50d05418467cd1c4e927ceb85c2ba9commit-bot@chromium.org     */
432d09ab846789a33a969f9ea8428555270fe4de23ebsalomon@google.com    bool willEffectReadDstColor() const;
433e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com
4348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
4358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
4378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Blending
4388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
4398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4411e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * Sets the blending function coefficients.
4428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * The blend function will be:
4448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *    D' = sat(S*srcCoef + D*dstCoef)
4458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *   where D is the existing destination color, S is the incoming source
4478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *   color, and D' is the new destination color that will be written. sat()
4488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *   is the saturation function.
4498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4501e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * @param srcCoef coefficient applied to the src color.
4511e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * @param dstCoef coefficient applied to the dst color.
4528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
4538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
454ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fSrcBlend = srcCoeff;
455ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fDstBlend = dstCoeff;
456515dcd36032997ce335daa0163c6d67e851bcad1commit-bot@chromium.org    #ifdef SK_DEBUG
45724ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org        if (GrBlendCoeffRefsDst(dstCoeff)) {
45824ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org            GrPrintf("Unexpected dst blend coeff. Won't work correctly with coverage stages.\n");
4598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
46024ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org        if (GrBlendCoeffRefsSrc(srcCoeff)) {
46124ab3b0ce50b3428f063849b6160e468f047487ccommit-bot@chromium.org            GrPrintf("Unexpected src blend coeff. Won't work correctly with coverage stages.\n");
4628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
4638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    #endif
4648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
4658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
466ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    GrBlendCoeff getSrcBlendCoeff() const { return fCommon.fSrcBlend; }
467ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    GrBlendCoeff getDstBlendCoeff() const { return fCommon.fDstBlend; }
4688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff,
4708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                          GrBlendCoeff* dstBlendCoeff) const {
471ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        *srcBlendCoeff = fCommon.fSrcBlend;
472ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        *dstBlendCoeff = fCommon.fDstBlend;
4738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
4748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the blending function constant referenced by the following blending
4771e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * coefficients:
47847059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com     *      kConstC_GrBlendCoeff
47947059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com     *      kIConstC_GrBlendCoeff
48047059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com     *      kConstA_GrBlendCoeff
48147059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com     *      kIConstA_GrBlendCoeff
4828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param constant the constant to set
4848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
485ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    void setBlendConstant(GrColor constant) { fCommon.fBlendConstant = constant; }
4868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Retrieves the last value set by setBlendConstant()
4898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return the blending constant value
4908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
491ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    GrColor getBlendConstant() const { return fCommon.fBlendConstant; }
4928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4932b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com    /**
4942b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * Determines whether multiplying the computed per-pixel color by the pixel's fractional
4952b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * coverage before the blend will give the correct final destination color. In general it
4962b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * will not as coverage is applied after blending.
4972b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     */
4982b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com    bool canTweakAlphaForCoverage() const;
4992b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com
5002b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com    /**
5012b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * Optimizations for blending / coverage to that can be applied based on the current state.
5022b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     */
5032b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com    enum BlendOptFlags {
5042b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        /**
5052b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         * No optimization
5062b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         */
5072b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        kNone_BlendOpt                  = 0,
5082b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        /**
5092b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         * Don't draw at all
5102b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         */
5112b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        kSkipDraw_BlendOptFlag          = 0x1,
5122b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        /**
5132b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         * Emit the src color, disable HW blending (replace dst with src)
5142b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         */
5152b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        kDisableBlend_BlendOptFlag      = 0x2,
5162b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        /**
5172b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         * The coverage value does not have to be computed separately from alpha, the the output
5182b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         * color can be the modulation of the two.
5192b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         */
5202b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        kCoverageAsAlpha_BlendOptFlag   = 0x4,
5212b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        /**
5222b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         * Instead of emitting a src color, emit coverage in the alpha channel and r,g,b are
5232b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         * "don't cares".
5242b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         */
5252b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        kEmitCoverage_BlendOptFlag      = 0x8,
5262b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        /**
5272b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         * Emit transparent black instead of the src color, no need to compute coverage.
5282b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com         */
5292b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com        kEmitTransBlack_BlendOptFlag    = 0x10,
5302b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com    };
5312b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com    GR_DECL_BITFIELD_OPS_FRIENDS(BlendOptFlags);
5322b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com
5332b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com    /**
5342b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * Determines what optimizations can be applied based on the blend. The coefficients may have
5352b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * to be tweaked in order for the optimization to work. srcCoeff and dstCoeff are optional
5362b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * params that receive the tweaked coefficients. Normally the function looks at the current
5372b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * state to see if coverage is enabled. By setting forceCoverage the caller can speculatively
5382b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * determine the blend optimizations that would be used if there was partial pixel coverage.
5392b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     *
5402b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * Subclasses of GrDrawTarget that actually draw (as opposed to those that just buffer for
5412b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     * playback) must call this function and respect the flags that replace the output color.
5422b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com     */
5432b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com    BlendOptFlags getBlendOpts(bool forceCoverage = false,
5442b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com                               GrBlendCoeff* srcCoeff = NULL,
5452b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com                               GrBlendCoeff* dstCoeff = NULL) const;
5462b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com
5478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
5488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
5508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name View Matrix
5518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
5528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
554137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com     * Sets the view matrix to identity and updates any installed effects to compensate for the
555137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com     * coord system change.
5568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
557137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com    bool setIdentityViewMatrix();
5588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
5608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Retrieves the current view matrix
5618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return the current view matrix.
5628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
563ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    const SkMatrix& getViewMatrix() const { return fCommon.fViewMatrix; }
5648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
5668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Retrieves the inverse of the current view matrix.
5678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
5688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  If the current view matrix is invertible, return true, and if matrix
5698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  is non-null, copy the inverse into it. If the current view matrix is
5708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  non-invertible, return false and ignore the matrix parameter.
5718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
5728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param matrix if not null, will receive a copy of the current inverse.
5738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
574b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com    bool getViewInverse(SkMatrix* matrix) const {
5758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // TODO: determine whether we really need to leave matrix unmodified
5768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // at call sites when inversion fails.
577b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com        SkMatrix inverse;
578ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        if (fCommon.fViewMatrix.invert(&inverse)) {
5798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (matrix) {
5808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                *matrix = inverse;
5818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
5828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            return true;
5838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
5848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return false;
5858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
5868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5875b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    ////////////////////////////////////////////////////////////////////////////
5885b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com
5895b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    /**
5902fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com     * Preconcats the current view matrix and restores the previous view matrix in the destructor.
591137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com     * Effect matrices are automatically adjusted to compensate and adjusted back in the destructor.
5925b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com     */
593a0b40280a49a8a43af7929ead3b3489951c58501commit-bot@chromium.org    class AutoViewMatrixRestore : public ::SkNoncopyable {
5948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    public:
5958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        AutoViewMatrixRestore() : fDrawState(NULL) {}
5962fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
597c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        AutoViewMatrixRestore(GrDrawState* ds, const SkMatrix& preconcatMatrix) {
5988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            fDrawState = NULL;
599c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com            this->set(ds, preconcatMatrix);
6008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
6012fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
6022fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        ~AutoViewMatrixRestore() { this->restore(); }
6032fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
604a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        /**
605a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * Can be called prior to destructor to restore the original matrix.
606a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         */
6072fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        void restore();
608f467ce7bc33af5f496e0619387551aedec6d2517skia.committer@gmail.com
609c78188896e28a4ae49e406a7422b345ae177dafebsalomon@google.com        void set(GrDrawState* drawState, const SkMatrix& preconcatMatrix);
6102fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
611137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com        /** Sets the draw state's matrix to identity. This can fail because the current view matrix
612137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com            is not invertible. */
613137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com        bool setIdentity(GrDrawState* drawState);
6142fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
6155b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    private:
616eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        void doEffectCoordChanges(const SkMatrix& coordChangeMatrix);
617eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com
618eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        GrDrawState*                                        fDrawState;
619eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        SkMatrix                                            fViewMatrix;
620eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        int                                                 fNumColorStages;
621eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        SkAutoSTArray<8, GrEffectStage::SavedCoordChange>   fSavedCoordChanges;
6225b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    };
6235b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com
6248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
6258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
6278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Render Target
6288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
6298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
631ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com     * Sets the render-target used at the next drawing call
6328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
6338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param target  The render target to set.
6348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
635d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    void setRenderTarget(GrRenderTarget* target) {
636ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fRenderTarget.reset(SkSafeRef(target));
6379ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com    }
6388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
640ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com     * Retrieves the currently set render-target.
6418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
6428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return    The currently set render target.
6438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
644ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    const GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
645ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    GrRenderTarget* getRenderTarget() { return fRenderTarget.get(); }
6468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
647a0b40280a49a8a43af7929ead3b3489951c58501commit-bot@chromium.org    class AutoRenderTargetRestore : public ::SkNoncopyable {
6488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    public:
649cadbcb8e536f89babb4e165bfdca18384e97d582bsalomon@google.com        AutoRenderTargetRestore() : fDrawState(NULL), fSavedTarget(NULL) {}
6508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) {
6518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            fDrawState = NULL;
6527460b378d68217167013ca889a4cdcae742908e7robertphillips@google.com            fSavedTarget = NULL;
6538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            this->set(ds, newTarget);
6548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
6559ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        ~AutoRenderTargetRestore() { this->restore(); }
6569ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
6579ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        void restore() {
6588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (NULL != fDrawState) {
6598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fDrawState->setRenderTarget(fSavedTarget);
6609ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com                fDrawState = NULL;
6618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
662a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org            SkSafeSetNull(fSavedTarget);
6639ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        }
6649ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
6659ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        void set(GrDrawState* ds, GrRenderTarget* newTarget) {
6669ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com            this->restore();
6679ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
6688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (NULL != ds) {
669f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org                SkASSERT(NULL == fSavedTarget);
6708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fSavedTarget = ds->getRenderTarget();
6719ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com                SkSafeRef(fSavedTarget);
6728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                ds->setRenderTarget(newTarget);
6739ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com                fDrawState = ds;
6748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
6758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
6768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    private:
6778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrDrawState* fDrawState;
6788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrRenderTarget* fSavedTarget;
6798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    };
6808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
6828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
6848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Stencil
6858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
6868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
6888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the stencil settings to use for the next draw.
6898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Changing the clip has the side-effect of possibly zeroing
6908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * out the client settable stencil bits. So multipass algorithms
6918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * using stencil should not change the clip between passes.
6928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param settings  the stencil settings to use.
6938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
6948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setStencil(const GrStencilSettings& settings) {
695ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fStencilSettings = settings;
6968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
6998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Shortcut to disable stencil testing and ops.
7008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
7018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void disableStencil() {
702ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fStencilSettings.setDisabled();
7038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
7048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
705ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    const GrStencilSettings& getStencil() const { return fCommon.fStencilSettings; }
7068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
707ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    GrStencilSettings* stencil() { return &fCommon.fStencilSettings; }
7088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
7108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
7128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name State Flags
7138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
7148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
7168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Flags that affect rendering. Controlled using enable/disableState(). All
7178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  default to disabled.
7188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
7198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    enum StateBits {
7208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
7218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Perform dithering. TODO: Re-evaluate whether we need this bit
7228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
7238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kDither_StateBit        = 0x01,
7248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
725cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
726cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
727cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * the 3D API.
7288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
7298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kHWAntialias_StateBit   = 0x02,
7308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
7318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Draws will respect the clip, otherwise the clip is ignored.
7328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
7338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kClip_StateBit          = 0x04,
7348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
7358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Disables writing to the color buffer. Useful when performing stencil
7368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * operations.
7378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
7388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kNoColorWrites_StateBit = 0x08,
7390342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com
740cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com        /**
741cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * Usually coverage is applied after color blending. The color is blended using the coeffs
742cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * specified by setBlendFunc(). The blended color is then combined with dst using coeffs
743cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * of src_coverage, 1-src_coverage. Sometimes we are explicitly drawing a coverage mask. In
744cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * this case there is no distinction between coverage and color and the caller needs direct
745cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * control over the blend coeffs. When set, there will be a single blend step controlled by
746cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * setBlendFunc() which will use coverage*color as the src color.
747cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         */
748cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         kCoverageDrawing_StateBit = 0x10,
749cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com
7508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // Users of the class may add additional bits to the vector
7518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kDummyStateBit,
7528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kLastPublicStateBit = kDummyStateBit-1,
7538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    };
7548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void resetStateFlags() {
756ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fFlagBits = 0;
7570fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
7580fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
7598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
7608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Enable render state settings.
7618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
7621e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * @param stateBits bitfield of StateBits specifying the states to enable
7638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
7648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void enableState(uint32_t stateBits) {
765ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fFlagBits |= stateBits;
7668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
7670fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
7688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
7698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Disable render state settings.
7708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
7711e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * @param stateBits bitfield of StateBits specifying the states to disable
7728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
7738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void disableState(uint32_t stateBits) {
774ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fFlagBits &= ~(stateBits);
7758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
7760fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
777d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com    /**
778d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com     * Enable or disable stateBits based on a boolean.
779d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com     *
7801e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * @param stateBits bitfield of StateBits to enable or disable
781d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com     * @param enable    if true enable stateBits, otherwise disable
782d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com     */
783d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com    void setState(uint32_t stateBits, bool enable) {
784d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com        if (enable) {
785d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com            this->enableState(stateBits);
786d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com        } else {
787d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com            this->disableState(stateBits);
788d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com        }
789d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com    }
790d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com
7918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isDitherState() const {
792ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        return 0 != (fCommon.fFlagBits & kDither_StateBit);
7938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
7940fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
7958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isHWAntialiasState() const {
796ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        return 0 != (fCommon.fFlagBits & kHWAntialias_StateBit);
7978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
7980fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
7998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isClipState() const {
800ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        return 0 != (fCommon.fFlagBits & kClip_StateBit);
8018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
8020fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
8038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isColorWriteDisabled() const {
804ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        return 0 != (fCommon.fFlagBits & kNoColorWrites_StateBit);
8058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
8068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
807cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com    bool isCoverageDrawing() const {
808ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        return 0 != (fCommon.fFlagBits & kCoverageDrawing_StateBit);
809cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com    }
810cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com
8118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isStateFlagEnabled(uint32_t stateBit) const {
812ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        return 0 != (stateBit & fCommon.fFlagBits);
8138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
8148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
8168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
8188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Face Culling
8198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
8208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    enum DrawFace {
822978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com        kInvalid_DrawFace = -1,
823978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com
8248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kBoth_DrawFace,
8258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kCCW_DrawFace,
8268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kCW_DrawFace,
8278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    };
8288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
8308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Controls whether clockwise, counterclockwise, or both faces are drawn.
8318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param face  the face(s) to draw.
8328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
8338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setDrawFace(DrawFace face) {
834f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(kInvalid_DrawFace != face);
835ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon.fDrawFace = face;
8368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
8378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
8398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Gets whether the target is drawing clockwise, counterclockwise,
8408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * or both faces.
8418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return the current draw face(s).
8428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
843ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    DrawFace getDrawFace() const { return fCommon.fDrawFace; }
844d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
8458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
8468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
84862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
8499381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    bool operator ==(const GrDrawState& s) const {
850eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        if (fRenderTarget.get() != s.fRenderTarget.get() ||
851eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com            fColorStages.count() != s.fColorStages.count() ||
852eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com            fCoverageStages.count() != s.fCoverageStages.count() ||
853eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com            fCommon != s.fCommon) {
8548fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com            return false;
8558fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com        }
856eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        for (int i = 0; i < fColorStages.count(); i++) {
857eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com            if (fColorStages[i] != s.fColorStages[i]) {
858f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com                return false;
859f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com            }
860eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        }
861eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        for (int i = 0; i < fCoverageStages.count(); i++) {
862eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com            if (fCoverageStages[i] != s.fCoverageStages[i]) {
86362b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com                return false;
86462b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com            }
86562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        }
86662b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        return true;
8679381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    }
8689381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    bool operator !=(const GrDrawState& s) const { return !(*this == s); }
86962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
870ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    GrDrawState& operator= (const GrDrawState& s) {
871f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages());
872ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        this->setRenderTarget(s.fRenderTarget.get());
873ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        fCommon = s.fCommon;
874eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        fColorStages = s.fColorStages;
875eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        fCoverageStages = s.fCoverageStages;
87662b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        return *this;
87762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    }
87862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
87962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.comprivate:
8802e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com
881137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com    void onReset(const SkMatrix* initialViewMatrix) {
882f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org        SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages());
883eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        fColorStages.reset();
884eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        fCoverageStages.reset();
885137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com
886137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com        fRenderTarget.reset(NULL);
887137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com
888137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com        this->setDefaultVertexAttribs();
889137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com
890137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com        fCommon.fColor = 0xffffffff;
891137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com        if (NULL == initialViewMatrix) {
892137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com            fCommon.fViewMatrix.reset();
893137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com        } else {
894137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com            fCommon.fViewMatrix = *initialViewMatrix;
895137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com        }
896137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com        fCommon.fSrcBlend = kOne_GrBlendCoeff;
897137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com        fCommon.fDstBlend = kZero_GrBlendCoeff;
898137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com        fCommon.fBlendConstant = 0x0;
899137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com        fCommon.fFlagBits = 0x0;
900137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com        fCommon.fStencilSettings.setDisabled();
901137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com        fCommon.fCoverage = 0xffffffff;
902137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com        fCommon.fDrawFace = kBoth_DrawFace;
903137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com    }
904137f1347abaf0bb6a945e91c2f6cb49f0ee69bc3bsalomon@google.com
905ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    /** Fields that are identical in GrDrawState and GrDrawState::DeferredState. */
906ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    struct CommonState {
907ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        // These fields are roughly sorted by decreasing likelihood of being different in op==
908429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com        GrColor               fColor;
909429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com        SkMatrix              fViewMatrix;
910429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com        GrBlendCoeff          fSrcBlend;
911429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com        GrBlendCoeff          fDstBlend;
912429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com        GrColor               fBlendConstant;
913429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com        uint32_t              fFlagBits;
914429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com        const GrVertexAttrib* fVAPtr;
915429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com        int                   fVACount;
916429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com        GrStencilSettings     fStencilSettings;
917429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com        GrColor               fCoverage;
918429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com        DrawFace              fDrawFace;
919054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com
920054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com        // This is simply a different representation of info in fVertexAttribs and thus does
921054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com        // not need to be compared in op==.
922054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com        int fFixedFunctionVertexAttribIndices[kGrFixedFunctionVertexAttribBindingCnt];
923054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com
924ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        bool operator== (const CommonState& other) const {
925054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com            bool result = fColor == other.fColor &&
926054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com                          fViewMatrix.cheapEqualTo(other.fViewMatrix) &&
927054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com                          fSrcBlend == other.fSrcBlend &&
928054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com                          fDstBlend == other.fDstBlend &&
929054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com                          fBlendConstant == other.fBlendConstant &&
930054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com                          fFlagBits == other.fFlagBits &&
931429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com                          fVACount == other.fVACount &&
932429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com                          !memcmp(fVAPtr, other.fVAPtr, fVACount * sizeof(GrVertexAttrib)) &&
933054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com                          fStencilSettings == other.fStencilSettings &&
934054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com                          fCoverage == other.fCoverage &&
935054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com                          fDrawFace == other.fDrawFace;
936f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org            SkASSERT(!result || 0 == memcmp(fFixedFunctionVertexAttribIndices,
937054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com                                            other.fFixedFunctionVertexAttribIndices,
938054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com                                            sizeof(fFixedFunctionVertexAttribIndices)));
939054ae99d93711c26e40682a0e3a03a47ea605c53jvanverth@google.com            return result;
940ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        }
941ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        bool operator!= (const CommonState& other) const { return !(*this == other); }
942ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    };
943ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com
944ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    /** GrDrawState uses GrEffectStages to hold stage state which holds a ref on GrEffectRef.
945ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        DeferredState must directly reference GrEffects, however. */
946ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    struct SavedEffectStage {
947ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        SavedEffectStage() : fEffect(NULL) {}
948ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        const GrEffect*                    fEffect;
949ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        GrEffectStage::SavedCoordChange    fCoordChange;
950ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    };
951ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com
952ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.compublic:
953ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    /**
954ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com     * DeferredState contains all of the data of a GrDrawState but does not hold refs on GrResource
955ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com     * objects. Resources are allowed to hit zero ref count while in DeferredStates. Their internal
956ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com     * dispose mechanism returns them to the cache. This allows recycling resources through the
957ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com     * the cache while they are in a deferred draw queue.
958ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com     */
959ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    class DeferredState {
960ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    public:
961ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        DeferredState() : fRenderTarget(NULL) {
9621acc3d7cc28c5631b5300578ab13439bdefd4e33commit-bot@chromium.org            SkDEBUGCODE(fInitialized = false;)
963ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        }
964ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        // TODO: Remove this when DeferredState no longer holds a ref to the RT
965ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        ~DeferredState() { SkSafeUnref(fRenderTarget); }
966ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com
967ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        void saveFrom(const GrDrawState& drawState) {
968ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            fCommon = drawState.fCommon;
969ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            // TODO: Here we will copy the GrRenderTarget pointer without taking a ref.
970ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            fRenderTarget = drawState.fRenderTarget.get();
971ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            SkSafeRef(fRenderTarget);
972ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            // Here we ref the effects directly rather than the effect-refs. TODO: When the effect-
973ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            // ref gets fully unref'ed it will cause the underlying effect to unref its resources
974ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            // and recycle them to the cache (if no one else is holding a ref to the resources).
975eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com            fStages.reset(drawState.fColorStages.count() + drawState.fCoverageStages.count());
976eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com            fColorStageCnt = drawState.fColorStages.count();
977eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com            for (int i = 0; i < fColorStageCnt; ++i) {
978eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com                fStages[i].saveFrom(drawState.fColorStages[i]);
979eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com            }
980eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com            for (int i = 0; i < drawState.fCoverageStages.count(); ++i) {
981eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com                fStages[i + fColorStageCnt].saveFrom(drawState.fCoverageStages[i]);
982ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            }
9831acc3d7cc28c5631b5300578ab13439bdefd4e33commit-bot@chromium.org            SkDEBUGCODE(fInitialized = true;)
984ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        }
985ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com
986ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        void restoreTo(GrDrawState* drawState) {
987f6de475e5cbd143f348ff7738919e397b7fe7f57tfarina@chromium.org            SkASSERT(fInitialized);
988ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            drawState->fCommon = fCommon;
989ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            drawState->setRenderTarget(fRenderTarget);
990eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com            // reinflate color/cov stage arrays.
9912d3b49201302f3f82e405a750724eae8ef82e5a0commit-bot@chromium.org            drawState->fColorStages.reset();
992eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com            for (int i = 0; i < fColorStageCnt; ++i) {
9932d3b49201302f3f82e405a750724eae8ef82e5a0commit-bot@chromium.org                SkNEW_APPEND_TO_TARRAY(&drawState->fColorStages, GrEffectStage, (fStages[i]));
994eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com            }
995eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com            int coverageStageCnt = fStages.count() - fColorStageCnt;
9962d3b49201302f3f82e405a750724eae8ef82e5a0commit-bot@chromium.org            drawState->fCoverageStages.reset();
997eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com            for (int i = 0; i < coverageStageCnt; ++i) {
9982d3b49201302f3f82e405a750724eae8ef82e5a0commit-bot@chromium.org                SkNEW_APPEND_TO_TARRAY(&drawState->fCoverageStages,
9992d3b49201302f3f82e405a750724eae8ef82e5a0commit-bot@chromium.org                                        GrEffectStage, (fStages[i + fColorStageCnt]));
1000ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            }
1001ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        }
1002ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com
1003ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        bool isEqual(const GrDrawState& state) const {
1004eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com            int numCoverageStages = fStages.count() - fColorStageCnt;
1005eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com            if (fRenderTarget != state.fRenderTarget.get() ||
1006eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com                fColorStageCnt != state.fColorStages.count() ||
1007eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com                numCoverageStages != state.fCoverageStages.count() ||
1008eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com                fCommon != state.fCommon) {
1009ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                return false;
1010ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            }
1011eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com            bool explicitLocalCoords = state.hasLocalCoordAttribute();
1012eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com            for (int i = 0; i < fColorStageCnt; ++i) {
1013eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com                if (!fStages[i].isEqual(state.fColorStages[i], explicitLocalCoords)) {
1014eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com                    return false;
1015eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com                }
1016eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com            }
1017eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com            for (int i = 0; i < numCoverageStages; ++i) {
1018eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com                int s = fColorStageCnt + i;
1019eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com                if (!fStages[s].isEqual(state.fCoverageStages[i], explicitLocalCoords)) {
1020ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                    return false;
1021ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com                }
1022ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            }
1023ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com            return true;
1024ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com        }
1025ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com
1026ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    private:
1027eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        typedef SkAutoSTArray<8, GrEffectStage::DeferredStage> DeferredStageArray;
1028eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com
10299b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        GrRenderTarget*                       fRenderTarget;
10309b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com        CommonState                           fCommon;
1031eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        int                                   fColorStageCnt;
1032eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com        DeferredStageArray                    fStages;
1033ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com
10341acc3d7cc28c5631b5300578ab13439bdefd4e33commit-bot@chromium.org        SkDEBUGCODE(bool fInitialized;)
1035ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com    };
1036ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.com
1037ca43208e4aaac817fbc8265542f995f24a3fb7bfbsalomon@google.comprivate:
10389b855c7c95ce9fff7a447e4a6bdf8a469c1f3097jvanverth@google.com
1039eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    SkAutoTUnref<GrRenderTarget>        fRenderTarget;
1040eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    CommonState                         fCommon;
1041eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com
1042eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    typedef SkSTArray<4, GrEffectStage> EffectStageArray;
1043eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    EffectStageArray                    fColorStages;
1044eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    EffectStageArray                    fCoverageStages;
1045eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com
1046eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    // Some of the auto restore objects assume that no effects are removed during their lifetime.
1047eb6879f50a5564eeb981ec5616b55bf685eb76fcbsalomon@google.com    // This is used to assert that this condition holds.
10481acc3d7cc28c5631b5300578ab13439bdefd4e33commit-bot@chromium.org    SkDEBUGCODE(int fBlockEffectRemovalCnt;)
10498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1050429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com    /**
1051429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com     *  Sets vertex attributes for next draw.
1052429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com     *
1053429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com     *  @param attribs    the array of vertex attributes to set.
1054429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com     *  @param count      the number of attributes being set, limited to kMaxVertexAttribCnt.
1055429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com     */
1056429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com    void setVertexAttribs(const GrVertexAttrib attribs[], int count);
1057429033038271147ed66b4bc2675ac98a5ccfa75crobertphillips@google.com
1058a4de8c257ea0be8ff7081f645249b6afe5c48e7ecommit-bot@chromium.org    typedef SkRefCnt INHERITED;
10599381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com};
10609381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
10612b446734cfa8201e5478648988de86b646cb9544bsalomon@google.comGR_MAKE_BITFIELD_OPS(GrDrawState::BlendOptFlags);
10622b446734cfa8201e5478648988de86b646cb9544bsalomon@google.com
10639381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#endif
1064