GrDrawState.h revision 8f9cbd62ec108d410b91155dcf6a4789c641246f
1/*
2 * Copyright 2011 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8#ifndef GrDrawState_DEFINED
9#define GrDrawState_DEFINED
10
11#include "GrColor.h"
12#include "GrMatrix.h"
13#include "GrNoncopyable.h"
14#include "GrSamplerState.h"
15#include "GrStencil.h"
16
17#include "SkXfermode.h"
18
19class GrRenderTarget;
20class GrTexture;
21
22struct GrDrawState {
23
24    /**
25     * Number of texture stages. Each stage takes as input a color and
26     * 2D texture coordinates. The color input to the first enabled stage is the
27     * per-vertex color or the constant color (setColor/setAlpha) if there are
28     * no per-vertex colors. For subsequent stages the input color is the output
29     * color from the previous enabled stage. The output color of each stage is
30     * the input color modulated with the result of a texture lookup. Texture
31     * lookups are specified by a texture a sampler (setSamplerState). Texture
32     * coordinates for each stage come from the vertices based on a
33     * GrVertexLayout bitfield. The output fragment color is the output color of
34     * the last enabled stage. The presence or absence of texture coordinates
35     * for each stage in the vertex layout indicates whether a stage is enabled
36     * or not.
37     */
38    enum {
39        kNumStages = 3,
40        kMaxTexCoords = kNumStages
41    };
42
43    /**
44     *  Bitfield used to indicate a set of stages.
45     */
46    typedef uint32_t StageMask;
47    GR_STATIC_ASSERT(sizeof(StageMask)*8 >= GrDrawState::kNumStages);
48
49    GrDrawState() {
50        // make sure any pad is zero for memcmp
51        // all GrDrawState members should default to something
52        // valid by the memset
53        memset(this, 0, sizeof(GrDrawState));
54
55        // memset exceptions
56        fColorFilterMode = SkXfermode::kDstIn_Mode;
57        fFirstCoverageStage = kNumStages;
58
59        // pedantic assertion that our ptrs will
60        // be NULL (0 ptr is mem addr 0)
61        GrAssert((intptr_t)(void*)NULL == 0LL);
62
63        GrAssert(fStencilSettings.isDisabled());
64        fFirstCoverageStage = kNumStages;
65    }
66
67    ///////////////////////////////////////////////////////////////////////////
68    /// @name Color
69    ////
70
71    /**
72     *  Sets color for next draw to a premultiplied-alpha color.
73     *
74     *  @param color    the color to set.
75     */
76    void setColor(GrColor color) { fColor = color; }
77
78    GrColor getColor() const { return fColor; }
79
80    /**
81     *  Sets the color to be used for the next draw to be
82     *  (r,g,b,a) = (alpha, alpha, alpha, alpha).
83     *
84     *  @param alpha The alpha value to set as the color.
85     */
86    void setAlpha(uint8_t a) {
87        this->setColor((a << 24) | (a << 16) | (a << 8) | a);
88    }
89
90    /**
91     * Add a color filter that can be represented by a color and a mode. Applied
92     * after color-computing texture stages.
93     */
94    void setColorFilter(GrColor c, SkXfermode::Mode mode) {
95        fColorFilterColor = c;
96        fColorFilterMode = mode;
97    }
98
99    GrColor getColorFilterColor() const { return fColorFilterColor; }
100    SkXfermode::Mode getColorFilterMode() const { return fColorFilterMode; }
101
102    /// @}
103
104    ///////////////////////////////////////////////////////////////////////////
105    /// @name Textures
106    ////
107
108    /**
109     * Sets the texture used at the next drawing call
110     *
111     * @param stage The texture stage for which the texture will be set
112     *
113     * @param texture The texture to set. Can be NULL though there is no
114     * advantage to settings a NULL texture if doing non-textured drawing
115     */
116    void setTexture(int stage, GrTexture* texture) {
117        GrAssert((unsigned)stage < kNumStages);
118        fTextures[stage] = texture;
119    }
120
121    /**
122     * Retrieves the currently set texture.
123     *
124     * @return    The currently set texture. The return value will be NULL if no
125     *            texture has been set, NULL was most recently passed to
126     *            setTexture, or the last setTexture was destroyed.
127     */
128    const GrTexture* getTexture(int stage) const {
129        GrAssert((unsigned)stage < kNumStages);
130        return fTextures[stage];
131    }
132    GrTexture* getTexture(int stage) {
133        GrAssert((unsigned)stage < kNumStages);
134        return fTextures[stage];
135    }
136
137    /// @}
138
139    ///////////////////////////////////////////////////////////////////////////
140    /// @name Samplers
141    ////
142
143    /**
144     * Returns the current sampler for a stage.
145     */
146    const GrSamplerState& getSampler(int stage) const {
147        GrAssert((unsigned)stage < kNumStages);
148        return fSamplerStates[stage];
149    }
150
151    /**
152     * Sets the sampler. This will be removed soon in favor of direct access.
153     */
154    void setSampler(int stage, const GrSamplerState& sampler) {
155        GrAssert((unsigned)stage < kNumStages);
156        fSamplerStates[stage] = sampler;
157    }
158
159    /**
160     * Writable pointer to a stage's sampler.
161     */
162    GrSamplerState* sampler(int stage) {
163        GrAssert((unsigned)stage < kNumStages);
164        return fSamplerStates + stage;
165    }
166
167    /**
168     * Preconcats the matrix of all samplers in the mask with the same matrix.
169     */
170    void preConcatSamplerMatrices(StageMask stageMask, const GrMatrix& matrix) {
171        GrAssert(!(stageMask & kIllegalStageMaskBits));
172        for (int i = 0; i < kNumStages; ++i) {
173            if ((1 << i) & stageMask) {
174                fSamplerStates[i].preConcatMatrix(matrix);
175            }
176        }
177    }
178
179    /// @}
180
181    ///////////////////////////////////////////////////////////////////////////
182    /// @name Coverage / Color Stages
183    ////
184
185    /**
186     * A common pattern is to compute a color with the initial stages and then
187     * modulate that color by a coverage value in later stage(s) (AA, mask-
188     * filters, glyph mask, etc). Color-filters, xfermodes, etc should be
189     * computed based on the pre-coverage-modulated color. The division of
190     * stages between color-computing and coverage-computing is specified by
191     * this method. Initially this is kNumStages (all stages
192     * are color-computing).
193     */
194    void setFirstCoverageStage(int firstCoverageStage) {
195        GrAssert((unsigned)firstCoverageStage <= kNumStages);
196        fFirstCoverageStage = firstCoverageStage;
197    }
198
199    /**
200     * Gets the index of the first coverage-computing stage.
201     */
202    int getFirstCoverageStage() const {
203        return fFirstCoverageStage;
204    }
205
206    ///@}
207
208    ///////////////////////////////////////////////////////////////////////////
209    /// @name Blending
210    ////
211
212    /**
213     * Sets the blending function coeffecients.
214     *
215     * The blend function will be:
216     *    D' = sat(S*srcCoef + D*dstCoef)
217     *
218     *   where D is the existing destination color, S is the incoming source
219     *   color, and D' is the new destination color that will be written. sat()
220     *   is the saturation function.
221     *
222     * @param srcCoef coeffecient applied to the src color.
223     * @param dstCoef coeffecient applied to the dst color.
224     */
225    void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
226        fSrcBlend = srcCoeff;
227        fDstBlend = dstCoeff;
228    #if GR_DEBUG
229        switch (dstCoeff) {
230        case kDC_BlendCoeff:
231        case kIDC_BlendCoeff:
232        case kDA_BlendCoeff:
233        case kIDA_BlendCoeff:
234            GrPrintf("Unexpected dst blend coeff. Won't work correctly with"
235                     "coverage stages.\n");
236            break;
237        default:
238            break;
239        }
240        switch (srcCoeff) {
241        case kSC_BlendCoeff:
242        case kISC_BlendCoeff:
243        case kSA_BlendCoeff:
244        case kISA_BlendCoeff:
245            GrPrintf("Unexpected src blend coeff. Won't work correctly with"
246                     "coverage stages.\n");
247            break;
248        default:
249            break;
250        }
251    #endif
252    }
253
254    GrBlendCoeff getSrcBlendCoeff() const { return fSrcBlend; }
255    GrBlendCoeff getDstBlendCoeff() const { return fDstBlend; }
256
257    void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff,
258                          GrBlendCoeff* dstBlendCoeff) const {
259        *srcBlendCoeff = fSrcBlend;
260        *dstBlendCoeff = fDstBlend;
261    }
262
263    /**
264     * Sets the blending function constant referenced by the following blending
265     * coeffecients:
266     *      kConstC_BlendCoeff
267     *      kIConstC_BlendCoeff
268     *      kConstA_BlendCoeff
269     *      kIConstA_BlendCoeff
270     *
271     * @param constant the constant to set
272     */
273    void setBlendConstant(GrColor constant) { fBlendConstant = constant; }
274
275    /**
276     * Retrieves the last value set by setBlendConstant()
277     * @return the blending constant value
278     */
279    GrColor getBlendConstant() const { return fBlendConstant; }
280
281    /// @}
282
283    ///////////////////////////////////////////////////////////////////////////
284    /// @name View Matrix
285    ////
286
287    /**
288     * Sets the matrix applied to veretx positions.
289     *
290     * In the post-view-matrix space the rectangle [0,w]x[0,h]
291     * fully covers the render target. (w and h are the width and height of the
292     * the rendertarget.)
293     */
294    void setViewMatrix(const GrMatrix& m) { fViewMatrix = m; }
295
296    /**
297     * Gets a writable pointer to the view matrix.
298     */
299    GrMatrix* viewMatrix() { return &fViewMatrix; }
300
301    /**
302     *  Multiplies the current view matrix by a matrix
303     *
304     *  After this call V' = V*m where V is the old view matrix,
305     *  m is the parameter to this function, and V' is the new view matrix.
306     *  (We consider positions to be column vectors so position vector p is
307     *  transformed by matrix X as p' = X*p.)
308     *
309     *  @param m the matrix used to modify the view matrix.
310     */
311    void preConcatViewMatrix(const GrMatrix& m) { fViewMatrix.preConcat(m); }
312
313    /**
314     *  Multiplies the current view matrix by a matrix
315     *
316     *  After this call V' = m*V where V is the old view matrix,
317     *  m is the parameter to this function, and V' is the new view matrix.
318     *  (We consider positions to be column vectors so position vector p is
319     *  transformed by matrix X as p' = X*p.)
320     *
321     *  @param m the matrix used to modify the view matrix.
322     */
323    void postConcatViewMatrix(const GrMatrix& m) { fViewMatrix.postConcat(m); }
324
325    /**
326     * Retrieves the current view matrix
327     * @return the current view matrix.
328     */
329    const GrMatrix& getViewMatrix() const { return fViewMatrix; }
330
331    /**
332     *  Retrieves the inverse of the current view matrix.
333     *
334     *  If the current view matrix is invertible, return true, and if matrix
335     *  is non-null, copy the inverse into it. If the current view matrix is
336     *  non-invertible, return false and ignore the matrix parameter.
337     *
338     * @param matrix if not null, will receive a copy of the current inverse.
339     */
340    bool getViewInverse(GrMatrix* matrix) const {
341        // TODO: determine whether we really need to leave matrix unmodified
342        // at call sites when inversion fails.
343        GrMatrix inverse;
344        if (fViewMatrix.invert(&inverse)) {
345            if (matrix) {
346                *matrix = inverse;
347            }
348            return true;
349        }
350        return false;
351    }
352
353    class AutoViewMatrixRestore : public ::GrNoncopyable {
354    public:
355        AutoViewMatrixRestore() : fDrawState(NULL) {}
356        AutoViewMatrixRestore(GrDrawState* ds, const GrMatrix& newMatrix) {
357            fDrawState = NULL;
358            this->set(ds, newMatrix);
359        }
360        AutoViewMatrixRestore(GrDrawState* ds) {
361            fDrawState = NULL;
362            this->set(ds);
363        }
364        ~AutoViewMatrixRestore() {
365            this->set(NULL, GrMatrix::I());
366        }
367        void set(GrDrawState* ds, const GrMatrix& newMatrix) {
368            if (NULL != fDrawState) {
369                fDrawState->setViewMatrix(fSavedMatrix);
370            }
371            if (NULL != ds) {
372                fSavedMatrix = ds->getViewMatrix();
373                ds->setViewMatrix(newMatrix);
374            }
375            fDrawState = ds;
376        }
377        void set(GrDrawState* ds) {
378            if (NULL != fDrawState) {
379                fDrawState->setViewMatrix(fSavedMatrix);
380            }
381            if (NULL != ds) {
382                fSavedMatrix = ds->getViewMatrix();
383            }
384            fDrawState = ds;
385        }
386    private:
387        GrDrawState* fDrawState;
388        GrMatrix fSavedMatrix;
389    };
390
391    /// @}
392
393    ///////////////////////////////////////////////////////////////////////////
394    /// @name Render Target
395    ////
396
397    /**
398     * Sets the rendertarget used at the next drawing call
399     *
400     * @param target  The render target to set.
401     */
402    void setRenderTarget(GrRenderTarget* target) { fRenderTarget = target; }
403
404    /**
405     * Retrieves the currently set rendertarget.
406     *
407     * @return    The currently set render target.
408     */
409    const GrRenderTarget* getRenderTarget() const { return fRenderTarget; }
410    GrRenderTarget* getRenderTarget() { return fRenderTarget; }
411
412    class AutoRenderTargetRestore : public ::GrNoncopyable {
413    public:
414        AutoRenderTargetRestore() : fDrawState(NULL) {}
415        AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) {
416            fDrawState = NULL;
417            this->set(ds, newTarget);
418        }
419        ~AutoRenderTargetRestore() { this->set(NULL, NULL); }
420        void set(GrDrawState* ds, GrRenderTarget* newTarget) {
421            if (NULL != fDrawState) {
422                fDrawState->setRenderTarget(fSavedTarget);
423            }
424            if (NULL != ds) {
425                fSavedTarget = ds->getRenderTarget();
426                ds->setRenderTarget(newTarget);
427            }
428            fDrawState = ds;
429        }
430    private:
431        GrDrawState* fDrawState;
432        GrRenderTarget* fSavedTarget;
433    };
434
435    /// @}
436
437    ///////////////////////////////////////////////////////////////////////////
438    /// @name Stencil
439    ////
440
441    /**
442     * Sets the stencil settings to use for the next draw.
443     * Changing the clip has the side-effect of possibly zeroing
444     * out the client settable stencil bits. So multipass algorithms
445     * using stencil should not change the clip between passes.
446     * @param settings  the stencil settings to use.
447     */
448    void setStencil(const GrStencilSettings& settings) {
449        fStencilSettings = settings;
450    }
451
452    /**
453     * Shortcut to disable stencil testing and ops.
454     */
455    void disableStencil() {
456        fStencilSettings.setDisabled();
457    }
458
459    const GrStencilSettings& getStencil() const { return fStencilSettings; }
460
461    GrStencilSettings* stencil() { return &fStencilSettings; }
462
463    /// @}
464
465    ///////////////////////////////////////////////////////////////////////////
466    // @name Edge AA
467    // There are two ways to perform antialiasing using edge equations. One
468    // is to specify an (linear or quadratic) edge eq per-vertex. This requires
469    // splitting vertices shared by primitives.
470    //
471    // The other is via setEdgeAAData which sets a set of edges and each
472    // is tested against all the edges.
473    ////
474
475    /**
476     * When specifying edges as vertex data this enum specifies what type of
477     * edges are in use. The edges are always 4 GrScalars in memory, even when
478     * the edge type requires fewer than 4.
479     */
480    enum VertexEdgeType {
481        /* 1-pixel wide line
482           2D implicit line eq (a*x + b*y +c = 0). 4th component unused */
483        kHairLine_EdgeType,
484        /* 1-pixel wide quadratic
485           u^2-v canonical coords (only 2 components used) */
486        kHairQuad_EdgeType
487    };
488
489    /**
490     * Determines the interpretation per-vertex edge data when the
491     * kEdge_VertexLayoutBit is set (see GrDrawTarget). When per-vertex edges
492     * are not specified the value of this setting has no effect.
493     */
494    void setVertexEdgeType(VertexEdgeType type) {
495        fVertexEdgeType = type;
496    }
497
498    VertexEdgeType getVertexEdgeType() const {
499        return fVertexEdgeType;
500    }
501
502    /**
503     * The absolute maximum number of edges that may be specified for
504     * a single draw call when performing edge antialiasing.  This is used for
505     * the size of several static buffers, so implementations of getMaxEdges()
506     * (below) should clamp to this value.
507     */
508    enum {
509        // TODO: this should be 32 when GrTesselatedPathRenderer is used
510        // Visual Studio 2010 does not permit a member array of size 0.
511        kMaxEdges = 1
512    };
513
514    class Edge {
515      public:
516        Edge() {}
517        Edge(float x, float y, float z) : fX(x), fY(y), fZ(z) {}
518        GrPoint intersect(const Edge& other) {
519            return GrPoint::Make(
520                SkFloatToScalar((fY * other.fZ - other.fY * fZ) /
521                                (fX * other.fY - other.fX * fY)),
522                SkFloatToScalar((fX * other.fZ - other.fX * fZ) /
523                                (other.fX * fY - fX * other.fY)));
524        }
525        float fX, fY, fZ;
526    };
527
528    /**
529     * Sets the edge data required for edge antialiasing.
530     *
531     * @param edges       3 * numEdges float values, representing the edge
532     *                    equations in Ax + By + C form
533     */
534    void setEdgeAAData(const Edge* edges, int numEdges) {
535        GrAssert(numEdges <= GrDrawState::kMaxEdges);
536        memcpy(fEdgeAAEdges, edges, numEdges * sizeof(GrDrawState::Edge));
537        fEdgeAANumEdges = numEdges;
538    }
539
540    int getNumAAEdges() const { return fEdgeAANumEdges; }
541
542    const Edge* getAAEdges() const { return fEdgeAAEdges; }
543
544    /// @}
545
546    ///////////////////////////////////////////////////////////////////////////
547    /// @name State Flags
548    ////
549
550    /**
551     *  Flags that affect rendering. Controlled using enable/disableState(). All
552     *  default to disabled.
553     */
554    enum StateBits {
555        /**
556         * Perform dithering. TODO: Re-evaluate whether we need this bit
557         */
558        kDither_StateBit        = 0x01,
559        /**
560         * Perform HW anti-aliasing. This means either HW FSAA, if supported
561         * by the render target, or smooth-line rendering if a line primitive
562         * is drawn and line smoothing is supported by the 3D API.
563         */
564        kHWAntialias_StateBit   = 0x02,
565        /**
566         * Draws will respect the clip, otherwise the clip is ignored.
567         */
568        kClip_StateBit          = 0x04,
569        /**
570         * Disables writing to the color buffer. Useful when performing stencil
571         * operations.
572         */
573        kNoColorWrites_StateBit = 0x08,
574        /**
575         * Modifies the behavior of edge AA specified by setEdgeAA. If set,
576         * will test edge pairs for convexity when rasterizing. Set this if the
577         * source polygon is non-convex.
578         */
579        kEdgeAAConcave_StateBit = 0x10,
580
581        // Users of the class may add additional bits to the vector
582        kDummyStateBit,
583        kLastPublicStateBit = kDummyStateBit-1,
584    };
585
586    void resetStateFlags() {
587        fFlagBits = 0;
588    }
589
590    /**
591     * Enable render state settings.
592     *
593     * @param flags   bitfield of StateBits specifing the states to enable
594     */
595    void enableState(uint32_t stateBits) {
596        fFlagBits |= stateBits;
597    }
598
599    /**
600     * Disable render state settings.
601     *
602     * @param flags   bitfield of StateBits specifing the states to disable
603     */
604    void disableState(uint32_t stateBits) {
605        fFlagBits &= ~(stateBits);
606    }
607
608    bool isDitherState() const {
609        return 0 != (fFlagBits & kDither_StateBit);
610    }
611
612    bool isHWAntialiasState() const {
613        return 0 != (fFlagBits & kHWAntialias_StateBit);
614    }
615
616    bool isClipState() const {
617        return 0 != (fFlagBits & kClip_StateBit);
618    }
619
620    bool isColorWriteDisabled() const {
621        return 0 != (fFlagBits & kNoColorWrites_StateBit);
622    }
623
624    bool isConcaveEdgeAAState() const {
625        return 0 != (fFlagBits & kEdgeAAConcave_StateBit);
626    }
627
628    bool isStateFlagEnabled(uint32_t stateBit) const {
629        return 0 != (stateBit & fFlagBits);
630    }
631
632    void copyStateFlags(const GrDrawState& ds) {
633        fFlagBits = ds.fFlagBits;
634    }
635
636    /// @}
637
638    ///////////////////////////////////////////////////////////////////////////
639    /// @name Face Culling
640    ////
641
642    enum DrawFace {
643        kBoth_DrawFace,
644        kCCW_DrawFace,
645        kCW_DrawFace,
646    };
647
648    /**
649     * Controls whether clockwise, counterclockwise, or both faces are drawn.
650     * @param face  the face(s) to draw.
651     */
652    void setDrawFace(DrawFace face) {
653        fDrawFace = face;
654    }
655
656    /**
657     * Gets whether the target is drawing clockwise, counterclockwise,
658     * or both faces.
659     * @return the current draw face(s).
660     */
661    DrawFace getDrawFace() const {
662        return fDrawFace;
663    }
664
665    /// @}
666
667    ///////////////////////////////////////////////////////////////////////////
668
669    // Most stages are usually not used, so conditionals here
670    // reduce the expected number of bytes touched by 50%.
671    bool operator ==(const GrDrawState& s) const {
672        if (memcmp(this, &s, this->leadingBytes())) return false;
673
674        for (int i = 0; i < kNumStages; i++) {
675            if (fTextures[i] &&
676                memcmp(&this->fSamplerStates[i], &s.fSamplerStates[i],
677                       sizeof(GrSamplerState))) {
678                return false;
679            }
680        }
681
682        return true;
683    }
684    bool operator !=(const GrDrawState& s) const { return !(*this == s); }
685
686    // Most stages are usually not used, so conditionals here
687    // reduce the expected number of bytes touched by 50%.
688    GrDrawState& operator =(const GrDrawState& s) {
689        memcpy(this, &s, this->leadingBytes());
690
691        for (int i = 0; i < kNumStages; i++) {
692            if (s.fTextures[i]) {
693                memcpy(&this->fSamplerStates[i], &s.fSamplerStates[i],
694                       sizeof(GrSamplerState));
695            }
696        }
697
698        return *this;
699    }
700
701private:
702    static const StageMask kIllegalStageMaskBits = ~((1 << kNumStages)-1);
703    uint8_t                 fFlagBits;
704    GrBlendCoeff            fSrcBlend : 8;
705    GrBlendCoeff            fDstBlend : 8;
706    DrawFace                fDrawFace : 8;
707    uint8_t                 fFirstCoverageStage;
708    SkXfermode::Mode        fColorFilterMode : 8;
709    GrColor                 fBlendConstant;
710    GrTexture*              fTextures[kNumStages];
711    GrRenderTarget*         fRenderTarget;
712    GrColor                 fColor;
713    GrColor                 fColorFilterColor;
714    GrStencilSettings       fStencilSettings;
715    GrMatrix                fViewMatrix;
716    // @{ Data for GrTesselatedPathRenderer
717    // TODO: currently ignored in copying & comparison for performance.
718    // Must be considered if GrTesselatedPathRenderer is being used.
719
720    VertexEdgeType          fVertexEdgeType;
721    int                     fEdgeAANumEdges;
722    Edge                    fEdgeAAEdges[kMaxEdges];
723
724    // @}
725    // This field must be last; it will not be copied or compared
726    // if the corresponding fTexture[] is NULL.
727    GrSamplerState          fSamplerStates[kNumStages];
728
729    size_t leadingBytes() const {
730        // Can't use offsetof() with non-POD types, so stuck with pointer math.
731        // TODO: ignores GrTesselatedPathRenderer data structures. We don't
732        // have a compile-time flag that lets us know if it's being used, and
733        // checking at runtime seems to cost 5% performance.
734        return (size_t) ((unsigned char*)&fEdgeAANumEdges -
735                         (unsigned char*)&fFlagBits);
736    }
737
738};
739
740#endif
741