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 "GrBlend.h"
12#include "GrDrawTargetCaps.h"
13#include "GrGpuResourceRef.h"
14#include "GrRODrawState.h"
15#include "effects/GrSimpleTextureEffect.h"
16
17class GrOptDrawState;
18
19/**
20 * Modifiable subclass derived from GrRODrawState. The majority of the data that represents a draw
21 * state is stored in the parent class. GrDrawState contains methods for setting, adding to, etc.
22 * various data members of the draw state. This class is used to configure the state used when
23 * issuing draws via GrDrawTarget.
24 */
25class GrDrawState : public GrRODrawState {
26public:
27    SK_DECLARE_INST_COUNT(GrDrawState)
28
29    GrDrawState() : fCachedOptState(NULL) {
30        SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
31        this->reset();
32    }
33
34    GrDrawState(const SkMatrix& initialViewMatrix) : fCachedOptState(NULL) {
35        SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
36        this->reset(initialViewMatrix);
37    }
38
39    /**
40     * Copies another draw state.
41     **/
42    GrDrawState(const GrDrawState& state) : INHERITED(), fCachedOptState(NULL) {
43        SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
44        *this = state;
45    }
46
47    /**
48     * Copies another draw state with a preconcat to the view matrix.
49     **/
50    GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatrix);
51
52    virtual ~GrDrawState();
53
54    /**
55     * Resets to the default state. GrProcessors will be removed from all stages.
56     */
57    void reset() { this->onReset(NULL); }
58
59    void reset(const SkMatrix& initialViewMatrix) { this->onReset(&initialViewMatrix); }
60
61    /**
62     * Initializes the GrDrawState based on a GrPaint, view matrix and render target. Note that
63     * GrDrawState encompasses more than GrPaint. Aspects of GrDrawState that have no GrPaint
64     * equivalents are set to default values with the exception of vertex attribute state which
65     * is unmodified by this function and clipping which will be enabled.
66     */
67    void setFromPaint(const GrPaint& , const SkMatrix& viewMatrix, GrRenderTarget*);
68
69    ///////////////////////////////////////////////////////////////////////////
70    /// @name Vertex Attributes
71    ////
72
73   /**
74     * The format of vertices is represented as an array of GrVertexAttribs, with each representing
75     * the type of the attribute, its offset, and semantic binding (see GrVertexAttrib in
76     * GrTypesPriv.h).
77     *
78     * The mapping of attributes with kEffect bindings to GrProcessor inputs is specified when
79     * setEffect is called.
80     */
81
82    /**
83     *  Sets vertex attributes for next draw. The object driving the templatization
84     *  should be a global GrVertexAttrib array that is never changed.
85     *
86     *  @param count      the number of attributes being set, limited to kMaxVertexAttribCnt.
87     *  @param stride     the number of bytes between successive vertex data.
88     */
89    template <const GrVertexAttrib A[]> void setVertexAttribs(int count, size_t stride) {
90        this->internalSetVertexAttribs(A, count, stride);
91    }
92
93    /**
94     *  Sets default vertex attributes for next draw. The default is a single attribute:
95     *  {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribType}
96     */
97    void setDefaultVertexAttribs();
98
99    /**
100     * Helper to save/restore vertex attribs
101     */
102     class AutoVertexAttribRestore {
103     public:
104         AutoVertexAttribRestore(GrDrawState* drawState);
105
106         ~AutoVertexAttribRestore() { fDrawState->internalSetVertexAttribs(fVAPtr, fVACount,
107                                                                           fVAStride); }
108
109     private:
110         GrDrawState*          fDrawState;
111         const GrVertexAttrib* fVAPtr;
112         int                   fVACount;
113         size_t                fVAStride;
114     };
115
116    /// @}
117
118    /**
119     * Depending on features available in the underlying 3D API and the color blend mode requested
120     * it may or may not be possible to correctly blend with fractional pixel coverage generated by
121     * the fragment shader.
122     *
123     * This function considers the current draw state and the draw target's capabilities to
124     * determine whether coverage can be handled correctly. This function assumes that the caller
125     * intends to specify fractional pixel coverage (via setCoverage(), through a coverage vertex
126     * attribute, or a coverage effect) but may not have specified it yet.
127     */
128    bool couldApplyCoverage(const GrDrawTargetCaps& caps) const;
129
130    /// @}
131
132    ///////////////////////////////////////////////////////////////////////////
133    /// @name Color
134    ////
135
136    /**
137     *  Sets color for next draw to a premultiplied-alpha color.
138     *
139     *  @param color    the color to set.
140     */
141    void setColor(GrColor color) {
142        if (color != fColor) {
143            fColor = color;
144            this->invalidateOptState();
145        }
146    }
147
148    /**
149     *  Sets the color to be used for the next draw to be
150     *  (r,g,b,a) = (alpha, alpha, alpha, alpha).
151     *
152     *  @param alpha The alpha value to set as the color.
153     */
154    void setAlpha(uint8_t a) { this->setColor((a << 24) | (a << 16) | (a << 8) | a); }
155
156    /// @}
157
158    ///////////////////////////////////////////////////////////////////////////
159    /// @name Coverage
160    ////
161
162    /**
163     * Sets a constant fractional coverage to be applied to the draw. The
164     * initial value (after construction or reset()) is 0xff. The constant
165     * coverage is ignored when per-vertex coverage is provided.
166     */
167    void setCoverage(uint8_t coverage) {
168        if (coverage != fCoverage) {
169            fCoverage = coverage;
170            this->invalidateOptState();
171        }
172    }
173
174    /// @}
175
176    /**
177     * The geometry processor is the sole element of the skia pipeline which can use the vertex,
178     * geometry, and tesselation shaders.  The GP may also compute a coverage in its fragment shader
179     * but is never put in the color processing pipeline.
180     */
181
182    const GrGeometryProcessor* setGeometryProcessor(const GrGeometryProcessor* geometryProcessor) {
183        SkASSERT(geometryProcessor);
184        SkASSERT(!this->hasGeometryProcessor());
185        fGeometryProcessor.reset(new GrGeometryStage(geometryProcessor));
186        this->invalidateOptState();
187        return geometryProcessor;
188    }
189
190    ///////////////////////////////////////////////////////////////////////////
191    /// @name Effect Stages
192    /// Each stage hosts a GrProcessor. The effect produces an output color or coverage in the
193    /// fragment shader. Its inputs are the output from the previous stage as well as some variables
194    /// available to it in the fragment and vertex shader (e.g. the vertex position, the dst color,
195    /// the fragment position, local coordinates).
196    ///
197    /// The stages are divided into two sets, color-computing and coverage-computing. The final
198    /// color stage produces the final pixel color. The coverage-computing stages function exactly
199    /// as the color-computing but the output of the final coverage stage is treated as a fractional
200    /// pixel coverage rather than as input to the src/dst color blend step.
201    ///
202    /// The input color to the first color-stage is either the constant color or interpolated
203    /// per-vertex colors. The input to the first coverage stage is either a constant coverage
204    /// (usually full-coverage) or interpolated per-vertex coverage.
205    ///
206    /// See the documentation of kCoverageDrawing_StateBit for information about disabling the
207    /// the color / coverage distinction.
208    ////
209
210    const GrFragmentProcessor* addColorProcessor(const GrFragmentProcessor* effect) {
211        SkASSERT(effect);
212        SkNEW_APPEND_TO_TARRAY(&fColorStages, GrFragmentStage, (effect));
213        this->invalidateOptState();
214        return effect;
215    }
216
217    const GrFragmentProcessor* addCoverageProcessor(const GrFragmentProcessor* effect) {
218        SkASSERT(effect);
219        SkNEW_APPEND_TO_TARRAY(&fCoverageStages, GrFragmentStage, (effect));
220        this->invalidateOptState();
221        return effect;
222    }
223
224    /**
225     * Creates a GrSimpleTextureEffect that uses local coords as texture coordinates.
226     */
227    void addColorTextureProcessor(GrTexture* texture, const SkMatrix& matrix) {
228        this->addColorProcessor(GrSimpleTextureEffect::Create(texture, matrix))->unref();
229    }
230
231    void addCoverageTextureProcessor(GrTexture* texture, const SkMatrix& matrix) {
232        this->addCoverageProcessor(GrSimpleTextureEffect::Create(texture, matrix))->unref();
233    }
234
235    void addColorTextureProcessor(GrTexture* texture,
236                                  const SkMatrix& matrix,
237                                  const GrTextureParams& params) {
238        this->addColorProcessor(GrSimpleTextureEffect::Create(texture, matrix, params))->unref();
239    }
240
241    void addCoverageTextureProcessor(GrTexture* texture,
242                                     const SkMatrix& matrix,
243                                     const GrTextureParams& params) {
244        this->addCoverageProcessor(GrSimpleTextureEffect::Create(texture, matrix, params))->unref();
245    }
246
247    /**
248     * When this object is destroyed it will remove any color/coverage effects from the draw state
249     * that were added after its constructor.
250     *
251     * This class has strange behavior around geometry processor. If there is a GP on the draw state
252     * it will assert that the GP is not modified until after the destructor of the ARE. If the
253     * draw state has a NULL GP when the ARE is constructed then it will reset it to null in the
254     * destructor.
255     *
256     * TODO: We'd prefer for the ARE to just save and restore the GP. However, this would add
257     * significant complexity to the multi-ref architecture for deferred drawing. Once GrDrawState
258     * and GrOptDrawState are fully separated then GrDrawState will never be in the deferred
259     * execution state and GrOptDrawState always will be (and will be immutable and therefore
260     * unable to have an ARE). At this point we can restore sanity and have the ARE save and restore
261     * the GP.
262     */
263    class AutoRestoreEffects : public ::SkNoncopyable {
264    public:
265        AutoRestoreEffects()
266            : fDrawState(NULL)
267            , fOriginalGPID(SK_InvalidUniqueID)
268            , fColorEffectCnt(0)
269            , fCoverageEffectCnt(0) {}
270
271        AutoRestoreEffects(GrDrawState* ds)
272            : fDrawState(NULL)
273            , fOriginalGPID(SK_InvalidUniqueID)
274            , fColorEffectCnt(0)
275            , fCoverageEffectCnt(0) {
276            this->set(ds);
277        }
278
279        ~AutoRestoreEffects() { this->set(NULL); }
280
281        void set(GrDrawState* ds);
282
283        bool isSet() const { return SkToBool(fDrawState); }
284
285    private:
286        GrDrawState*    fDrawState;
287        uint32_t        fOriginalGPID;
288        int             fColorEffectCnt;
289        int             fCoverageEffectCnt;
290    };
291
292    /// @}
293
294    ///////////////////////////////////////////////////////////////////////////
295    /// @name Blending
296    ////
297
298    /**
299     * Sets the blending function coefficients.
300     *
301     * The blend function will be:
302     *    D' = sat(S*srcCoef + D*dstCoef)
303     *
304     *   where D is the existing destination color, S is the incoming source
305     *   color, and D' is the new destination color that will be written. sat()
306     *   is the saturation function.
307     *
308     * @param srcCoef coefficient applied to the src color.
309     * @param dstCoef coefficient applied to the dst color.
310     */
311    void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) {
312        if (srcCoeff != fSrcBlend || dstCoeff != fDstBlend) {
313            fSrcBlend = srcCoeff;
314            fDstBlend = dstCoeff;
315            this->invalidateOptState();
316        }
317    #ifdef SK_DEBUG
318        if (GrBlendCoeffRefsDst(dstCoeff)) {
319            GrPrintf("Unexpected dst blend coeff. Won't work correctly with coverage stages.\n");
320        }
321        if (GrBlendCoeffRefsSrc(srcCoeff)) {
322            GrPrintf("Unexpected src blend coeff. Won't work correctly with coverage stages.\n");
323        }
324    #endif
325    }
326
327    /**
328     * Sets the blending function constant referenced by the following blending
329     * coefficients:
330     *      kConstC_GrBlendCoeff
331     *      kIConstC_GrBlendCoeff
332     *      kConstA_GrBlendCoeff
333     *      kIConstA_GrBlendCoeff
334     *
335     * @param constant the constant to set
336     */
337    void setBlendConstant(GrColor constant) {
338        if (constant != fBlendConstant) {
339            fBlendConstant = constant;
340            this->invalidateOptState();
341        }
342    }
343
344    /// @}
345
346    ///////////////////////////////////////////////////////////////////////////
347    /// @name View Matrix
348    ////
349
350    /**
351     * Sets the view matrix to identity and updates any installed effects to compensate for the
352     * coord system change.
353     */
354    bool setIdentityViewMatrix();
355
356    ////////////////////////////////////////////////////////////////////////////
357
358    /**
359     * Preconcats the current view matrix and restores the previous view matrix in the destructor.
360     * Effect matrices are automatically adjusted to compensate and adjusted back in the destructor.
361     */
362    class AutoViewMatrixRestore : public ::SkNoncopyable {
363    public:
364        AutoViewMatrixRestore() : fDrawState(NULL) {}
365
366        AutoViewMatrixRestore(GrDrawState* ds, const SkMatrix& preconcatMatrix) {
367            fDrawState = NULL;
368            this->set(ds, preconcatMatrix);
369        }
370
371        ~AutoViewMatrixRestore() { this->restore(); }
372
373        /**
374         * Can be called prior to destructor to restore the original matrix.
375         */
376        void restore();
377
378        void set(GrDrawState* drawState, const SkMatrix& preconcatMatrix);
379
380        /** Sets the draw state's matrix to identity. This can fail because the current view matrix
381            is not invertible. */
382        bool setIdentity(GrDrawState* drawState);
383
384    private:
385        void doEffectCoordChanges(const SkMatrix& coordChangeMatrix);
386
387        GrDrawState*                                           fDrawState;
388        SkMatrix                                               fViewMatrix;
389        int                                                    fNumColorStages;
390        bool                                                   fHasGeometryProcessor;
391        SkAutoSTArray<8, GrProcessorStage::SavedCoordChange>   fSavedCoordChanges;
392    };
393
394    /// @}
395
396    ///////////////////////////////////////////////////////////////////////////
397    /// @name Render Target
398    ////
399
400    /**
401     * Sets the render-target used at the next drawing call
402     *
403     * @param target  The render target to set.
404     */
405    void setRenderTarget(GrRenderTarget* target) {
406        fRenderTarget.set(SkSafeRef(target), GrIORef::kWrite_IOType);
407        this->invalidateOptState();
408    }
409
410    /// @}
411
412    ///////////////////////////////////////////////////////////////////////////
413    /// @name Stencil
414    ////
415
416    /**
417     * Sets the stencil settings to use for the next draw.
418     * Changing the clip has the side-effect of possibly zeroing
419     * out the client settable stencil bits. So multipass algorithms
420     * using stencil should not change the clip between passes.
421     * @param settings  the stencil settings to use.
422     */
423    void setStencil(const GrStencilSettings& settings) {
424        if (settings != fStencilSettings) {
425            fStencilSettings = settings;
426            this->invalidateOptState();
427        }
428    }
429
430    /**
431     * Shortcut to disable stencil testing and ops.
432     */
433    void disableStencil() {
434        if (!fStencilSettings.isDisabled()) {
435            fStencilSettings.setDisabled();
436            this->invalidateOptState();
437        }
438    }
439
440    GrStencilSettings* stencil() { return &fStencilSettings; }
441
442    /// @}
443
444    ///////////////////////////////////////////////////////////////////////////
445    /// @name State Flags
446    ////
447
448    void resetStateFlags() {
449        if (0 != fFlagBits) {
450            fFlagBits = 0;
451            this->invalidateOptState();
452        }
453    }
454
455    /**
456     * Enable render state settings.
457     *
458     * @param stateBits bitfield of StateBits specifying the states to enable
459     */
460    void enableState(uint32_t stateBits) {
461        if (stateBits & ~fFlagBits) {
462            fFlagBits |= stateBits;
463            this->invalidateOptState();
464        }
465    }
466
467    /**
468     * Disable render state settings.
469     *
470     * @param stateBits bitfield of StateBits specifying the states to disable
471     */
472    void disableState(uint32_t stateBits) {
473        if (stateBits & fFlagBits) {
474            fFlagBits &= ~(stateBits);
475            this->invalidateOptState();
476        }
477    }
478
479    /**
480     * Enable or disable stateBits based on a boolean.
481     *
482     * @param stateBits bitfield of StateBits to enable or disable
483     * @param enable    if true enable stateBits, otherwise disable
484     */
485    void setState(uint32_t stateBits, bool enable) {
486        if (enable) {
487            this->enableState(stateBits);
488        } else {
489            this->disableState(stateBits);
490        }
491    }
492
493    /// @}
494
495    ///////////////////////////////////////////////////////////////////////////
496    /// @name Face Culling
497    ////
498
499    /**
500     * Controls whether clockwise, counterclockwise, or both faces are drawn.
501     * @param face  the face(s) to draw.
502     */
503    void setDrawFace(DrawFace face) {
504        SkASSERT(kInvalid_DrawFace != face);
505        fDrawFace = face;
506    }
507
508    /// @}
509
510    ///////////////////////////////////////////////////////////////////////////
511    /// @name Hints
512    /// Hints that when provided can enable optimizations.
513    ////
514
515    void setHint(Hints hint, bool value) { fHints = value ? (fHints | hint) : (fHints & ~hint); }
516
517    /// @}
518
519    ///////////////////////////////////////////////////////////////////////////
520
521    /** Return type for CombineIfPossible. */
522    enum CombinedState {
523        /** The GrDrawStates cannot be combined. */
524        kIncompatible_CombinedState,
525        /** Either draw state can be used in place of the other. */
526        kAOrB_CombinedState,
527        /** Use the first draw state. */
528        kA_CombinedState,
529        /** Use the second draw state. */
530        kB_CombinedState,
531    };
532
533    /** This function determines whether the GrDrawStates used for two draws can be combined into
534        a single GrDrawState. This is used to avoid storing redundant GrDrawStates and to determine
535        if draws can be batched. The return value indicates whether combining is possible and, if
536        so, which of the two inputs should be used. */
537    static CombinedState CombineIfPossible(const GrDrawState& a, const GrDrawState& b,
538                                           const GrDrawTargetCaps& caps);
539
540    GrDrawState& operator= (const GrDrawState& that);
541
542    /**
543     * Returns a snapshot of the current optimized state. If the current drawState has a valid
544     * cached optimiezed state it will simply return a pointer to it otherwise it will create a new
545     * GrOptDrawState. In all cases the GrOptDrawState is reffed and ownership is given to the
546     * caller.
547     */
548    GrOptDrawState* createOptState(const GrDrawTargetCaps&) const;
549
550private:
551    void invalidateOptState() const;
552
553    void onReset(const SkMatrix* initialViewMatrix);
554
555    // Some of the auto restore objects assume that no effects are removed during their lifetime.
556    // This is used to assert that this condition holds.
557    SkDEBUGCODE(int fBlockEffectRemovalCnt;)
558
559    void internalSetVertexAttribs(const GrVertexAttrib attribs[], int count, size_t stride);
560
561    mutable GrOptDrawState* fCachedOptState;
562    mutable uint32_t fCachedCapsID;
563
564    typedef GrRODrawState INHERITED;
565};
566
567#endif
568