GrDrawState.h revision 46d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24
19381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com/*
29381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * Copyright 2011 Google Inc.
39381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com *
49381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * Use of this source code is governed by a BSD-style license that can be
59381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com * found in the LICENSE file.
69381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com */
79381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
89381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#ifndef GrDrawState_DEFINED
99381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#define GrDrawState_DEFINED
109381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
112eaaefd7e6a58339b3f93333f1e9cc92252cc303bsalomon@google.com#include "GrBackendEffectFactory.h"
129381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#include "GrColor.h"
13b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com#include "SkMatrix.h"
142e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com#include "GrRefCnt.h"
1508283afc265f1153834256fc1012519813ba6b73bsalomon@google.com#include "GrEffectStage.h"
169381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#include "GrStencil.h"
1764aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com#include "GrTexture.h"
189ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com#include "GrRenderTarget.h"
1968b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com#include "effects/GrSimpleTextureEffect.h"
209381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
219381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#include "SkXfermode.h"
229381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
23af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.comclass GrPaint;
249381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
252e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.comclass GrDrawState : public GrRefCnt {
262e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.compublic:
27fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com    SK_DECLARE_INST_COUNT(GrDrawState)
28d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
299381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    /**
301322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * Total number of effect stages. Each stage can host a GrEffect. A stage is enabled if it has a
311322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * GrEffect. The effect produces an output color in the fragment shader. It's inputs are the
321322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * output from the previous enabled stage and a position. The position is either derived from
331322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * the interpolated vertex positions or explicit per-vertex coords, depending upon the
341322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * GrVertexLayout used to draw.
35bf5cad4e9c5808493b35cb9b0000a2d36b7f9b78robertphillips@google.com     *
361322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * The stages are divided into two sets, color-computing and coverage-computing. The final color
371322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * stage produces the final pixel color. The coverage-computing stages function exactly as the
381322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * color-computing but the output of the final coverage stage is treated as a fractional pixel
391322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * coverage rather than as input to the src/dst color blend step.
401322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     *
411322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * The input color to the first enabled color-stage is either the constant color or interpolated
421322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * per-vertex colors, depending upon GrVertexLayout. The input to the first coverage stage is
431322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * either a constant coverage (usually full-coverage), interpolated per-vertex coverage, or
441322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * edge-AA computed coverage. (This latter is going away as soon as it can be rewritten as a
451322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * GrEffect).
461322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     *
47cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com     * See the documentation of kCoverageDrawing_StateBit for information about disabling the
48cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com     * the color / coverage distinction.
49cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com     *
501322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * Stages 0 through GrPaint::kTotalStages-1 are reserved for stages copied from the client's
511322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * GrPaint. Stages GrPaint::kTotalStages through kNumStages-2 are earmarked for use by
521322134a3a7232e4ae3433733ed425fd9966bd5cbsalomon@google.com     * GrTextContext and GrPathRenderer-derived classes. kNumStages-1 is earmarked for clipping
53dfdb7e5240276493077b7c6e1f3cc8b8a0e195babsalomon@google.com     * by GrClipMaskManager.
549381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     */
559381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    enum {
56580711694654b8edc70028d09c4211445b661466twiz@google.com        kNumStages = 5,
579381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        kMaxTexCoords = kNumStages
589381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    };
599381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
60d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    GrDrawState()
619ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        : fRenderTarget(NULL) {
629ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
6352a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        this->reset();
6452a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    }
6546f7afb9867200b568c21736da8a8bbb56b20e30bsalomon@google.com
66d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    GrDrawState(const GrDrawState& state)
679ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        : fRenderTarget(NULL) {
689ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
6946f7afb9867200b568c21736da8a8bbb56b20e30bsalomon@google.com        *this = state;
7046f7afb9867200b568c21736da8a8bbb56b20e30bsalomon@google.com    }
7146f7afb9867200b568c21736da8a8bbb56b20e30bsalomon@google.com
729ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com    virtual ~GrDrawState() {
737d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        this->disableStages();
749ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        GrSafeSetNull(fRenderTarget);
759ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com    }
769ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
7752a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    /**
787d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com     * Resets to the default state.
7908283afc265f1153834256fc1012519813ba6b73bsalomon@google.com     * GrEffects will be removed from all stages.
80d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     */
8152a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    void reset() {
829ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
837d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        this->disableStages();
8452a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com
8552a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        fColor = 0xffffffff;
86861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fViewMatrix.reset();
87861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        GrSafeSetNull(fRenderTarget);
8847059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        fSrcBlend = kOne_GrBlendCoeff;
8947059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        fDstBlend = kZero_GrBlendCoeff;
90861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fBlendConstant = 0x0;
91861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fFlagBits = 0x0;
92861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fVertexEdgeType = kHairLine_EdgeType;
93861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fStencilSettings.setDisabled();
94861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fFirstCoverageStage = kNumStages;
95861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fCoverage = 0xffffffff;
96861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fColorFilterMode = SkXfermode::kDst_Mode;
97861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fColorFilterColor = 0x0;
98861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fDrawFace = kBoth_DrawFace;
99af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com    }
100af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com
101af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com    /**
102af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com     * Initializes the GrDrawState based on a GrPaint. Note that GrDrawState
1031e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * encompasses more than GrPaint. Aspects of GrDrawState that have no
104af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com     * GrPaint equivalents are not modified. GrPaint has fewer stages than
105af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com     * GrDrawState. The extra GrDrawState stages are disabled.
106af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com     */
107af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com    void setFromPaint(const GrPaint& paint);
1088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
1108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Color
1118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
1128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
1148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Sets color for next draw to a premultiplied-alpha color.
1158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
1168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param color    the color to set.
1178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
1188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setColor(GrColor color) { fColor = color; }
1198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrColor getColor() const { return fColor; }
1218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
1238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Sets the color to be used for the next draw to be
1248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  (r,g,b,a) = (alpha, alpha, alpha, alpha).
1258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
1268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param alpha The alpha value to set as the color.
1278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
1288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setAlpha(uint8_t a) {
1298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        this->setColor((a << 24) | (a << 16) | (a << 8) | a);
1308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
1318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
1338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Add a color filter that can be represented by a color and a mode. Applied
1348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * after color-computing texture stages.
1358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
1368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setColorFilter(GrColor c, SkXfermode::Mode mode) {
1378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fColorFilterColor = c;
1388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fColorFilterMode = mode;
1398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
1408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrColor getColorFilterColor() const { return fColorFilterColor; }
1428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    SkXfermode::Mode getColorFilterMode() const { return fColorFilterMode; }
1438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1445b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    /**
1455b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com     * Constructor sets the color to be 'color' which is undone by the destructor.
1465b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com     */
1475b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    class AutoColorRestore : public ::GrNoncopyable {
1485b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    public:
1495b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        AutoColorRestore(GrDrawState* drawState, GrColor color) {
1505b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com            fDrawState = drawState;
1515b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com            fOldColor = fDrawState->getColor();
1525b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com            fDrawState->setColor(color);
1535b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        }
1545b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        ~AutoColorRestore() {
1555b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com            fDrawState->setColor(fOldColor);
1565b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        }
1575b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    private:
1585b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        GrDrawState*    fDrawState;
1595b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        GrColor         fOldColor;
1605b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    };
1615b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com
1628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
1638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
1652401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    /// @name Coverage
1662401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    ////
1672401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com
1682401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    /**
169d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     * Sets a constant fractional coverage to be applied to the draw. The
1702401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     * initial value (after construction or reset()) is 0xff. The constant
1712401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     * coverage is ignored when per-vertex coverage is provided.
1722401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     */
1732401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    void setCoverage(uint8_t coverage) {
1742401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com        fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage);
1752401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    }
1762401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com
1772401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    /**
1782401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     * Version of above that specifies 4 channel per-vertex color. The value
1792401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     * should be premultiplied.
1802401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     */
1812401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    void setCoverage4(GrColor coverage) {
1822401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com        fCoverage = coverage;
1832401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    }
1842401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com
1852401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    GrColor getCoverage() const {
1862401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com        return fCoverage;
1872401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    }
1882401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com
1892401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    /// @}
1902401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com
1912401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
1928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Textures
1938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
1948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
19668b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com     * Creates a GrSimpleTextureEffect.
1971e8f016305805d4d8cad74aba3a21b78486f9d6ftomhudson@google.com     */
198b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com    void createTextureEffect(int stageIdx, GrTexture* texture, const SkMatrix& matrix) {
19908283afc265f1153834256fc1012519813ba6b73bsalomon@google.com        GrAssert(!this->getStage(stageIdx).getEffect());
20068b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com        GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix);
201d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com        this->stage(stageIdx)->setEffect(effect)->unref();
202dfdb7e5240276493077b7c6e1f3cc8b8a0e195babsalomon@google.com    }
20308283afc265f1153834256fc1012519813ba6b73bsalomon@google.com    void createTextureEffect(int stageIdx,
20408283afc265f1153834256fc1012519813ba6b73bsalomon@google.com                             GrTexture* texture,
205b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com                             const SkMatrix& matrix,
206dfdb7e5240276493077b7c6e1f3cc8b8a0e195babsalomon@google.com                             const GrTextureParams& params) {
20708283afc265f1153834256fc1012519813ba6b73bsalomon@google.com        GrAssert(!this->getStage(stageIdx).getEffect());
20868b58c95384dd6c2fd389a5b4bbf8fc468819454bsalomon@google.com        GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params);
209d8b5faca043100d7a1e4594b4d10e462532af390bsalomon@google.com        this->stage(stageIdx)->setEffect(effect)->unref();
2101ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com    }
2111ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com
2127d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com    bool stagesDisabled() {
2137d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        for (int i = 0; i < kNumStages; ++i) {
21408283afc265f1153834256fc1012519813ba6b73bsalomon@google.com            if (NULL != fStages[i].getEffect()) {
2157d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com                return false;
2167d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com            }
2177d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        }
2183eee8fbe0f280bc1dea59dc0b0ebd8021b51137ftomhudson@google.com        return true;
2197d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com    }
220676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com
22108283afc265f1153834256fc1012519813ba6b73bsalomon@google.com    void disableStage(int stageIdx) {
22208283afc265f1153834256fc1012519813ba6b73bsalomon@google.com        fStages[stageIdx].setEffect(NULL);
223676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com    }
224676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com
225972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    /**
226f271cc7183fe48ac64d2d9a454eb013c91b42d53bsalomon@google.com     * Release all the GrEffects referred to by this draw state.
227972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com     */
2287d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com    void disableStages() {
229972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com        for (int i = 0; i < kNumStages; ++i) {
230676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com            this->disableStage(i);
231972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com        }
232972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    }
233972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com
2347d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com    class AutoStageDisable : public ::GrNoncopyable {
235972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    public:
2367d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        AutoStageDisable(GrDrawState* ds) : fDrawState(ds) {}
2377d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        ~AutoStageDisable() {
238972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com            if (NULL != fDrawState) {
2397d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com                fDrawState->disableStages();
240972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com            }
241972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com        }
242972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    private:
243972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com        GrDrawState* fDrawState;
244972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    };
245972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com
2468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
2478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
24908283afc265f1153834256fc1012519813ba6b73bsalomon@google.com    /// @name Stages
2508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
2518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
25308283afc265f1153834256fc1012519813ba6b73bsalomon@google.com     * Returns the current stage by index.
2548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
25508283afc265f1153834256fc1012519813ba6b73bsalomon@google.com    const GrEffectStage& getStage(int stageIdx) const {
25608283afc265f1153834256fc1012519813ba6b73bsalomon@google.com        GrAssert((unsigned)stageIdx < kNumStages);
25708283afc265f1153834256fc1012519813ba6b73bsalomon@google.com        return fStages[stageIdx];
2588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
2598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
26108283afc265f1153834256fc1012519813ba6b73bsalomon@google.com     * Writable pointer to a stage.
2628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
26308283afc265f1153834256fc1012519813ba6b73bsalomon@google.com    GrEffectStage* stage(int stageIdx) {
26408283afc265f1153834256fc1012519813ba6b73bsalomon@google.com        GrAssert((unsigned)stageIdx < kNumStages);
26508283afc265f1153834256fc1012519813ba6b73bsalomon@google.com        return fStages + stageIdx;
2668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
2678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
269288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com     * Called when the source coord system is changing. preConcat gives the transformation from the
270288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com     * old coord system to the new coord system.
2718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
272b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com    void preConcatStageMatrices(const SkMatrix& preConcat) {
2738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        for (int i = 0; i < kNumStages; ++i) {
274e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com            if (this->isStageEnabled(i)) {
27508283afc265f1153834256fc1012519813ba6b73bsalomon@google.com                fStages[i].preConcatCoordChange(preConcat);
2768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
2778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
2788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
2798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
280e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com    /**
281288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com     * Called when the source coord system is changing. preConcatInverse is the inverse of the
282288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com     * transformation from the old coord system to the new coord system. Returns false if the matrix
283288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com     * cannot be inverted.
284e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com     */
285b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com    bool preConcatStageMatricesWithInverse(const SkMatrix& preConcatInverse) {
286b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com        SkMatrix inv;
287e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        bool computed = false;
288e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        for (int i = 0; i < kNumStages; ++i) {
289e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com            if (this->isStageEnabled(i)) {
290288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com                if (!computed && !preConcatInverse.invert(&inv)) {
291e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com                    return false;
292e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com                } else {
293e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com                    computed = true;
294e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com                }
29508283afc265f1153834256fc1012519813ba6b73bsalomon@google.com                fStages[i].preConcatCoordChange(preConcatInverse);
296e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com            }
297e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        }
298e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        return true;
299e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com    }
300e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com
3018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
3028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
3048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Coverage / Color Stages
3058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
3068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * A common pattern is to compute a color with the initial stages and then
3098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * modulate that color by a coverage value in later stage(s) (AA, mask-
310d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     * filters, glyph mask, etc). Color-filters, xfermodes, etc should be
311d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     * computed based on the pre-coverage-modulated color. The division of
312d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     * stages between color-computing and coverage-computing is specified by
3138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * this method. Initially this is kNumStages (all stages
3148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * are color-computing).
3158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setFirstCoverageStage(int firstCoverageStage) {
3178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((unsigned)firstCoverageStage <= kNumStages);
318d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        fFirstCoverageStage = firstCoverageStage;
3198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
3208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Gets the index of the first coverage-computing stage.
3238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    int getFirstCoverageStage() const {
325d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        return fFirstCoverageStage;
3268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
3278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///@}
3298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
3318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Blending
3328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
3338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3351e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * Sets the blending function coefficients.
3368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * The blend function will be:
3388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *    D' = sat(S*srcCoef + D*dstCoef)
3398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *   where D is the existing destination color, S is the incoming source
3418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *   color, and D' is the new destination color that will be written. sat()
3428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *   is the saturation function.
3438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3441e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * @param srcCoef coefficient applied to the src color.
3451e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * @param dstCoef coefficient applied to the dst color.
3468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
3488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fSrcBlend = srcCoeff;
3498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fDstBlend = dstCoeff;
3508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    #if GR_DEBUG
3518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        switch (dstCoeff) {
35247059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kDC_GrBlendCoeff:
35347059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kIDC_GrBlendCoeff:
35447059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kDA_GrBlendCoeff:
35547059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kIDA_GrBlendCoeff:
3568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
3578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                     "coverage stages.\n");
3588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
3598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        default:
3608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
3618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
3628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        switch (srcCoeff) {
36347059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kSC_GrBlendCoeff:
36447059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kISC_GrBlendCoeff:
36547059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kSA_GrBlendCoeff:
36647059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kISA_GrBlendCoeff:
3678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            GrPrintf("Unexpected src blend coeff. Won't work correctly with"
3688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                     "coverage stages.\n");
3698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
3708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        default:
3718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
3728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
3738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    #endif
3748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
3758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrBlendCoeff getSrcBlendCoeff() const { return fSrcBlend; }
3778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrBlendCoeff getDstBlendCoeff() const { return fDstBlend; }
3788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff,
3808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                          GrBlendCoeff* dstBlendCoeff) const {
3818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        *srcBlendCoeff = fSrcBlend;
3828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        *dstBlendCoeff = fDstBlend;
3838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
3848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the blending function constant referenced by the following blending
3871e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * coefficients:
38847059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com     *      kConstC_GrBlendCoeff
38947059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com     *      kIConstC_GrBlendCoeff
39047059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com     *      kConstA_GrBlendCoeff
39147059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com     *      kIConstA_GrBlendCoeff
3928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param constant the constant to set
3948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setBlendConstant(GrColor constant) { fBlendConstant = constant; }
3968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Retrieves the last value set by setBlendConstant()
3998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return the blending constant value
4008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
4018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrColor getBlendConstant() const { return fBlendConstant; }
4028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
4048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
4068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name View Matrix
4078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
4088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
410a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com     * Sets the matrix applied to vertex positions.
4118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * In the post-view-matrix space the rectangle [0,w]x[0,h]
4138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * fully covers the render target. (w and h are the width and height of the
4148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * the rendertarget.)
4158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
416b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com    void setViewMatrix(const SkMatrix& m) { fViewMatrix = m; }
4178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Gets a writable pointer to the view matrix.
4208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
421b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com    SkMatrix* viewMatrix() { return &fViewMatrix; }
4228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Multiplies the current view matrix by a matrix
4258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  After this call V' = V*m where V is the old view matrix,
4278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  m is the parameter to this function, and V' is the new view matrix.
4288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  (We consider positions to be column vectors so position vector p is
4298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  transformed by matrix X as p' = X*p.)
4308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param m the matrix used to modify the view matrix.
4328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
433b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com    void preConcatViewMatrix(const SkMatrix& m) { fViewMatrix.preConcat(m); }
4348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Multiplies the current view matrix by a matrix
4378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  After this call V' = m*V where V is the old view matrix,
4398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  m is the parameter to this function, and V' is the new view matrix.
4408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  (We consider positions to be column vectors so position vector p is
4418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  transformed by matrix X as p' = X*p.)
4428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param m the matrix used to modify the view matrix.
4448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
445b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com    void postConcatViewMatrix(const SkMatrix& m) { fViewMatrix.postConcat(m); }
4468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Retrieves the current view matrix
4498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return the current view matrix.
4508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
451b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com    const SkMatrix& getViewMatrix() const { return fViewMatrix; }
4528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Retrieves the inverse of the current view matrix.
4558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  If the current view matrix is invertible, return true, and if matrix
4578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  is non-null, copy the inverse into it. If the current view matrix is
4588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  non-invertible, return false and ignore the matrix parameter.
4598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param matrix if not null, will receive a copy of the current inverse.
4618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
462b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com    bool getViewInverse(SkMatrix* matrix) const {
4638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // TODO: determine whether we really need to leave matrix unmodified
4648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // at call sites when inversion fails.
465b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com        SkMatrix inverse;
4668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        if (fViewMatrix.invert(&inverse)) {
4678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (matrix) {
4688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                *matrix = inverse;
4698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
4708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            return true;
4718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
4728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return false;
4738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
4748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4755b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    ////////////////////////////////////////////////////////////////////////////
4765b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com
4775b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    /**
4782fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com     * Preconcats the current view matrix and restores the previous view matrix in the destructor.
479c196b522d06919885c6bbe28b7b06d2e5b2cb9bfbsalomon@google.com     * Effect matrices are automatically adjusted to compensate.
4805b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com     */
4818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    class AutoViewMatrixRestore : public ::GrNoncopyable {
4828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    public:
4838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        AutoViewMatrixRestore() : fDrawState(NULL) {}
4842fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
4852fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        AutoViewMatrixRestore(GrDrawState* ds,
486b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com                              const SkMatrix& preconcatMatrix,
4872fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com                              uint32_t explicitCoordStageMask = 0) {
4888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            fDrawState = NULL;
4892fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com            this->set(ds, preconcatMatrix, explicitCoordStageMask);
4908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
4912fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
4922fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        ~AutoViewMatrixRestore() { this->restore(); }
4932fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
494a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        /**
495a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * Can be called prior to destructor to restore the original matrix.
496a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         */
4972fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        void restore();
498f467ce7bc33af5f496e0619387551aedec6d2517skia.committer@gmail.com
4992fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        void set(GrDrawState* drawState,
500b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com                 const SkMatrix& preconcatMatrix,
5012fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com                 uint32_t explicitCoordStageMask = 0);
5022fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
503ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com        bool isSet() const { return NULL != fDrawState; }
5042fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
5058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    private:
506288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com        GrDrawState*                        fDrawState;
507b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com        SkMatrix                            fViewMatrix;
50808283afc265f1153834256fc1012519813ba6b73bsalomon@google.com        GrEffectStage::SavedCoordChange     fSavedCoordChanges[GrDrawState::kNumStages];
509288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com        uint32_t                            fRestoreMask;
5109381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    };
5119381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
5125b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    ////////////////////////////////////////////////////////////////////////////
5135b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com
5145b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    /**
5152fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com     * This sets the view matrix to identity and adjusts stage matrices to compensate. The
5162fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com     * destructor undoes the changes, restoring the view matrix that was set before the
5172fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com     * constructor. It is similar to passing the inverse of the current view matrix to
5182fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com     * AutoViewMatrixRestore, but lazily computes the inverse only if necessary.
5195b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com     */
5205b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    class AutoDeviceCoordDraw : ::GrNoncopyable {
5215b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    public:
5222fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        AutoDeviceCoordDraw() : fDrawState(NULL) {}
5235b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        /**
5242fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com         * If a stage's texture matrix is applied to explicit per-vertex coords, rather than to
5252fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com         * positions, then we don't want to modify its matrix. The explicitCoordStageMask is used
5262fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com         * to specify such stages.
5275b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com         */
5285b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        AutoDeviceCoordDraw(GrDrawState* drawState,
5292fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com                            uint32_t explicitCoordStageMask = 0) {
5302fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com            fDrawState = NULL;
5312fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com            this->set(drawState, explicitCoordStageMask);
5322fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        }
5332fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
534a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        ~AutoDeviceCoordDraw() { this->restore(); }
535a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com
5362fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        bool set(GrDrawState* drawState, uint32_t explicitCoordStageMask = 0);
5372fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
538a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        /**
539a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * Returns true if this object was successfully initialized on to a GrDrawState. It may
540a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * return false because a non-default constructor or set() were never called or because
541a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * the view matrix was not invertible.
542a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         */
5435b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        bool succeeded() const { return NULL != fDrawState; }
5442fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
545a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        /**
546a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * Returns the matrix that was set previously set on the drawState. This is only valid
547a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * if succeeded returns true.
548a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         */
549b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com        const SkMatrix& getOriginalMatrix() const {
550a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com            GrAssert(this->succeeded());
551a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com            return fViewMatrix;
552a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        }
5532fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
554a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        /**
555a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * Can be called prior to destructor to restore the original matrix.
556a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         */
557a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        void restore();
5582fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
5595b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    private:
560288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com        GrDrawState*                        fDrawState;
561b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com        SkMatrix                            fViewMatrix;
56208283afc265f1153834256fc1012519813ba6b73bsalomon@google.com        GrEffectStage::SavedCoordChange     fSavedCoordChanges[GrDrawState::kNumStages];
563288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com        uint32_t                            fRestoreMask;
5645b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    };
5655b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com
5668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
5678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
5698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Render Target
5708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
5718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
5738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the rendertarget used at the next drawing call
5748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
5758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param target  The render target to set.
5768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
577d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    void setRenderTarget(GrRenderTarget* target) {
5789ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        GrSafeAssign(fRenderTarget, target);
5799ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com    }
5808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
5828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Retrieves the currently set rendertarget.
5838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
5848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return    The currently set render target.
5858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
5868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    const GrRenderTarget* getRenderTarget() const { return fRenderTarget; }
5878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrRenderTarget* getRenderTarget() { return fRenderTarget; }
5888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    class AutoRenderTargetRestore : public ::GrNoncopyable {
5908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    public:
591cadbcb8e536f89babb4e165bfdca18384e97d582bsalomon@google.com        AutoRenderTargetRestore() : fDrawState(NULL), fSavedTarget(NULL) {}
5928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) {
5938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            fDrawState = NULL;
5947460b378d68217167013ca889a4cdcae742908e7robertphillips@google.com            fSavedTarget = NULL;
5958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            this->set(ds, newTarget);
5968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
5979ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        ~AutoRenderTargetRestore() { this->restore(); }
5989ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
5999ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        void restore() {
6008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (NULL != fDrawState) {
6018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fDrawState->setRenderTarget(fSavedTarget);
6029ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com                fDrawState = NULL;
6038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
6049ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com            GrSafeSetNull(fSavedTarget);
6059ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        }
6069ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
6079ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        void set(GrDrawState* ds, GrRenderTarget* newTarget) {
6089ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com            this->restore();
6099ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
6108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (NULL != ds) {
6119ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com                GrAssert(NULL == fSavedTarget);
6128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fSavedTarget = ds->getRenderTarget();
6139ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com                SkSafeRef(fSavedTarget);
6148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                ds->setRenderTarget(newTarget);
6159ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com                fDrawState = ds;
6168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
6178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
6188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    private:
6198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrDrawState* fDrawState;
6208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrRenderTarget* fSavedTarget;
6218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    };
6228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
6248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
6268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Stencil
6278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
6288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
6308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the stencil settings to use for the next draw.
6318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Changing the clip has the side-effect of possibly zeroing
6328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * out the client settable stencil bits. So multipass algorithms
6338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * using stencil should not change the clip between passes.
6348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param settings  the stencil settings to use.
6358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
6368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setStencil(const GrStencilSettings& settings) {
6378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fStencilSettings = settings;
6388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
6418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Shortcut to disable stencil testing and ops.
6428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
6438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void disableStencil() {
6448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fStencilSettings.setDisabled();
6458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    const GrStencilSettings& getStencil() const { return fStencilSettings; }
6488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrStencilSettings* stencil() { return &fStencilSettings; }
6508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
6528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
6548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // @name Edge AA
6551e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com    // Edge equations can be specified to perform anti-aliasing. Because the
6567ffe6810c6787f7a353ef3fe8fab3fc6440aae19bsalomon@google.com    // edges are specified as per-vertex data, vertices that are shared by
6577ffe6810c6787f7a353ef3fe8fab3fc6440aae19bsalomon@google.com    // multiple edges must be split.
6588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    //
6598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
6608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
6629381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * When specifying edges as vertex data this enum specifies what type of
66381712883419f76e25d2ffec38a9438284a45a48dbsalomon@google.com     * edges are in use. The edges are always 4 SkScalars in memory, even when
6649381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * the edge type requires fewer than 4.
66593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com     *
66693c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com     * TODO: Fix the fact that HairLine and Circle edge types use y-down coords.
66793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com     *       (either adjust in VS or use origin_upper_left in GLSL)
6689381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     */
6699381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    enum VertexEdgeType {
6709381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        /* 1-pixel wide line
6719381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com           2D implicit line eq (a*x + b*y +c = 0). 4th component unused */
6729381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        kHairLine_EdgeType,
673d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        /* Quadratic specified by u^2-v canonical coords (only 2
67469cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com           components used). Coverage based on signed distance with negative
67593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com           being inside, positive outside. Edge specified in window space
67693c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com           (y-down) */
67769cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com        kQuad_EdgeType,
67869cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com        /* Same as above but for hairline quadratics. Uses unsigned distance.
67969cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com           Coverage is min(0, 1-distance). */
68069cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com        kHairQuad_EdgeType,
68193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com        /* Circle specified as center_x, center_y, outer_radius, inner_radius
68293c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com           all in window space (y-down). */
68393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com        kCircle_EdgeType,
68446d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com        /* Axis-aligned ellipse specified as center_x, center_y, x_radius, x_radius/y_radius
68546d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com           all in window space (y-down). */
68646d3d39e65e0b3ea2ad7c91c176ccafb4df0fa24jvanverth@google.com        kEllipse_EdgeType,
68769cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com
68869cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com        kVertexEdgeTypeCnt
6899381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    };
6909381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
6919381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    /**
692d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     * Determines the interpretation per-vertex edge data when the
6938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * kEdge_VertexLayoutBit is set (see GrDrawTarget). When per-vertex edges
6948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * are not specified the value of this setting has no effect.
6958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
6968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setVertexEdgeType(VertexEdgeType type) {
69769cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com        GrAssert(type >=0 && type < kVertexEdgeTypeCnt);
6988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fVertexEdgeType = type;
6998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
7008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
70152a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    VertexEdgeType getVertexEdgeType() const { return fVertexEdgeType; }
7028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
7048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
7068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name State Flags
7078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
7088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
7108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Flags that affect rendering. Controlled using enable/disableState(). All
7118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  default to disabled.
7128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
7138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    enum StateBits {
7148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
7158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Perform dithering. TODO: Re-evaluate whether we need this bit
7168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
7178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kDither_StateBit        = 0x01,
7188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
719cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
720cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
721cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * the 3D API.
7228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
7238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kHWAntialias_StateBit   = 0x02,
7248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
7258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Draws will respect the clip, otherwise the clip is ignored.
7268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
7278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kClip_StateBit          = 0x04,
7288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
7298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Disables writing to the color buffer. Useful when performing stencil
7308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * operations.
7318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
7328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kNoColorWrites_StateBit = 0x08,
7330342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com
734cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com        /**
735cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * Usually coverage is applied after color blending. The color is blended using the coeffs
736cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * specified by setBlendFunc(). The blended color is then combined with dst using coeffs
737cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * of src_coverage, 1-src_coverage. Sometimes we are explicitly drawing a coverage mask. In
738cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * this case there is no distinction between coverage and color and the caller needs direct
739cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * control over the blend coeffs. When set, there will be a single blend step controlled by
740cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         * setBlendFunc() which will use coverage*color as the src color.
741cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         */
742cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com         kCoverageDrawing_StateBit = 0x10,
743cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com
7448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // Users of the class may add additional bits to the vector
7458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kDummyStateBit,
7468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kLastPublicStateBit = kDummyStateBit-1,
7478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    };
7488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void resetStateFlags() {
7508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fFlagBits = 0;
7510fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
7520fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
7538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
7548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Enable render state settings.
7558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
7561e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * @param stateBits bitfield of StateBits specifying the states to enable
7578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
7588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void enableState(uint32_t stateBits) {
7598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fFlagBits |= stateBits;
7608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
7610fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
7628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
7638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Disable render state settings.
7648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
7651e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * @param stateBits bitfield of StateBits specifying the states to disable
7668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
7678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void disableState(uint32_t stateBits) {
7688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fFlagBits &= ~(stateBits);
7698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
7700fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
771d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com    /**
772d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com     * Enable or disable stateBits based on a boolean.
773d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com     *
7741e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * @param stateBits bitfield of StateBits to enable or disable
775d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com     * @param enable    if true enable stateBits, otherwise disable
776d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com     */
777d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com    void setState(uint32_t stateBits, bool enable) {
778d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com        if (enable) {
779d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com            this->enableState(stateBits);
780d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com        } else {
781d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com            this->disableState(stateBits);
782d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com        }
783d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com    }
784d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com
7858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isDitherState() const {
7868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return 0 != (fFlagBits & kDither_StateBit);
7878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
7880fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
7898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isHWAntialiasState() const {
7908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return 0 != (fFlagBits & kHWAntialias_StateBit);
7918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
7920fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
7938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isClipState() const {
7948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return 0 != (fFlagBits & kClip_StateBit);
7958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
7960fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
7978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isColorWriteDisabled() const {
7988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return 0 != (fFlagBits & kNoColorWrites_StateBit);
7998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
8008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
801cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com    bool isCoverageDrawing() const {
802cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com        return 0 != (fFlagBits & kCoverageDrawing_StateBit);
803cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com    }
804cf939ae54842fc7408ee68a41427086962b4c3dcbsalomon@google.com
8058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isStateFlagEnabled(uint32_t stateBit) const {
8068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return 0 != (stateBit & fFlagBits);
8078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
8088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
8108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
8128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Face Culling
8138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
8148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    enum DrawFace {
816978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com        kInvalid_DrawFace = -1,
817978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com
8188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kBoth_DrawFace,
8198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kCCW_DrawFace,
8208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kCW_DrawFace,
8218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    };
8228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
8248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Controls whether clockwise, counterclockwise, or both faces are drawn.
8258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param face  the face(s) to draw.
8268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
8278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setDrawFace(DrawFace face) {
828978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com        GrAssert(kInvalid_DrawFace != face);
8298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fDrawFace = face;
8308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
8318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
8338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Gets whether the target is drawing clockwise, counterclockwise,
8348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * or both faces.
8358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return the current draw face(s).
8368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
83752a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    DrawFace getDrawFace() const { return fDrawFace; }
838d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
8398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
8408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
84262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
843f13f58804659175925042a291304d483a4fd9278tomhudson@google.com    bool isStageEnabled(int s) const {
844f13f58804659175925042a291304d483a4fd9278tomhudson@google.com        GrAssert((unsigned)s < kNumStages);
84508283afc265f1153834256fc1012519813ba6b73bsalomon@google.com        return (NULL != fStages[s].getEffect());
846f13f58804659175925042a291304d483a4fd9278tomhudson@google.com    }
847f13f58804659175925042a291304d483a4fd9278tomhudson@google.com
84862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    // Most stages are usually not used, so conditionals here
84962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    // reduce the expected number of bytes touched by 50%.
8509381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    bool operator ==(const GrDrawState& s) const {
851861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        if (fColor != s.fColor ||
852861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            !s.fViewMatrix.cheapEqualTo(fViewMatrix) ||
853861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fRenderTarget != s.fRenderTarget ||
854861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fSrcBlend != s.fSrcBlend ||
855861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fDstBlend != s.fDstBlend ||
856861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fBlendConstant != s.fBlendConstant ||
857861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fFlagBits != s.fFlagBits ||
858861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fVertexEdgeType != s.fVertexEdgeType ||
859861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fStencilSettings != s.fStencilSettings ||
860861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fFirstCoverageStage != s.fFirstCoverageStage ||
861861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fCoverage != s.fCoverage ||
862861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fColorFilterMode != s.fColorFilterMode ||
863861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fColorFilterColor != s.fColorFilterColor ||
864861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fDrawFace != s.fDrawFace) {
8658fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com            return false;
8668fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com        }
86762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
86862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        for (int i = 0; i < kNumStages; i++) {
869f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com            bool enabled = this->isStageEnabled(i);
870f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com            if (enabled != s.isStageEnabled(i)) {
871f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com                return false;
872f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com            }
87308283afc265f1153834256fc1012519813ba6b73bsalomon@google.com            if (enabled && this->fStages[i] != s.fStages[i]) {
87462b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com                return false;
87562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com            }
87662b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        }
87762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        return true;
8789381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    }
8799381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    bool operator !=(const GrDrawState& s) const { return !(*this == s); }
88062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
881d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    // Most stages are usually not used, so conditionals here
88262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    // reduce the expected number of bytes touched by 50%.
88362b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    GrDrawState& operator =(const GrDrawState& s) {
884861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fColor = s.fColor;
8858fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com        fViewMatrix = s.fViewMatrix;
886861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        SkRefCnt_SafeAssign(fRenderTarget, s.fRenderTarget);
887861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fSrcBlend = s.fSrcBlend;
888861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fDstBlend = s.fDstBlend;
889861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fBlendConstant = s.fBlendConstant;
890861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fFlagBits = s.fFlagBits;
891861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fVertexEdgeType = s.fVertexEdgeType;
892861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fStencilSettings = s.fStencilSettings;
893861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fFirstCoverageStage = s.fFirstCoverageStage;
894861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fCoverage = s.fCoverage;
895861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fColorFilterMode = s.fColorFilterMode;
896861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fColorFilterColor = s.fColorFilterColor;
897861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fDrawFace = s.fDrawFace;
8988fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com
89962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        for (int i = 0; i < kNumStages; i++) {
900e742bf0ab19659145325ac894f7e0b78c8efbd89tomhudson@google.com            if (s.isStageEnabled(i)) {
90108283afc265f1153834256fc1012519813ba6b73bsalomon@google.com                this->fStages[i] = s.fStages[i];
90262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com            }
90362b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        }
9049ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
90562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        return *this;
90662b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    }
90762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
90862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.comprivate:
9092e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com
9101e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com    // These fields are roughly sorted by decreasing likelihood of being different in op==
911861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com    GrColor             fColor;
912b9086a026844e4cfd08b219e49ce3f12294cba98bsalomon@google.com    SkMatrix            fViewMatrix;
913861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com    GrRenderTarget*     fRenderTarget;
914861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com    GrBlendCoeff        fSrcBlend;
915861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com    GrBlendCoeff        fDstBlend;
916861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com    GrColor             fBlendConstant;
917861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com    uint32_t            fFlagBits;
918c077d1eaa8322087f3cc954c3b2e9af7fef103fcrobertphillips@google.com    VertexEdgeType      fVertexEdgeType;
91952a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    GrStencilSettings   fStencilSettings;
92069ffcf0d34878be7a1d2493785bf4df363199b10robertphillips@google.com    int                 fFirstCoverageStage;
9212401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    GrColor             fCoverage;
92252a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    SkXfermode::Mode    fColorFilterMode;
923861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com    GrColor             fColorFilterColor;
924861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com    DrawFace            fDrawFace;
9258fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com
9268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // This field must be last; it will not be copied or compared
9278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // if the corresponding fTexture[] is NULL.
92808283afc265f1153834256fc1012519813ba6b73bsalomon@google.com    GrEffectStage       fStages[kNumStages];
9298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
930fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com    typedef GrRefCnt INHERITED;
9319381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com};
9329381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
9339381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#endif
934