GrDrawState.h revision 0fec61d19ca9088d54f58bd0a67150171b83d66c
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"
130fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@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
490fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    GrDrawState() {
500fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        // make sure any pad is zero for memcmp
510fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        // all GrDrawState members should default to something
520fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        // valid by the memset
530fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        memset(this, 0, sizeof(GrDrawState));
540fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
550fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        // memset exceptions
560fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        fColorFilterMode = SkXfermode::kDstIn_Mode;
570fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        fFirstCoverageStage = kNumStages;
580fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
590fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        // pedantic assertion that our ptrs will
600fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        // be NULL (0 ptr is mem addr 0)
610fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        GrAssert((intptr_t)(void*)NULL == 0LL);
620fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
630fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        GrAssert(fStencilSettings.isDisabled());
640fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        fFirstCoverageStage = kNumStages;
650fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
660fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
670fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
680fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /// @name Color
690fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    ////
700fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
710fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
720fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *  Sets color for next draw to a premultiplied-alpha color.
730fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *
740fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *  @param color    the color to set.
750fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     */
760fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    void setColor(GrColor color) { fColor = color; }
770fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
780fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    GrColor getColor() const { return fColor; }
790fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
800fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
810fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *  Sets the color to be used for the next draw to be
820fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *  (r,g,b,a) = (alpha, alpha, alpha, alpha).
830fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *
840fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *  @param alpha The alpha value to set as the color.
850fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     */
860fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    void setAlpha(uint8_t a) {
870fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        this->setColor((a << 24) | (a << 16) | (a << 8) | a);
880fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
890fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
900fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
910fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * Add a color filter that can be represented by a color and a mode. Applied
920fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * after color-computing texture stages.
930fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     */
940fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    void setColorFilter(GrColor c, SkXfermode::Mode mode) {
950fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        fColorFilterColor = c;
960fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        fColorFilterMode = mode;
970fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
980fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
990fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    GrColor getColorFilterColor() const { return fColorFilterColor; }
1000fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    SkXfermode::Mode getColorFilterMode() const { return fColorFilterMode; }
1010fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
1020fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /// @}
1030fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
1040fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
1050fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /// @name Textures
1060fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    ////
1070fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
1080fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
1090fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * Sets the texture used at the next drawing call
1100fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *
1110fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * @param stage The texture stage for which the texture will be set
1120fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *
1130fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * @param texture The texture to set. Can be NULL though there is no
1140fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * advantage to settings a NULL texture if doing non-textured drawing
1150fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     */
1160fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    void setTexture(int stage, GrTexture* texture) {
1170fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        GrAssert((unsigned)stage < kNumStages);
1180fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        fTextures[stage] = texture;
1190fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
1200fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
1210fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
1220fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * Retrieves the currently set texture.
1230fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *
1240fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * @return    The currently set texture. The return value will be NULL if no
1250fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *            texture has been set, NULL was most recently passed to
1260fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *            setTexture, or the last setTexture was destroyed.
1270fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     */
1280fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    const GrTexture* getTexture(int stage) const {
1290fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        GrAssert((unsigned)stage < kNumStages);
1300fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        return fTextures[stage];
1310fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
1320fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    GrTexture* getTexture(int stage) {
1330fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        GrAssert((unsigned)stage < kNumStages);
1340fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        return fTextures[stage];
1350fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
1360fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
1370fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /// @}
1380fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
1390fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
1400fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /// @name Samplers
1410fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    ////
1420fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
1430fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
1440fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * Returns the current sampler for a stage.
1450fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     */
1460fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    const GrSamplerState& getSampler(int stage) const {
1470fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        GrAssert((unsigned)stage < kNumStages);
1480fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        return fSamplers[stage];
1490fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
1500fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
1510fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
1520fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * Writable pointer to a stage's sampler.
1530fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     */
1540fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    GrSamplerState* sampler(int stage) {
1550fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        GrAssert((unsigned)stage < kNumStages);
1560fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        return fSamplers + stage;
1570fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
1580fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
1590fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
1600fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * Preconcats the matrix of all samplers in the mask with the same matrix.
1610fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     */
1620fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    void preConcatSamplerMatrices(StageMask stageMask, const GrMatrix& matrix) {
1630fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        GrAssert(!(stageMask & kIllegalStageMaskBits));
1640fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        for (int i = 0; i < kNumStages; ++i) {
1650fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com            if ((1 << i) & stageMask) {
1660fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com                fSamplers[i].preConcatMatrix(matrix);
1670fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com            }
1680fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        }
1690fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
1700fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
1710fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /// @}
1720fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
1730fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
1740fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /// @name Coverage / Color Stages
1750fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    ////
1760fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
1770fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
1780fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * A common pattern is to compute a color with the initial stages and then
1790fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * modulate that color by a coverage value in later stage(s) (AA, mask-
1800fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * filters, glyph mask, etc). Color-filters, xfermodes, etc should be
1810fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * computed based on the pre-coverage-modulated color. The division of
1820fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * stages between color-computing and coverage-computing is specified by
1830fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * this method. Initially this is kNumStages (all stages
1840fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * are color-computing).
1850fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     */
1860fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    void setFirstCoverageStage(int firstCoverageStage) {
1870fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        GrAssert((unsigned)firstCoverageStage < kNumStages);
1880fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        fFirstCoverageStage = firstCoverageStage;
1890fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
1900fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
1910fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
1920fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * Gets the index of the first coverage-computing stage.
1930fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     */
1940fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    int getFirstCoverageStage() const {
1950fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        return fFirstCoverageStage;
1960fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
1970fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
1980fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    ///@}
1990fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
2000fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
2010fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /// @name Blending
2020fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    ////
2030fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
2040fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
2050fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * Sets the blending function coeffecients.
2060fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *
2070fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * The blend function will be:
2080fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *    D' = sat(S*srcCoef + D*dstCoef)
2090fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *
2100fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *   where D is the existing destination color, S is the incoming source
2110fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *   color, and D' is the new destination color that will be written. sat()
2120fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *   is the saturation function.
2130fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *
2140fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * @param srcCoef coeffecient applied to the src color.
2150fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * @param dstCoef coeffecient applied to the dst color.
2160fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     */
2170fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
2180fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        fSrcBlend = srcCoeff;
2190fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        fDstBlend = dstCoeff;
2200fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    #if GR_DEBUG
2210fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        switch (dstCoeff) {
2220fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        case kDC_BlendCoeff:
2230fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        case kIDC_BlendCoeff:
2240fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        case kDA_BlendCoeff:
2250fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        case kIDA_BlendCoeff:
2260fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com            GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
2270fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com                     "coverage stages.\n");
2280fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com            break;
2290fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        default:
2300fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com            break;
2310fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        }
2320fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        switch (srcCoeff) {
2330fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        case kSC_BlendCoeff:
2340fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        case kISC_BlendCoeff:
2350fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        case kSA_BlendCoeff:
2360fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        case kISA_BlendCoeff:
2370fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com            GrPrintf("Unexpected src blend coeff. Won't work correctly with"
2380fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com                     "coverage stages.\n");
2390fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com            break;
2400fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        default:
2410fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com            break;
2420fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        }
2430fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    #endif
2440fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
2450fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
2460fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    GrBlendCoeff getSrcBlendCoeff() const { return fSrcBlend; }
2470fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    GrBlendCoeff getDstBlendCoeff() const { return fDstBlend; }
2480fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
2490fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff,
2500fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com                          GrBlendCoeff* dstBlendCoeff) const {
2510fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        *srcBlendCoeff = fSrcBlend;
2520fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        *dstBlendCoeff = fDstBlend;
2530fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
2540fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
2550fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
2560fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * Sets the blending function constant referenced by the following blending
2570fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * coeffecients:
2580fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *      kConstC_BlendCoeff
2590fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *      kIConstC_BlendCoeff
2600fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *      kConstA_BlendCoeff
2610fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *      kIConstA_BlendCoeff
2620fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *
2630fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * @param constant the constant to set
2640fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     */
2650fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    void setBlendConstant(GrColor constant) { fBlendConstant = constant; }
2660fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
2670fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
2680fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * Retrieves the last value set by setBlendConstant()
2690fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * @return the blending constant value
2700fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     */
2710fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    GrColor getBlendConstant() const { return fBlendConstant; }
2720fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
2730fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /// @}
2740fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
2750fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
2760fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /// @name View Matrix
2770fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    ////
2780fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
2790fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
2800fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * Sets the matrix applied to veretx positions.
2810fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *
2820fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * In the post-view-matrix space the rectangle [0,w]x[0,h]
2830fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * fully covers the render target. (w and h are the width and height of the
2840fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * the rendertarget.)
2850fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     */
2860fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    void setViewMatrix(const GrMatrix& m) { fViewMatrix = m; }
2870fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
2880fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
2890fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * Gets a writable pointer to the view matrix.
2900fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     */
2910fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    GrMatrix* viewMatrix() { return &fViewMatrix; }
2920fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
2930fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
2940fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *  Multiplies the current view matrix by a matrix
2950fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *
2960fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *  After this call V' = V*m where V is the old view matrix,
2970fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *  m is the parameter to this function, and V' is the new view matrix.
2980fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *  (We consider positions to be column vectors so position vector p is
2990fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *  transformed by matrix X as p' = X*p.)
3000fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *
3010fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *  @param m the matrix used to modify the view matrix.
3020fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     */
3030fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    void preConcatViewMatrix(const GrMatrix& m) { fViewMatrix.preConcat(m); }
3040fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
3050fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
3060fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *  Multiplies the current view matrix by a matrix
3070fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *
3080fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *  After this call V' = m*V where V is the old view matrix,
3090fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *  m is the parameter to this function, and V' is the new view matrix.
3100fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *  (We consider positions to be column vectors so position vector p is
3110fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *  transformed by matrix X as p' = X*p.)
3120fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *
3130fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *  @param m the matrix used to modify the view matrix.
3140fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     */
3150fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    void postConcatViewMatrix(const GrMatrix& m) { fViewMatrix.postConcat(m); }
3160fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
3170fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
3180fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * Retrieves the current view matrix
3190fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * @return the current view matrix.
3200fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     */
3210fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    const GrMatrix& getViewMatrix() const { return fViewMatrix; }
3220fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
3230fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
3240fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *  Retrieves the inverse of the current view matrix.
3250fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *
3260fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *  If the current view matrix is invertible, return true, and if matrix
3270fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *  is non-null, copy the inverse into it. If the current view matrix is
3280fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *  non-invertible, return false and ignore the matrix parameter.
3290fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *
3300fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * @param matrix if not null, will receive a copy of the current inverse.
3310fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     */
3320fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    bool getViewInverse(GrMatrix* matrix) const {
3330fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        // TODO: determine whether we really need to leave matrix unmodified
3340fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        // at call sites when inversion fails.
3350fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        GrMatrix inverse;
3360fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        if (fViewMatrix.invert(&inverse)) {
3370fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com            if (matrix) {
3380fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com                *matrix = inverse;
3390fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com            }
3400fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com            return true;
3410fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        }
3420fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        return false;
3430fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
3440fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
3450fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /// @}
3460fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
3470fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
3480fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /// @name Render Target
3490fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    ////
3500fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
3510fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
3520fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * Sets the rendertarget used at the next drawing call
3530fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *
3540fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * @param target  The render target to set.
3550fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     */
3560fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    void setRenderTarget(GrRenderTarget* target) { fRenderTarget = target; }
3570fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
3580fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
3590fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * Retrieves the currently set rendertarget.
3600fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *
3610fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * @return    The currently set render target.
3620fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     */
3630fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    const GrRenderTarget* getRenderTarget() const { return fRenderTarget; }
3640fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    GrRenderTarget* getRenderTarget() { return fRenderTarget; }
3650fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
3660fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    class AutoRenderTargetRestore : public ::GrNoncopyable {
3670fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    public:
3680fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        AutoRenderTargetRestore() : fDrawState(NULL) {}
3690fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) {
3700fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com            this->set(ds, newTarget);
3710fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        }
3720fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        ~AutoRenderTargetRestore() { this->set(NULL, NULL); }
3730fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        void set(GrDrawState* ds, GrRenderTarget* newTarget) {
3740fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com            if (NULL != fDrawState) {
3750fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com                fDrawState->setRenderTarget(fSavedTarget);
3760fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com            }
3770fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com            if (NULL != ds) {
3780fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com                fSavedTarget = ds->getRenderTarget();
3790fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com                ds->setRenderTarget(newTarget);
3800fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com            }
3810fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com            fDrawState = ds;
3820fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        }
3830fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    private:
3840fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        GrDrawState* fDrawState;
3850fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        GrRenderTarget* fSavedTarget;
3869381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    };
3879381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
3880fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /// @}
3890fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
3900fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
3910fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /// @name Stencil
3920fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    ////
3930fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
3940fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
3950fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * Sets the stencil settings to use for the next draw.
3960fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * Changing the clip has the side-effect of possibly zeroing
3970fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * out the client settable stencil bits. So multipass algorithms
3980fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * using stencil should not change the clip between passes.
3990fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * @param settings  the stencil settings to use.
4000fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     */
4010fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    void setStencil(const GrStencilSettings& settings) {
4020fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        fStencilSettings = settings;
4030fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
4040fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
4050fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
4060fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * Shortcut to disable stencil testing and ops.
4070fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     */
4080fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    void disableStencil() {
4090fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        fStencilSettings.setDisabled();
4100fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
4110fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
4120fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    const GrStencilSettings& getStencil() const { return fStencilSettings; }
4130fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
4140fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    GrStencilSettings* stencil() { return &fStencilSettings; }
4150fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
4160fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /// @}
4170fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
4180fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
4190fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    // @name Edge AA
4200fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    // There are two ways to perform antialiasing using edge equations. One
4210fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    // is to specify an (linear or quadratic) edge eq per-vertex. This requires
4220fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    // splitting vertices shared by primitives.
4230fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    //
4240fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    // The other is via setEdgeAAData which sets a set of edges and each
4250fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    // is tested against all the edges.
4260fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    ////
4270fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
4280fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
4299381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * When specifying edges as vertex data this enum specifies what type of
4309381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * edges are in use. The edges are always 4 GrScalars in memory, even when
4319381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * the edge type requires fewer than 4.
4329381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     */
4339381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    enum VertexEdgeType {
4349381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        /* 1-pixel wide line
4359381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com           2D implicit line eq (a*x + b*y +c = 0). 4th component unused */
4369381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        kHairLine_EdgeType,
4379381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        /* 1-pixel wide quadratic
4389381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com           u^2-v canonical coords (only 2 components used) */
4399381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        kHairQuad_EdgeType
4409381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    };
4419381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
4429381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    /**
4430fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * Determines the interpretation per-vertex edge data when the
4440fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * kEdge_VertexLayoutBit is set (see GrDrawTarget). When per-vertex edges
4450fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * are not specified the value of this setting has no effect.
4460fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     */
4470fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    void setVertexEdgeType(VertexEdgeType type) {
4480fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        fVertexEdgeType = type;
4490fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
4500fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
4510fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    VertexEdgeType getVertexEdgeType() const {
4520fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        return fVertexEdgeType;
4530fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
4540fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
4550fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
4569381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * The absolute maximum number of edges that may be specified for
4579381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * a single draw call when performing edge antialiasing.  This is used for
4589381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * the size of several static buffers, so implementations of getMaxEdges()
4599381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     * (below) should clamp to this value.
4609381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com     */
4619381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    enum {
46262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        // TODO: this should be 32 when GrTesselatedPathRenderer is used
46362b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        // Visual Studio 2010 does not permit a member array of size 0.
46462b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        kMaxEdges = 1
4659381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    };
4669381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
4679381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    class Edge {
4689381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com      public:
4699381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        Edge() {}
4709381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        Edge(float x, float y, float z) : fX(x), fY(y), fZ(z) {}
4719381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        GrPoint intersect(const Edge& other) {
4729381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com            return GrPoint::Make(
47372e49b8982586a5d8b0425f16d909c05a36ea8c3bsalomon@google.com                SkFloatToScalar((fY * other.fZ - other.fY * fZ) /
47472e49b8982586a5d8b0425f16d909c05a36ea8c3bsalomon@google.com                                (fX * other.fY - other.fX * fY)),
47572e49b8982586a5d8b0425f16d909c05a36ea8c3bsalomon@google.com                SkFloatToScalar((fX * other.fZ - other.fX * fZ) /
47672e49b8982586a5d8b0425f16d909c05a36ea8c3bsalomon@google.com                                (other.fX * fY - fX * other.fY)));
4779381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        }
4789381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com        float fX, fY, fZ;
4799381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    };
4809381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
4810fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
4820fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * Sets the edge data required for edge antialiasing.
4830fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *
4840fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * @param edges       3 * numEdges float values, representing the edge
4850fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *                    equations in Ax + By + C form
4860fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     */
4870fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    void setEdgeAAData(const Edge* edges, int numEdges) {
4880fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        GrAssert(numEdges <= GrDrawState::kMaxEdges);
4890fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        memcpy(fEdgeAAEdges, edges, numEdges * sizeof(GrDrawState::Edge));
4900fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        fEdgeAANumEdges = numEdges;
4910fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
4929381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
4930fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    int getNumAAEdges() const { return fEdgeAANumEdges; }
4949381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
4950fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    const Edge* getAAEdges() const { return fEdgeAAEdges; }
4960fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
4970fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /// @}
4980fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
4990fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
5000fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /// @name State Flags
5010fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    ////
5020fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
5030fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
5040fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *  Flags that affect rendering. Controlled using enable/disableState(). All
5050fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *  default to disabled.
5060fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     */
5070fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    enum StateBits {
5080fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        /**
5090fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com         * Perform dithering. TODO: Re-evaluate whether we need this bit
5100fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com         */
5110fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        kDither_StateBit        = 0x01,
5120fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        /**
5130fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com         * Perform HW anti-aliasing. This means either HW FSAA, if supported
5140fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com         * by the render target, or smooth-line rendering if a line primitive
5150fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com         * is drawn and line smoothing is supported by the 3D API.
5160fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com         */
5170fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        kHWAntialias_StateBit   = 0x02,
5180fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        /**
5190fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com         * Draws will respect the clip, otherwise the clip is ignored.
5200fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com         */
5210fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        kClip_StateBit          = 0x04,
5220fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        /**
5230fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com         * Disables writing to the color buffer. Useful when performing stencil
5240fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com         * operations.
5250fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com         */
5260fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        kNoColorWrites_StateBit = 0x08,
5270fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        /**
5280fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com         * Modifies the behavior of edge AA specified by setEdgeAA. If set,
5290fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com         * will test edge pairs for convexity when rasterizing. Set this if the
5300fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com         * source polygon is non-convex.
5310fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com         */
5320fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        kEdgeAAConcave_StateBit = 0x10,
5330fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
5340fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        // Users of the class may add additional bits to the vector
5350fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        kDummyStateBit,
5360fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        kLastPublicStateBit = kDummyStateBit-1,
5370fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    };
5380fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
5390fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    void resetStateFlags() {
5400fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        fFlagBits = 0;
5419381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    }
5429381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
5430fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
5440fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * Enable render state settings.
5450fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *
5460fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * @param flags   bitfield of StateBits specifing the states to enable
5470fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     */
5480fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    void enableState(uint32_t stateBits) {
5490fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        fFlagBits |= stateBits;
5500fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
5519381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
5520fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
5530fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * Disable render state settings.
5540fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     *
5550fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * @param flags   bitfield of StateBits specifing the states to disable
5560fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     */
5570fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    void disableState(uint32_t stateBits) {
5580fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        fFlagBits &= ~(stateBits);
5590fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
56062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
5610fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    bool isDitherState() const {
5620fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        return 0 != (fFlagBits & kDither_StateBit);
5630fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
56462b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
5650fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    bool isHWAntialiasState() const {
5660fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        return 0 != (fFlagBits & kHWAntialias_StateBit);
5670fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
56862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
5690fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    bool isClipState() const {
5700fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        return 0 != (fFlagBits & kClip_StateBit);
5710fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
57262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
5730fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    bool isColorWriteDisabled() const {
5740fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        return 0 != (fFlagBits & kNoColorWrites_StateBit);
5750fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
5760fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
5770fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    bool isConcaveEdgeAAState() const {
5780fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        return 0 != (fFlagBits & kEdgeAAConcave_StateBit);
5790fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
5800fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
5810fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    bool isStateFlagEnabled(uint32_t stateBit) const {
5820fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        return 0 != (stateBit & fFlagBits);
5830fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
5840fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
5850fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    void copyStateFlags(const GrDrawState& ds) {
5860fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        fFlagBits = ds.fFlagBits;
5870fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
5880fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
5890fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /// @}
5900fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
5910fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
5920fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /// @name Face Culling
5930fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    ////
5940fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
5950fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    enum DrawFace {
5960fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        kBoth_DrawFace,
5970fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        kCCW_DrawFace,
5980fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        kCW_DrawFace,
5990fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    };
6000fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
6010fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
6020fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * Controls whether clockwise, counterclockwise, or both faces are drawn.
6030fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * @param face  the face(s) to draw.
6040fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     */
6050fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    void setDrawFace(DrawFace face) {
6060fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        fDrawFace = face;
6070fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
6080fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
6090fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /**
6100fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * Gets whether the target is drawing clockwise, counterclockwise,
6110fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * or both faces.
6120fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     * @return the current draw face(s).
6130fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com     */
6140fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    DrawFace getDrawFace() const {
6150fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com        return fDrawFace;
6160fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    }
6170fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
6180fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    /// @}
6190fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
6200fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    ///////////////////////////////////////////////////////////////////////////
62162b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
62262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    // Most stages are usually not used, so conditionals here
62362b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    // reduce the expected number of bytes touched by 50%.
6249381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    bool operator ==(const GrDrawState& s) const {
62562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        if (memcmp(this, &s, this->leadingBytes())) return false;
62662b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
62762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        for (int i = 0; i < kNumStages; i++) {
62862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com            if (fTextures[i] &&
6290fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com                memcmp(&this->fSamplers[i], &s.fSamplers[i],
63062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com                       sizeof(GrSamplerState))) {
63162b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com                return false;
63262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com            }
63362b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        }
63462b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
63562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        return true;
6369381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    }
6379381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com    bool operator !=(const GrDrawState& s) const { return !(*this == s); }
63862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
63962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    // Most stages are usually not used, so conditionals here
64062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    // reduce the expected number of bytes touched by 50%.
64162b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    GrDrawState& operator =(const GrDrawState& s) {
64262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        memcpy(this, &s, this->leadingBytes());
64362b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
64462b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        for (int i = 0; i < kNumStages; i++) {
64562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com            if (s.fTextures[i]) {
6460fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com                memcpy(&this->fSamplers[i], &s.fSamplers[i],
64762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com                       sizeof(GrSamplerState));
64862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com            }
64962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        }
65062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
65162b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        return *this;
65262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    }
65362b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
65462b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.comprivate:
6550fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    static const StageMask kIllegalStageMaskBits = ~((1 << kNumStages)-1);
6560fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    uint8_t                 fFlagBits;
6570fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    GrBlendCoeff            fSrcBlend : 8;
6580fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    GrBlendCoeff            fDstBlend : 8;
6590fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    DrawFace                fDrawFace : 8;
6600fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    uint8_t                 fFirstCoverageStage;
6610fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    SkXfermode::Mode        fColorFilterMode : 8;
6620fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    GrColor                 fBlendConstant;
6630fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    GrTexture*              fTextures[kNumStages];
6640fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    GrRenderTarget*         fRenderTarget;
6650fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    GrColor                 fColor;
6660fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    GrColor                 fColorFilterColor;
6670fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
6680fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    GrStencilSettings       fStencilSettings;
6690fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    GrMatrix                fViewMatrix;
6700fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
6710fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    // @{ Data for GrTesselatedPathRenderer
6720fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    // TODO: currently ignored in copying & comparison for performance.
6730fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    // Must be considered if GrTesselatedPathRenderer is being used.
6740fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
6750fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    int                     fEdgeAANumEdges;
6760fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    VertexEdgeType          fVertexEdgeType;
6770fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    Edge                    fEdgeAAEdges[kMaxEdges];
6780fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
6790fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    // @}
6800fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
6810fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    // This field must be last; it will not be copied or compared
6820fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    // if the corresponding fTexture[] is NULL.
6830fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com    GrSamplerState          fSamplers[kNumStages];
6840fec61d19ca9088d54f58bd0a67150171b83d66cbsalomon@google.com
68562b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    size_t leadingBytes() const {
68662b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        // Can't use offsetof() with non-POD types, so stuck with pointer math.
68762b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        // TODO: ignores GrTesselatedPathRenderer data structures. We don't
68862b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        // have a compile-time flag that lets us know if it's being used, and
68962b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        // checking at runtime seems to cost 5% performance.
69062b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com        return (size_t) ((unsigned char*)&fEdgeAANumEdges -
69162b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com                         (unsigned char*)&fFlagBits);
69262b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com    }
69362b09687857c923b1044be0aef4dd900f8379b22tomhudson@google.com
6949381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com};
6959381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com
6969381363050ec9d3e724076a8e9152bfa9a8de1d1tomhudson@google.com#endif
697