GrDrawState.h revision 8f9cbd62ec108d410b91155dcf6a4789c641246f
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"
149381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#include "GrSamplerState.h"
159381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#include "GrStencil.h"
169381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
179381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#include "SkXfermode.h"
189381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
199381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.comclass GrRenderTarget;
209381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.comclass GrTexture;
219381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
229381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.comstruct GrDrawState {
239381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
249381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    /**
259381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * Number of texture stages. Each stage takes as input a color and
269381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * 2D texture coordinates. The color input to the first enabled stage is the
279381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * per-vertex color or the constant color (setColor/setAlpha) if there are
289381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * no per-vertex colors. For subsequent stages the input color is the output
299381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * color from the previous enabled stage. The output color of each stage is
309381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * the input color modulated with the result of a texture lookup. Texture
319381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * lookups are specified by a texture a sampler (setSamplerState). Texture
329381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * coordinates for each stage come from the vertices based on a
339381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * GrVertexLayout bitfield. The output fragment color is the output color of
349381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * the last enabled stage. The presence or absence of texture coordinates
359381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * for each stage in the vertex layout indicates whether a stage is enabled
369381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * or not.
379381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     */
389381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    enum {
399381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        kNumStages = 3,
409381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        kMaxTexCoords = kNumStages
419381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    };
429381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
4339ee0ffa72fbd5df6d3ec6db4fdad0c1bc3946fdbsalomon@google.com    /**
4439ee0ffa72fbd5df6d3ec6db4fdad0c1bc3946fdbsalomon@google.com     *  Bitfield used to indicate a set of stages.
4539ee0ffa72fbd5df6d3ec6db4fdad0c1bc3946fdbsalomon@google.com     */
4639ee0ffa72fbd5df6d3ec6db4fdad0c1bc3946fdbsalomon@google.com    typedef uint32_t StageMask;
4739ee0ffa72fbd5df6d3ec6db4fdad0c1bc3946fdbsalomon@google.com    GR_STATIC_ASSERT(sizeof(StageMask)*8 >= GrDrawState::kNumStages);
4839ee0ffa72fbd5df6d3ec6db4fdad0c1bc3946fdbsalomon@google.com
498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrDrawState() {
508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // make sure any pad is zero for memcmp
518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // all GrDrawState members should default to something
528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // valid by the memset
538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        memset(this, 0, sizeof(GrDrawState));
548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // memset exceptions
568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fColorFilterMode = SkXfermode::kDstIn_Mode;
578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fFirstCoverageStage = kNumStages;
588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // pedantic assertion that our ptrs will
608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // be NULL (0 ptr is mem addr 0)
618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((intptr_t)(void*)NULL == 0LL);
628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert(fStencilSettings.isDisabled());
648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fFirstCoverageStage = kNumStages;
658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Color
698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Sets color for next draw to a premultiplied-alpha color.
738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param color    the color to set.
758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setColor(GrColor color) { fColor = color; }
778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrColor getColor() const { return fColor; }
798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Sets the color to be used for the next draw to be
828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  (r,g,b,a) = (alpha, alpha, alpha, alpha).
838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param alpha The alpha value to set as the color.
858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setAlpha(uint8_t a) {
878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        this->setColor((a << 24) | (a << 16) | (a << 8) | a);
888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Add a color filter that can be represented by a color and a mode. Applied
928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * after color-computing texture stages.
938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setColorFilter(GrColor c, SkXfermode::Mode mode) {
958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fColorFilterColor = c;
968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fColorFilterMode = mode;
978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrColor getColorFilterColor() const { return fColorFilterColor; }
1008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    SkXfermode::Mode getColorFilterMode() const { return fColorFilterMode; }
1018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
1038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
1058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Textures
1068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
1078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
1098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the texture used at the next drawing call
1108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
1118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param stage The texture stage for which the texture will be set
1128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
1138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param texture The texture to set. Can be NULL though there is no
1148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * advantage to settings a NULL texture if doing non-textured drawing
1158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
1168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setTexture(int stage, GrTexture* texture) {
1178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((unsigned)stage < kNumStages);
1188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fTextures[stage] = texture;
1198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
1208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
1228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Retrieves the currently set texture.
1238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
1248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return    The currently set texture. The return value will be NULL if no
1258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *            texture has been set, NULL was most recently passed to
1268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *            setTexture, or the last setTexture was destroyed.
1278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
1288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    const GrTexture* getTexture(int stage) const {
1298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((unsigned)stage < kNumStages);
1308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return fTextures[stage];
1318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
1328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrTexture* getTexture(int stage) {
1338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((unsigned)stage < kNumStages);
1348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return fTextures[stage];
1358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
1368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
1388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
1408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Samplers
1418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
1428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
1448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Returns the current sampler for a stage.
1458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
1468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    const GrSamplerState& getSampler(int stage) const {
1478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((unsigned)stage < kNumStages);
1488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return fSamplerStates[stage];
1498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
1508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
1528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the sampler. This will be removed soon in favor of direct access.
1538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
1548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setSampler(int stage, const GrSamplerState& sampler) {
1558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((unsigned)stage < kNumStages);
1568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fSamplerStates[stage] = sampler;
1578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
1588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
1608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Writable pointer to a stage's sampler.
1618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
1628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrSamplerState* sampler(int stage) {
1638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((unsigned)stage < kNumStages);
1648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return fSamplerStates + stage;
1658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
1668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
1688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Preconcats the matrix of all samplers in the mask with the same matrix.
1698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
1708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void preConcatSamplerMatrices(StageMask stageMask, const GrMatrix& matrix) {
1718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert(!(stageMask & kIllegalStageMaskBits));
1728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        for (int i = 0; i < kNumStages; ++i) {
1738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if ((1 << i) & stageMask) {
1748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fSamplerStates[i].preConcatMatrix(matrix);
1758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
1768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
1778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
1788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
1808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
1828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Coverage / Color Stages
1838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
1848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
1868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * A common pattern is to compute a color with the initial stages and then
1878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * modulate that color by a coverage value in later stage(s) (AA, mask-
1888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * filters, glyph mask, etc). Color-filters, xfermodes, etc should be
1898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * computed based on the pre-coverage-modulated color. The division of
1908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * stages between color-computing and coverage-computing is specified by
1918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * this method. Initially this is kNumStages (all stages
1928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * are color-computing).
1938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
1948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setFirstCoverageStage(int firstCoverageStage) {
1958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((unsigned)firstCoverageStage <= kNumStages);
1968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fFirstCoverageStage = firstCoverageStage;
1978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
1988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
2008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Gets the index of the first coverage-computing stage.
2018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
2028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    int getFirstCoverageStage() const {
2038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return fFirstCoverageStage;
2048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
2058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///@}
2078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
2098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Blending
2108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
2118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
2138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the blending function coeffecients.
2148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
2158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * The blend function will be:
2168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *    D' = sat(S*srcCoef + D*dstCoef)
2178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
2188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *   where D is the existing destination color, S is the incoming source
2198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *   color, and D' is the new destination color that will be written. sat()
2208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *   is the saturation function.
2218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
2228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param srcCoef coeffecient applied to the src color.
2238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param dstCoef coeffecient applied to the dst color.
2248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
2258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
2268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fSrcBlend = srcCoeff;
2278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fDstBlend = dstCoeff;
2288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    #if GR_DEBUG
2298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        switch (dstCoeff) {
2308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        case kDC_BlendCoeff:
2318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        case kIDC_BlendCoeff:
2328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        case kDA_BlendCoeff:
2338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        case kIDA_BlendCoeff:
2348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
2358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                     "coverage stages.\n");
2368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
2378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        default:
2388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
2398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
2408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        switch (srcCoeff) {
2418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        case kSC_BlendCoeff:
2428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        case kISC_BlendCoeff:
2438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        case kSA_BlendCoeff:
2448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        case kISA_BlendCoeff:
2458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            GrPrintf("Unexpected src blend coeff. Won't work correctly with"
2468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                     "coverage stages.\n");
2478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
2488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        default:
2498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
2508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
2518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    #endif
2528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
2538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrBlendCoeff getSrcBlendCoeff() const { return fSrcBlend; }
2558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrBlendCoeff getDstBlendCoeff() const { return fDstBlend; }
2568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff,
2588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                          GrBlendCoeff* dstBlendCoeff) const {
2598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        *srcBlendCoeff = fSrcBlend;
2608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        *dstBlendCoeff = fDstBlend;
2618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
2628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
2648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the blending function constant referenced by the following blending
2658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * coeffecients:
2668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *      kConstC_BlendCoeff
2678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *      kIConstC_BlendCoeff
2688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *      kConstA_BlendCoeff
2698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *      kIConstA_BlendCoeff
2708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
2718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param constant the constant to set
2728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
2738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setBlendConstant(GrColor constant) { fBlendConstant = constant; }
2748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
2768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Retrieves the last value set by setBlendConstant()
2778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return the blending constant value
2788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
2798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrColor getBlendConstant() const { return fBlendConstant; }
2808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
2828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
2848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name View Matrix
2858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
2868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
2888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the matrix applied to veretx positions.
2898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
2908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * In the post-view-matrix space the rectangle [0,w]x[0,h]
2918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * fully covers the render target. (w and h are the width and height of the
2928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * the rendertarget.)
2938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
2948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setViewMatrix(const GrMatrix& m) { fViewMatrix = m; }
2958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
2978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Gets a writable pointer to the view matrix.
2988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
2998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrMatrix* viewMatrix() { return &fViewMatrix; }
3008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Multiplies the current view matrix by a matrix
3038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  After this call V' = V*m where V is the old view matrix,
3058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  m is the parameter to this function, and V' is the new view matrix.
3068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  (We consider positions to be column vectors so position vector p is
3078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  transformed by matrix X as p' = X*p.)
3088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param m the matrix used to modify the view matrix.
3108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void preConcatViewMatrix(const GrMatrix& m) { fViewMatrix.preConcat(m); }
3128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Multiplies the current view matrix by a matrix
3158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  After this call V' = m*V where V is the old view matrix,
3178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  m is the parameter to this function, and V' is the new view matrix.
3188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  (We consider positions to be column vectors so position vector p is
3198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  transformed by matrix X as p' = X*p.)
3208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param m the matrix used to modify the view matrix.
3228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void postConcatViewMatrix(const GrMatrix& m) { fViewMatrix.postConcat(m); }
3248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Retrieves the current view matrix
3278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return the current view matrix.
3288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    const GrMatrix& getViewMatrix() const { return fViewMatrix; }
3308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Retrieves the inverse of the current view matrix.
3338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  If the current view matrix is invertible, return true, and if matrix
3358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  is non-null, copy the inverse into it. If the current view matrix is
3368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  non-invertible, return false and ignore the matrix parameter.
3378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param matrix if not null, will receive a copy of the current inverse.
3398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool getViewInverse(GrMatrix* matrix) const {
3418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // TODO: determine whether we really need to leave matrix unmodified
3428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // at call sites when inversion fails.
3438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrMatrix inverse;
3448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        if (fViewMatrix.invert(&inverse)) {
3458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (matrix) {
3468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                *matrix = inverse;
3478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
3488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            return true;
3498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
3508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return false;
3518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
3528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    class AutoViewMatrixRestore : public ::GrNoncopyable {
3548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    public:
3558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        AutoViewMatrixRestore() : fDrawState(NULL) {}
3568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        AutoViewMatrixRestore(GrDrawState* ds, const GrMatrix& newMatrix) {
3578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            fDrawState = NULL;
3588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            this->set(ds, newMatrix);
3598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
3608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        AutoViewMatrixRestore(GrDrawState* ds) {
3618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            fDrawState = NULL;
3628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            this->set(ds);
3638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
3648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        ~AutoViewMatrixRestore() {
3658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            this->set(NULL, GrMatrix::I());
3668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
3678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        void set(GrDrawState* ds, const GrMatrix& newMatrix) {
3688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (NULL != fDrawState) {
3698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fDrawState->setViewMatrix(fSavedMatrix);
3708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
3718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (NULL != ds) {
3728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fSavedMatrix = ds->getViewMatrix();
3738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                ds->setViewMatrix(newMatrix);
3748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
3758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            fDrawState = ds;
3768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
3778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        void set(GrDrawState* ds) {
3788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (NULL != fDrawState) {
3798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fDrawState->setViewMatrix(fSavedMatrix);
3808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
3818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (NULL != ds) {
3828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fSavedMatrix = ds->getViewMatrix();
3838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
3848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            fDrawState = ds;
3858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
3868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    private:
3878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrDrawState* fDrawState;
3888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrMatrix fSavedMatrix;
3899381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    };
3909381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
3918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
3928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
3948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Render Target
3958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
3968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the rendertarget used at the next drawing call
3998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param target  The render target to set.
4018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
4028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setRenderTarget(GrRenderTarget* target) { fRenderTarget = target; }
4038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Retrieves the currently set rendertarget.
4068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return    The currently set render target.
4088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
4098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    const GrRenderTarget* getRenderTarget() const { return fRenderTarget; }
4108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrRenderTarget* getRenderTarget() { return fRenderTarget; }
4118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    class AutoRenderTargetRestore : public ::GrNoncopyable {
4138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    public:
4148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        AutoRenderTargetRestore() : fDrawState(NULL) {}
4158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) {
4168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            fDrawState = NULL;
4178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            this->set(ds, newTarget);
4188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
4198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        ~AutoRenderTargetRestore() { this->set(NULL, NULL); }
4208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        void set(GrDrawState* ds, GrRenderTarget* newTarget) {
4218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (NULL != fDrawState) {
4228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fDrawState->setRenderTarget(fSavedTarget);
4238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
4248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (NULL != ds) {
4258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fSavedTarget = ds->getRenderTarget();
4268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                ds->setRenderTarget(newTarget);
4278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
4288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            fDrawState = ds;
4298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
4308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    private:
4318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrDrawState* fDrawState;
4328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrRenderTarget* fSavedTarget;
4338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    };
4348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
4368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
4388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Stencil
4398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
4408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the stencil settings to use for the next draw.
4438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Changing the clip has the side-effect of possibly zeroing
4448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * out the client settable stencil bits. So multipass algorithms
4458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * using stencil should not change the clip between passes.
4468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param settings  the stencil settings to use.
4478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
4488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setStencil(const GrStencilSettings& settings) {
4498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fStencilSettings = settings;
4508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
4518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Shortcut to disable stencil testing and ops.
4548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
4558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void disableStencil() {
4568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fStencilSettings.setDisabled();
4578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
4588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    const GrStencilSettings& getStencil() const { return fStencilSettings; }
4608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrStencilSettings* stencil() { return &fStencilSettings; }
4628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
4648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
4668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // @name Edge AA
4678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // There are two ways to perform antialiasing using edge equations. One
4688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // is to specify an (linear or quadratic) edge eq per-vertex. This requires
4698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // splitting vertices shared by primitives.
4708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    //
4718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // The other is via setEdgeAAData which sets a set of edges and each
4728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // is tested against all the edges.
4738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
4748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4769381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * When specifying edges as vertex data this enum specifies what type of
4779381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * edges are in use. The edges are always 4 GrScalars in memory, even when
4789381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * the edge type requires fewer than 4.
4799381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     */
4809381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    enum VertexEdgeType {
4819381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        /* 1-pixel wide line
4829381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com           2D implicit line eq (a*x + b*y +c = 0). 4th component unused */
4839381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        kHairLine_EdgeType,
4849381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        /* 1-pixel wide quadratic
4859381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com           u^2-v canonical coords (only 2 components used) */
4869381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        kHairQuad_EdgeType
4879381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    };
4889381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
4899381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    /**
4908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Determines the interpretation per-vertex edge data when the
4918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * kEdge_VertexLayoutBit is set (see GrDrawTarget). When per-vertex edges
4928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * are not specified the value of this setting has no effect.
4938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
4948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setVertexEdgeType(VertexEdgeType type) {
4958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fVertexEdgeType = type;
4968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
4978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    VertexEdgeType getVertexEdgeType() const {
4998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return fVertexEdgeType;
5008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
5018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
5039381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * The absolute maximum number of edges that may be specified for
5049381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * a single draw call when performing edge antialiasing.  This is used for
5059381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * the size of several static buffers, so implementations of getMaxEdges()
5069381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * (below) should clamp to this value.
5079381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     */
5089381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    enum {
50962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        // TODO: this should be 32 when GrTesselatedPathRenderer is used
51062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        // Visual Studio 2010 does not permit a member array of size 0.
51162b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        kMaxEdges = 1
5129381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    };
5139381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
5149381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    class Edge {
5159381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com      public:
5169381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        Edge() {}
5179381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        Edge(float x, float y, float z) : fX(x), fY(y), fZ(z) {}
5189381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        GrPoint intersect(const Edge& other) {
5199381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com            return GrPoint::Make(
52072e49b8982586a5d8b0425f16d909c05a36ea8c3bsalomon@google.com                SkFloatToScalar((fY * other.fZ - other.fY * fZ) /
52172e49b8982586a5d8b0425f16d909c05a36ea8c3bsalomon@google.com                                (fX * other.fY - other.fX * fY)),
52272e49b8982586a5d8b0425f16d909c05a36ea8c3bsalomon@google.com                SkFloatToScalar((fX * other.fZ - other.fX * fZ) /
52372e49b8982586a5d8b0425f16d909c05a36ea8c3bsalomon@google.com                                (other.fX * fY - fX * other.fY)));
5249381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        }
5259381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        float fX, fY, fZ;
5269381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    };
5279381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
5288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
5298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the edge data required for edge antialiasing.
5308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
5318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param edges       3 * numEdges float values, representing the edge
5328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *                    equations in Ax + By + C form
5338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
5348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setEdgeAAData(const Edge* edges, int numEdges) {
5358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert(numEdges <= GrDrawState::kMaxEdges);
5368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        memcpy(fEdgeAAEdges, edges, numEdges * sizeof(GrDrawState::Edge));
5378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fEdgeAANumEdges = numEdges;
5388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
5390fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
5408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    int getNumAAEdges() const { return fEdgeAANumEdges; }
5410fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
5428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    const Edge* getAAEdges() const { return fEdgeAAEdges; }
5438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
5458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
5478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name State Flags
5488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
5498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
5518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Flags that affect rendering. Controlled using enable/disableState(). All
5528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  default to disabled.
5538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
5548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    enum StateBits {
5558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
5568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Perform dithering. TODO: Re-evaluate whether we need this bit
5578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
5588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kDither_StateBit        = 0x01,
5598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
5608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Perform HW anti-aliasing. This means either HW FSAA, if supported
5618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * by the render target, or smooth-line rendering if a line primitive
5628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * is drawn and line smoothing is supported by the 3D API.
5638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
5648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kHWAntialias_StateBit   = 0x02,
5658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
5668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Draws will respect the clip, otherwise the clip is ignored.
5678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
5688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kClip_StateBit          = 0x04,
5698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
5708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Disables writing to the color buffer. Useful when performing stencil
5718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * operations.
5728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
5738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kNoColorWrites_StateBit = 0x08,
5748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
5758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Modifies the behavior of edge AA specified by setEdgeAA. If set,
5768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * will test edge pairs for convexity when rasterizing. Set this if the
5778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * source polygon is non-convex.
5788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
5798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kEdgeAAConcave_StateBit = 0x10,
5808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // Users of the class may add additional bits to the vector
5828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kDummyStateBit,
5838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kLastPublicStateBit = kDummyStateBit-1,
5848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    };
5858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void resetStateFlags() {
5878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fFlagBits = 0;
5880fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
5890fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
5908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
5918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Enable render state settings.
5928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
5938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param flags   bitfield of StateBits specifing the states to enable
5948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
5958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void enableState(uint32_t stateBits) {
5968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fFlagBits |= stateBits;
5978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
5980fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
5998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
6008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Disable render state settings.
6018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
6028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param flags   bitfield of StateBits specifing the states to disable
6038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
6048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void disableState(uint32_t stateBits) {
6058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fFlagBits &= ~(stateBits);
6068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6070fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
6088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isDitherState() const {
6098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return 0 != (fFlagBits & kDither_StateBit);
6108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6110fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
6128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isHWAntialiasState() const {
6138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return 0 != (fFlagBits & kHWAntialias_StateBit);
6148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6150fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
6168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isClipState() const {
6178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return 0 != (fFlagBits & kClip_StateBit);
6188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6190fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
6208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isColorWriteDisabled() const {
6218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return 0 != (fFlagBits & kNoColorWrites_StateBit);
6228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isConcaveEdgeAAState() const {
6258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return 0 != (fFlagBits & kEdgeAAConcave_StateBit);
6268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isStateFlagEnabled(uint32_t stateBit) const {
6298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return 0 != (stateBit & fFlagBits);
6308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void copyStateFlags(const GrDrawState& ds) {
6338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fFlagBits = ds.fFlagBits;
6348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
6378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
6398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Face Culling
6408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
6418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    enum DrawFace {
6438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kBoth_DrawFace,
6448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kCCW_DrawFace,
6458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kCW_DrawFace,
6468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    };
6478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
6498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Controls whether clockwise, counterclockwise, or both faces are drawn.
6508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param face  the face(s) to draw.
6518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
6528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setDrawFace(DrawFace face) {
6538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fDrawFace = face;
6548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
6578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Gets whether the target is drawing clockwise, counterclockwise,
6588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * or both faces.
6598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return the current draw face(s).
6608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
6618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    DrawFace getDrawFace() const {
6628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return fDrawFace;
6638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
6668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
66862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
66962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    // Most stages are usually not used, so conditionals here
67062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    // reduce the expected number of bytes touched by 50%.
6719381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    bool operator ==(const GrDrawState& s) const {
67262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        if (memcmp(this, &s, this->leadingBytes())) return false;
67362b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
67462b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        for (int i = 0; i < kNumStages; i++) {
67562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com            if (fTextures[i] &&
6763d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com                memcmp(&this->fSamplerStates[i], &s.fSamplerStates[i],
67762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com                       sizeof(GrSamplerState))) {
67862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com                return false;
67962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com            }
68062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        }
68162b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
68262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        return true;
6839381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    }
6849381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    bool operator !=(const GrDrawState& s) const { return !(*this == s); }
68562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
68662b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    // Most stages are usually not used, so conditionals here
68762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    // reduce the expected number of bytes touched by 50%.
68862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    GrDrawState& operator =(const GrDrawState& s) {
68962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        memcpy(this, &s, this->leadingBytes());
69062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
69162b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        for (int i = 0; i < kNumStages; i++) {
69262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com            if (s.fTextures[i]) {
6933d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com                memcpy(&this->fSamplerStates[i], &s.fSamplerStates[i],
69462b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com                       sizeof(GrSamplerState));
69562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com            }
69662b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        }
69762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
69862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        return *this;
69962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    }
70062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
70162b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.comprivate:
7028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    static const StageMask kIllegalStageMaskBits = ~((1 << kNumStages)-1);
7038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    uint8_t                 fFlagBits;
7048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrBlendCoeff            fSrcBlend : 8;
7058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrBlendCoeff            fDstBlend : 8;
7068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    DrawFace                fDrawFace : 8;
7078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    uint8_t                 fFirstCoverageStage;
7088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    SkXfermode::Mode        fColorFilterMode : 8;
7098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrColor                 fBlendConstant;
7108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrTexture*              fTextures[kNumStages];
7118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrRenderTarget*         fRenderTarget;
7128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrColor                 fColor;
7138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrColor                 fColorFilterColor;
7148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrStencilSettings       fStencilSettings;
7158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrMatrix                fViewMatrix;
7168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // @{ Data for GrTesselatedPathRenderer
7178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // TODO: currently ignored in copying & comparison for performance.
7188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // Must be considered if GrTesselatedPathRenderer is being used.
7198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    VertexEdgeType          fVertexEdgeType;
7218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    int                     fEdgeAANumEdges;
7228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    Edge                    fEdgeAAEdges[kMaxEdges];
7238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // @}
7258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // This field must be last; it will not be copied or compared
7268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // if the corresponding fTexture[] is NULL.
7278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrSamplerState          fSamplerStates[kNumStages];
7288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
72962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    size_t leadingBytes() const {
73062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        // Can't use offsetof() with non-POD types, so stuck with pointer math.
73162b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        // TODO: ignores GrTesselatedPathRenderer data structures. We don't
73262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        // have a compile-time flag that lets us know if it's being used, and
73362b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        // checking at runtime seems to cost 5% performance.
73462b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        return (size_t) ((unsigned char*)&fEdgeAANumEdges -
73562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com                         (unsigned char*)&fFlagBits);
73662b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    }
73762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
7389381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com};
7399381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
7409381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#endif
741