blob: f47913a41ae049b2b214ac166a1291f4c09bf3a2 [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"
14#include "GrStencil.h"
15#include "GrTypesPriv.h"
16#include "SkMatrix.h"
17#include "SkRefCnt.h"
18
19class GrDrawState;
egdaniel3658f382014-09-15 07:01:59 -070020
egdaniel3658f382014-09-15 07:01:59 -070021/**
egdaniel89af44a2014-09-26 06:15:04 -070022 * Class that holds an optimized version of a GrDrawState. It is meant to be an immutable class,
23 * and contains all data needed to set the state for a gpu draw.
egdaniel3658f382014-09-15 07:01:59 -070024 */
egdaniel89af44a2014-09-26 06:15:04 -070025class GrOptDrawState : public SkRefCnt {
egdaniel3658f382014-09-15 07:01:59 -070026public:
egdanielb109ac22014-10-07 06:45:44 -070027 /**
28 * Returns a snapshot of the current optimized state. If the current drawState has a valid
29 * cached optimiezed state it will simply return a pointer to it otherwise it will create a new
30 * GrOptDrawState. In all cases the GrOptDrawState is reffed and ownership is given to the
31 * caller.
32 */
33 static GrOptDrawState* Create(const GrDrawState& drawState, const GrDrawTargetCaps& caps,
34 GrGpu::DrawType drawType);
35
egdaniel170f90b2014-09-16 12:54:40 -070036 bool operator== (const GrOptDrawState& that) const;
37
egdaniel89af44a2014-09-26 06:15:04 -070038 ///////////////////////////////////////////////////////////////////////////
39 /// @name Vertex Attributes
40 ////
41
42 enum {
43 kMaxVertexAttribCnt = kLast_GrVertexAttribBinding + 4,
44 };
45
46 const GrVertexAttrib* getVertexAttribs() const { return fVAPtr; }
47 int getVertexAttribCount() const { return fVACount; }
48
49 size_t getVertexStride() const { return fVAStride; }
50
51 /**
52 * Getters for index into getVertexAttribs() for particular bindings. -1 is returned if the
53 * binding does not appear in the current attribs. These bindings should appear only once in
54 * the attrib array.
55 */
56
57 int positionAttributeIndex() const {
58 return fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding];
59 }
60 int localCoordAttributeIndex() const {
61 return fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding];
62 }
63 int colorVertexAttributeIndex() const {
64 return fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding];
65 }
66 int coverageVertexAttributeIndex() const {
67 return fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding];
68 }
69
70 bool hasLocalCoordAttribute() const {
71 return -1 != fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding];
72 }
73 bool hasColorVertexAttribute() const {
74 return -1 != fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding];
75 }
76 bool hasCoverageVertexAttribute() const {
77 return -1 != fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding];
78 }
79
80 /// @}
81
82 ///////////////////////////////////////////////////////////////////////////
83 /// @name Color
84 ////
85
86 GrColor getColor() const { return fColor; }
87
88 /// @}
89
90 ///////////////////////////////////////////////////////////////////////////
91 /// @name Coverage
92 ////
93
94 uint8_t getCoverage() const { return fCoverage; }
95
96 GrColor getCoverageColor() const {
97 return GrColorPackRGBA(fCoverage, fCoverage, fCoverage, fCoverage);
98 }
99
100 /// @}
101
102 ///////////////////////////////////////////////////////////////////////////
103 /// @name Effect Stages
104 /// Each stage hosts a GrProcessor. The effect produces an output color or coverage in the
105 /// fragment shader. Its inputs are the output from the previous stage as well as some variables
106 /// available to it in the fragment and vertex shader (e.g. the vertex position, the dst color,
107 /// the fragment position, local coordinates).
108 ///
109 /// The stages are divided into two sets, color-computing and coverage-computing. The final
110 /// color stage produces the final pixel color. The coverage-computing stages function exactly
111 /// as the color-computing but the output of the final coverage stage is treated as a fractional
112 /// pixel coverage rather than as input to the src/dst color blend step.
113 ///
114 /// The input color to the first color-stage is either the constant color or interpolated
115 /// per-vertex colors. The input to the first coverage stage is either a constant coverage
116 /// (usually full-coverage) or interpolated per-vertex coverage.
117 ///
118 /// See the documentation of kCoverageDrawing_StateBit for information about disabling the
119 /// the color / coverage distinction.
120 ////
121
egdanield9aa2182014-10-09 13:47:05 -0700122 int numColorStages() const { return fNumColorStages; }
123 int numCoverageStages() const { return fFragmentStages.count() - fNumColorStages; }
124 int numFragmentStages() const { return fFragmentStages.count(); }
egdaniel89af44a2014-09-26 06:15:04 -0700125 int numTotalStages() const {
egdanield9aa2182014-10-09 13:47:05 -0700126 return this->numFragmentStages() + (this->hasGeometryProcessor() ? 1 : 0);
egdaniel89af44a2014-09-26 06:15:04 -0700127 }
128
129 bool hasGeometryProcessor() const { return SkToBool(fGeometryProcessor.get()); }
joshualitta5305a12014-10-10 17:47:00 -0700130 const GrGeometryProcessor* getGeometryProcessor() const { return fGeometryProcessor.get(); }
egdanield9aa2182014-10-09 13:47:05 -0700131 const GrFragmentStage& getColorStage(int idx) const {
132 SkASSERT(idx < this->numColorStages());
133 return fFragmentStages[idx];
134 }
135 const GrFragmentStage& getCoverageStage(int idx) const {
136 SkASSERT(idx < this->numCoverageStages());
137 return fFragmentStages[fNumColorStages + idx];
138 }
139 const GrFragmentStage& getFragmentStage(int idx) const { return fFragmentStages[idx]; }
egdaniel89af44a2014-09-26 06:15:04 -0700140
141 /// @}
142
143 ///////////////////////////////////////////////////////////////////////////
144 /// @name Blending
145 ////
146
147 GrBlendCoeff getSrcBlendCoeff() const { return fSrcBlend; }
148 GrBlendCoeff getDstBlendCoeff() const { return fDstBlend; }
149
150 /**
151 * Retrieves the last value set by setBlendConstant()
152 * @return the blending constant value
153 */
154 GrColor getBlendConstant() const { return fBlendConstant; }
155
156 /// @}
157
158 ///////////////////////////////////////////////////////////////////////////
159 /// @name View Matrix
160 ////
161
162 /**
163 * Retrieves the current view matrix
164 * @return the current view matrix.
165 */
166 const SkMatrix& getViewMatrix() const { return fViewMatrix; }
167
168 /**
169 * Retrieves the inverse of the current view matrix.
170 *
171 * If the current view matrix is invertible, return true, and if matrix
172 * is non-null, copy the inverse into it. If the current view matrix is
173 * non-invertible, return false and ignore the matrix parameter.
174 *
175 * @param matrix if not null, will receive a copy of the current inverse.
176 */
177 bool getViewInverse(SkMatrix* matrix) const {
178 SkMatrix inverse;
179 if (fViewMatrix.invert(&inverse)) {
180 if (matrix) {
181 *matrix = inverse;
182 }
183 return true;
184 }
185 return false;
186 }
187
188 /// @}
189
190 ///////////////////////////////////////////////////////////////////////////
191 /// @name Render Target
192 ////
193
194 /**
195 * Retrieves the currently set render-target.
196 *
197 * @return The currently set render target.
198 */
199 GrRenderTarget* getRenderTarget() const {
200 return static_cast<GrRenderTarget*>(fRenderTarget.getResource());
201 }
202
203 /// @}
204
205 ///////////////////////////////////////////////////////////////////////////
206 /// @name Stencil
207 ////
208
209 const GrStencilSettings& getStencil() const { return fStencilSettings; }
210
211 /// @}
212
213 ///////////////////////////////////////////////////////////////////////////
214 /// @name State Flags
215 ////
216
217 /**
218 * Flags that affect rendering. Controlled using enable/disableState(). All
219 * default to disabled.
220 */
221 enum StateBits {
222 /**
223 * Perform dithering. TODO: Re-evaluate whether we need this bit
224 */
225 kDither_StateBit = 0x01,
226 /**
227 * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target,
228 * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by
229 * the 3D API.
230 */
231 kHWAntialias_StateBit = 0x02,
232 /**
233 * Draws will respect the clip, otherwise the clip is ignored.
234 */
235 kClip_StateBit = 0x04,
236 /**
237 * Disables writing to the color buffer. Useful when performing stencil
238 * operations.
239 */
240 kNoColorWrites_StateBit = 0x08,
241
242 /**
243 * Usually coverage is applied after color blending. The color is blended using the coeffs
244 * specified by setBlendFunc(). The blended color is then combined with dst using coeffs
245 * of src_coverage, 1-src_coverage. Sometimes we are explicitly drawing a coverage mask. In
246 * this case there is no distinction between coverage and color and the caller needs direct
247 * control over the blend coeffs. When set, there will be a single blend step controlled by
248 * setBlendFunc() which will use coverage*color as the src color.
249 */
250 kCoverageDrawing_StateBit = 0x10,
251
252 // Users of the class may add additional bits to the vector
253 kDummyStateBit,
254 kLastPublicStateBit = kDummyStateBit-1,
255 };
256
257 bool isStateFlagEnabled(uint32_t stateBit) const { return 0 != (stateBit & fFlagBits); }
258
259 bool isDitherState() const { return 0 != (fFlagBits & kDither_StateBit); }
260 bool isHWAntialiasState() const { return 0 != (fFlagBits & kHWAntialias_StateBit); }
261 bool isClipState() const { return 0 != (fFlagBits & kClip_StateBit); }
262 bool isColorWriteDisabled() const { return 0 != (fFlagBits & kNoColorWrites_StateBit); }
263 bool isCoverageDrawing() const { return 0 != (fFlagBits & kCoverageDrawing_StateBit); }
264
265 /// @}
266
267 ///////////////////////////////////////////////////////////////////////////
268 /// @name Face Culling
269 ////
270
271 enum DrawFace {
272 kInvalid_DrawFace = -1,
273
274 kBoth_DrawFace,
275 kCCW_DrawFace,
276 kCW_DrawFace,
277 };
278
279 /**
280 * Gets whether the target is drawing clockwise, counterclockwise,
281 * or both faces.
282 * @return the current draw face(s).
283 */
284 DrawFace getDrawFace() const { return fDrawFace; }
285
286 /// @}
287
288 ///////////////////////////////////////////////////////////////////////////
289
290 /** Return type for CombineIfPossible. */
291 enum CombinedState {
292 /** The GrDrawStates cannot be combined. */
293 kIncompatible_CombinedState,
294 /** Either draw state can be used in place of the other. */
295 kAOrB_CombinedState,
296 /** Use the first draw state. */
297 kA_CombinedState,
298 /** Use the second draw state. */
299 kB_CombinedState,
300 };
301
egdaniel170f90b2014-09-16 12:54:40 -0700302 bool inputColorIsUsed() const { return fInputColorIsUsed; }
303 bool inputCoverageIsUsed() const { return fInputCoverageIsUsed; }
304
egdaniela7dc0a82014-09-17 08:25:05 -0700305 bool readsDst() const { return fReadsDst; }
306 bool readsFragPosition() const { return fReadsFragPosition; }
egdaniela7dc0a82014-09-17 08:25:05 -0700307 bool requiresLocalCoordAttrib() const { return fRequiresLocalCoordAttrib; }
308
egdanielc0648242014-09-22 13:17:02 -0700309 ///////////////////////////////////////////////////////////////////////////
310 /// @name Stage Output Types
311 ////
312
313 enum PrimaryOutputType {
314 // Modulate color and coverage, write result as the color output.
315 kModulate_PrimaryOutputType,
316 // Combines the coverage, dst, and color as coverage * color + (1 - coverage) * dst. This
317 // can only be set if fDstReadKey is non-zero.
318 kCombineWithDst_PrimaryOutputType,
319
320 kPrimaryOutputTypeCnt,
321 };
322
323 enum SecondaryOutputType {
324 // There is no secondary output
325 kNone_SecondaryOutputType,
326 // Writes coverage as the secondary output. Only set if dual source blending is supported
327 // and primary output is kModulate.
328 kCoverage_SecondaryOutputType,
329 // Writes coverage * (1 - colorA) as the secondary output. Only set if dual source blending
330 // is supported and primary output is kModulate.
331 kCoverageISA_SecondaryOutputType,
332 // Writes coverage * (1 - colorRGBA) as the secondary output. Only set if dual source
333 // blending is supported and primary output is kModulate.
334 kCoverageISC_SecondaryOutputType,
335
336 kSecondaryOutputTypeCnt,
337 };
338
339 PrimaryOutputType getPrimaryOutputType() const { return fPrimaryOutputType; }
340 SecondaryOutputType getSecondaryOutputType() const { return fSecondaryOutputType; }
341
342 /// @}
343
egdaniel170f90b2014-09-16 12:54:40 -0700344private:
egdaniel3658f382014-09-15 07:01:59 -0700345 /**
egdaniel89af44a2014-09-26 06:15:04 -0700346 * Optimizations for blending / coverage to that can be applied based on the current state.
347 */
348 enum BlendOptFlags {
349 /**
350 * No optimization
351 */
352 kNone_BlendOpt = 0,
353 /**
354 * Don't draw at all
355 */
356 kSkipDraw_BlendOptFlag = 0x1,
357 /**
358 * The coverage value does not have to be computed separately from alpha, the the output
359 * color can be the modulation of the two.
360 */
361 kCoverageAsAlpha_BlendOptFlag = 0x2,
362 /**
363 * Instead of emitting a src color, emit coverage in the alpha channel and r,g,b are
364 * "don't cares".
365 */
366 kEmitCoverage_BlendOptFlag = 0x4,
367 /**
368 * Emit transparent black instead of the src color, no need to compute coverage.
369 */
370 kEmitTransBlack_BlendOptFlag = 0x8,
371 };
372 GR_DECL_BITFIELD_OPS_FRIENDS(BlendOptFlags);
373
374 /**
egdaniel3658f382014-09-15 07:01:59 -0700375 * Constructs and optimized drawState out of a GrRODrawState.
376 */
egdaniel170f90b2014-09-16 12:54:40 -0700377 GrOptDrawState(const GrDrawState& drawState, BlendOptFlags blendOptFlags,
egdanielc0648242014-09-22 13:17:02 -0700378 GrBlendCoeff optSrcCoeff, GrBlendCoeff optDstCoeff,
379 const GrDrawTargetCaps& caps);
egdaniel3658f382014-09-15 07:01:59 -0700380
egdaniel170f90b2014-09-16 12:54:40 -0700381 /**
egdaniel3658f382014-09-15 07:01:59 -0700382 * Loops through all the color stage effects to check if the stage will ignore color input or
383 * always output a constant color. In the ignore color input case we can ignore all previous
384 * stages. In the constant color case, we can ignore all previous stages and
egdaniel9cf45bf2014-10-08 06:49:10 -0700385 * the current one and set the state color to the constant color.
egdaniel3658f382014-09-15 07:01:59 -0700386 */
egdaniel9cf45bf2014-10-08 06:49:10 -0700387 void computeEffectiveColorStages(const GrDrawState& ds, int* firstColorStageIdx,
388 uint8_t* fixFunctionVAToRemove);
egdaniel3658f382014-09-15 07:01:59 -0700389
egdaniel170f90b2014-09-16 12:54:40 -0700390 /**
egdaniel3658f382014-09-15 07:01:59 -0700391 * Loops through all the coverage stage effects to check if the stage will ignore color input.
392 * If a coverage stage will ignore input, then we can ignore all coverage stages before it. We
egdaniel9cf45bf2014-10-08 06:49:10 -0700393 * loop to determine the first effective coverage stage.
egdaniel3658f382014-09-15 07:01:59 -0700394 */
egdaniel9cf45bf2014-10-08 06:49:10 -0700395 void computeEffectiveCoverageStages(const GrDrawState& ds, int* firstCoverageStageIdx);
egdaniel3658f382014-09-15 07:01:59 -0700396
egdaniel170f90b2014-09-16 12:54:40 -0700397 /**
egdaniel3658f382014-09-15 07:01:59 -0700398 * This function takes in a flag and removes the corresponding fixed function vertex attributes.
399 * The flags are in the same order as GrVertexAttribBinding array. If bit i of removeVAFlags is
400 * set, then vertex attributes with binding (GrVertexAttribute)i will be removed.
401 */
402 void removeFixedFunctionVertexAttribs(uint8_t removeVAFlags);
403
egdaniel170f90b2014-09-16 12:54:40 -0700404 /**
405 * Alter the OptDrawState (adjusting stages, vertex attribs, flags, etc.) based on the
406 * BlendOptFlags.
407 */
egdaniel9cf45bf2014-10-08 06:49:10 -0700408 void adjustFromBlendOpts(const GrDrawState& ds, int* firstColorStageIdx,
409 int* firstCoverageStageIdx, uint8_t* fixedFunctionVAToRemove);
egdaniel3658f382014-09-15 07:01:59 -0700410
egdaniela7dc0a82014-09-17 08:25:05 -0700411 /**
412 * Loop over the effect stages to determine various info like what data they will read and what
413 * shaders they require.
414 */
egdaniel9cf45bf2014-10-08 06:49:10 -0700415 void getStageStats(const GrDrawState& ds, int firstColorStageIdx, int firstCoverageStageIdx);
egdaniela7dc0a82014-09-17 08:25:05 -0700416
egdanielc0648242014-09-22 13:17:02 -0700417 /**
418 * Calculates the primary and secondary output types of the shader. For certain output types
419 * the function may adjust the blend coefficients. After this function is called the src and dst
420 * blend coeffs will represent those used by backend API.
421 */
egdaniel9cf45bf2014-10-08 06:49:10 -0700422 void setOutputStateInfo(const GrDrawState& ds, const GrDrawTargetCaps&,
423 int firstCoverageStageIdx, bool* separateCoverageFromColor);
egdanielc0648242014-09-22 13:17:02 -0700424
egdaniel89af44a2014-09-26 06:15:04 -0700425 bool isEqual(const GrOptDrawState& that) const;
426
427 // These fields are roughly sorted by decreasing likelihood of being different in op==
428 typedef GrTGpuResourceRef<GrRenderTarget> ProgramRenderTarget;
429 ProgramRenderTarget fRenderTarget;
430 GrColor fColor;
431 SkMatrix fViewMatrix;
432 GrColor fBlendConstant;
433 uint32_t fFlagBits;
434 const GrVertexAttrib* fVAPtr;
435 int fVACount;
436 size_t fVAStride;
437 GrStencilSettings fStencilSettings;
438 uint8_t fCoverage;
439 DrawFace fDrawFace;
440 GrBlendCoeff fSrcBlend;
441 GrBlendCoeff fDstBlend;
442
egdaniel9cf45bf2014-10-08 06:49:10 -0700443 typedef SkSTArray<8, GrFragmentStage> FragmentStageArray;
joshualitta5305a12014-10-10 17:47:00 -0700444 typedef GrProgramElementRef<const GrGeometryProcessor> ProgramGeometryProcessor;
445 ProgramGeometryProcessor fGeometryProcessor;
446 FragmentStageArray fFragmentStages;
egdanield9aa2182014-10-09 13:47:05 -0700447
448 // This function is equivalent to the offset into fFragmentStages where coverage stages begin.
joshualitta5305a12014-10-10 17:47:00 -0700449 int fNumColorStages;
egdaniel89af44a2014-09-26 06:15:04 -0700450
451 // This is simply a different representation of info in fVertexAttribs and thus does
452 // not need to be compared in op==.
453 int fFixedFunctionVertexAttribIndices[kGrFixedFunctionVertexAttribBindingCnt];
454
egdaniel3658f382014-09-15 07:01:59 -0700455 // These flags are needed to protect the code from creating an unused uniform color/coverage
456 // which will cause shader compiler errors.
457 bool fInputColorIsUsed;
458 bool fInputCoverageIsUsed;
459
egdaniela7dc0a82014-09-17 08:25:05 -0700460 // These flags give aggregated info on the effect stages that are used when building programs.
461 bool fReadsDst;
462 bool fReadsFragPosition;
egdaniela7dc0a82014-09-17 08:25:05 -0700463 bool fRequiresLocalCoordAttrib;
464
egdaniel3658f382014-09-15 07:01:59 -0700465 SkAutoSTArray<4, GrVertexAttrib> fOptVA;
466
egdaniel170f90b2014-09-16 12:54:40 -0700467 BlendOptFlags fBlendOptFlags;
468
egdanielc0648242014-09-22 13:17:02 -0700469 // Fragment shader color outputs
470 PrimaryOutputType fPrimaryOutputType : 8;
471 SecondaryOutputType fSecondaryOutputType : 8;
472
egdaniel89af44a2014-09-26 06:15:04 -0700473 typedef SkRefCnt INHERITED;
egdaniel3658f382014-09-15 07:01:59 -0700474};
475
egdaniel89af44a2014-09-26 06:15:04 -0700476GR_MAKE_BITFIELD_OPS(GrOptDrawState::BlendOptFlags);
477
egdaniel3658f382014-09-15 07:01:59 -0700478#endif
egdaniel89af44a2014-09-26 06:15:04 -0700479