GrDrawState.h revision 580711694654b8edc70028d09c4211445b661466
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"
199381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
209381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#include "SkXfermode.h"
219381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
229381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
232e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.comclass GrDrawState : public GrRefCnt {
242e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.compublic:
25fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com    SK_DECLARE_INST_COUNT(GrDrawState)
26fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com
279381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    /**
289381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * Number of texture stages. Each stage takes as input a color and
299381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * 2D texture coordinates. The color input to the first enabled stage is the
309381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * per-vertex color or the constant color (setColor/setAlpha) if there are
319381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * no per-vertex colors. For subsequent stages the input color is the output
329381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * color from the previous enabled stage. The output color of each stage is
339381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * the input color modulated with the result of a texture lookup. Texture
349381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * lookups are specified by a texture a sampler (setSamplerState). Texture
359381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * coordinates for each stage come from the vertices based on a
369381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * GrVertexLayout bitfield. The output fragment color is the output color of
379381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * the last enabled stage. The presence or absence of texture coordinates
389381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * for each stage in the vertex layout indicates whether a stage is enabled
399381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * or not.
40bf5cad4e9c5808493b35cb9b0000a2d36b7f9b78robertphillips@google.com     *
41bf5cad4e9c5808493b35cb9b0000a2d36b7f9b78robertphillips@google.com     * Stages 0 through GrPaint::kTotalStages-1 are reserved for setting up
42bf5cad4e9c5808493b35cb9b0000a2d36b7f9b78robertphillips@google.com     * the draw (i.e., textures and filter masks). Stages GrPaint::kTotalStages
43bf5cad4e9c5808493b35cb9b0000a2d36b7f9b78robertphillips@google.com     * through kNumStages-1 are earmarked for use by GrTextContext and
44bf5cad4e9c5808493b35cb9b0000a2d36b7f9b78robertphillips@google.com     * GrPathRenderer-derived classes.
459381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     */
469381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    enum {
47580711694654b8edc70028d09c4211445b661466twiz@google.com        kNumStages = 5,
489381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        kMaxTexCoords = kNumStages
499381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    };
509381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
5139ee0ffa72fbd5df6d3ec6db4fdad0c1bc3946fdbsalomon@google.com    /**
5239ee0ffa72fbd5df6d3ec6db4fdad0c1bc3946fdbsalomon@google.com     *  Bitfield used to indicate a set of stages.
5339ee0ffa72fbd5df6d3ec6db4fdad0c1bc3946fdbsalomon@google.com     */
5439ee0ffa72fbd5df6d3ec6db4fdad0c1bc3946fdbsalomon@google.com    typedef uint32_t StageMask;
5539ee0ffa72fbd5df6d3ec6db4fdad0c1bc3946fdbsalomon@google.com    GR_STATIC_ASSERT(sizeof(StageMask)*8 >= GrDrawState::kNumStages);
5639ee0ffa72fbd5df6d3ec6db4fdad0c1bc3946fdbsalomon@google.com
579ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com    GrDrawState()
589ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        : fRenderTarget(NULL) {
599ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
609ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        for (int i = 0; i < kNumStages; ++i) {
619ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com            fTextures[i] = NULL;
629ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        }
639ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
6452a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        this->reset();
6552a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    }
6646f7afb9867200b568c21736da8a8bbb56b20e30bsalomon@google.com
679ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com    GrDrawState(const GrDrawState& state)
689ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        : fRenderTarget(NULL) {
699ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
709ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        for (int i = 0; i < kNumStages; ++i) {
719ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com            fTextures[i] = NULL;
729ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        }
739ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
7446f7afb9867200b568c21736da8a8bbb56b20e30bsalomon@google.com        *this = state;
7546f7afb9867200b568c21736da8a8bbb56b20e30bsalomon@google.com    }
7646f7afb9867200b568c21736da8a8bbb56b20e30bsalomon@google.com
779ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com    virtual ~GrDrawState() {
787d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        this->disableStages();
799ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        GrSafeSetNull(fRenderTarget);
809ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com    }
819ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
8252a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    /**
837d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com     * Resets to the default state.
847d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com     * Sampler states *will* be modified: textures or CustomStage objects
857d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com     * will be released.
8652a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com     */
8752a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    void reset() {
889ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
897d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        this->disableStages();
909ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        GrSafeSetNull(fRenderTarget);
919ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // make sure any pad is zero for memcmp
9352a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        // all GrDrawState members should default to something valid by the
9452a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        // the memset except those initialized individually below. There should
9552a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        // be no padding between the individually initialized members.
962e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com        memset(this->podStart(), 0, this->memsetSize());
972e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com
988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // pedantic assertion that our ptrs will
998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // be NULL (0 ptr is mem addr 0)
1008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((intptr_t)(void*)NULL == 0LL);
10152a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        GR_STATIC_ASSERT(0 == kBoth_DrawFace);
1028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert(fStencilSettings.isDisabled());
10352a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com
10452a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        // memset exceptions
10552a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        fColor = 0xffffffff;
1062401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com        fCoverage = 0xffffffff;
1078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fFirstCoverageStage = kNumStages;
10852a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        fColorFilterMode = SkXfermode::kDst_Mode;
10947059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        fSrcBlend = kOne_GrBlendCoeff;
11047059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        fDstBlend = kZero_GrBlendCoeff;
11152a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        fViewMatrix.reset();
11252a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com
11352a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        // ensure values that will be memcmp'ed in == but not memset in reset()
11452a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        // are tightly packed
1152e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com        GrAssert(this->memsetSize() +  sizeof(fColor) + sizeof(fCoverage) +
1162401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com                 sizeof(fFirstCoverageStage) + sizeof(fColorFilterMode) +
1179ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com                 sizeof(fSrcBlend) + sizeof(fDstBlend) + sizeof(fTextures) +
1189ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com                 sizeof(fRenderTarget) == this->podSize());
1198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
1208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
1228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Color
1238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
1248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
1268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Sets color for next draw to a premultiplied-alpha color.
1278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
1288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param color    the color to set.
1298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
1308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setColor(GrColor color) { fColor = color; }
1318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrColor getColor() const { return fColor; }
1338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
1358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Sets the color to be used for the next draw to be
1368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  (r,g,b,a) = (alpha, alpha, alpha, alpha).
1378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
1388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param alpha The alpha value to set as the color.
1398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
1408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setAlpha(uint8_t a) {
1418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        this->setColor((a << 24) | (a << 16) | (a << 8) | a);
1428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
1438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
1458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Add a color filter that can be represented by a color and a mode. Applied
1468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * after color-computing texture stages.
1478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
1488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setColorFilter(GrColor c, SkXfermode::Mode mode) {
1498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fColorFilterColor = c;
1508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fColorFilterMode = mode;
1518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
1528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrColor getColorFilterColor() const { return fColorFilterColor; }
1548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    SkXfermode::Mode getColorFilterMode() const { return fColorFilterMode; }
1558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@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    /**
1632401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@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    /**
1908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the texture used at the next drawing call
1918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
1928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param stage The texture stage for which the texture will be set
1938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
1948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param texture The texture to set. Can be NULL though there is no
1958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * advantage to settings a NULL texture if doing non-textured drawing
1968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
1978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setTexture(int stage, GrTexture* texture) {
1988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((unsigned)stage < kNumStages);
1991942c05e9c51b462355626155c1bdc3fc43161cfrobertphillips@google.com
2009ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        GrSafeAssign(fTextures[stage], texture);
2018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
2028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
2048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Retrieves the currently set texture.
2058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
2068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return    The currently set texture. The return value will be NULL if no
2078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *            texture has been set, NULL was most recently passed to
2088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *            setTexture, or the last setTexture was destroyed.
2098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
2108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    const GrTexture* getTexture(int stage) const {
2118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((unsigned)stage < kNumStages);
212e742bf0ab19659145325ac894f7e0b78c8efbd89tomhudson@google.com        GrAssert(!this->getSampler(stage).getCustomStage() ||
213e742bf0ab19659145325ac894f7e0b78c8efbd89tomhudson@google.com                 !fTextures[stage] ||
214e742bf0ab19659145325ac894f7e0b78c8efbd89tomhudson@google.com                 fTextures[stage] == this->getSampler(stage).getCustomStage()->texture(0));
215e742bf0ab19659145325ac894f7e0b78c8efbd89tomhudson@google.com        if (this->getSampler(stage).getCustomStage()) {
216e742bf0ab19659145325ac894f7e0b78c8efbd89tomhudson@google.com            return this->getSampler(stage).getCustomStage()->texture(0);
217e742bf0ab19659145325ac894f7e0b78c8efbd89tomhudson@google.com        }
2188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return fTextures[stage];
2198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
2208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrTexture* getTexture(int stage) {
2218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((unsigned)stage < kNumStages);
222e742bf0ab19659145325ac894f7e0b78c8efbd89tomhudson@google.com        GrAssert(!this->getSampler(stage).getCustomStage() ||
223e742bf0ab19659145325ac894f7e0b78c8efbd89tomhudson@google.com                 !fTextures[stage] ||
224e742bf0ab19659145325ac894f7e0b78c8efbd89tomhudson@google.com                 fTextures[stage] == this->getSampler(stage).getCustomStage()->texture(0));
225e742bf0ab19659145325ac894f7e0b78c8efbd89tomhudson@google.com        if (this->getSampler(stage).getCustomStage()) {
226e742bf0ab19659145325ac894f7e0b78c8efbd89tomhudson@google.com            return this->getSampler(stage).getCustomStage()->texture(0);
227e742bf0ab19659145325ac894f7e0b78c8efbd89tomhudson@google.com        }
2288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return fTextures[stage];
2298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
2308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2317d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com    bool stagesDisabled() {
2327d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        for (int i = 0; i < kNumStages; ++i) {
2337d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com            if (NULL != fTextures[i] ||
2347d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com                NULL != fSamplerStates[i].getCustomStage()) {
2357d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com                return false;
2367d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com            }
2377d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        }
2383eee8fbe0f280bc1dea59dc0b0ebd8021b51137ftomhudson@google.com        return true;
2397d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com    }
240676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com
241676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com    void disableStage(int index) {
242676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com        GrSafeSetNull(fTextures[index]);
243676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com        fSamplerStates[index].setCustomStage(NULL);
244676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com    }
245676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com
246972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    /**
2477d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com     * Release all the textures and custom stages referred to by this
2487d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com     * draw state.
249972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com     */
2507d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com    void disableStages() {
251972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com        for (int i = 0; i < kNumStages; ++i) {
252676e66096c60615bac52f365111596de5c4ca8a6tomhudson@google.com            this->disableStage(i);
253972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com        }
254972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    }
255972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com
2567d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com    class AutoStageDisable : public ::GrNoncopyable {
257972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    public:
2587d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        AutoStageDisable(GrDrawState* ds) : fDrawState(ds) {}
2597d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com        ~AutoStageDisable() {
260972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com            if (NULL != fDrawState) {
2617d6afdd795eb4c7ce8f5a327117cfdba5f957ddbtomhudson@google.com                fDrawState->disableStages();
262972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com            }
263972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com        }
264972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    private:
265972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com        GrDrawState* fDrawState;
266972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com    };
267972265db219ce25b5159879c75e6c62efaf0fa79robertphillips@google.com
2688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
2698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
2718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Samplers
2728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
2738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
2758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Returns the current sampler for a stage.
2768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
2778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    const GrSamplerState& getSampler(int stage) const {
2788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((unsigned)stage < kNumStages);
2798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return fSamplerStates[stage];
2808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
2818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
2838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Writable pointer to a stage's sampler.
2848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
2858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrSamplerState* sampler(int stage) {
2868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((unsigned)stage < kNumStages);
2878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return fSamplerStates + stage;
2888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
2898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
2918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Preconcats the matrix of all samplers in the mask with the same matrix.
2928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
2938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void preConcatSamplerMatrices(StageMask stageMask, const GrMatrix& matrix) {
2948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert(!(stageMask & kIllegalStageMaskBits));
2958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        for (int i = 0; i < kNumStages; ++i) {
2968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if ((1 << i) & stageMask) {
2978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fSamplerStates[i].preConcatMatrix(matrix);
2988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
2998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
3008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
3018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
3038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
3058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Coverage / Color Stages
3068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
3078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * A common pattern is to compute a color with the initial stages and then
3108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * modulate that color by a coverage value in later stage(s) (AA, mask-
3118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * filters, glyph mask, etc). Color-filters, xfermodes, etc should be
3128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * computed based on the pre-coverage-modulated color. The division of
3138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * stages between color-computing and coverage-computing is specified by
3148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * this method. Initially this is kNumStages (all stages
3158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * are color-computing).
3168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setFirstCoverageStage(int firstCoverageStage) {
3188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((unsigned)firstCoverageStage <= kNumStages);
3198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fFirstCoverageStage = firstCoverageStage;
3208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
3218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Gets the index of the first coverage-computing stage.
3248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    int getFirstCoverageStage() const {
3268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return fFirstCoverageStage;
3278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
3288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///@}
3308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
3328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Blending
3338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
3348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the blending function coeffecients.
3378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * The blend function will be:
3398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *    D' = sat(S*srcCoef + D*dstCoef)
3408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *   where D is the existing destination color, S is the incoming source
3428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *   color, and D' is the new destination color that will be written. sat()
3438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *   is the saturation function.
3448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param srcCoef coeffecient applied to the src color.
3468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param dstCoef coeffecient applied to the dst color.
3478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
3498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fSrcBlend = srcCoeff;
3508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fDstBlend = dstCoeff;
3518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    #if GR_DEBUG
3528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        switch (dstCoeff) {
35347059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kDC_GrBlendCoeff:
35447059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kIDC_GrBlendCoeff:
35547059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kDA_GrBlendCoeff:
35647059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kIDA_GrBlendCoeff:
3578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
3588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                     "coverage stages.\n");
3598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
3608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        default:
3618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
3628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
3638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        switch (srcCoeff) {
36447059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kSC_GrBlendCoeff:
36547059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kISC_GrBlendCoeff:
36647059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kSA_GrBlendCoeff:
36747059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com        case kISA_GrBlendCoeff:
3688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            GrPrintf("Unexpected src blend coeff. Won't work correctly with"
3698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                     "coverage stages.\n");
3708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
3718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        default:
3728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
3738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
3748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    #endif
3758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
3768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrBlendCoeff getSrcBlendCoeff() const { return fSrcBlend; }
3788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrBlendCoeff getDstBlendCoeff() const { return fDstBlend; }
3798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff,
3818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                          GrBlendCoeff* dstBlendCoeff) const {
3828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        *srcBlendCoeff = fSrcBlend;
3838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        *dstBlendCoeff = fDstBlend;
3848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
3858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the blending function constant referenced by the following blending
3888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * coeffecients:
38947059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com     *      kConstC_GrBlendCoeff
39047059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com     *      kIConstC_GrBlendCoeff
39147059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com     *      kConstA_GrBlendCoeff
39247059542e7aa153926377456a6c611e55c8e428cbsalomon@google.com     *      kIConstA_GrBlendCoeff
3938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param constant the constant to set
3958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setBlendConstant(GrColor constant) { fBlendConstant = constant; }
3978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Retrieves the last value set by setBlendConstant()
4008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return the blending constant value
4018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
4028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrColor getBlendConstant() const { return fBlendConstant; }
4038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
4058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
4078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name View Matrix
4088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
4098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
411a72eef322c686954cdffa849dc26d8133b802f1drobertphillips@google.com     * Sets the matrix applied to vertex positions.
4128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * In the post-view-matrix space the rectangle [0,w]x[0,h]
4148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * fully covers the render target. (w and h are the width and height of the
4158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * the rendertarget.)
4168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
4178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setViewMatrix(const GrMatrix& m) { fViewMatrix = m; }
4188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Gets a writable pointer to the view matrix.
4218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
4228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrMatrix* viewMatrix() { return &fViewMatrix; }
4238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Multiplies the current view matrix by a matrix
4268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  After this call V' = V*m where V is the old view matrix,
4288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  m is the parameter to this function, and V' is the new view matrix.
4298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  (We consider positions to be column vectors so position vector p is
4308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  transformed by matrix X as p' = X*p.)
4318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param m the matrix used to modify the view matrix.
4338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
4348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void preConcatViewMatrix(const GrMatrix& m) { fViewMatrix.preConcat(m); }
4358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Multiplies the current view matrix by a matrix
4388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  After this call V' = m*V where V is the old view matrix,
4408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  m is the parameter to this function, and V' is the new view matrix.
4418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  (We consider positions to be column vectors so position vector p is
4428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  transformed by matrix X as p' = X*p.)
4438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param m the matrix used to modify the view matrix.
4458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
4468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void postConcatViewMatrix(const GrMatrix& m) { fViewMatrix.postConcat(m); }
4478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Retrieves the current view matrix
4508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return the current view matrix.
4518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
4528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    const GrMatrix& getViewMatrix() const { return fViewMatrix; }
4538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Retrieves the inverse of the current view matrix.
4568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  If the current view matrix is invertible, return true, and if matrix
4588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  is non-null, copy the inverse into it. If the current view matrix is
4598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  non-invertible, return false and ignore the matrix parameter.
4608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param matrix if not null, will receive a copy of the current inverse.
4628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
4638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool getViewInverse(GrMatrix* matrix) const {
4648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // TODO: determine whether we really need to leave matrix unmodified
4658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // at call sites when inversion fails.
4668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrMatrix inverse;
4678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        if (fViewMatrix.invert(&inverse)) {
4688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (matrix) {
4698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                *matrix = inverse;
4708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
4718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            return true;
4728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
4738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return false;
4748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
4758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    class AutoViewMatrixRestore : public ::GrNoncopyable {
4778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    public:
4788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        AutoViewMatrixRestore() : fDrawState(NULL) {}
4798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        AutoViewMatrixRestore(GrDrawState* ds, const GrMatrix& newMatrix) {
4808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            fDrawState = NULL;
4818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            this->set(ds, newMatrix);
4828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
4838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        AutoViewMatrixRestore(GrDrawState* ds) {
4848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            fDrawState = NULL;
4858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            this->set(ds);
4868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
4878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        ~AutoViewMatrixRestore() {
4888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            this->set(NULL, GrMatrix::I());
4898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
4908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        void set(GrDrawState* ds, const GrMatrix& newMatrix) {
4918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (NULL != fDrawState) {
4928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fDrawState->setViewMatrix(fSavedMatrix);
4938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
4948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (NULL != ds) {
4958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fSavedMatrix = ds->getViewMatrix();
4968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                ds->setViewMatrix(newMatrix);
4978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
4988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            fDrawState = ds;
4998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
5008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        void set(GrDrawState* ds) {
5018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (NULL != fDrawState) {
5028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fDrawState->setViewMatrix(fSavedMatrix);
5038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
5048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (NULL != ds) {
5058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fSavedMatrix = ds->getViewMatrix();
5068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
5078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            fDrawState = ds;
5088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
509ded4f4b163f5aa19c22c871178c55ecb34623846bsalomon@google.com        bool isSet() const { return NULL != fDrawState; }
5108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    private:
5118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrDrawState* fDrawState;
5128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrMatrix fSavedMatrix;
5139381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    };
5149381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
5158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
5168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
5188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Render Target
5198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
5208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
5228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the rendertarget used at the next drawing call
5238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
5248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param target  The render target to set.
5258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
5269ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com    void setRenderTarget(GrRenderTarget* target) {
5279ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        GrSafeAssign(fRenderTarget, target);
5289ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com    }
5298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
5318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Retrieves the currently set rendertarget.
5328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
5338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return    The currently set render target.
5348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
5358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    const GrRenderTarget* getRenderTarget() const { return fRenderTarget; }
5368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrRenderTarget* getRenderTarget() { return fRenderTarget; }
5378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    class AutoRenderTargetRestore : public ::GrNoncopyable {
5398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    public:
540cadbcb8e536f89babb4e165bfdca18384e97d582bsalomon@google.com        AutoRenderTargetRestore() : fDrawState(NULL), fSavedTarget(NULL) {}
5418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) {
5428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            fDrawState = NULL;
5437460b378d68217167013ca889a4cdcae742908e7robertphillips@google.com            fSavedTarget = NULL;
5448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            this->set(ds, newTarget);
5458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
5469ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        ~AutoRenderTargetRestore() { this->restore(); }
5479ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
5489ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        void restore() {
5498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (NULL != fDrawState) {
5508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fDrawState->setRenderTarget(fSavedTarget);
5519ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com                fDrawState = NULL;
5528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
5539ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com            GrSafeSetNull(fSavedTarget);
5549ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        }
5559ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
5569ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        void set(GrDrawState* ds, GrRenderTarget* newTarget) {
5579ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com            this->restore();
5589ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
5598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (NULL != ds) {
5609ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com                GrAssert(NULL == fSavedTarget);
5618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fSavedTarget = ds->getRenderTarget();
5629ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com                SkSafeRef(fSavedTarget);
5638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                ds->setRenderTarget(newTarget);
5649ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com                fDrawState = ds;
5658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
5668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
5678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    private:
5688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrDrawState* fDrawState;
5698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrRenderTarget* fSavedTarget;
5708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    };
5718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
5738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
5758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Stencil
5768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
5778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
5798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the stencil settings to use for the next draw.
5808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Changing the clip has the side-effect of possibly zeroing
5818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * out the client settable stencil bits. So multipass algorithms
5828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * using stencil should not change the clip between passes.
5838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param settings  the stencil settings to use.
5848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
5858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setStencil(const GrStencilSettings& settings) {
5868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fStencilSettings = settings;
5878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
5888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
5908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Shortcut to disable stencil testing and ops.
5918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
5928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void disableStencil() {
5938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fStencilSettings.setDisabled();
5948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
5958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    const GrStencilSettings& getStencil() const { return fStencilSettings; }
5978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrStencilSettings* stencil() { return &fStencilSettings; }
5998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
6018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
60350bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org    /// @name Color Matrix
60450bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org    ////
60550bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org
60650bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org    /**
60750bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org     * Sets the color matrix to use for the next draw.
60850bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org     * @param matrix  the 5x4 matrix to apply to the incoming color
60950bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org     */
61050bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org    void setColorMatrix(const float matrix[20]) {
61150bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org        memcpy(fColorMatrix, matrix, sizeof(fColorMatrix));
61250bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org    }
61350bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org
61450bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org    const float* getColorMatrix() const { return fColorMatrix; }
61550bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org
61650bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org    /// @}
61750bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org
61850bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org    ///////////////////////////////////////////////////////////////////////////
6198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // @name Edge AA
6207ffe6810c6787f7a353ef3fe8fab3fc6440aae19bsalomon@google.com    // Edge equations can be specified to perform antialiasing. Because the
6217ffe6810c6787f7a353ef3fe8fab3fc6440aae19bsalomon@google.com    // edges are specified as per-vertex data, vertices that are shared by
6227ffe6810c6787f7a353ef3fe8fab3fc6440aae19bsalomon@google.com    // multiple edges must be split.
6238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    //
6248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
6258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
6279381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * When specifying edges as vertex data this enum specifies what type of
6289381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * edges are in use. The edges are always 4 GrScalars in memory, even when
6299381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * the edge type requires fewer than 4.
63093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com     *
63193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com     * TODO: Fix the fact that HairLine and Circle edge types use y-down coords.
63293c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com     *       (either adjust in VS or use origin_upper_left in GLSL)
6339381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     */
6349381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    enum VertexEdgeType {
6359381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        /* 1-pixel wide line
6369381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com           2D implicit line eq (a*x + b*y +c = 0). 4th component unused */
6379381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        kHairLine_EdgeType,
63869cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com        /* Quadratic specified by u^2-v canonical coords (only 2
63969cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com           components used). Coverage based on signed distance with negative
64093c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com           being inside, positive outside. Edge specified in window space
64193c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com           (y-down) */
64269cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com        kQuad_EdgeType,
64369cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com        /* Same as above but for hairline quadratics. Uses unsigned distance.
64469cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com           Coverage is min(0, 1-distance). */
64569cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com        kHairQuad_EdgeType,
64693c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com        /* Circle specified as center_x, center_y, outer_radius, inner_radius
64793c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com           all in window space (y-down). */
64893c9660cd158c5d0cab0ba4223e4257f699d5bb8bsalomon@google.com        kCircle_EdgeType,
64969cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com
65069cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com        kVertexEdgeTypeCnt
6519381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    };
6529381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
6539381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    /**
6548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Determines the interpretation per-vertex edge data when the
6558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * kEdge_VertexLayoutBit is set (see GrDrawTarget). When per-vertex edges
6568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * are not specified the value of this setting has no effect.
6578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
6588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setVertexEdgeType(VertexEdgeType type) {
65969cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com        GrAssert(type >=0 && type < kVertexEdgeTypeCnt);
6608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fVertexEdgeType = type;
6618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
66352a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    VertexEdgeType getVertexEdgeType() const { return fVertexEdgeType; }
6648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
6668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
6688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name State Flags
6698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
6708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
6728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Flags that affect rendering. Controlled using enable/disableState(). All
6738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  default to disabled.
6748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
6758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    enum StateBits {
6768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
6778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Perform dithering. TODO: Re-evaluate whether we need this bit
6788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
6798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kDither_StateBit        = 0x01,
6808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
6818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Perform HW anti-aliasing. This means either HW FSAA, if supported
6828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * by the render target, or smooth-line rendering if a line primitive
6838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * is drawn and line smoothing is supported by the 3D API.
6848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
6858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kHWAntialias_StateBit   = 0x02,
6868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
6878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Draws will respect the clip, otherwise the clip is ignored.
6888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
6898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kClip_StateBit          = 0x04,
6908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
6918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Disables writing to the color buffer. Useful when performing stencil
6928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * operations.
6938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
6948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kNoColorWrites_StateBit = 0x08,
6958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
69650bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org         * Draws will apply the color matrix, otherwise the color matrix is
69750bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org         * ignored.
69850bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org         */
69950bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org        kColorMatrix_StateBit   = 0x20,
7008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // Users of the class may add additional bits to the vector
7028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kDummyStateBit,
7038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kLastPublicStateBit = kDummyStateBit-1,
7048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    };
7058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void resetStateFlags() {
7078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fFlagBits = 0;
7080fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
7090fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
7108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
7118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Enable render state settings.
7128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
7138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param flags   bitfield of StateBits specifing the states to enable
7148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
7158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void enableState(uint32_t stateBits) {
7168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fFlagBits |= stateBits;
7178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
7180fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
7198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
7208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Disable render state settings.
7218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
7228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param flags   bitfield of StateBits specifing the states to disable
7238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
7248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void disableState(uint32_t stateBits) {
7258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fFlagBits &= ~(stateBits);
7268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
7270fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
7288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isDitherState() const {
7298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return 0 != (fFlagBits & kDither_StateBit);
7308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
7310fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
7328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isHWAntialiasState() const {
7338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return 0 != (fFlagBits & kHWAntialias_StateBit);
7348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
7350fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
7368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isClipState() const {
7378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return 0 != (fFlagBits & kClip_StateBit);
7388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
7390fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
7408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isColorWriteDisabled() const {
7418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return 0 != (fFlagBits & kNoColorWrites_StateBit);
7428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
7438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isStateFlagEnabled(uint32_t stateBit) const {
7458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return 0 != (stateBit & fFlagBits);
7468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
7478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
7498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
7518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Face Culling
7528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
7538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    enum DrawFace {
755978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com        kInvalid_DrawFace = -1,
756978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com
7578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kBoth_DrawFace,
7588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kCCW_DrawFace,
7598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kCW_DrawFace,
7608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    };
7618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
7638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Controls whether clockwise, counterclockwise, or both faces are drawn.
7648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param face  the face(s) to draw.
7658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
7668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setDrawFace(DrawFace face) {
767978c8c61ba1e792567e9d8e6629c2c4ee59727b7bsalomon@google.com        GrAssert(kInvalid_DrawFace != face);
7688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fDrawFace = face;
7698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
7708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
7728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Gets whether the target is drawing clockwise, counterclockwise,
7738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * or both faces.
7748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return the current draw face(s).
7758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
77652a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    DrawFace getDrawFace() const { return fDrawFace; }
7778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
7798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
78162b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
782f13f58804659175925042a291304d483a4fd9278tomhudson@google.com    bool isStageEnabled(int s) const {
783f13f58804659175925042a291304d483a4fd9278tomhudson@google.com        GrAssert((unsigned)s < kNumStages);
784f13f58804659175925042a291304d483a4fd9278tomhudson@google.com        return (NULL != fTextures[s]) ||
785f13f58804659175925042a291304d483a4fd9278tomhudson@google.com               (NULL != fSamplerStates[s].getCustomStage());
786f13f58804659175925042a291304d483a4fd9278tomhudson@google.com    }
787f13f58804659175925042a291304d483a4fd9278tomhudson@google.com
78862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    // Most stages are usually not used, so conditionals here
78962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    // reduce the expected number of bytes touched by 50%.
7909381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    bool operator ==(const GrDrawState& s) const {
7912e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com        if (memcmp(this->podStart(), s.podStart(), this->podSize())) {
7928fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com            return false;
7938fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com        }
7948fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com
7958fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com        if (!s.fViewMatrix.cheapEqualTo(fViewMatrix)) {
7968fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com            return false;
7978fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com        }
79862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
79962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        for (int i = 0; i < kNumStages; i++) {
800f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com            bool enabled = this->isStageEnabled(i);
801f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com            if (enabled != s.isStageEnabled(i)) {
802f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com                return false;
803f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com            }
804f2f8fc37265a6ef06897117451a3a9238287c13bbsalomon@google.com            if (enabled && this->fSamplerStates[i] != s.fSamplerStates[i]) {
80562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com                return false;
80662b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com            }
80762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        }
8089b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com        if (kColorMatrix_StateBit & s.fFlagBits) {
8099b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com            if (memcmp(fColorMatrix,
8109b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com                        s.fColorMatrix,
8119b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com                        sizeof(fColorMatrix))) {
8129b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com                return false;
8139b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com            }
8149b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com        }
81562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
81662b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        return true;
8179381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    }
8189381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    bool operator !=(const GrDrawState& s) const { return !(*this == s); }
81962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
82062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    // Most stages are usually not used, so conditionals here
82162b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    // reduce the expected number of bytes touched by 50%.
82262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    GrDrawState& operator =(const GrDrawState& s) {
8232e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com        memcpy(this->podStart(), s.podStart(), this->podSize());
82462b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
8258fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com        fViewMatrix = s.fViewMatrix;
8268fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com
82762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        for (int i = 0; i < kNumStages; i++) {
8289ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com            SkSafeRef(fTextures[i]);            // already copied by memcpy
829e742bf0ab19659145325ac894f7e0b78c8efbd89tomhudson@google.com            if (s.isStageEnabled(i)) {
83002b1ea24fd1152cb5a93e05b4d78700740140db6tomhudson@google.com                this->fSamplerStates[i] = s.fSamplerStates[i];
83162b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com            }
83262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        }
8339ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
8349ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        SkSafeRef(fRenderTarget);               // already copied by memcpy
8359ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
8369b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com        if (kColorMatrix_StateBit & s.fFlagBits) {
8379b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com            memcpy(this->fColorMatrix, s.fColorMatrix, sizeof(fColorMatrix));
8389b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com        }
83962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
84062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        return *this;
84162b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    }
84262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
84362b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.comprivate:
8442e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com
8452e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com    const void* podStart() const {
8462e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com        return reinterpret_cast<const void*>(&fPodStartMarker);
8472e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com    }
8482e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com    void* podStart() {
8492e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com        return reinterpret_cast<void*>(&fPodStartMarker);
8502e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com    }
8512e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com    size_t memsetSize() const {
8522e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com        return reinterpret_cast<size_t>(&fMemsetEndMarker) -
8532e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com               reinterpret_cast<size_t>(&fPodStartMarker) +
8542e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com               sizeof(fMemsetEndMarker);
8552e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com    }
8562e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com    size_t podSize() const {
8572e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com        // Can't use offsetof() with non-POD types, so stuck with pointer math.
8582e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com        return reinterpret_cast<size_t>(&fPodEndMarker) -
8592e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com               reinterpret_cast<size_t>(&fPodStartMarker) +
8602e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com               sizeof(fPodEndMarker);
8612e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com    }
8622e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com
863cf6285b89b8820641ffb6871d4b3275bfe783f51caryclark@google.com    static const StageMask kIllegalStageMaskBits = ~((1U << kNumStages)-1);
86452a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    // @{ these fields can be initialized with memset to 0
8652e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com    union {
8662e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com        GrColor             fBlendConstant;
8672e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com        GrColor             fPodStartMarker;
8682e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com    };
86952a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    GrColor             fColorFilterColor;
87052a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    DrawFace            fDrawFace;
871c077d1eaa8322087f3cc954c3b2e9af7fef103fcrobertphillips@google.com    VertexEdgeType      fVertexEdgeType;
87252a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    GrStencilSettings   fStencilSettings;
8732e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com    union {
8749ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        uint32_t        fFlagBits;
8759ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com        uint32_t        fMemsetEndMarker;
8762e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com    };
87752a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    // @}
87852a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com
8792e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com    // @{ Initialized to values other than zero, but memcmp'ed in operator==
8802e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com    // and memcpy'ed in operator=.
8819ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com    GrTexture*          fTextures[kNumStages];
8829ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com    GrRenderTarget*     fRenderTarget;
8839ec075366ed94802a142fc5e948d19a774f85b43robertphillips@google.com
88469ffcf0d34878be7a1d2493785bf4df363199b10robertphillips@google.com    int                 fFirstCoverageStage;
88569ffcf0d34878be7a1d2493785bf4df363199b10robertphillips@google.com
88652a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    GrColor             fColor;
8872401ae8fd3c1f6282f571b5a7e0a499e9f4c09abbsalomon@google.com    GrColor             fCoverage;
88852a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    SkXfermode::Mode    fColorFilterMode;
88952a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    GrBlendCoeff        fSrcBlend;
8902e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com    union {
891c077d1eaa8322087f3cc954c3b2e9af7fef103fcrobertphillips@google.com        GrBlendCoeff    fDstBlend;
892c077d1eaa8322087f3cc954c3b2e9af7fef103fcrobertphillips@google.com        GrBlendCoeff    fPodEndMarker;
8932e3d144dfdbc4596d33baef7396316f88f412cc8bsalomon@google.com    };
89452a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    // @}
89552a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com
8968fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com    GrMatrix            fViewMatrix;
8978fe84b53a64b5d92f3aabdd8e7fc7b2ee15c0a75bsalomon@google.com
8988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // This field must be last; it will not be copied or compared
8998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // if the corresponding fTexture[] is NULL.
90052a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    GrSamplerState      fSamplerStates[kNumStages];
9019b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com    // only compared if the color matrix enable flag is set
9029b1517edc7eb3e116902a3b3da447a73aaa56585bsalomon@google.com    float               fColorMatrix[20];       // 5 x 4 matrix
9038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
904fa35e3ddcc9d130ce87c927218bdf27879c38711reed@google.com    typedef GrRefCnt INHERITED;
9059381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com};
9069381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
9079381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#endif
908