GrDrawState.h revision f467ce7bc33af5f496e0619387551aedec6d2517
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"
138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com#include "GrNoncopyable.h"
142e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com#include "GrRefCnt.h"
159381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#include "GrSamplerState.h"
169381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#include "GrStencil.h"
1764aef2bacd1f5c25ffd9347aabd6265c9b60c0f4bsalomon@google.com#include "GrTexture.h"
189ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com#include "GrRenderTarget.h"
191e8f016305805d4d8cad74aba3a21b78486f9d6ftomhudson@google.com#include "effects/GrSingleTextureEffect.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    /**
309381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * Number of texture stages. Each stage takes as input a color and
319381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * 2D texture coordinates. The color input to the first enabled stage is the
329381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * per-vertex color or the constant color (setColor/setAlpha) if there are
339381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * no per-vertex colors. For subsequent stages the input color is the output
349381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * color from the previous enabled stage. The output color of each stage is
359381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * the input color modulated with the result of a texture lookup. Texture
369381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * lookups are specified by a texture a sampler (setSamplerState). Texture
379381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * coordinates for each stage come from the vertices based on a
389381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * GrVertexLayout bitfield. The output fragment color is the output color of
399381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * the last enabled stage. The presence or absence of texture coordinates
409381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * for each stage in the vertex layout indicates whether a stage is enabled
419381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * or not.
42bf5cad4e9c5808493b35cb9b0000a2d36b7f9b78robertphillips@google.com     *
43bf5cad4e9c5808493b35cb9b0000a2d36b7f9b78robertphillips@google.com     * Stages 0 through GrPaint::kTotalStages-1 are reserved for setting up
44d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     * the draw (i.e., textures and filter masks). Stages GrPaint::kTotalStages
45d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     * through kNumStages-1 are earmarked for use by GrTextContext and
46bf5cad4e9c5808493b35cb9b0000a2d36b7f9b78robertphillips@google.com     * GrPathRenderer-derived classes.
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.
727d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com     * Sampler states *will* be modified: textures or CustomStage objects
737d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com     * will be released.
74d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     */
7552a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    void reset() {
769ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
777d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        this->disableStages();
7852a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com
7952a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        fColor = 0xffffffff;
80861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fViewMatrix.reset();
81861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        GrSafeSetNull(fRenderTarget);
8247059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        fSrcBlend = kOne_GrBlendCoeff;
8347059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        fDstBlend = kZero_GrBlendCoeff;
84861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fBlendConstant = 0x0;
85861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fFlagBits = 0x0;
86861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fVertexEdgeType = kHairLine_EdgeType;
87861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fStencilSettings.setDisabled();
88861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fFirstCoverageStage = kNumStages;
89861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fCoverage = 0xffffffff;
90861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fColorFilterMode = SkXfermode::kDst_Mode;
91861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fColorFilterColor = 0x0;
92861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fDrawFace = kBoth_DrawFace;
93af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com    }
94af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com
95af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com    /**
96af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com     * Initializes the GrDrawState based on a GrPaint. Note that GrDrawState
97af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com     * encompases more than GrPaint. Aspects of GrDrawState that have no
98af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com     * GrPaint equivalents are not modified. GrPaint has fewer stages than
99af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com     * GrDrawState. The extra GrDrawState stages are disabled.
100af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com     */
101af84e748cedbf43e2d0e8d2eac9b7800c8d8ca19bsalomon@google.com    void setFromPaint(const GrPaint& paint);
1028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
1048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Color
1058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
1068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
1088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Sets color for next draw to a premultiplied-alpha color.
1098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
1108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param color    the color to set.
1118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
1128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setColor(GrColor color) { fColor = color; }
1138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrColor getColor() const { return fColor; }
1158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
1178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Sets the color to be used for the next draw to be
1188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  (r,g,b,a) = (alpha, alpha, alpha, alpha).
1198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
1208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param alpha The alpha value to set as the color.
1218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
1228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setAlpha(uint8_t a) {
1238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        this->setColor((a << 24) | (a << 16) | (a << 8) | a);
1248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
1258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
1278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Add a color filter that can be represented by a color and a mode. Applied
1288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * after color-computing texture stages.
1298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
1308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setColorFilter(GrColor c, SkXfermode::Mode mode) {
1318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fColorFilterColor = c;
1328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fColorFilterMode = mode;
1338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
1348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrColor getColorFilterColor() const { return fColorFilterColor; }
1368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    SkXfermode::Mode getColorFilterMode() const { return fColorFilterMode; }
1378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1385b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    /**
1395b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com     * Constructor sets the color to be 'color' which is undone by the destructor.
1405b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com     */
1415b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    class AutoColorRestore : public ::GrNoncopyable {
1425b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    public:
1435b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        AutoColorRestore(GrDrawState* drawState, GrColor color) {
1445b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com            fDrawState = drawState;
1455b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com            fOldColor = fDrawState->getColor();
1465b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com            fDrawState->setColor(color);
1475b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        }
1485b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        ~AutoColorRestore() {
1495b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com            fDrawState->setColor(fOldColor);
1505b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        }
1515b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    private:
1525b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        GrDrawState*    fDrawState;
1535b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        GrColor         fOldColor;
1545b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    };
1555b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com
1568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
1578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
1592401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    /// @name Coverage
1602401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    ////
1612401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com
1622401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    /**
163d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     * Sets a constant fractional coverage to be applied to the draw. The
1642401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     * initial value (after construction or reset()) is 0xff. The constant
1652401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     * coverage is ignored when per-vertex coverage is provided.
1662401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     */
1672401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    void setCoverage(uint8_t coverage) {
1682401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com        fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage);
1692401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    }
1702401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com
1712401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    /**
1722401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     * Version of above that specifies 4 channel per-vertex color. The value
1732401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     * should be premultiplied.
1742401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com     */
1752401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    void setCoverage4(GrColor coverage) {
1762401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com        fCoverage = coverage;
1772401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    }
1782401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com
1792401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    GrColor getCoverage() const {
1802401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com        return fCoverage;
1812401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    }
1822401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com
1832401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    /// @}
1842401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com
1852401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
1868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Textures
1878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
1888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
1901e8f016305805d4d8cad74aba3a21b78486f9d6ftomhudson@google.com     * Creates a GrSingleTextureEffect.
1911e8f016305805d4d8cad74aba3a21b78486f9d6ftomhudson@google.com     */
1921e8f016305805d4d8cad74aba3a21b78486f9d6ftomhudson@google.com    void createTextureEffect(int stage, GrTexture* texture) {
1931e8f016305805d4d8cad74aba3a21b78486f9d6ftomhudson@google.com        GrAssert(!this->getSampler(stage).getCustomStage());
1941e8f016305805d4d8cad74aba3a21b78486f9d6ftomhudson@google.com        this->sampler(stage)->setCustomStage(
1951e8f016305805d4d8cad74aba3a21b78486f9d6ftomhudson@google.com            SkNEW_ARGS(GrSingleTextureEffect, (texture)))->unref();
1961e8f016305805d4d8cad74aba3a21b78486f9d6ftomhudson@google.com    }
1971ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com    void createTextureEffect(int stage, GrTexture* texture, const GrTextureParams& params) {
1981ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com        GrAssert(!this->getSampler(stage).getCustomStage());
1991ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com        this->sampler(stage)->setCustomStage(
2001ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com            SkNEW_ARGS(GrSingleTextureEffect, (texture, params)))->unref();
2011ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com    }
2021ce49fc91714ce8974d11246d29ebe7b97b5fe98bsalomon@google.com
2031e8f016305805d4d8cad74aba3a21b78486f9d6ftomhudson@google.com
2047d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com    bool stagesDisabled() {
2057d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        for (int i = 0; i < kNumStages; ++i) {
206cddaf340f1474cc1ff429b8ef9bc8739c72f80babsalomon@google.com            if (NULL != fSamplerStates[i].getCustomStage()) {
2077d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com                return false;
2087d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com            }
2097d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        }
2103eee8fbe0f280bc1dea59dc0b0ebd8021b51137ftomhudson@google.com        return true;
2117d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com    }
212676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com
213676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com    void disableStage(int index) {
214676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com        fSamplerStates[index].setCustomStage(NULL);
215676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com    }
216676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com
217972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    /**
2187d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com     * Release all the textures and custom stages referred to by this
2197d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com     * draw state.
220972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com     */
2217d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com    void disableStages() {
222972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com        for (int i = 0; i < kNumStages; ++i) {
223676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com            this->disableStage(i);
224972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com        }
225972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    }
226972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com
2277d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com    class AutoStageDisable : public ::GrNoncopyable {
228972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    public:
2297d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        AutoStageDisable(GrDrawState* ds) : fDrawState(ds) {}
2307d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        ~AutoStageDisable() {
231972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com            if (NULL != fDrawState) {
2327d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com                fDrawState->disableStages();
233972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com            }
234972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com        }
235972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    private:
236972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com        GrDrawState* fDrawState;
237972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    };
238972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com
2398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
2408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
2428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Samplers
2438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
2448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
2468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Returns the current sampler for a stage.
2478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
2488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    const GrSamplerState& getSampler(int stage) const {
2498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((unsigned)stage < kNumStages);
2508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return fSamplerStates[stage];
2518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
2528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
2548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Writable pointer to a stage's sampler.
2558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
2568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrSamplerState* sampler(int stage) {
2578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((unsigned)stage < kNumStages);
2588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return fSamplerStates + stage;
2598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
2608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
262e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com     * Preconcats the matrix of all samplers of enabled stages with a matrix.
2638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
264e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com    void preConcatSamplerMatrices(const GrMatrix& matrix) {
2658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        for (int i = 0; i < kNumStages; ++i) {
266e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com            if (this->isStageEnabled(i)) {
2678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fSamplerStates[i].preConcatMatrix(matrix);
2688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
2698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
2708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
2718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
272e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com    /**
273e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com     * Preconcats the matrix of all samplers in the mask with the inverse of a
274e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com     * matrix. If the matrix inverse cannot be computed (and there is at least
275e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com     * one enabled stage) then false is returned.
276e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com     */
277e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com    bool preConcatSamplerMatricesWithInverse(const GrMatrix& matrix) {
278e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        GrMatrix inv;
279e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        bool computed = false;
280e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        for (int i = 0; i < kNumStages; ++i) {
281e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com            if (this->isStageEnabled(i)) {
282e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com                if (!computed && !matrix.invert(&inv)) {
283e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com                    return false;
284e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com                } else {
285e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com                    computed = true;
286e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com                }
287e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com                fSamplerStates[i].preConcatMatrix(inv);
288e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com            }
289e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        }
290e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com        return true;
291e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com    }
292e3d3216fe17b6afb2e613271b5246a2766e12df6bsalomon@google.com
2938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
2948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
2968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Coverage / Color Stages
2978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
2988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * A common pattern is to compute a color with the initial stages and then
3018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * modulate that color by a coverage value in later stage(s) (AA, mask-
302d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     * filters, glyph mask, etc). Color-filters, xfermodes, etc should be
303d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     * computed based on the pre-coverage-modulated color. The division of
304d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     * stages between color-computing and coverage-computing is specified by
3058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * this method. Initially this is kNumStages (all stages
3068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * are color-computing).
3078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setFirstCoverageStage(int firstCoverageStage) {
3098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((unsigned)firstCoverageStage <= kNumStages);
310d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        fFirstCoverageStage = firstCoverageStage;
3118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
3128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Gets the index of the first coverage-computing stage.
3158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    int getFirstCoverageStage() const {
317d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        return fFirstCoverageStage;
3188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
3198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///@}
3218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
3238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Blending
3248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
3258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the blending function coeffecients.
3288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * The blend function will be:
3308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *    D' = sat(S*srcCoef + D*dstCoef)
3318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *   where D is the existing destination color, S is the incoming source
3338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *   color, and D' is the new destination color that will be written. sat()
3348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *   is the saturation function.
3358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param srcCoef coeffecient applied to the src color.
3378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param dstCoef coeffecient applied to the dst color.
3388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
3408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fSrcBlend = srcCoeff;
3418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fDstBlend = dstCoeff;
3428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    #if GR_DEBUG
3438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        switch (dstCoeff) {
34447059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kDC_GrBlendCoeff:
34547059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kIDC_GrBlendCoeff:
34647059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kDA_GrBlendCoeff:
34747059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kIDA_GrBlendCoeff:
3488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
3498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                     "coverage stages.\n");
3508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
3518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        default:
3528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
3538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
3548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        switch (srcCoeff) {
35547059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kSC_GrBlendCoeff:
35647059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kISC_GrBlendCoeff:
35747059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kSA_GrBlendCoeff:
35847059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kISA_GrBlendCoeff:
3598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            GrPrintf("Unexpected src blend coeff. Won't work correctly with"
3608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                     "coverage stages.\n");
3618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
3628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        default:
3638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
3648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
3658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    #endif
3668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
3678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrBlendCoeff getSrcBlendCoeff() const { return fSrcBlend; }
3698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrBlendCoeff getDstBlendCoeff() const { return fDstBlend; }
3708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff,
3728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                          GrBlendCoeff* dstBlendCoeff) const {
3738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        *srcBlendCoeff = fSrcBlend;
3748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        *dstBlendCoeff = fDstBlend;
3758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
3768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the blending function constant referenced by the following blending
3798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * coeffecients:
38047059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com     *      kConstC_GrBlendCoeff
38147059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com     *      kIConstC_GrBlendCoeff
38247059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com     *      kConstA_GrBlendCoeff
38347059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com     *      kIConstA_GrBlendCoeff
3848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param constant the constant to set
3868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setBlendConstant(GrColor constant) { fBlendConstant = constant; }
3888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Retrieves the last value set by setBlendConstant()
3918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return the blending constant value
3928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrColor getBlendConstant() const { return fBlendConstant; }
3948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
3968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
3988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name View Matrix
3998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
4008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
402a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com     * Sets the matrix applied to vertex positions.
4038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * In the post-view-matrix space the rectangle [0,w]x[0,h]
4058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * fully covers the render target. (w and h are the width and height of the
4068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * the rendertarget.)
4078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
4088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setViewMatrix(const GrMatrix& m) { fViewMatrix = m; }
4098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Gets a writable pointer to the view matrix.
4128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
4138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrMatrix* viewMatrix() { return &fViewMatrix; }
4148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Multiplies the current view matrix by a matrix
4178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  After this call V' = V*m where V is the old view matrix,
4198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  m is the parameter to this function, and V' is the new view matrix.
4208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  (We consider positions to be column vectors so position vector p is
4218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  transformed by matrix X as p' = X*p.)
4228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param m the matrix used to modify the view matrix.
4248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
4258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void preConcatViewMatrix(const GrMatrix& m) { fViewMatrix.preConcat(m); }
4268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Multiplies the current view matrix by a matrix
4298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  After this call V' = m*V where V is the old view matrix,
4318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  m is the parameter to this function, and V' is the new view matrix.
4328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  (We consider positions to be column vectors so position vector p is
4338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  transformed by matrix X as p' = X*p.)
4348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param m the matrix used to modify the view matrix.
4368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
4378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void postConcatViewMatrix(const GrMatrix& m) { fViewMatrix.postConcat(m); }
4388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Retrieves the current view matrix
4418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return the current view matrix.
4428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
4438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    const GrMatrix& getViewMatrix() const { return fViewMatrix; }
4448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Retrieves the inverse of the current view matrix.
4478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  If the current view matrix is invertible, return true, and if matrix
4498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  is non-null, copy the inverse into it. If the current view matrix is
4508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  non-invertible, return false and ignore the matrix parameter.
4518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param matrix if not null, will receive a copy of the current inverse.
4538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
4548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool getViewInverse(GrMatrix* matrix) const {
4558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // TODO: determine whether we really need to leave matrix unmodified
4568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // at call sites when inversion fails.
4578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrMatrix inverse;
4588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        if (fViewMatrix.invert(&inverse)) {
4598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (matrix) {
4608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                *matrix = inverse;
4618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
4628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            return true;
4638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
4648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return false;
4658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
4668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4675b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    ////////////////////////////////////////////////////////////////////////////
4685b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com
4695b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    /**
4702fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com     * Preconcats the current view matrix and restores the previous view matrix in the destructor.
4712fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com     * Stage matrices are automatically adjusted to compensate.
4725b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com     */
4738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    class AutoViewMatrixRestore : public ::GrNoncopyable {
4748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    public:
4758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        AutoViewMatrixRestore() : fDrawState(NULL) {}
4762fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
4772fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        AutoViewMatrixRestore(GrDrawState* ds,
4782fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com                              const GrMatrix& preconcatMatrix,
4792fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com                              uint32_t explicitCoordStageMask = 0) {
4808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            fDrawState = NULL;
4812fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com            this->set(ds, preconcatMatrix, explicitCoordStageMask);
4828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
4832fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
4842fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        ~AutoViewMatrixRestore() { this->restore(); }
4852fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
486a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        /**
487a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * Can be called prior to destructor to restore the original matrix.
488a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         */
4892fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        void restore();
490f467ce7bc33af5f496e0619387551aedec6d2517skia.committer@gmail.com
4912fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        void set(GrDrawState* drawState,
4922fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com                 const GrMatrix& preconcatMatrix,
4932fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com                 uint32_t explicitCoordStageMask = 0);
4942fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
495ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com        bool isSet() const { return NULL != fDrawState; }
4962fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
4978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    private:
4982fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        GrDrawState*       fDrawState;
4992fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        GrMatrix           fViewMatrix;
5002fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        GrMatrix           fSamplerMatrices[GrDrawState::kNumStages];
5012fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        uint32_t           fRestoreMask;
5029381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    };
5039381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
5045b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    ////////////////////////////////////////////////////////////////////////////
5055b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com
5065b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    /**
5072fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com     * This sets the view matrix to identity and adjusts stage matrices to compensate. The
5082fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com     * destructor undoes the changes, restoring the view matrix that was set before the
5092fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com     * constructor. It is similar to passing the inverse of the current view matrix to
5102fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com     * AutoViewMatrixRestore, but lazily computes the inverse only if necessary.
5115b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com     */
5125b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    class AutoDeviceCoordDraw : ::GrNoncopyable {
5135b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    public:
5142fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        AutoDeviceCoordDraw() : fDrawState(NULL) {}
5155b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        /**
5162fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com         * If a stage's texture matrix is applied to explicit per-vertex coords, rather than to
5172fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com         * positions, then we don't want to modify its matrix. The explicitCoordStageMask is used
5182fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com         * to specify such stages.
5195b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com         */
5205b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        AutoDeviceCoordDraw(GrDrawState* drawState,
5212fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com                            uint32_t explicitCoordStageMask = 0) {
5222fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com            fDrawState = NULL;
5232fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com            this->set(drawState, explicitCoordStageMask);
5242fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        }
5252fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
526a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        ~AutoDeviceCoordDraw() { this->restore(); }
527a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com
5282fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        bool set(GrDrawState* drawState, uint32_t explicitCoordStageMask = 0);
5292fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
530a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        /**
531a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * Returns true if this object was successfully initialized on to a GrDrawState. It may
532a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * return false because a non-default constructor or set() were never called or because
533a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * the view matrix was not invertible.
534a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         */
5355b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        bool succeeded() const { return NULL != fDrawState; }
5362fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
537a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        /**
538a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * Returns the matrix that was set previously set on the drawState. This is only valid
539a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * if succeeded returns true.
540a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         */
541a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        const GrMatrix& getOriginalMatrix() const {
542a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com            GrAssert(this->succeeded());
543a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com            return fViewMatrix;
544a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        }
5452fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
546a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        /**
547a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         * Can be called prior to destructor to restore the original matrix.
548a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com         */
549a834746cc1bd92301fd0840a221ca1623c0bbb29bsalomon@google.com        void restore();
5502fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com
5515b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    private:
5525b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        GrDrawState*       fDrawState;
5535b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        GrMatrix           fViewMatrix;
5545b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com        GrMatrix           fSamplerMatrices[GrDrawState::kNumStages];
5552fdcdeb86788206c23410109b3e2b7976747fd11bsalomon@google.com        uint32_t           fRestoreMask;
5565b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com    };
5575b3e890c376f2211218c43edd11939cfc78fd60absalomon@google.com
5588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
5598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
5618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Render Target
5628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
5638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
5658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the rendertarget used at the next drawing call
5668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
5678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param target  The render target to set.
5688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
569d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    void setRenderTarget(GrRenderTarget* target) {
5709ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        GrSafeAssign(fRenderTarget, target);
5719ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com    }
5728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
5748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Retrieves the currently set rendertarget.
5758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
5768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return    The currently set render target.
5778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
5788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    const GrRenderTarget* getRenderTarget() const { return fRenderTarget; }
5798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrRenderTarget* getRenderTarget() { return fRenderTarget; }
5808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    class AutoRenderTargetRestore : public ::GrNoncopyable {
5828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    public:
583cadbcb8e536f89babb4e165bfdca18384e97d582bsalomon@google.com        AutoRenderTargetRestore() : fDrawState(NULL), fSavedTarget(NULL) {}
5848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) {
5858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            fDrawState = NULL;
5867460b378d68217167013ca889a4cdcae742908e7robertphillips@google.com            fSavedTarget = NULL;
5878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            this->set(ds, newTarget);
5888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
5899ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        ~AutoRenderTargetRestore() { this->restore(); }
5909ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
5919ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        void restore() {
5928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (NULL != fDrawState) {
5938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fDrawState->setRenderTarget(fSavedTarget);
5949ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com                fDrawState = NULL;
5958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
5969ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com            GrSafeSetNull(fSavedTarget);
5979ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        }
5989ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
5999ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        void set(GrDrawState* ds, GrRenderTarget* newTarget) {
6009ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com            this->restore();
6019ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
6028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (NULL != ds) {
6039ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com                GrAssert(NULL == fSavedTarget);
6048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fSavedTarget = ds->getRenderTarget();
6059ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com                SkSafeRef(fSavedTarget);
6068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                ds->setRenderTarget(newTarget);
6079ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com                fDrawState = ds;
6088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
6098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
6108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    private:
6118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrDrawState* fDrawState;
6128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrRenderTarget* fSavedTarget;
6138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    };
6148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
6168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
6188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Stencil
6198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
6208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
6228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the stencil settings to use for the next draw.
6238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Changing the clip has the side-effect of possibly zeroing
6248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * out the client settable stencil bits. So multipass algorithms
6258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * using stencil should not change the clip between passes.
6268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param settings  the stencil settings to use.
6278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
6288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setStencil(const GrStencilSettings& settings) {
6298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fStencilSettings = settings;
6308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
6338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Shortcut to disable stencil testing and ops.
6348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
6358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void disableStencil() {
6368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fStencilSettings.setDisabled();
6378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    const GrStencilSettings& getStencil() const { return fStencilSettings; }
6408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrStencilSettings* stencil() { return &fStencilSettings; }
6428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
6448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
64650bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org    /// @name Color Matrix
64750bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org    ////
64850bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org
64950bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org    /**
65050bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org     * Sets the color matrix to use for the next draw.
65150bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org     * @param matrix  the 5x4 matrix to apply to the incoming color
65250bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org     */
65350bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org    void setColorMatrix(const float matrix[20]) {
65450bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org        memcpy(fColorMatrix, matrix, sizeof(fColorMatrix));
65550bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org    }
65650bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org
65750bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org    const float* getColorMatrix() const { return fColorMatrix; }
65850bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org
65950bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org    /// @}
66050bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org
66150bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org    ///////////////////////////////////////////////////////////////////////////
6628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // @name Edge AA
6637ffe6810c6787f7a353ef3fe8fab3fc6440aae19bsalomon@google.com    // Edge equations can be specified to perform antialiasing. Because the
6647ffe6810c6787f7a353ef3fe8fab3fc6440aae19bsalomon@google.com    // edges are specified as per-vertex data, vertices that are shared by
6657ffe6810c6787f7a353ef3fe8fab3fc6440aae19bsalomon@google.com    // multiple edges must be split.
6668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    //
6678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
6688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
6709381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * When specifying edges as vertex data this enum specifies what type of
6719381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * edges are in use. The edges are always 4 GrScalars in memory, even when
6729381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * the edge type requires fewer than 4.
67393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com     *
67493c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com     * TODO: Fix the fact that HairLine and Circle edge types use y-down coords.
67593c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com     *       (either adjust in VS or use origin_upper_left in GLSL)
6769381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     */
6779381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    enum VertexEdgeType {
6789381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        /* 1-pixel wide line
6799381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com           2D implicit line eq (a*x + b*y +c = 0). 4th component unused */
6809381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        kHairLine_EdgeType,
681d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com        /* Quadratic specified by u^2-v canonical coords (only 2
68269cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com           components used). Coverage based on signed distance with negative
68393c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com           being inside, positive outside. Edge specified in window space
68493c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com           (y-down) */
68569cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com        kQuad_EdgeType,
68669cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com        /* Same as above but for hairline quadratics. Uses unsigned distance.
68769cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com           Coverage is min(0, 1-distance). */
68869cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com        kHairQuad_EdgeType,
68993c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com        /* Circle specified as center_x, center_y, outer_radius, inner_radius
69093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com           all in window space (y-down). */
69193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com        kCircle_EdgeType,
69269cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com
69369cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com        kVertexEdgeTypeCnt
6949381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    };
6959381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
6969381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    /**
697d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com     * Determines the interpretation per-vertex edge data when the
6988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * kEdge_VertexLayoutBit is set (see GrDrawTarget). When per-vertex edges
6998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * are not specified the value of this setting has no effect.
7008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
7018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setVertexEdgeType(VertexEdgeType type) {
70269cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com        GrAssert(type >=0 && type < kVertexEdgeTypeCnt);
7038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fVertexEdgeType = type;
7048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
7058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
70652a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    VertexEdgeType getVertexEdgeType() const { return fVertexEdgeType; }
7078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
7098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
7118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name State Flags
7128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
7138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
7158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Flags that affect rendering. Controlled using enable/disableState(). All
7168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  default to disabled.
7178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
7188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    enum StateBits {
7198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
7208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Perform dithering. TODO: Re-evaluate whether we need this bit
7218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
7228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kDither_StateBit        = 0x01,
7238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
7248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Perform HW anti-aliasing. This means either HW FSAA, if supported
7258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * by the render target, or smooth-line rendering if a line primitive
7268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * is drawn and line smoothing is supported by the 3D API.
7278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
7288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kHWAntialias_StateBit   = 0x02,
7298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
7308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Draws will respect the clip, otherwise the clip is ignored.
7318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
7328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kClip_StateBit          = 0x04,
7338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
7348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Disables writing to the color buffer. Useful when performing stencil
7358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * operations.
7368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
7378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kNoColorWrites_StateBit = 0x08,
7388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
73950bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org         * Draws will apply the color matrix, otherwise the color matrix is
74050bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org         * ignored.
74150bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org         */
7420342a85091fd430c90a142d155dc9642aa729d9ebsalomon@google.com        kColorMatrix_StateBit   = 0x10,
7430342a85091fd430c90a142d155dc9642aa729d9ebsalomon@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     *
756d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com     * @param stateBits bitfield of StateBits specifing 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     *
765d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com     * @param stateBits bitfield of StateBits specifing 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     *
774d5d69ffaea117428972db48796f7e75f0d1dab34bsalomon@google.com     * @param stateBits bitfield of StateBits to enable or disablt
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
8018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isStateFlagEnabled(uint32_t stateBit) const {
8028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return 0 != (stateBit & fFlagBits);
8038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
8048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
8068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
8088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Face Culling
8098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
8108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    enum DrawFace {
812978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com        kInvalid_DrawFace = -1,
813978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com
8148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kBoth_DrawFace,
8158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kCCW_DrawFace,
8168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kCW_DrawFace,
8178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    };
8188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
8208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Controls whether clockwise, counterclockwise, or both faces are drawn.
8218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param face  the face(s) to draw.
8228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
8238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setDrawFace(DrawFace face) {
824978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com        GrAssert(kInvalid_DrawFace != face);
8258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fDrawFace = face;
8268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
8278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
8298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Gets whether the target is drawing clockwise, counterclockwise,
8308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * or both faces.
8318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return the current draw face(s).
8328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
83352a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    DrawFace getDrawFace() const { return fDrawFace; }
834d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com
8358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
8368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
8378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
83862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
839f13f58804659175925042a291304d483a4fd9278tomhudson@google.com    bool isStageEnabled(int s) const {
840f13f58804659175925042a291304d483a4fd9278tomhudson@google.com        GrAssert((unsigned)s < kNumStages);
841cddaf340f1474cc1ff429b8ef9bc8739c72f80babsalomon@google.com        return (NULL != fSamplerStates[s].getCustomStage());
842f13f58804659175925042a291304d483a4fd9278tomhudson@google.com    }
843f13f58804659175925042a291304d483a4fd9278tomhudson@google.com
84462b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    // Most stages are usually not used, so conditionals here
84562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    // reduce the expected number of bytes touched by 50%.
8469381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    bool operator ==(const GrDrawState& s) const {
847861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        if (fColor != s.fColor ||
848861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            !s.fViewMatrix.cheapEqualTo(fViewMatrix) ||
849861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fRenderTarget != s.fRenderTarget ||
850861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fSrcBlend != s.fSrcBlend ||
851861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fDstBlend != s.fDstBlend ||
852861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fBlendConstant != s.fBlendConstant ||
853861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fFlagBits != s.fFlagBits ||
854861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fVertexEdgeType != s.fVertexEdgeType ||
855861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fStencilSettings != s.fStencilSettings ||
856861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fFirstCoverageStage != s.fFirstCoverageStage ||
857861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fCoverage != s.fCoverage ||
858861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fColorFilterMode != s.fColorFilterMode ||
859861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fColorFilterColor != s.fColorFilterColor ||
860861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com            fDrawFace != s.fDrawFace) {
8618fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com            return false;
8628fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com        }
86362b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
86462b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        for (int i = 0; i < kNumStages; i++) {
865f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com            bool enabled = this->isStageEnabled(i);
866f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com            if (enabled != s.isStageEnabled(i)) {
867f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com                return false;
868f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com            }
869f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com            if (enabled && this->fSamplerStates[i] != s.fSamplerStates[i]) {
87062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com                return false;
87162b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com            }
87262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        }
8739b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com        if (kColorMatrix_StateBit & s.fFlagBits) {
8749b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com            if (memcmp(fColorMatrix,
8759b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com                        s.fColorMatrix,
8769b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com                        sizeof(fColorMatrix))) {
8779b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com                return false;
8789b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com            }
8799b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com        }
88062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
88162b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        return true;
8829381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    }
8839381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    bool operator !=(const GrDrawState& s) const { return !(*this == s); }
88462b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
885d6176b0dcacb124539e0cfd051e6d93a9782f020rmistry@google.com    // Most stages are usually not used, so conditionals here
88662b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    // reduce the expected number of bytes touched by 50%.
88762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    GrDrawState& operator =(const GrDrawState& s) {
888861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fColor = s.fColor;
8898fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com        fViewMatrix = s.fViewMatrix;
890861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        SkRefCnt_SafeAssign(fRenderTarget, s.fRenderTarget);
891861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fSrcBlend = s.fSrcBlend;
892861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fDstBlend = s.fDstBlend;
893861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fBlendConstant = s.fBlendConstant;
894861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fFlagBits = s.fFlagBits;
895861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fVertexEdgeType = s.fVertexEdgeType;
896861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fStencilSettings = s.fStencilSettings;
897861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fFirstCoverageStage = s.fFirstCoverageStage;
898861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fCoverage = s.fCoverage;
899861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fColorFilterMode = s.fColorFilterMode;
900861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fColorFilterColor = s.fColorFilterColor;
901861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com        fDrawFace = s.fDrawFace;
9028fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com
90362b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        for (int i = 0; i < kNumStages; i++) {
904e742bf0ab19659145325ac894f7e0b78c8efbd89tomhudson@google.com            if (s.isStageEnabled(i)) {
90502b1ea24fd1152cb5a93e05b4d78700740140db6tomhudson@google.com                this->fSamplerStates[i] = s.fSamplerStates[i];
90662b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com            }
90762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        }
9089ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
9099b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com        if (kColorMatrix_StateBit & s.fFlagBits) {
9109b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com            memcpy(this->fColorMatrix, s.fColorMatrix, sizeof(fColorMatrix));
9119b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com        }
91262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
91362b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        return *this;
91462b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    }
91562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
91662b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.comprivate:
9172e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com
918861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com    // These fields are roughly sorted by decreasing liklihood of being different in op==
919861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com    GrColor             fColor;
920861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com    GrMatrix            fViewMatrix;
921861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com    GrRenderTarget*     fRenderTarget;
922861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com    GrBlendCoeff        fSrcBlend;
923861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com    GrBlendCoeff        fDstBlend;
924861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com    GrColor             fBlendConstant;
925861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com    uint32_t            fFlagBits;
926c077d1eaa8322087f3cc954c3b2e9af7fef103fcrobertphillips@google.com    VertexEdgeType      fVertexEdgeType;
92752a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    GrStencilSettings   fStencilSettings;
92869ffcf0d34878be7a1d2493785bf4df363199b10robertphillips@google.com    int                 fFirstCoverageStage;
9292401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    GrColor             fCoverage;
93052a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    SkXfermode::Mode    fColorFilterMode;
931861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com    GrColor             fColorFilterColor;
932861b3a28c3cad66040805140de8c06ad6fceb5dabsalomon@google.com    DrawFace            fDrawFace;
9338fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com
9348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // This field must be last; it will not be copied or compared
9358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // if the corresponding fTexture[] is NULL.
93652a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    GrSamplerState      fSamplerStates[kNumStages];
9379b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com    // only compared if the color matrix enable flag is set
9389b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com    float               fColorMatrix[20];       // 5 x 4 matrix
9398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
940fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com    typedef GrRefCnt INHERITED;
9419381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com};
9429381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
9439381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#endif
944