GrDrawState.h revision f271cc7183fe48ac64d2d9a454eb013c91b42d53
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
119381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#include "GrColor.h"
129381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#include "GrMatrix.h"
132e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com#include "GrRefCnt.h"
149381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#include "GrSamplerState.h"
159381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#include "GrStencil.h"
1664aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com#include "GrTexture.h"
179ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com#include "GrRenderTarget.h"
181e8f016305805d4d8cad74aba3a21b78486f9d6ftomhudson@google.com#include "effects/GrSingleTextureEffect.h"
199381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
209381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#include "SkXfermode.h"
219381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
22af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.comclass GrPaint;
239381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
242e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.comclass GrDrawState : public GrRefCnt {
252e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.compublic:
26fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com    SK_DECLARE_INST_COUNT(GrDrawState)
27d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
289381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    /**
299381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * Number of texture stages. Each stage takes as input a color and
309381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * 2D texture coordinates. The color input to the first enabled stage is the
319381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * per-vertex color or the constant color (setColor/setAlpha) if there are
329381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * no per-vertex colors. For subsequent stages the input color is the output
339381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * color from the previous enabled stage. The output color of each stage is
349381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * the input color modulated with the result of a texture lookup. Texture
359381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * lookups are specified by a texture a sampler (setSamplerState). Texture
369381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * coordinates for each stage come from the vertices based on a
379381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * GrVertexLayout bitfield. The output fragment color is the output color of
389381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * the last enabled stage. The presence or absence of texture coordinates
399381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * for each stage in the vertex layout indicates whether a stage is enabled
409381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * or not.
41bf5cad4e9c5808493b35cb9b0000a2d36b7f9b78robertphillips@google.com     *
42bf5cad4e9c5808493b35cb9b0000a2d36b7f9b78robertphillips@google.com     * Stages 0 through GrPaint::kTotalStages-1 are reserved for setting up
43d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     * the draw (i.e., textures and filter masks). Stages GrPaint::kTotalStages
44dfdb7e5240276493077b7c6e1f3cc8b8a0e195babsalomon@google.com     * through kNumStages-2 are earmarked for use by GrTextContext and
45dfdb7e5240276493077b7c6e1f3cc8b8a0e195babsalomon@google.com     * GrPathRenderer-derived classes. kNumStages-1 is earmarked for clipping
46dfdb7e5240276493077b7c6e1f3cc8b8a0e195babsalomon@google.com     * by GrClipMaskManager.
479381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     */
489381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    enum {
49580711694654b8edc70028d09c4211445b661466twiz@google.com        kNumStages = 5,
509381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        kMaxTexCoords = kNumStages
519381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    };
529381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
53d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    GrDrawState()
549ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        : fRenderTarget(NULL) {
559ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
5652a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        this->reset();
5752a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    }
5846f7afb9867200b568c21736da8a8bbb56b20e30bsalomon@google.com
59d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    GrDrawState(const GrDrawState& state)
609ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        : fRenderTarget(NULL) {
619ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
6246f7afb9867200b568c21736da8a8bbb56b20e30bsalomon@google.com        *this = state;
6346f7afb9867200b568c21736da8a8bbb56b20e30bsalomon@google.com    }
6446f7afb9867200b568c21736da8a8bbb56b20e30bsalomon@google.com
659ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com    virtual ~GrDrawState() {
667d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        this->disableStages();
679ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        GrSafeSetNull(fRenderTarget);
689ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com    }
699ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
7052a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    /**
717d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com     * Resets to the default state.
726f261bed0252e3f3caa595798364e0bf12a2573absalomon@google.com     * Sampler states *will* be modified: textures or GrEffect objects will be released.
73d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     */
7452a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    void reset() {
759ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
767d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        this->disableStages();
7752a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com
7852a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        fColor = 0xffffffff;
79861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fViewMatrix.reset();
80861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        GrSafeSetNull(fRenderTarget);
8147059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        fSrcBlend = kOne_GrBlendCoeff;
8247059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        fDstBlend = kZero_GrBlendCoeff;
83861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fBlendConstant = 0x0;
84861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fFlagBits = 0x0;
85861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fVertexEdgeType = kHairLine_EdgeType;
86861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fStencilSettings.setDisabled();
87861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fFirstCoverageStage = kNumStages;
88861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fCoverage = 0xffffffff;
89861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fColorFilterMode = SkXfermode::kDst_Mode;
90861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fColorFilterColor = 0x0;
91861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fDrawFace = kBoth_DrawFace;
92af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com    }
93af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com
94af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com    /**
95af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com     * Initializes the GrDrawState based on a GrPaint. Note that GrDrawState
961e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * encompasses more than GrPaint. Aspects of GrDrawState that have no
97af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com     * GrPaint equivalents are not modified. GrPaint has fewer stages than
98af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com     * GrDrawState. The extra GrDrawState stages are disabled.
99af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com     */
100af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com    void setFromPaint(const GrPaint& paint);
1018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
1038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Color
1048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
1058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
1078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Sets color for next draw to a premultiplied-alpha color.
1088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
1098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param color    the color to set.
1108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
1118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setColor(GrColor color) { fColor = color; }
1128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrColor getColor() const { return fColor; }
1148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
1168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Sets the color to be used for the next draw to be
1178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  (r,g,b,a) = (alpha, alpha, alpha, alpha).
1188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
1198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param alpha The alpha value to set as the color.
1208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
1218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setAlpha(uint8_t a) {
1228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        this->setColor((a << 24) | (a << 16) | (a << 8) | a);
1238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
1248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
1268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Add a color filter that can be represented by a color and a mode. Applied
1278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * after color-computing texture stages.
1288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
1298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setColorFilter(GrColor c, SkXfermode::Mode mode) {
1308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fColorFilterColor = c;
1318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fColorFilterMode = mode;
1328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
1338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrColor getColorFilterColor() const { return fColorFilterColor; }
1358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    SkXfermode::Mode getColorFilterMode() const { return fColorFilterMode; }
1368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1375b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    /**
1385b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com     * Constructor sets the color to be 'color' which is undone by the destructor.
1395b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com     */
1405b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    class AutoColorRestore : public ::GrNoncopyable {
1415b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    public:
1425b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        AutoColorRestore(GrDrawState* drawState, GrColor color) {
1435b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com            fDrawState = drawState;
1445b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com            fOldColor = fDrawState->getColor();
1455b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com            fDrawState->setColor(color);
1465b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        }
1475b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        ~AutoColorRestore() {
1485b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com            fDrawState->setColor(fOldColor);
1495b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        }
1505b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    private:
1515b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        GrDrawState*    fDrawState;
1525b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        GrColor         fOldColor;
1535b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    };
1545b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com
1558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
1568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
1582401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    /// @name Coverage
1592401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    ////
1602401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com
1612401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    /**
162d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     * Sets a constant fractional coverage to be applied to the draw. The
1632401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     * initial value (after construction or reset()) is 0xff. The constant
1642401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     * coverage is ignored when per-vertex coverage is provided.
1652401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     */
1662401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    void setCoverage(uint8_t coverage) {
1672401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com        fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage);
1682401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    }
1692401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com
1702401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    /**
1712401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     * Version of above that specifies 4 channel per-vertex color. The value
1722401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     * should be premultiplied.
1732401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     */
1742401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    void setCoverage4(GrColor coverage) {
1752401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com        fCoverage = coverage;
1762401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    }
1772401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com
1782401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    GrColor getCoverage() const {
1792401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com        return fCoverage;
1802401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    }
1812401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com
1822401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    /// @}
1832401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com
1842401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
1858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Textures
1868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
1878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
1891e8f016305805d4d8cad74aba3a21b78486f9d6ftomhudson@google.com     * Creates a GrSingleTextureEffect.
1901e8f016305805d4d8cad74aba3a21b78486f9d6ftomhudson@google.com     */
1911e8f016305805d4d8cad74aba3a21b78486f9d6ftomhudson@google.com    void createTextureEffect(int stage, GrTexture* texture) {
1926f261bed0252e3f3caa595798364e0bf12a2573absalomon@google.com        GrAssert(!this->getSampler(stage).getEffect());
1936f261bed0252e3f3caa595798364e0bf12a2573absalomon@google.com        this->sampler(stage)->setEffect(
1941e8f016305805d4d8cad74aba3a21b78486f9d6ftomhudson@google.com            SkNEW_ARGS(GrSingleTextureEffect, (texture)))->unref();
1951e8f016305805d4d8cad74aba3a21b78486f9d6ftomhudson@google.com    }
196dfdb7e5240276493077b7c6e1f3cc8b8a0e195babsalomon@google.com    void createTextureEffect(int stage, GrTexture* texture, const GrMatrix& matrix) {
1976f261bed0252e3f3caa595798364e0bf12a2573absalomon@google.com        GrAssert(!this->getSampler(stage).getEffect());
198f271cc7183fe48ac64d2d9a454eb013c91b42d53bsalomon@google.com        GrEffect* effect = SkNEW_ARGS(GrSingleTextureEffect, (texture));
199f271cc7183fe48ac64d2d9a454eb013c91b42d53bsalomon@google.com        this->sampler(stage)->setEffect(effect, matrix)->unref();
200dfdb7e5240276493077b7c6e1f3cc8b8a0e195babsalomon@google.com    }
201dfdb7e5240276493077b7c6e1f3cc8b8a0e195babsalomon@google.com    void createTextureEffect(int stage, GrTexture* texture,
202dfdb7e5240276493077b7c6e1f3cc8b8a0e195babsalomon@google.com                             const GrMatrix& matrix,
203dfdb7e5240276493077b7c6e1f3cc8b8a0e195babsalomon@google.com                             const GrTextureParams& params) {
2046f261bed0252e3f3caa595798364e0bf12a2573absalomon@google.com        GrAssert(!this->getSampler(stage).getEffect());
205f271cc7183fe48ac64d2d9a454eb013c91b42d53bsalomon@google.com        GrEffect* effect = SkNEW_ARGS(GrSingleTextureEffect, (texture, params));
206f271cc7183fe48ac64d2d9a454eb013c91b42d53bsalomon@google.com        this->sampler(stage)->setEffect(effect, matrix)->unref();
2071ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com    }
2081ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com
2091e8f016305805d4d8cad74aba3a21b78486f9d6ftomhudson@google.com
2107d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com    bool stagesDisabled() {
2117d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        for (int i = 0; i < kNumStages; ++i) {
2126f261bed0252e3f3caa595798364e0bf12a2573absalomon@google.com            if (NULL != fSamplerStates[i].getEffect()) {
2137d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com                return false;
2147d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com            }
2157d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        }
2163eee8fbe0f280bc1dea59dc0b0ebd8021b51137ftomhudson@google.com        return true;
2177d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com    }
218676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com
219676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com    void disableStage(int index) {
2206f261bed0252e3f3caa595798364e0bf12a2573absalomon@google.com        fSamplerStates[index].setEffect(NULL);
221676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com    }
222676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com
223972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    /**
224f271cc7183fe48ac64d2d9a454eb013c91b42d53bsalomon@google.com     * Release all the GrEffects referred to by this draw state.
225972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com     */
2267d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com    void disableStages() {
227972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com        for (int i = 0; i < kNumStages; ++i) {
228676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com            this->disableStage(i);
229972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com        }
230972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    }
231972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com
2327d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com    class AutoStageDisable : public ::GrNoncopyable {
233972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    public:
2347d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        AutoStageDisable(GrDrawState* ds) : fDrawState(ds) {}
2357d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        ~AutoStageDisable() {
236972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com            if (NULL != fDrawState) {
2377d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com                fDrawState->disableStages();
238972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com            }
239972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com        }
240972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    private:
241972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com        GrDrawState* fDrawState;
242972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    };
243972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com
2448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
2458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
2478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Samplers
2488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
2498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
2518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Returns the current sampler for a stage.
2528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
2538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    const GrSamplerState& getSampler(int stage) const {
2548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((unsigned)stage < kNumStages);
2558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return fSamplerStates[stage];
2568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
2578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
2598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Writable pointer to a stage's sampler.
2608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
2618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrSamplerState* sampler(int stage) {
2628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((unsigned)stage < kNumStages);
2638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return fSamplerStates + stage;
2648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
2658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
267288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com     * Called when the source coord system is changing. preConcat gives the transformation from the
268288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com     * old coord system to the new coord system.
2698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
270288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com    void preConcatSamplerMatrices(const GrMatrix& preConcat) {
2718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        for (int i = 0; i < kNumStages; ++i) {
272e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com            if (this->isStageEnabled(i)) {
273288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com                fSamplerStates[i].preConcatCoordChange(preConcat);
2748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
2758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
2768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
2778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
278e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com    /**
279288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com     * Called when the source coord system is changing. preConcatInverse is the inverse of the
280288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com     * transformation from the old coord system to the new coord system. Returns false if the matrix
281288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com     * cannot be inverted.
282e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com     */
283288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com    bool preConcatSamplerMatricesWithInverse(const GrMatrix& preConcatInverse) {
284e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        GrMatrix inv;
285e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        bool computed = false;
286e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        for (int i = 0; i < kNumStages; ++i) {
287e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com            if (this->isStageEnabled(i)) {
288288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com                if (!computed && !preConcatInverse.invert(&inv)) {
289e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com                    return false;
290e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com                } else {
291e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com                    computed = true;
292e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com                }
293288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com                fSamplerStates[i].preConcatCoordChange(preConcatInverse);
294e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com            }
295e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        }
296e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        return true;
297e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com    }
298e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com
2998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
3008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
3028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Coverage / Color Stages
3038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
3048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * A common pattern is to compute a color with the initial stages and then
3078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * modulate that color by a coverage value in later stage(s) (AA, mask-
308d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     * filters, glyph mask, etc). Color-filters, xfermodes, etc should be
309d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     * computed based on the pre-coverage-modulated color. The division of
310d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     * stages between color-computing and coverage-computing is specified by
3118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * this method. Initially this is kNumStages (all stages
3128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * are color-computing).
3138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setFirstCoverageStage(int firstCoverageStage) {
3158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((unsigned)firstCoverageStage <= kNumStages);
316d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        fFirstCoverageStage = firstCoverageStage;
3178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
3188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Gets the index of the first coverage-computing stage.
3218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    int getFirstCoverageStage() const {
323d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        return fFirstCoverageStage;
3248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
3258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///@}
3278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
3298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Blending
3308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
3318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3331e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * Sets the blending function coefficients.
3348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * The blend function will be:
3368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *    D' = sat(S*srcCoef + D*dstCoef)
3378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *   where D is the existing destination color, S is the incoming source
3398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *   color, and D' is the new destination color that will be written. sat()
3408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *   is the saturation function.
3418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3421e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * @param srcCoef coefficient applied to the src color.
3431e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * @param dstCoef coefficient applied to the dst color.
3448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
3468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fSrcBlend = srcCoeff;
3478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fDstBlend = dstCoeff;
3488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    #if GR_DEBUG
3498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        switch (dstCoeff) {
35047059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kDC_GrBlendCoeff:
35147059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kIDC_GrBlendCoeff:
35247059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kDA_GrBlendCoeff:
35347059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kIDA_GrBlendCoeff:
3548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
3558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                     "coverage stages.\n");
3568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
3578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        default:
3588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
3598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
3608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        switch (srcCoeff) {
36147059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kSC_GrBlendCoeff:
36247059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kISC_GrBlendCoeff:
36347059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kSA_GrBlendCoeff:
36447059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kISA_GrBlendCoeff:
3658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            GrPrintf("Unexpected src blend coeff. Won't work correctly with"
3668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                     "coverage stages.\n");
3678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
3688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        default:
3698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
3708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
3718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    #endif
3728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
3738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrBlendCoeff getSrcBlendCoeff() const { return fSrcBlend; }
3758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrBlendCoeff getDstBlendCoeff() const { return fDstBlend; }
3768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff,
3788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                          GrBlendCoeff* dstBlendCoeff) const {
3798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        *srcBlendCoeff = fSrcBlend;
3808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        *dstBlendCoeff = fDstBlend;
3818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
3828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the blending function constant referenced by the following blending
3851e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * coefficients:
38647059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com     *      kConstC_GrBlendCoeff
38747059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com     *      kIConstC_GrBlendCoeff
38847059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com     *      kConstA_GrBlendCoeff
38947059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com     *      kIConstA_GrBlendCoeff
3908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param constant the constant to set
3928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setBlendConstant(GrColor constant) { fBlendConstant = constant; }
3948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Retrieves the last value set by setBlendConstant()
3978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return the blending constant value
3988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrColor getBlendConstant() const { return fBlendConstant; }
4008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
4028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
4048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name View Matrix
4058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
4068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
408a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com     * Sets the matrix applied to vertex positions.
4098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * In the post-view-matrix space the rectangle [0,w]x[0,h]
4118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * fully covers the render target. (w and h are the width and height of the
4128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * the rendertarget.)
4138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
4148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setViewMatrix(const GrMatrix& m) { fViewMatrix = m; }
4158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Gets a writable pointer to the view matrix.
4188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
4198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrMatrix* viewMatrix() { return &fViewMatrix; }
4208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Multiplies the current view matrix by a matrix
4238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  After this call V' = V*m where V is the old view matrix,
4258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  m is the parameter to this function, and V' is the new view matrix.
4268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  (We consider positions to be column vectors so position vector p is
4278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  transformed by matrix X as p' = X*p.)
4288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param m the matrix used to modify the view matrix.
4308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
4318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void preConcatViewMatrix(const GrMatrix& m) { fViewMatrix.preConcat(m); }
4328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Multiplies the current view matrix by a matrix
4358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  After this call V' = m*V where V is the old view matrix,
4378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  m is the parameter to this function, and V' is the new view matrix.
4388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  (We consider positions to be column vectors so position vector p is
4398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  transformed by matrix X as p' = X*p.)
4408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param m the matrix used to modify the view matrix.
4428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
4438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void postConcatViewMatrix(const GrMatrix& m) { fViewMatrix.postConcat(m); }
4448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Retrieves the current view matrix
4478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return the current view matrix.
4488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
4498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    const GrMatrix& getViewMatrix() const { return fViewMatrix; }
4508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Retrieves the inverse of the current view matrix.
4538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  If the current view matrix is invertible, return true, and if matrix
4558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  is non-null, copy the inverse into it. If the current view matrix is
4568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  non-invertible, return false and ignore the matrix parameter.
4578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param matrix if not null, will receive a copy of the current inverse.
4598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
4608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool getViewInverse(GrMatrix* matrix) const {
4618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // TODO: determine whether we really need to leave matrix unmodified
4628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // at call sites when inversion fails.
4638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrMatrix inverse;
4648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        if (fViewMatrix.invert(&inverse)) {
4658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (matrix) {
4668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                *matrix = inverse;
4678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
4688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            return true;
4698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
4708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return false;
4718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
4728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4735b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    ////////////////////////////////////////////////////////////////////////////
4745b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com
4755b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    /**
4762fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com     * Preconcats the current view matrix and restores the previous view matrix in the destructor.
4772fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com     * Stage matrices are automatically adjusted to compensate.
4785b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com     */
4798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    class AutoViewMatrixRestore : public ::GrNoncopyable {
4808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    public:
4818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        AutoViewMatrixRestore() : fDrawState(NULL) {}
4822fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
4832fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        AutoViewMatrixRestore(GrDrawState* ds,
4842fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com                              const GrMatrix& preconcatMatrix,
4852fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com                              uint32_t explicitCoordStageMask = 0) {
4868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            fDrawState = NULL;
4872fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com            this->set(ds, preconcatMatrix, explicitCoordStageMask);
4888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
4892fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
4902fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        ~AutoViewMatrixRestore() { this->restore(); }
4912fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
492a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        /**
493a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * Can be called prior to destructor to restore the original matrix.
494a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         */
4952fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        void restore();
496f467ce7bc33af5f496e0619387551aedec6d2517skia.committer@gmail.com
4972fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        void set(GrDrawState* drawState,
4982fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com                 const GrMatrix& preconcatMatrix,
4992fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com                 uint32_t explicitCoordStageMask = 0);
5002fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
501ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com        bool isSet() const { return NULL != fDrawState; }
5022fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
5038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    private:
504288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com        GrDrawState*                        fDrawState;
505288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com        GrMatrix                            fViewMatrix;
506288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com        GrSamplerState::SavedCoordChange    fSavedCoordChanges[GrDrawState::kNumStages];
507288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com        uint32_t                            fRestoreMask;
5089381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    };
5099381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
5105b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    ////////////////////////////////////////////////////////////////////////////
5115b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com
5125b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    /**
5132fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com     * This sets the view matrix to identity and adjusts stage matrices to compensate. The
5142fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com     * destructor undoes the changes, restoring the view matrix that was set before the
5152fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com     * constructor. It is similar to passing the inverse of the current view matrix to
5162fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com     * AutoViewMatrixRestore, but lazily computes the inverse only if necessary.
5175b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com     */
5185b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    class AutoDeviceCoordDraw : ::GrNoncopyable {
5195b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    public:
5202fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        AutoDeviceCoordDraw() : fDrawState(NULL) {}
5215b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        /**
5222fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com         * If a stage's texture matrix is applied to explicit per-vertex coords, rather than to
5232fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com         * positions, then we don't want to modify its matrix. The explicitCoordStageMask is used
5242fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com         * to specify such stages.
5255b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com         */
5265b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        AutoDeviceCoordDraw(GrDrawState* drawState,
5272fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com                            uint32_t explicitCoordStageMask = 0) {
5282fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com            fDrawState = NULL;
5292fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com            this->set(drawState, explicitCoordStageMask);
5302fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        }
5312fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
532a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        ~AutoDeviceCoordDraw() { this->restore(); }
533a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com
5342fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        bool set(GrDrawState* drawState, uint32_t explicitCoordStageMask = 0);
5352fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
536a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        /**
537a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * Returns true if this object was successfully initialized on to a GrDrawState. It may
538a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * return false because a non-default constructor or set() were never called or because
539a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * the view matrix was not invertible.
540a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         */
5415b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        bool succeeded() const { return NULL != fDrawState; }
5422fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
543a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        /**
544a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * Returns the matrix that was set previously set on the drawState. This is only valid
545a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * if succeeded returns true.
546a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         */
547a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        const GrMatrix& getOriginalMatrix() const {
548a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com            GrAssert(this->succeeded());
549a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com            return fViewMatrix;
550a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        }
5512fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
552a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        /**
553a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * Can be called prior to destructor to restore the original matrix.
554a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         */
555a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        void restore();
5562fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
5575b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    private:
558288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com        GrDrawState*                        fDrawState;
559288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com        GrMatrix                            fViewMatrix;
560288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com        GrSamplerState::SavedCoordChange    fSavedCoordChanges[GrDrawState::kNumStages];
561288d9549b42a4eb934e814790f2b7a81f017a9c5bsalomon@google.com        uint32_t                            fRestoreMask;
5625b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    };
5635b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com
5648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
5658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
5678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Render Target
5688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
5698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
5718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the rendertarget used at the next drawing call
5728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
5738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param target  The render target to set.
5748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
575d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    void setRenderTarget(GrRenderTarget* target) {
5769ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        GrSafeAssign(fRenderTarget, target);
5779ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com    }
5788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
5808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Retrieves the currently set rendertarget.
5818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
5828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return    The currently set render target.
5838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
5848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    const GrRenderTarget* getRenderTarget() const { return fRenderTarget; }
5858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrRenderTarget* getRenderTarget() { return fRenderTarget; }
5868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    class AutoRenderTargetRestore : public ::GrNoncopyable {
5888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    public:
589cadbcb8e536f89babb4e165bfdca18384e97d582bsalomon@google.com        AutoRenderTargetRestore() : fDrawState(NULL), fSavedTarget(NULL) {}
5908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) {
5918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            fDrawState = NULL;
5927460b378d68217167013ca889a4cdcae742908e7robertphillips@google.com            fSavedTarget = NULL;
5938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            this->set(ds, newTarget);
5948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
5959ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        ~AutoRenderTargetRestore() { this->restore(); }
5969ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
5979ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        void restore() {
5988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (NULL != fDrawState) {
5998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fDrawState->setRenderTarget(fSavedTarget);
6009ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com                fDrawState = NULL;
6018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
6029ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com            GrSafeSetNull(fSavedTarget);
6039ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        }
6049ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
6059ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        void set(GrDrawState* ds, GrRenderTarget* newTarget) {
6069ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com            this->restore();
6079ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
6088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (NULL != ds) {
6099ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com                GrAssert(NULL == fSavedTarget);
6108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fSavedTarget = ds->getRenderTarget();
6119ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com                SkSafeRef(fSavedTarget);
6128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                ds->setRenderTarget(newTarget);
6139ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com                fDrawState = ds;
6148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
6158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
6168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    private:
6178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrDrawState* fDrawState;
6188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrRenderTarget* fSavedTarget;
6198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    };
6208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
6228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
6248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Stencil
6258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
6268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
6288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the stencil settings to use for the next draw.
6298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Changing the clip has the side-effect of possibly zeroing
6308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * out the client settable stencil bits. So multipass algorithms
6318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * using stencil should not change the clip between passes.
6328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param settings  the stencil settings to use.
6338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
6348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setStencil(const GrStencilSettings& settings) {
6358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fStencilSettings = settings;
6368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
6398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Shortcut to disable stencil testing and ops.
6408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
6418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void disableStencil() {
6428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fStencilSettings.setDisabled();
6438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    const GrStencilSettings& getStencil() const { return fStencilSettings; }
6468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrStencilSettings* stencil() { return &fStencilSettings; }
6488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
6508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
6528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // @name Edge AA
6531e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com    // Edge equations can be specified to perform anti-aliasing. Because the
6547ffe6810c6787f7a353ef3fe8fab3fc6440aae19bsalomon@google.com    // edges are specified as per-vertex data, vertices that are shared by
6557ffe6810c6787f7a353ef3fe8fab3fc6440aae19bsalomon@google.com    // multiple edges must be split.
6568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    //
6578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
6588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
6609381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * When specifying edges as vertex data this enum specifies what type of
6619381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * edges are in use. The edges are always 4 GrScalars in memory, even when
6629381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * the edge type requires fewer than 4.
66393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com     *
66493c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com     * TODO: Fix the fact that HairLine and Circle edge types use y-down coords.
66593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com     *       (either adjust in VS or use origin_upper_left in GLSL)
6669381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     */
6679381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    enum VertexEdgeType {
6689381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        /* 1-pixel wide line
6699381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com           2D implicit line eq (a*x + b*y +c = 0). 4th component unused */
6709381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        kHairLine_EdgeType,
671d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        /* Quadratic specified by u^2-v canonical coords (only 2
67269cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com           components used). Coverage based on signed distance with negative
67393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com           being inside, positive outside. Edge specified in window space
67493c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com           (y-down) */
67569cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com        kQuad_EdgeType,
67669cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com        /* Same as above but for hairline quadratics. Uses unsigned distance.
67769cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com           Coverage is min(0, 1-distance). */
67869cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com        kHairQuad_EdgeType,
67993c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com        /* Circle specified as center_x, center_y, outer_radius, inner_radius
68093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com           all in window space (y-down). */
68193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com        kCircle_EdgeType,
68269cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com
68369cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com        kVertexEdgeTypeCnt
6849381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    };
6859381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
6869381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    /**
687d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     * Determines the interpretation per-vertex edge data when the
6888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * kEdge_VertexLayoutBit is set (see GrDrawTarget). When per-vertex edges
6898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * are not specified the value of this setting has no effect.
6908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
6918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setVertexEdgeType(VertexEdgeType type) {
69269cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com        GrAssert(type >=0 && type < kVertexEdgeTypeCnt);
6938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fVertexEdgeType = type;
6948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
69652a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    VertexEdgeType getVertexEdgeType() const { return fVertexEdgeType; }
6978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
6998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
7018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name State Flags
7028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
7038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
7058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Flags that affect rendering. Controlled using enable/disableState(). All
7068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  default to disabled.
7078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
7088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    enum StateBits {
7098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
7108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Perform dithering. TODO: Re-evaluate whether we need this bit
7118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
7128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kDither_StateBit        = 0x01,
7138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
7148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Perform HW anti-aliasing. This means either HW FSAA, if supported
7158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * by the render target, or smooth-line rendering if a line primitive
7168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * is drawn and line smoothing is supported by the 3D API.
7178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
7188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kHWAntialias_StateBit   = 0x02,
7198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
7208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Draws will respect the clip, otherwise the clip is ignored.
7218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
7228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kClip_StateBit          = 0x04,
7238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
7248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Disables writing to the color buffer. Useful when performing stencil
7258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * operations.
7268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
7278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kNoColorWrites_StateBit = 0x08,
7280342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com
7298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // Users of the class may add additional bits to the vector
7308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kDummyStateBit,
7318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kLastPublicStateBit = kDummyStateBit-1,
7328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    };
7338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void resetStateFlags() {
7358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fFlagBits = 0;
7360fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
7370fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
7388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
7398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Enable render state settings.
7408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
7411e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * @param stateBits bitfield of StateBits specifying the states to enable
7428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
7438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void enableState(uint32_t stateBits) {
7448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fFlagBits |= stateBits;
7458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
7460fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
7478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
7488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Disable render state settings.
7498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
7501e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * @param stateBits bitfield of StateBits specifying the states to disable
7518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
7528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void disableState(uint32_t stateBits) {
7538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fFlagBits &= ~(stateBits);
7548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
7550fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
756d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com    /**
757d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com     * Enable or disable stateBits based on a boolean.
758d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com     *
7591e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com     * @param stateBits bitfield of StateBits to enable or disable
760d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com     * @param enable    if true enable stateBits, otherwise disable
761d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com     */
762d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com    void setState(uint32_t stateBits, bool enable) {
763d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com        if (enable) {
764d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com            this->enableState(stateBits);
765d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com        } else {
766d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com            this->disableState(stateBits);
767d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com        }
768d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com    }
769d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com
7708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isDitherState() const {
7718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return 0 != (fFlagBits & kDither_StateBit);
7728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
7730fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
7748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isHWAntialiasState() const {
7758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return 0 != (fFlagBits & kHWAntialias_StateBit);
7768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
7770fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
7788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isClipState() const {
7798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return 0 != (fFlagBits & kClip_StateBit);
7808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
7810fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
7828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isColorWriteDisabled() const {
7838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return 0 != (fFlagBits & kNoColorWrites_StateBit);
7848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
7858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isStateFlagEnabled(uint32_t stateBit) const {
7878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return 0 != (stateBit & fFlagBits);
7888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
7898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
7918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
7938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Face Culling
7948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
7958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    enum DrawFace {
797978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com        kInvalid_DrawFace = -1,
798978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com
7998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kBoth_DrawFace,
8008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kCCW_DrawFace,
8018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kCW_DrawFace,
8028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    };
8038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
8058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Controls whether clockwise, counterclockwise, or both faces are drawn.
8068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param face  the face(s) to draw.
8078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
8088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setDrawFace(DrawFace face) {
809978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com        GrAssert(kInvalid_DrawFace != face);
8108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fDrawFace = face;
8118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
8128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
8148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Gets whether the target is drawing clockwise, counterclockwise,
8158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * or both faces.
8168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return the current draw face(s).
8178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
81852a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    DrawFace getDrawFace() const { return fDrawFace; }
819d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
8208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
8218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
82362b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
824f13f58804659175925042a291304d483a4fd9278tomhudson@google.com    bool isStageEnabled(int s) const {
825f13f58804659175925042a291304d483a4fd9278tomhudson@google.com        GrAssert((unsigned)s < kNumStages);
8266f261bed0252e3f3caa595798364e0bf12a2573absalomon@google.com        return (NULL != fSamplerStates[s].getEffect());
827f13f58804659175925042a291304d483a4fd9278tomhudson@google.com    }
828f13f58804659175925042a291304d483a4fd9278tomhudson@google.com
82962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    // Most stages are usually not used, so conditionals here
83062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    // reduce the expected number of bytes touched by 50%.
8319381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    bool operator ==(const GrDrawState& s) const {
832861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        if (fColor != s.fColor ||
833861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            !s.fViewMatrix.cheapEqualTo(fViewMatrix) ||
834861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fRenderTarget != s.fRenderTarget ||
835861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fSrcBlend != s.fSrcBlend ||
836861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fDstBlend != s.fDstBlend ||
837861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fBlendConstant != s.fBlendConstant ||
838861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fFlagBits != s.fFlagBits ||
839861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fVertexEdgeType != s.fVertexEdgeType ||
840861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fStencilSettings != s.fStencilSettings ||
841861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fFirstCoverageStage != s.fFirstCoverageStage ||
842861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fCoverage != s.fCoverage ||
843861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fColorFilterMode != s.fColorFilterMode ||
844861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fColorFilterColor != s.fColorFilterColor ||
845861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fDrawFace != s.fDrawFace) {
8468fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com            return false;
8478fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com        }
84862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
84962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        for (int i = 0; i < kNumStages; i++) {
850f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com            bool enabled = this->isStageEnabled(i);
851f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com            if (enabled != s.isStageEnabled(i)) {
852f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com                return false;
853f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com            }
854f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com            if (enabled && this->fSamplerStates[i] != s.fSamplerStates[i]) {
85562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com                return false;
85662b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com            }
85762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        }
85862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        return true;
8599381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    }
8609381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    bool operator !=(const GrDrawState& s) const { return !(*this == s); }
86162b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
862d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    // Most stages are usually not used, so conditionals here
86362b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    // reduce the expected number of bytes touched by 50%.
86462b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    GrDrawState& operator =(const GrDrawState& s) {
865861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fColor = s.fColor;
8668fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com        fViewMatrix = s.fViewMatrix;
867861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        SkRefCnt_SafeAssign(fRenderTarget, s.fRenderTarget);
868861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fSrcBlend = s.fSrcBlend;
869861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fDstBlend = s.fDstBlend;
870861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fBlendConstant = s.fBlendConstant;
871861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fFlagBits = s.fFlagBits;
872861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fVertexEdgeType = s.fVertexEdgeType;
873861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fStencilSettings = s.fStencilSettings;
874861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fFirstCoverageStage = s.fFirstCoverageStage;
875861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fCoverage = s.fCoverage;
876861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fColorFilterMode = s.fColorFilterMode;
877861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fColorFilterColor = s.fColorFilterColor;
878861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fDrawFace = s.fDrawFace;
8798fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com
88062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        for (int i = 0; i < kNumStages; i++) {
881e742bf0ab19659145325ac894f7e0b78c8efbd89tomhudson@google.com            if (s.isStageEnabled(i)) {
88202b1ea24fd1152cb5a93e05b4d78700740140db6tomhudson@google.com                this->fSamplerStates[i] = s.fSamplerStates[i];
88362b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com            }
88462b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        }
8859ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
88662b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        return *this;
88762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    }
88862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
88962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.comprivate:
8902e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com
8911e269b5a08610da13c3aee23809bb45b17e7b663bsalomon@google.com    // These fields are roughly sorted by decreasing likelihood of being different in op==
892861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com    GrColor             fColor;
893861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com    GrMatrix            fViewMatrix;
894861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com    GrRenderTarget*     fRenderTarget;
895861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com    GrBlendCoeff        fSrcBlend;
896861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com    GrBlendCoeff        fDstBlend;
897861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com    GrColor             fBlendConstant;
898861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com    uint32_t            fFlagBits;
899c077d1eaa8322087f3cc954c3b2e9af7fef103fcrobertphillips@google.com    VertexEdgeType      fVertexEdgeType;
90052a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    GrStencilSettings   fStencilSettings;
90169ffcf0d34878be7a1d2493785bf4df363199b10robertphillips@google.com    int                 fFirstCoverageStage;
9022401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    GrColor             fCoverage;
90352a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    SkXfermode::Mode    fColorFilterMode;
904861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com    GrColor             fColorFilterColor;
905861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com    DrawFace            fDrawFace;
9068fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com
9078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // This field must be last; it will not be copied or compared
9088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // if the corresponding fTexture[] is NULL.
90952a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    GrSamplerState      fSamplerStates[kNumStages];
9108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
911fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com    typedef GrRefCnt INHERITED;
9129381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com};
9139381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
9149381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#endif
915