GrPipelineBuilder.h revision 52a5dcb43b5acbde377f664807b0f75af8bb1666
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() {
5052a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        this->reset();
5152a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    }
5252a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com
5352a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    /**
5452a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com     * Resets to the default state. Sampler states will not be modified.
5552a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com     */
5652a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    void reset() {
578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // make sure any pad is zero for memcmp
5852a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        // all GrDrawState members should default to something valid by the
5952a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        // the memset except those initialized individually below. There should
6052a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        // be no padding between the individually initialized members.
6152a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        static const size_t kMemsetSize =
6252a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com            reinterpret_cast<intptr_t>(&fColor) -
6352a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com            reinterpret_cast<intptr_t>(this);
6452a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        memset(this, 0, kMemsetSize);
658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // pedantic assertion that our ptrs will
668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // be NULL (0 ptr is mem addr 0)
678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((intptr_t)(void*)NULL == 0LL);
6852a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        GR_STATIC_ASSERT(0 == kBoth_DrawFace);
698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert(fStencilSettings.isDisabled());
7052a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com
7152a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        // memset exceptions
7252a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        fColor = 0xffffffff;
738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fFirstCoverageStage = kNumStages;
7452a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        fColorFilterMode = SkXfermode::kDst_Mode;
7552a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        fSrcBlend = kOne_BlendCoeff;
7652a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        fDstBlend = kZero_BlendCoeff;
7752a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        fViewMatrix.reset();
7852a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com
7952a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        // ensure values that will be memcmp'ed in == but not memset in reset()
8052a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        // are tightly packed
8152a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        GrAssert(kMemsetSize + + sizeof(fColorMatrix) + sizeof(fRenderTarget) +
8252a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com                 sizeof(fColor) + sizeof(fFirstCoverageStage) +
8352a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com                 sizeof(fColorFilterMode) + sizeof(fSrcBlend) +
8452a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com                 sizeof(fDstBlend) + sizeof(GrMatrix) ==
8552a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com                 reinterpret_cast<intptr_t>(&fEdgeAANumEdges) -
8652a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com                 reinterpret_cast<intptr_t>(this));
8752a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com
8852a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com        fEdgeAANumEdges = 0;
898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Color
938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Sets color for next draw to a premultiplied-alpha color.
978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param color    the color to set.
998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
1008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setColor(GrColor color) { fColor = color; }
1018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrColor getColor() const { return fColor; }
1038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
1058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Sets the color to be used for the next draw to be
1068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  (r,g,b,a) = (alpha, alpha, alpha, alpha).
1078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
1088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param alpha The alpha value to set as the color.
1098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
1108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setAlpha(uint8_t a) {
1118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        this->setColor((a << 24) | (a << 16) | (a << 8) | a);
1128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
1138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
1158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Add a color filter that can be represented by a color and a mode. Applied
1168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * after color-computing texture stages.
1178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
1188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setColorFilter(GrColor c, SkXfermode::Mode mode) {
1198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fColorFilterColor = c;
1208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fColorFilterMode = mode;
1218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
1228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrColor getColorFilterColor() const { return fColorFilterColor; }
1248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    SkXfermode::Mode getColorFilterMode() const { return fColorFilterMode; }
1258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
1278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
1298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Textures
1308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
1318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
1338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the texture used at the next drawing call
1348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
1358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param stage The texture stage for which the texture will be set
1368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
1378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param texture The texture to set. Can be NULL though there is no
1388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * advantage to settings a NULL texture if doing non-textured drawing
1398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
1408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setTexture(int stage, GrTexture* texture) {
1418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((unsigned)stage < kNumStages);
1428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fTextures[stage] = texture;
1438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
1448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
1468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Retrieves the currently set texture.
1478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
1488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return    The currently set texture. The return value will be NULL if no
1498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *            texture has been set, NULL was most recently passed to
1508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *            setTexture, or the last setTexture was destroyed.
1518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
1528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    const GrTexture* getTexture(int stage) const {
1538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((unsigned)stage < kNumStages);
1548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return fTextures[stage];
1558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
1568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrTexture* getTexture(int stage) {
1578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((unsigned)stage < kNumStages);
1588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return fTextures[stage];
1598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
1608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
1628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
1648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Samplers
1658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
1668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
1688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Returns the current sampler for a stage.
1698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
1708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    const GrSamplerState& getSampler(int stage) const {
1718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((unsigned)stage < kNumStages);
1728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return fSamplerStates[stage];
1738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
1748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
1768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Writable pointer to a stage's sampler.
1778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
1788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrSamplerState* sampler(int stage) {
1798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((unsigned)stage < kNumStages);
1808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return fSamplerStates + stage;
1818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
1828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
1848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Preconcats the matrix of all samplers in the mask with the same matrix.
1858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
1868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void preConcatSamplerMatrices(StageMask stageMask, const GrMatrix& matrix) {
1878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert(!(stageMask & kIllegalStageMaskBits));
1888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        for (int i = 0; i < kNumStages; ++i) {
1898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if ((1 << i) & stageMask) {
1908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fSamplerStates[i].preConcatMatrix(matrix);
1918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
1928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
1938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
1948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
1968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
1978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
1988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Coverage / Color Stages
1998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
2008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
2028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * A common pattern is to compute a color with the initial stages and then
2038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * modulate that color by a coverage value in later stage(s) (AA, mask-
2048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * filters, glyph mask, etc). Color-filters, xfermodes, etc should be
2058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * computed based on the pre-coverage-modulated color. The division of
2068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * stages between color-computing and coverage-computing is specified by
2078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * this method. Initially this is kNumStages (all stages
2088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * are color-computing).
2098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
2108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setFirstCoverageStage(int firstCoverageStage) {
2118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert((unsigned)firstCoverageStage <= kNumStages);
2128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fFirstCoverageStage = firstCoverageStage;
2138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
2148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
2168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Gets the index of the first coverage-computing stage.
2178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
2188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    int getFirstCoverageStage() const {
2198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return fFirstCoverageStage;
2208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
2218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///@}
2238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
2258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Blending
2268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
2278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
2298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the blending function coeffecients.
2308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
2318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * The blend function will be:
2328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *    D' = sat(S*srcCoef + D*dstCoef)
2338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
2348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *   where D is the existing destination color, S is the incoming source
2358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *   color, and D' is the new destination color that will be written. sat()
2368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *   is the saturation function.
2378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
2388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param srcCoef coeffecient applied to the src color.
2398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param dstCoef coeffecient applied to the dst color.
2408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
2418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
2428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fSrcBlend = srcCoeff;
2438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fDstBlend = dstCoeff;
2448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    #if GR_DEBUG
2458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        switch (dstCoeff) {
2468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        case kDC_BlendCoeff:
2478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        case kIDC_BlendCoeff:
2488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        case kDA_BlendCoeff:
2498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        case kIDA_BlendCoeff:
2508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
2518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                     "coverage stages.\n");
2528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
2538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        default:
2548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
2558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
2568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        switch (srcCoeff) {
2578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        case kSC_BlendCoeff:
2588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        case kISC_BlendCoeff:
2598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        case kSA_BlendCoeff:
2608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        case kISA_BlendCoeff:
2618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            GrPrintf("Unexpected src blend coeff. Won't work correctly with"
2628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                     "coverage stages.\n");
2638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
2648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        default:
2658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            break;
2668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
2678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    #endif
2688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
2698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrBlendCoeff getSrcBlendCoeff() const { return fSrcBlend; }
2718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrBlendCoeff getDstBlendCoeff() const { return fDstBlend; }
2728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff,
2748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                          GrBlendCoeff* dstBlendCoeff) const {
2758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        *srcBlendCoeff = fSrcBlend;
2768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        *dstBlendCoeff = fDstBlend;
2778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
2788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
2808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the blending function constant referenced by the following blending
2818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * coeffecients:
2828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *      kConstC_BlendCoeff
2838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *      kIConstC_BlendCoeff
2848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *      kConstA_BlendCoeff
2858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *      kIConstA_BlendCoeff
2868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
2878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param constant the constant to set
2888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
2898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setBlendConstant(GrColor constant) { fBlendConstant = constant; }
2908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
2928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Retrieves the last value set by setBlendConstant()
2938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return the blending constant value
2948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
2958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrColor getBlendConstant() const { return fBlendConstant; }
2968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
2988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
2998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
3008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name View Matrix
3018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
3028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the matrix applied to veretx positions.
3058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * In the post-view-matrix space the rectangle [0,w]x[0,h]
3078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * fully covers the render target. (w and h are the width and height of the
3088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * the rendertarget.)
3098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setViewMatrix(const GrMatrix& m) { fViewMatrix = m; }
3118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Gets a writable pointer to the view matrix.
3148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrMatrix* viewMatrix() { return &fViewMatrix; }
3168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Multiplies the current view matrix by a matrix
3198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  After this call V' = V*m where V is the old view matrix,
3218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  m is the parameter to this function, and V' is the new view matrix.
3228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  (We consider positions to be column vectors so position vector p is
3238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  transformed by matrix X as p' = X*p.)
3248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param m the matrix used to modify the view matrix.
3268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void preConcatViewMatrix(const GrMatrix& m) { fViewMatrix.preConcat(m); }
3288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Multiplies the current view matrix by a matrix
3318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  After this call V' = m*V where V is the old view matrix,
3338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  m is the parameter to this function, and V' is the new view matrix.
3348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  (We consider positions to be column vectors so position vector p is
3358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  transformed by matrix X as p' = X*p.)
3368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  @param m the matrix used to modify the view matrix.
3388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void postConcatViewMatrix(const GrMatrix& m) { fViewMatrix.postConcat(m); }
3408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Retrieves the current view matrix
3438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return the current view matrix.
3448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    const GrMatrix& getViewMatrix() const { return fViewMatrix; }
3468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
3488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Retrieves the inverse of the current view matrix.
3498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  If the current view matrix is invertible, return true, and if matrix
3518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  is non-null, copy the inverse into it. If the current view matrix is
3528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  non-invertible, return false and ignore the matrix parameter.
3538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
3548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param matrix if not null, will receive a copy of the current inverse.
3558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
3568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool getViewInverse(GrMatrix* matrix) const {
3578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // TODO: determine whether we really need to leave matrix unmodified
3588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // at call sites when inversion fails.
3598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrMatrix inverse;
3608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        if (fViewMatrix.invert(&inverse)) {
3618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (matrix) {
3628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                *matrix = inverse;
3638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
3648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            return true;
3658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
3668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return false;
3678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
3688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
3698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    class AutoViewMatrixRestore : public ::GrNoncopyable {
3708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    public:
3718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        AutoViewMatrixRestore() : fDrawState(NULL) {}
3728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        AutoViewMatrixRestore(GrDrawState* ds, const GrMatrix& newMatrix) {
3738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            fDrawState = NULL;
3748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            this->set(ds, newMatrix);
3758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
3768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        AutoViewMatrixRestore(GrDrawState* ds) {
3778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            fDrawState = NULL;
3788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            this->set(ds);
3798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
3808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        ~AutoViewMatrixRestore() {
3818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            this->set(NULL, GrMatrix::I());
3828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
3838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        void set(GrDrawState* ds, const GrMatrix& newMatrix) {
3848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (NULL != fDrawState) {
3858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fDrawState->setViewMatrix(fSavedMatrix);
3868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
3878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (NULL != ds) {
3888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fSavedMatrix = ds->getViewMatrix();
3898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                ds->setViewMatrix(newMatrix);
3908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
3918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            fDrawState = ds;
3928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
3938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        void set(GrDrawState* ds) {
3948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (NULL != fDrawState) {
3958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fDrawState->setViewMatrix(fSavedMatrix);
3968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
3978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (NULL != ds) {
3988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fSavedMatrix = ds->getViewMatrix();
3998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
4008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            fDrawState = ds;
4018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
4028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    private:
4038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrDrawState* fDrawState;
4048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrMatrix fSavedMatrix;
4059381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    };
4069381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
4078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
4088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
4108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Render Target
4118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
4128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the rendertarget used at the next drawing call
4158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param target  The render target to set.
4178f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
4188f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setRenderTarget(GrRenderTarget* target) { fRenderTarget = target; }
4198f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4208f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4218f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Retrieves the currently set rendertarget.
4228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
4238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return    The currently set render target.
4248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
4258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    const GrRenderTarget* getRenderTarget() const { return fRenderTarget; }
4268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrRenderTarget* getRenderTarget() { return fRenderTarget; }
4278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    class AutoRenderTargetRestore : public ::GrNoncopyable {
4298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    public:
430cadbcb8e536f89babb4e165bfdca18384e97d582bsalomon@google.com        AutoRenderTargetRestore() : fDrawState(NULL), fSavedTarget(NULL) {}
4318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) {
4328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            fDrawState = NULL;
4338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            this->set(ds, newTarget);
4348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
4358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        ~AutoRenderTargetRestore() { this->set(NULL, NULL); }
4368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        void set(GrDrawState* ds, GrRenderTarget* newTarget) {
4378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (NULL != fDrawState) {
4388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fDrawState->setRenderTarget(fSavedTarget);
4398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
4408f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            if (NULL != ds) {
4418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                fSavedTarget = ds->getRenderTarget();
4428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com                ds->setRenderTarget(newTarget);
4438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            }
4448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com            fDrawState = ds;
4458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        }
4468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    private:
4478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrDrawState* fDrawState;
4488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrRenderTarget* fSavedTarget;
4498f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    };
4508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
4528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4538f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
4548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Stencil
4558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
4568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4578f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the stencil settings to use for the next draw.
4598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Changing the clip has the side-effect of possibly zeroing
4608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * out the client settable stencil bits. So multipass algorithms
4618f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * using stencil should not change the clip between passes.
4628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param settings  the stencil settings to use.
4638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
4648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setStencil(const GrStencilSettings& settings) {
4658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fStencilSettings = settings;
4668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
4678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
4698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Shortcut to disable stencil testing and ops.
4708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
4718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void disableStencil() {
4728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fStencilSettings.setDisabled();
4738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
4748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    const GrStencilSettings& getStencil() const { return fStencilSettings; }
4768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    GrStencilSettings* stencil() { return &fStencilSettings; }
4788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
4808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
4818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
48250bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org    /// @name Color Matrix
48350bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org    ////
48450bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org
48550bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org    /**
48650bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org     * Sets the color matrix to use for the next draw.
48750bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org     * @param matrix  the 5x4 matrix to apply to the incoming color
48850bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org     */
48950bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org    void setColorMatrix(const float matrix[20]) {
49050bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org        memcpy(fColorMatrix, matrix, sizeof(fColorMatrix));
49150bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org    }
49250bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org
49350bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org    const float* getColorMatrix() const { return fColorMatrix; }
49450bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org
49550bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org    /// @}
49650bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org
49750bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org    ///////////////////////////////////////////////////////////////////////////
4988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // @name Edge AA
4998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // There are two ways to perform antialiasing using edge equations. One
5008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // is to specify an (linear or quadratic) edge eq per-vertex. This requires
5018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // splitting vertices shared by primitives.
5028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    //
5038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // The other is via setEdgeAAData which sets a set of edges and each
5048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // is tested against all the edges.
5058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
5068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
5089381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * When specifying edges as vertex data this enum specifies what type of
5099381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * edges are in use. The edges are always 4 GrScalars in memory, even when
5109381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * the edge type requires fewer than 4.
5119381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     */
5129381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    enum VertexEdgeType {
5139381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        /* 1-pixel wide line
5149381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com           2D implicit line eq (a*x + b*y +c = 0). 4th component unused */
5159381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        kHairLine_EdgeType,
51669cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com        /* Quadratic specified by u^2-v canonical coords (only 2
51769cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com           components used). Coverage based on signed distance with negative
51869cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com           being inside, positive outside.*/
51969cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com        kQuad_EdgeType,
52069cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com        /* Same as above but for hairline quadratics. Uses unsigned distance.
52169cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com           Coverage is min(0, 1-distance). */
52269cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com        kHairQuad_EdgeType,
52369cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com
52469cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com        kVertexEdgeTypeCnt
5259381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    };
5269381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
5279381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    /**
5288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Determines the interpretation per-vertex edge data when the
5298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * kEdge_VertexLayoutBit is set (see GrDrawTarget). When per-vertex edges
5308f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * are not specified the value of this setting has no effect.
5318f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
5328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setVertexEdgeType(VertexEdgeType type) {
53369cc6ad20ed03f35f9d3c8119a2c32187669a22bbsalomon@google.com        GrAssert(type >=0 && type < kVertexEdgeTypeCnt);
5348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fVertexEdgeType = type;
5358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
5368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
53752a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    VertexEdgeType getVertexEdgeType() const { return fVertexEdgeType; }
5388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
5409381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * The absolute maximum number of edges that may be specified for
5419381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * a single draw call when performing edge antialiasing.  This is used for
5429381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * the size of several static buffers, so implementations of getMaxEdges()
5439381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * (below) should clamp to this value.
5449381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     */
5459381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    enum {
54662b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        // TODO: this should be 32 when GrTesselatedPathRenderer is used
54762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        // Visual Studio 2010 does not permit a member array of size 0.
54862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        kMaxEdges = 1
5499381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    };
5509381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
5519381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    class Edge {
5529381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com      public:
5539381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        Edge() {}
5549381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        Edge(float x, float y, float z) : fX(x), fY(y), fZ(z) {}
5559381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        GrPoint intersect(const Edge& other) {
5569381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com            return GrPoint::Make(
55772e49b8982586a5d8b0425f16d909c05a36ea8c3bsalomon@google.com                SkFloatToScalar((fY * other.fZ - other.fY * fZ) /
55872e49b8982586a5d8b0425f16d909c05a36ea8c3bsalomon@google.com                                (fX * other.fY - other.fX * fY)),
55972e49b8982586a5d8b0425f16d909c05a36ea8c3bsalomon@google.com                SkFloatToScalar((fX * other.fZ - other.fX * fZ) /
56072e49b8982586a5d8b0425f16d909c05a36ea8c3bsalomon@google.com                                (other.fX * fY - fX * other.fY)));
5619381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        }
5629381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        float fX, fY, fZ;
5639381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    };
5649381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
5658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
5668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Sets the edge data required for edge antialiasing.
5678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
5688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param edges       3 * numEdges float values, representing the edge
5698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *                    equations in Ax + By + C form
5708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
5718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setEdgeAAData(const Edge* edges, int numEdges) {
5728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        GrAssert(numEdges <= GrDrawState::kMaxEdges);
5738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        memcpy(fEdgeAAEdges, edges, numEdges * sizeof(GrDrawState::Edge));
5748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fEdgeAANumEdges = numEdges;
5758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
5760fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
5778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    int getNumAAEdges() const { return fEdgeAANumEdges; }
5780fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
5798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    const Edge* getAAEdges() const { return fEdgeAAEdges; }
5808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
5828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
5848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name State Flags
5858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
5868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
5878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
5888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  Flags that affect rendering. Controlled using enable/disableState(). All
5898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *  default to disabled.
5908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
5918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    enum StateBits {
5928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
5938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Perform dithering. TODO: Re-evaluate whether we need this bit
5948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
5958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kDither_StateBit        = 0x01,
5968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
5978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Perform HW anti-aliasing. This means either HW FSAA, if supported
5988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * by the render target, or smooth-line rendering if a line primitive
5998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * is drawn and line smoothing is supported by the 3D API.
6008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
6018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kHWAntialias_StateBit   = 0x02,
6028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
6038f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Draws will respect the clip, otherwise the clip is ignored.
6048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
6058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kClip_StateBit          = 0x04,
6068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
6078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Disables writing to the color buffer. Useful when performing stencil
6088f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * operations.
6098f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
6108f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kNoColorWrites_StateBit = 0x08,
6118f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        /**
6128f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * Modifies the behavior of edge AA specified by setEdgeAA. If set,
6138f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * will test edge pairs for convexity when rasterizing. Set this if the
6148f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         * source polygon is non-convex.
6158f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com         */
6168f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kEdgeAAConcave_StateBit = 0x10,
61750bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org        /**
61850bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org         * Draws will apply the color matrix, otherwise the color matrix is
61950bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org         * ignored.
62050bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org         */
62150bdad85db2fe6be4d0bf0c5b6473f712b1bdd32senorblanco@chromium.org        kColorMatrix_StateBit   = 0x20,
6228f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6238f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        // Users of the class may add additional bits to the vector
6248f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kDummyStateBit,
6258f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kLastPublicStateBit = kDummyStateBit-1,
6268f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    };
6278f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6288f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void resetStateFlags() {
6298f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fFlagBits = 0;
6300fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
6310fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
6328f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
6338f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Enable render state settings.
6348f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
6358f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param flags   bitfield of StateBits specifing the states to enable
6368f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
6378f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void enableState(uint32_t stateBits) {
6388f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fFlagBits |= stateBits;
6398f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6400fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
6418f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
6428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Disable render state settings.
6438f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     *
6448f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param flags   bitfield of StateBits specifing the states to disable
6458f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
6468f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void disableState(uint32_t stateBits) {
6478f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fFlagBits &= ~(stateBits);
6488f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6490fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
6508f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isDitherState() const {
6518f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return 0 != (fFlagBits & kDither_StateBit);
6528f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6530fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
6548f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isHWAntialiasState() const {
6558f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return 0 != (fFlagBits & kHWAntialias_StateBit);
6568f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6570fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
6588f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isClipState() const {
6598f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return 0 != (fFlagBits & kClip_StateBit);
6608f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6610fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
6628f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isColorWriteDisabled() const {
6638f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return 0 != (fFlagBits & kNoColorWrites_StateBit);
6648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isConcaveEdgeAAState() const {
6678f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return 0 != (fFlagBits & kEdgeAAConcave_StateBit);
6688f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6708f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    bool isStateFlagEnabled(uint32_t stateBit) const {
6718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        return 0 != (stateBit & fFlagBits);
6728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6738f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void copyStateFlags(const GrDrawState& ds) {
6758f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fFlagBits = ds.fFlagBits;
6768f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6778f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6788f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
6798f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6808f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
6818f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @name Face Culling
6828f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ////
6838f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6848f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    enum DrawFace {
6858f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kBoth_DrawFace,
6868f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kCCW_DrawFace,
6878f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        kCW_DrawFace,
6888f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    };
6898f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6908f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
6918f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Controls whether clockwise, counterclockwise, or both faces are drawn.
6928f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @param face  the face(s) to draw.
6938f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
6948f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    void setDrawFace(DrawFace face) {
6958f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com        fDrawFace = face;
6968f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    }
6978f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
6988f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /**
6998f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * Gets whether the target is drawing clockwise, counterclockwise,
7008f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * or both faces.
7018f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     * @return the current draw face(s).
7028f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com     */
70352a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    DrawFace getDrawFace() const { return fDrawFace; }
7048f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7058f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    /// @}
7068f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
7078f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
70862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
70962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    // Most stages are usually not used, so conditionals here
71062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    // reduce the expected number of bytes touched by 50%.
7119381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    bool operator ==(const GrDrawState& s) const {
71262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        if (memcmp(this, &s, this->leadingBytes())) return false;
71362b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
71462b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        for (int i = 0; i < kNumStages; i++) {
71562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com            if (fTextures[i] &&
7163d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com                memcmp(&this->fSamplerStates[i], &s.fSamplerStates[i],
71762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com                       sizeof(GrSamplerState))) {
71862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com                return false;
71962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com            }
72062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        }
72162b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
72262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        return true;
7239381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    }
7249381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    bool operator !=(const GrDrawState& s) const { return !(*this == s); }
72562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
72662b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    // Most stages are usually not used, so conditionals here
72762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    // reduce the expected number of bytes touched by 50%.
72862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    GrDrawState& operator =(const GrDrawState& s) {
72962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        memcpy(this, &s, this->leadingBytes());
73062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
73162b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        for (int i = 0; i < kNumStages; i++) {
73262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com            if (s.fTextures[i]) {
7333d0835b6ac0003c18147b6e9ca76a497b92d1d40bsalomon@google.com                memcpy(&this->fSamplerStates[i], &s.fSamplerStates[i],
73462b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com                       sizeof(GrSamplerState));
73562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com            }
73662b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        }
73762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
73862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        return *this;
73962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    }
74062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
74162b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.comprivate:
7428f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    static const StageMask kIllegalStageMaskBits = ~((1 << kNumStages)-1);
74352a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    // @{ these fields can be initialized with memset to 0
74452a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    GrColor             fBlendConstant;
74552a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    GrTexture*          fTextures[kNumStages];
74652a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    GrColor             fColorFilterColor;
74752a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    uint32_t            fFlagBits;
74852a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    DrawFace            fDrawFace;
74952a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    VertexEdgeType      fVertexEdgeType;
75052a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    GrStencilSettings   fStencilSettings;
75152a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    float               fColorMatrix[20];       // 5 x 4 matrix
75252a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    GrRenderTarget*     fRenderTarget;
75352a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    // @}
75452a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com
75552a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    // @{ Initialized to values other than zero
75652a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    GrColor             fColor;
75752a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    int                 fFirstCoverageStage;
75852a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    SkXfermode::Mode    fColorFilterMode;
75952a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    GrBlendCoeff        fSrcBlend;
76052a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    GrBlendCoeff        fDstBlend;
76152a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    GrMatrix            fViewMatrix;
76252a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    // @}
76352a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com
7648f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // @{ Data for GrTesselatedPathRenderer
7658f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // TODO: currently ignored in copying & comparison for performance.
7668f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // Must be considered if GrTesselatedPathRenderer is being used.
76752a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    int                 fEdgeAANumEdges;
76852a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    Edge                fEdgeAAEdges[kMaxEdges];
7698f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // @}
77052a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com
7718f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // This field must be last; it will not be copied or compared
7728f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com    // if the corresponding fTexture[] is NULL.
77352a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com    GrSamplerState      fSamplerStates[kNumStages];
7748f9cbd62ec108d410b91155dcf6a4789c641246fbsalomon@google.com
77562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    size_t leadingBytes() const {
77662b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        // Can't use offsetof() with non-POD types, so stuck with pointer math.
77762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        // TODO: ignores GrTesselatedPathRenderer data structures. We don't
77862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        // have a compile-time flag that lets us know if it's being used, and
77962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        // checking at runtime seems to cost 5% performance.
78062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        return (size_t) ((unsigned char*)&fEdgeAANumEdges -
78152a5dcb43b5acbde377f664807b0f75af8bb1666bsalomon@google.com                         (unsigned char*)&fBlendConstant);
78262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    }
78362b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
7849381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com};
7859381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
7869381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#endif
787