c32294b14bb51ad445b82f1bc34fd9b749fffcc5
[platform/framework/web/crosswalk.git] / src / third_party / skia / src / gpu / GrOptDrawState.h
1 /*
2  * Copyright 2014 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 GrOptDrawState_DEFINED
9 #define GrOptDrawState_DEFINED
10
11 #include "GrColor.h"
12 #include "GrGpu.h"
13 #include "GrProcessorStage.h"
14 #include "GrProgramDesc.h"
15 #include "GrStencil.h"
16 #include "GrTypesPriv.h"
17 #include "SkMatrix.h"
18 #include "SkRefCnt.h"
19
20 class GrDeviceCoordTexture;
21 class GrDrawState;
22
23 /**
24  * Class that holds an optimized version of a GrDrawState. It is meant to be an immutable class,
25  * and contains all data needed to set the state for a gpu draw.
26  */
27 class GrOptDrawState : public SkRefCnt {
28 public:
29     /**
30      * Returns a snapshot of the current optimized state. If the current drawState has a valid
31      * cached optimiezed state it will simply return a pointer to it otherwise it will create a new
32      * GrOptDrawState. In all cases the GrOptDrawState is reffed and ownership is given to the
33      * caller.
34      */
35     static GrOptDrawState* Create(const GrDrawState& drawState, GrGpu*,
36                                   const GrDeviceCoordTexture* dstCopy, GrGpu::DrawType drawType);
37
38     bool operator== (const GrOptDrawState& that) const;
39
40     ///////////////////////////////////////////////////////////////////////////
41     /// @name Vertex Attributes
42     ////
43
44     enum {
45         kMaxVertexAttribCnt = kLast_GrVertexAttribBinding + 4,
46     };
47
48     const GrVertexAttrib* getVertexAttribs() const { return fVAPtr; }
49     int getVertexAttribCount() const { return fVACount; }
50
51     size_t getVertexStride() const { return fVAStride; }
52
53     /// @}
54
55     ///////////////////////////////////////////////////////////////////////////
56     /// @name Color
57     ////
58
59     GrColor getColor() const { return fColor; }
60
61     /// @}
62
63     ///////////////////////////////////////////////////////////////////////////
64     /// @name Coverage
65     ////
66
67     uint8_t getCoverage() const { return fCoverage; }
68
69     GrColor getCoverageColor() const {
70         return GrColorPackRGBA(fCoverage, fCoverage, fCoverage, fCoverage);
71     }
72
73     /// @}
74
75     ///////////////////////////////////////////////////////////////////////////
76     /// @name Effect Stages
77     /// Each stage hosts a GrProcessor. The effect produces an output color or coverage in the
78     /// fragment shader. Its inputs are the output from the previous stage as well as some variables
79     /// available to it in the fragment and vertex shader (e.g. the vertex position, the dst color,
80     /// the fragment position, local coordinates).
81     ///
82     /// The stages are divided into two sets, color-computing and coverage-computing. The final
83     /// color stage produces the final pixel color. The coverage-computing stages function exactly
84     /// as the color-computing but the output of the final coverage stage is treated as a fractional
85     /// pixel coverage rather than as input to the src/dst color blend step.
86     ///
87     /// The input color to the first color-stage is either the constant color or interpolated
88     /// per-vertex colors. The input to the first coverage stage is either a constant coverage
89     /// (usually full-coverage) or interpolated per-vertex coverage.
90     ///
91     /// See the documentation of kCoverageDrawing_StateBit for information about disabling the
92     /// the color / coverage distinction.
93     ////
94
95     int numColorStages() const { return fNumColorStages; }
96     int numCoverageStages() const { return fFragmentStages.count() - fNumColorStages; }
97     int numFragmentStages() const { return fFragmentStages.count(); }
98     int numTotalStages() const {
99          return this->numFragmentStages() + (this->hasGeometryProcessor() ? 1 : 0);
100     }
101
102     bool hasGeometryProcessor() const { return SkToBool(fGeometryProcessor.get()); }
103     const GrGeometryProcessor* getGeometryProcessor() const { return fGeometryProcessor.get(); }
104     const GrFragmentStage& getColorStage(int idx) const {
105         SkASSERT(idx < this->numColorStages());
106         return fFragmentStages[idx];
107     }
108     const GrFragmentStage& getCoverageStage(int idx) const {
109         SkASSERT(idx < this->numCoverageStages());
110         return fFragmentStages[fNumColorStages + idx];
111     }
112     const GrFragmentStage& getFragmentStage(int idx) const { return fFragmentStages[idx]; }
113
114     /// @}
115
116     ///////////////////////////////////////////////////////////////////////////
117     /// @name Blending
118     ////
119
120     GrBlendCoeff getSrcBlendCoeff() const { return fSrcBlend; }
121     GrBlendCoeff getDstBlendCoeff() const { return fDstBlend; }
122
123     /**
124      * Retrieves the last value set by setBlendConstant()
125      * @return the blending constant value
126      */
127     GrColor getBlendConstant() const { return fBlendConstant; }
128
129     /// @}
130
131     ///////////////////////////////////////////////////////////////////////////
132     /// @name View Matrix
133     ////
134
135     /**
136      * Retrieves the current view matrix
137      * @return the current view matrix.
138      */
139     const SkMatrix& getViewMatrix() const { return fViewMatrix; }
140
141     /**
142      *  Retrieves the inverse of the current view matrix.
143      *
144      *  If the current view matrix is invertible, return true, and if matrix
145      *  is non-null, copy the inverse into it. If the current view matrix is
146      *  non-invertible, return false and ignore the matrix parameter.
147      *
148      * @param matrix if not null, will receive a copy of the current inverse.
149      */
150     bool getViewInverse(SkMatrix* matrix) const {
151         SkMatrix inverse;
152         if (fViewMatrix.invert(&inverse)) {
153             if (matrix) {
154                 *matrix = inverse;
155             }
156             return true;
157         }
158         return false;
159     }
160
161     /// @}
162
163     ///////////////////////////////////////////////////////////////////////////
164     /// @name Render Target
165     ////
166
167     /**
168      * Retrieves the currently set render-target.
169      *
170      * @return    The currently set render target.
171      */
172     GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
173
174     /// @}
175
176     ///////////////////////////////////////////////////////////////////////////
177     /// @name Stencil
178     ////
179
180     const GrStencilSettings& getStencil() const { return fStencilSettings; }
181
182     /// @}
183
184     ///////////////////////////////////////////////////////////////////////////
185     /// @name State Flags
186     ////
187
188     /**
189      *  Flags that affect rendering. Controlled using enable/disableState(). All
190      *  default to disabled.
191      */
192     enum StateBits {
193         /**
194          * Perform dithering. TODO: Re-evaluate whether we need this bit
195          */
196         kDither_StateBit        = 0x01,
197         /**
198          * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
199          * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
200          * the 3D API.
201          */
202         kHWAntialias_StateBit   = 0x02,
203         /**
204          * Draws will respect the clip, otherwise the clip is ignored.
205          */
206         kClip_StateBit          = 0x04,
207         /**
208          * Disables writing to the color buffer. Useful when performing stencil
209          * operations.
210          */
211         kNoColorWrites_StateBit = 0x08,
212
213         /**
214          * Usually coverage is applied after color blending. The color is blended using the coeffs
215          * specified by setBlendFunc(). The blended color is then combined with dst using coeffs
216          * of src_coverage, 1-src_coverage. Sometimes we are explicitly drawing a coverage mask. In
217          * this case there is no distinction between coverage and color and the caller needs direct
218          * control over the blend coeffs. When set, there will be a single blend step controlled by
219          * setBlendFunc() which will use coverage*color as the src color.
220          */
221          kCoverageDrawing_StateBit = 0x10,
222
223         // Users of the class may add additional bits to the vector
224         kDummyStateBit,
225         kLastPublicStateBit = kDummyStateBit-1,
226     };
227
228     bool isStateFlagEnabled(uint32_t stateBit) const { return 0 != (stateBit & fFlagBits); }
229
230     bool isDitherState() const { return 0 != (fFlagBits & kDither_StateBit); }
231     bool isHWAntialiasState() const { return 0 != (fFlagBits & kHWAntialias_StateBit); }
232     bool isClipState() const { return 0 != (fFlagBits & kClip_StateBit); }
233     bool isColorWriteDisabled() const { return 0 != (fFlagBits & kNoColorWrites_StateBit); }
234     bool isCoverageDrawing() const { return 0 != (fFlagBits & kCoverageDrawing_StateBit); }
235
236     /// @}
237
238     ///////////////////////////////////////////////////////////////////////////
239     /// @name Face Culling
240     ////
241
242     enum DrawFace {
243         kInvalid_DrawFace = -1,
244
245         kBoth_DrawFace,
246         kCCW_DrawFace,
247         kCW_DrawFace,
248     };
249
250     /**
251      * Gets whether the target is drawing clockwise, counterclockwise,
252      * or both faces.
253      * @return the current draw face(s).
254      */
255     DrawFace getDrawFace() const { return fDrawFace; }
256
257     /// @}
258
259     ///////////////////////////////////////////////////////////////////////////
260
261     /** Return type for CombineIfPossible. */
262     enum CombinedState {
263         /** The GrDrawStates cannot be combined. */
264         kIncompatible_CombinedState,
265         /** Either draw state can be used in place of the other. */
266         kAOrB_CombinedState,
267         /** Use the first draw state. */
268         kA_CombinedState,
269         /** Use the second draw state. */
270         kB_CombinedState,
271     };
272
273     /// @}
274
275     const GrProgramDesc& programDesc() const { return fDesc; }
276
277 private:
278     /**
279      * Optimizations for blending / coverage to that can be applied based on the current state.
280      */
281     enum BlendOptFlags {
282         /**
283          * No optimization
284          */
285         kNone_BlendOpt                  = 0,
286         /**
287          * Don't draw at all
288          */
289         kSkipDraw_BlendOptFlag          = 0x1,
290         /**
291          * The coverage value does not have to be computed separately from alpha, the the output
292          * color can be the modulation of the two.
293          */
294         kCoverageAsAlpha_BlendOptFlag   = 0x2,
295         /**
296          * Instead of emitting a src color, emit coverage in the alpha channel and r,g,b are
297          * "don't cares".
298          */
299         kEmitCoverage_BlendOptFlag      = 0x4,
300         /**
301          * Emit transparent black instead of the src color, no need to compute coverage.
302          */
303         kEmitTransBlack_BlendOptFlag    = 0x8,
304     };
305     GR_DECL_BITFIELD_OPS_FRIENDS(BlendOptFlags);
306
307     /**
308      * Constructs and optimized drawState out of a GrRODrawState.
309      */
310     GrOptDrawState(const GrDrawState& drawState, BlendOptFlags blendOptFlags,
311                    GrBlendCoeff optSrcCoeff, GrBlendCoeff optDstCoeff,
312                    GrGpu*, const GrDeviceCoordTexture* dstCopy, GrGpu::DrawType);
313
314     /**
315      * Loops through all the color stage effects to check if the stage will ignore color input or
316      * always output a constant color. In the ignore color input case we can ignore all previous
317      * stages. In the constant color case, we can ignore all previous stages and
318      * the current one and set the state color to the constant color.
319      */
320     void computeEffectiveColorStages(const GrDrawState& ds, GrProgramDesc::DescInfo*,
321                                      int* firstColorStageIdx, uint8_t* fixFunctionVAToRemove);
322
323     /**
324      * Loops through all the coverage stage effects to check if the stage will ignore color input.
325      * If a coverage stage will ignore input, then we can ignore all coverage stages before it. We
326      * loop to determine the first effective coverage stage.
327      */
328     void computeEffectiveCoverageStages(const GrDrawState& ds, GrProgramDesc::DescInfo* descInfo,
329                                         int* firstCoverageStageIdx);
330
331     /**
332      * This function takes in a flag and removes the corresponding fixed function vertex attributes.
333      * The flags are in the same order as GrVertexAttribBinding array. If bit i of removeVAFlags is
334      * set, then vertex attributes with binding (GrVertexAttribute)i will be removed.
335      */
336     void removeFixedFunctionVertexAttribs(uint8_t removeVAFlags, GrProgramDesc::DescInfo*);
337
338     /**
339      * Alter the OptDrawState (adjusting stages, vertex attribs, flags, etc.) based on the
340      * BlendOptFlags.
341      */
342     void adjustFromBlendOpts(const GrDrawState& ds, GrProgramDesc::DescInfo*,
343                              int* firstColorStageIdx, int* firstCoverageStageIdx,
344                              uint8_t* fixedFunctionVAToRemove);
345
346     /**
347      * Loop over the effect stages to determine various info like what data they will read and what
348      * shaders they require.
349      */
350     void getStageStats(const GrDrawState& ds, int firstColorStageIdx, int firstCoverageStageIdx,
351                        GrProgramDesc::DescInfo*);
352
353     /**
354      * Calculates the primary and secondary output types of the shader. For certain output types
355      * the function may adjust the blend coefficients. After this function is called the src and dst
356      * blend coeffs will represent those used by backend API.
357      */
358     void setOutputStateInfo(const GrDrawState& ds, const GrDrawTargetCaps&,
359                             int firstCoverageStageIdx, GrProgramDesc::DescInfo*,
360                             bool* separateCoverageFromColor);
361
362     bool isEqual(const GrOptDrawState& that) const;
363
364     // These fields are roughly sorted by decreasing likelihood of being different in op==
365     typedef GrTGpuResourceRef<GrRenderTarget> ProgramRenderTarget;
366     ProgramRenderTarget                 fRenderTarget;
367     GrColor                             fColor;
368     SkMatrix                            fViewMatrix;
369     GrColor                             fBlendConstant;
370     uint32_t                            fFlagBits;
371     const GrVertexAttrib*               fVAPtr;
372     int                                 fVACount;
373     size_t                              fVAStride;
374     GrStencilSettings                   fStencilSettings;
375     uint8_t                             fCoverage;
376     DrawFace                            fDrawFace;
377     GrBlendCoeff                        fSrcBlend;
378     GrBlendCoeff                        fDstBlend;
379
380     typedef SkSTArray<8, GrFragmentStage> FragmentStageArray;
381     typedef GrProgramElementRef<const GrGeometryProcessor> ProgramGeometryProcessor;
382     ProgramGeometryProcessor            fGeometryProcessor;
383     FragmentStageArray                  fFragmentStages;
384
385     // This function is equivalent to the offset into fFragmentStages where coverage stages begin.
386     int                                 fNumColorStages;
387
388     SkAutoSTArray<4, GrVertexAttrib> fOptVA;
389
390     BlendOptFlags   fBlendOptFlags;
391
392     GrProgramDesc fDesc;
393
394     typedef SkRefCnt INHERITED;
395 };
396
397 GR_MAKE_BITFIELD_OPS(GrOptDrawState::BlendOptFlags);
398
399 #endif
400