blob: c32294b14bb51ad445b82f1bc34fd9b749fffcc5 [file] [log] [blame]
egdaniel3658f382014-09-15 07:01:59 -07001/*
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
egdanielb109ac22014-10-07 06:45:44 -070011#include "GrColor.h"
12#include "GrGpu.h"
13#include "GrProcessorStage.h"
joshualitt79f8fae2014-10-28 17:59:26 -070014#include "GrProgramDesc.h"
egdanielb109ac22014-10-07 06:45:44 -070015#include "GrStencil.h"
16#include "GrTypesPriv.h"
17#include "SkMatrix.h"
18#include "SkRefCnt.h"
19
joshualitt79f8fae2014-10-28 17:59:26 -070020class GrDeviceCoordTexture;
egdanielb109ac22014-10-07 06:45:44 -070021class GrDrawState;
egdaniel3658f382014-09-15 07:01:59 -070022
egdaniel3658f382014-09-15 07:01:59 -070023/**
egdaniel89af44a2014-09-26 06:15:04 -070024 * 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.
egdaniel3658f382014-09-15 07:01:59 -070026 */
egdaniel89af44a2014-09-26 06:15:04 -070027class GrOptDrawState : public SkRefCnt {
egdaniel3658f382014-09-15 07:01:59 -070028public:
egdanielb109ac22014-10-07 06:45:44 -070029 /**
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 */
joshualitt79f8fae2014-10-28 17:59:26 -070035 static GrOptDrawState* Create(const GrDrawState& drawState, GrGpu*,
36 const GrDeviceCoordTexture* dstCopy, GrGpu::DrawType drawType);
egdanielb109ac22014-10-07 06:45:44 -070037
egdaniel170f90b2014-09-16 12:54:40 -070038 bool operator== (const GrOptDrawState& that) const;
39
egdaniel89af44a2014-09-26 06:15:04 -070040 ///////////////////////////////////////////////////////////////////////////
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
egdaniel89af44a2014-09-26 06:15:04 -070053 /// @}
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
egdanield9aa2182014-10-09 13:47:05 -070095 int numColorStages() const { return fNumColorStages; }
96 int numCoverageStages() const { return fFragmentStages.count() - fNumColorStages; }
97 int numFragmentStages() const { return fFragmentStages.count(); }
egdaniel89af44a2014-09-26 06:15:04 -070098 int numTotalStages() const {
egdanield9aa2182014-10-09 13:47:05 -070099 return this->numFragmentStages() + (this->hasGeometryProcessor() ? 1 : 0);
egdaniel89af44a2014-09-26 06:15:04 -0700100 }
101
102 bool hasGeometryProcessor() const { return SkToBool(fGeometryProcessor.get()); }
joshualitta5305a12014-10-10 17:47:00 -0700103 const GrGeometryProcessor* getGeometryProcessor() const { return fGeometryProcessor.get(); }
egdanield9aa2182014-10-09 13:47:05 -0700104 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]; }
egdaniel89af44a2014-09-26 06:15:04 -0700113
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 */
bsalomon37dd3312014-11-03 08:47:23 -0800172 GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); }
egdaniel89af44a2014-09-26 06:15:04 -0700173
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
egdanielc0648242014-09-22 13:17:02 -0700273 /// @}
274
joshualitt79f8fae2014-10-28 17:59:26 -0700275 const GrProgramDesc& programDesc() const { return fDesc; }
276
egdaniel170f90b2014-09-16 12:54:40 -0700277private:
egdaniel3658f382014-09-15 07:01:59 -0700278 /**
egdaniel89af44a2014-09-26 06:15:04 -0700279 * 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 /**
egdaniel3658f382014-09-15 07:01:59 -0700308 * Constructs and optimized drawState out of a GrRODrawState.
309 */
egdaniel170f90b2014-09-16 12:54:40 -0700310 GrOptDrawState(const GrDrawState& drawState, BlendOptFlags blendOptFlags,
egdanielc0648242014-09-22 13:17:02 -0700311 GrBlendCoeff optSrcCoeff, GrBlendCoeff optDstCoeff,
joshualitt79f8fae2014-10-28 17:59:26 -0700312 GrGpu*, const GrDeviceCoordTexture* dstCopy, GrGpu::DrawType);
egdaniel3658f382014-09-15 07:01:59 -0700313
egdaniel170f90b2014-09-16 12:54:40 -0700314 /**
egdaniel3658f382014-09-15 07:01:59 -0700315 * 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
egdaniel9cf45bf2014-10-08 06:49:10 -0700318 * the current one and set the state color to the constant color.
egdaniel3658f382014-09-15 07:01:59 -0700319 */
joshualitt79f8fae2014-10-28 17:59:26 -0700320 void computeEffectiveColorStages(const GrDrawState& ds, GrProgramDesc::DescInfo*,
321 int* firstColorStageIdx, uint8_t* fixFunctionVAToRemove);
egdaniel3658f382014-09-15 07:01:59 -0700322
egdaniel170f90b2014-09-16 12:54:40 -0700323 /**
egdaniel3658f382014-09-15 07:01:59 -0700324 * 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
egdaniel9cf45bf2014-10-08 06:49:10 -0700326 * loop to determine the first effective coverage stage.
egdaniel3658f382014-09-15 07:01:59 -0700327 */
joshualitt79f8fae2014-10-28 17:59:26 -0700328 void computeEffectiveCoverageStages(const GrDrawState& ds, GrProgramDesc::DescInfo* descInfo,
329 int* firstCoverageStageIdx);
egdaniel3658f382014-09-15 07:01:59 -0700330
egdaniel170f90b2014-09-16 12:54:40 -0700331 /**
egdaniel3658f382014-09-15 07:01:59 -0700332 * 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 */
joshualitt79f8fae2014-10-28 17:59:26 -0700336 void removeFixedFunctionVertexAttribs(uint8_t removeVAFlags, GrProgramDesc::DescInfo*);
egdaniel3658f382014-09-15 07:01:59 -0700337
egdaniel170f90b2014-09-16 12:54:40 -0700338 /**
339 * Alter the OptDrawState (adjusting stages, vertex attribs, flags, etc.) based on the
340 * BlendOptFlags.
341 */
joshualitt79f8fae2014-10-28 17:59:26 -0700342 void adjustFromBlendOpts(const GrDrawState& ds, GrProgramDesc::DescInfo*,
343 int* firstColorStageIdx, int* firstCoverageStageIdx,
344 uint8_t* fixedFunctionVAToRemove);
egdaniel3658f382014-09-15 07:01:59 -0700345
egdaniela7dc0a82014-09-17 08:25:05 -0700346 /**
347 * Loop over the effect stages to determine various info like what data they will read and what
348 * shaders they require.
349 */
joshualitt79f8fae2014-10-28 17:59:26 -0700350 void getStageStats(const GrDrawState& ds, int firstColorStageIdx, int firstCoverageStageIdx,
351 GrProgramDesc::DescInfo*);
egdaniela7dc0a82014-09-17 08:25:05 -0700352
egdanielc0648242014-09-22 13:17:02 -0700353 /**
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 */
egdaniel9cf45bf2014-10-08 06:49:10 -0700358 void setOutputStateInfo(const GrDrawState& ds, const GrDrawTargetCaps&,
joshualitt79f8fae2014-10-28 17:59:26 -0700359 int firstCoverageStageIdx, GrProgramDesc::DescInfo*,
360 bool* separateCoverageFromColor);
egdanielc0648242014-09-22 13:17:02 -0700361
egdaniel89af44a2014-09-26 06:15:04 -0700362 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
egdaniel9cf45bf2014-10-08 06:49:10 -0700380 typedef SkSTArray<8, GrFragmentStage> FragmentStageArray;
joshualitta5305a12014-10-10 17:47:00 -0700381 typedef GrProgramElementRef<const GrGeometryProcessor> ProgramGeometryProcessor;
382 ProgramGeometryProcessor fGeometryProcessor;
383 FragmentStageArray fFragmentStages;
egdanield9aa2182014-10-09 13:47:05 -0700384
385 // This function is equivalent to the offset into fFragmentStages where coverage stages begin.
joshualitta5305a12014-10-10 17:47:00 -0700386 int fNumColorStages;
egdaniel89af44a2014-09-26 06:15:04 -0700387
egdaniel3658f382014-09-15 07:01:59 -0700388 SkAutoSTArray<4, GrVertexAttrib> fOptVA;
389
egdaniel170f90b2014-09-16 12:54:40 -0700390 BlendOptFlags fBlendOptFlags;
391
joshualitt79f8fae2014-10-28 17:59:26 -0700392 GrProgramDesc fDesc;
egdanielc0648242014-09-22 13:17:02 -0700393
egdaniel89af44a2014-09-26 06:15:04 -0700394 typedef SkRefCnt INHERITED;
egdaniel3658f382014-09-15 07:01:59 -0700395};
396
egdaniel89af44a2014-09-26 06:15:04 -0700397GR_MAKE_BITFIELD_OPS(GrOptDrawState::BlendOptFlags);
398
egdaniel3658f382014-09-15 07:01:59 -0700399#endif
egdaniel89af44a2014-09-26 06:15:04 -0700400