|
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 "GrBackendEffectFactory.h" |
|
12 #include "GrBlend.h" |
|
13 #include "GrColor.h" |
|
14 #include "GrEffectStage.h" |
|
15 #include "GrPaint.h" |
|
16 #include "GrPoint.h" |
|
17 #include "GrRenderTarget.h" |
|
18 #include "GrStencil.h" |
|
19 #include "GrTemplates.h" |
|
20 #include "GrTexture.h" |
|
21 #include "GrTypesPriv.h" |
|
22 #include "effects/GrSimpleTextureEffect.h" |
|
23 |
|
24 #include "SkMatrix.h" |
|
25 #include "SkTypes.h" |
|
26 #include "SkXfermode.h" |
|
27 |
|
28 class GrDrawState : public SkRefCnt { |
|
29 public: |
|
30 SK_DECLARE_INST_COUNT(GrDrawState) |
|
31 |
|
32 GrDrawState() { |
|
33 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;) |
|
34 this->reset(); |
|
35 } |
|
36 |
|
37 GrDrawState(const SkMatrix& initialViewMatrix) { |
|
38 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;) |
|
39 this->reset(initialViewMatrix); |
|
40 } |
|
41 |
|
42 /** |
|
43 * Copies another draw state. |
|
44 **/ |
|
45 GrDrawState(const GrDrawState& state) : INHERITED() { |
|
46 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;) |
|
47 *this = state; |
|
48 } |
|
49 |
|
50 /** |
|
51 * Copies another draw state with a preconcat to the view matrix. |
|
52 **/ |
|
53 GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatrix) { |
|
54 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;) |
|
55 *this = state; |
|
56 if (!preConcatMatrix.isIdentity()) { |
|
57 for (int i = 0; i < fColorStages.count(); ++i) { |
|
58 fColorStages[i].localCoordChange(preConcatMatrix); |
|
59 } |
|
60 for (int i = 0; i < fCoverageStages.count(); ++i) { |
|
61 fCoverageStages[i].localCoordChange(preConcatMatrix); |
|
62 } |
|
63 } |
|
64 } |
|
65 |
|
66 virtual ~GrDrawState() { SkASSERT(0 == fBlockEffectRemovalCnt); } |
|
67 |
|
68 /** |
|
69 * Resets to the default state. GrEffects will be removed from all stages. |
|
70 */ |
|
71 void reset() { this->onReset(NULL); } |
|
72 |
|
73 void reset(const SkMatrix& initialViewMatrix) { this->onReset(&initialViewMatrix); } |
|
74 |
|
75 /** |
|
76 * Initializes the GrDrawState based on a GrPaint, view matrix and render target. Note that |
|
77 * GrDrawState encompasses more than GrPaint. Aspects of GrDrawState that have no GrPaint |
|
78 * equivalents are set to default values. Clipping will be enabled. |
|
79 */ |
|
80 void setFromPaint(const GrPaint& , const SkMatrix& viewMatrix, GrRenderTarget*); |
|
81 |
|
82 /////////////////////////////////////////////////////////////////////////// |
|
83 /// @name Vertex Attributes |
|
84 //// |
|
85 |
|
86 enum { |
|
87 kMaxVertexAttribCnt = kLast_GrVertexAttribBinding + 4, |
|
88 }; |
|
89 |
|
90 /** |
|
91 * The format of vertices is represented as an array of GrVertexAttribs, with each representing |
|
92 * the type of the attribute, its offset, and semantic binding (see GrVertexAttrib in |
|
93 * GrTypesPriv.h). |
|
94 * |
|
95 * The mapping of attributes with kEffect bindings to GrEffect inputs is specified when |
|
96 * setEffect is called. |
|
97 */ |
|
98 |
|
99 /** |
|
100 * Sets vertex attributes for next draw. The object driving the templatization |
|
101 * should be a global GrVertexAttrib array that is never changed. |
|
102 */ |
|
103 template <const GrVertexAttrib A[]> void setVertexAttribs(int count) { |
|
104 this->setVertexAttribs(A, count); |
|
105 } |
|
106 |
|
107 const GrVertexAttrib* getVertexAttribs() const { return fCommon.fVAPtr; } |
|
108 int getVertexAttribCount() const { return fCommon.fVACount; } |
|
109 |
|
110 size_t getVertexSize() const; |
|
111 |
|
112 /** |
|
113 * Sets default vertex attributes for next draw. The default is a single attribute: |
|
114 * {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribType} |
|
115 */ |
|
116 void setDefaultVertexAttribs(); |
|
117 |
|
118 /** |
|
119 * Getters for index into getVertexAttribs() for particular bindings. -1 is returned if the |
|
120 * binding does not appear in the current attribs. These bindings should appear only once in |
|
121 * the attrib array. |
|
122 */ |
|
123 |
|
124 int positionAttributeIndex() const { |
|
125 return fCommon.fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding]; |
|
126 } |
|
127 int localCoordAttributeIndex() const { |
|
128 return fCommon.fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding]; |
|
129 } |
|
130 int colorVertexAttributeIndex() const { |
|
131 return fCommon.fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding]; |
|
132 } |
|
133 int coverageVertexAttributeIndex() const { |
|
134 return fCommon.fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding]; |
|
135 } |
|
136 |
|
137 bool hasLocalCoordAttribute() const { |
|
138 return -1 != fCommon.fFixedFunctionVertexAttribIndices[kLocalCoord_GrVertexAttribBinding]; |
|
139 } |
|
140 bool hasColorVertexAttribute() const { |
|
141 return -1 != fCommon.fFixedFunctionVertexAttribIndices[kColor_GrVertexAttribBinding]; |
|
142 } |
|
143 bool hasCoverageVertexAttribute() const { |
|
144 return -1 != fCommon.fFixedFunctionVertexAttribIndices[kCoverage_GrVertexAttribBinding]; |
|
145 } |
|
146 |
|
147 bool validateVertexAttribs() const; |
|
148 |
|
149 /** |
|
150 * Helper to save/restore vertex attribs |
|
151 */ |
|
152 class AutoVertexAttribRestore { |
|
153 public: |
|
154 AutoVertexAttribRestore(GrDrawState* drawState) { |
|
155 SkASSERT(NULL != drawState); |
|
156 fDrawState = drawState; |
|
157 fVAPtr = drawState->fCommon.fVAPtr; |
|
158 fVACount = drawState->fCommon.fVACount; |
|
159 fDrawState->setDefaultVertexAttribs(); |
|
160 } |
|
161 |
|
162 ~AutoVertexAttribRestore(){ |
|
163 fDrawState->setVertexAttribs(fVAPtr, fVACount); |
|
164 } |
|
165 |
|
166 private: |
|
167 GrDrawState* fDrawState; |
|
168 const GrVertexAttrib* fVAPtr; |
|
169 int fVACount; |
|
170 }; |
|
171 |
|
172 /** |
|
173 * Accessing positions, local coords, or colors, of a vertex within an array is a hassle |
|
174 * involving casts and simple math. These helpers exist to keep GrDrawTarget clients' code a bit |
|
175 * nicer looking. |
|
176 */ |
|
177 |
|
178 /** |
|
179 * Gets a pointer to a GrPoint of a vertex's position or texture |
|
180 * coordinate. |
|
181 * @param vertices the vertex array |
|
182 * @param vertexIndex the index of the vertex in the array |
|
183 * @param vertexSize the size of each vertex in the array |
|
184 * @param offset the offset in bytes of the vertex component. |
|
185 * Defaults to zero (corresponding to vertex position) |
|
186 * @return pointer to the vertex component as a GrPoint |
|
187 */ |
|
188 static GrPoint* GetVertexPoint(void* vertices, |
|
189 int vertexIndex, |
|
190 int vertexSize, |
|
191 int offset = 0) { |
|
192 intptr_t start = GrTCast<intptr_t>(vertices); |
|
193 return GrTCast<GrPoint*>(start + offset + |
|
194 vertexIndex * vertexSize); |
|
195 } |
|
196 static const GrPoint* GetVertexPoint(const void* vertices, |
|
197 int vertexIndex, |
|
198 int vertexSize, |
|
199 int offset = 0) { |
|
200 intptr_t start = GrTCast<intptr_t>(vertices); |
|
201 return GrTCast<const GrPoint*>(start + offset + |
|
202 vertexIndex * vertexSize); |
|
203 } |
|
204 |
|
205 /** |
|
206 * Gets a pointer to a GrColor inside a vertex within a vertex array. |
|
207 * @param vertices the vetex array |
|
208 * @param vertexIndex the index of the vertex in the array |
|
209 * @param vertexSize the size of each vertex in the array |
|
210 * @param offset the offset in bytes of the vertex color |
|
211 * @return pointer to the vertex component as a GrColor |
|
212 */ |
|
213 static GrColor* GetVertexColor(void* vertices, |
|
214 int vertexIndex, |
|
215 int vertexSize, |
|
216 int offset) { |
|
217 intptr_t start = GrTCast<intptr_t>(vertices); |
|
218 return GrTCast<GrColor*>(start + offset + |
|
219 vertexIndex * vertexSize); |
|
220 } |
|
221 static const GrColor* GetVertexColor(const void* vertices, |
|
222 int vertexIndex, |
|
223 int vertexSize, |
|
224 int offset) { |
|
225 const intptr_t start = GrTCast<intptr_t>(vertices); |
|
226 return GrTCast<const GrColor*>(start + offset + |
|
227 vertexIndex * vertexSize); |
|
228 } |
|
229 |
|
230 /// @} |
|
231 |
|
232 /** |
|
233 * Determines whether src alpha is guaranteed to be one for all src pixels |
|
234 */ |
|
235 bool srcAlphaWillBeOne() const; |
|
236 |
|
237 /** |
|
238 * Determines whether the output coverage is guaranteed to be one for all pixels hit by a draw. |
|
239 */ |
|
240 bool hasSolidCoverage() const; |
|
241 |
|
242 /// @} |
|
243 |
|
244 /////////////////////////////////////////////////////////////////////////// |
|
245 /// @name Color |
|
246 //// |
|
247 |
|
248 /** |
|
249 * Sets color for next draw to a premultiplied-alpha color. |
|
250 * |
|
251 * @param color the color to set. |
|
252 */ |
|
253 void setColor(GrColor color) { fCommon.fColor = color; } |
|
254 |
|
255 GrColor getColor() const { return fCommon.fColor; } |
|
256 |
|
257 /** |
|
258 * Sets the color to be used for the next draw to be |
|
259 * (r,g,b,a) = (alpha, alpha, alpha, alpha). |
|
260 * |
|
261 * @param alpha The alpha value to set as the color. |
|
262 */ |
|
263 void setAlpha(uint8_t a) { |
|
264 this->setColor((a << 24) | (a << 16) | (a << 8) | a); |
|
265 } |
|
266 |
|
267 /** |
|
268 * Constructor sets the color to be 'color' which is undone by the destructor. |
|
269 */ |
|
270 class AutoColorRestore : public ::SkNoncopyable { |
|
271 public: |
|
272 AutoColorRestore() : fDrawState(NULL), fOldColor(0) {} |
|
273 |
|
274 AutoColorRestore(GrDrawState* drawState, GrColor color) { |
|
275 fDrawState = NULL; |
|
276 this->set(drawState, color); |
|
277 } |
|
278 |
|
279 void reset() { |
|
280 if (NULL != fDrawState) { |
|
281 fDrawState->setColor(fOldColor); |
|
282 fDrawState = NULL; |
|
283 } |
|
284 } |
|
285 |
|
286 void set(GrDrawState* drawState, GrColor color) { |
|
287 this->reset(); |
|
288 fDrawState = drawState; |
|
289 fOldColor = fDrawState->getColor(); |
|
290 fDrawState->setColor(color); |
|
291 } |
|
292 |
|
293 ~AutoColorRestore() { this->reset(); } |
|
294 private: |
|
295 GrDrawState* fDrawState; |
|
296 GrColor fOldColor; |
|
297 }; |
|
298 |
|
299 /// @} |
|
300 |
|
301 /////////////////////////////////////////////////////////////////////////// |
|
302 /// @name Coverage |
|
303 //// |
|
304 |
|
305 /** |
|
306 * Sets a constant fractional coverage to be applied to the draw. The |
|
307 * initial value (after construction or reset()) is 0xff. The constant |
|
308 * coverage is ignored when per-vertex coverage is provided. |
|
309 */ |
|
310 void setCoverage(uint8_t coverage) { |
|
311 fCommon.fCoverage = GrColorPackRGBA(coverage, coverage, coverage, coverage); |
|
312 } |
|
313 |
|
314 uint8_t getCoverage() const { |
|
315 return GrColorUnpackR(fCommon.fCoverage); |
|
316 } |
|
317 |
|
318 GrColor getCoverageColor() const { |
|
319 return fCommon.fCoverage; |
|
320 } |
|
321 |
|
322 /// @} |
|
323 |
|
324 /////////////////////////////////////////////////////////////////////////// |
|
325 /// @name Effect Stages |
|
326 /// Each stage hosts a GrEffect. The effect produces an output color or coverage in the fragment |
|
327 /// shader. Its inputs are the output from the previous stage as well as some variables |
|
328 /// available to it in the fragment and vertex shader (e.g. the vertex position, the dst color, |
|
329 /// the fragment position, local coordinates). |
|
330 /// |
|
331 /// The stages are divided into two sets, color-computing and coverage-computing. The final |
|
332 /// color stage produces the final pixel color. The coverage-computing stages function exactly |
|
333 /// as the color-computing but the output of the final coverage stage is treated as a fractional |
|
334 /// pixel coverage rather than as input to the src/dst color blend step. |
|
335 /// |
|
336 /// The input color to the first color-stage is either the constant color or interpolated |
|
337 /// per-vertex colors. The input to the first coverage stage is either a constant coverage |
|
338 /// (usually full-coverage) or interpolated per-vertex coverage. |
|
339 /// |
|
340 /// See the documentation of kCoverageDrawing_StateBit for information about disabling the |
|
341 /// the color / coverage distinction. |
|
342 //// |
|
343 |
|
344 const GrEffectRef* addColorEffect(const GrEffectRef* effect, int attr0 = -1, int attr1 = -1) { |
|
345 SkASSERT(NULL != effect); |
|
346 SkNEW_APPEND_TO_TARRAY(&fColorStages, GrEffectStage, (effect, attr0, attr1)); |
|
347 return effect; |
|
348 } |
|
349 |
|
350 const GrEffectRef* addCoverageEffect(const GrEffectRef* effect, int attr0 = -1, int attr1 = -1) { |
|
351 SkASSERT(NULL != effect); |
|
352 SkNEW_APPEND_TO_TARRAY(&fCoverageStages, GrEffectStage, (effect, attr0, attr1)); |
|
353 return effect; |
|
354 } |
|
355 |
|
356 /** |
|
357 * Creates a GrSimpleTextureEffect that uses local coords as texture coordinates. |
|
358 */ |
|
359 void addColorTextureEffect(GrTexture* texture, const SkMatrix& matrix) { |
|
360 GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix); |
|
361 this->addColorEffect(effect)->unref(); |
|
362 } |
|
363 |
|
364 void addCoverageTextureEffect(GrTexture* texture, const SkMatrix& matrix) { |
|
365 GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix); |
|
366 this->addCoverageEffect(effect)->unref(); |
|
367 } |
|
368 |
|
369 void addColorTextureEffect(GrTexture* texture, |
|
370 const SkMatrix& matrix, |
|
371 const GrTextureParams& params) { |
|
372 GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params); |
|
373 this->addColorEffect(effect)->unref(); |
|
374 } |
|
375 |
|
376 void addCoverageTextureEffect(GrTexture* texture, |
|
377 const SkMatrix& matrix, |
|
378 const GrTextureParams& params) { |
|
379 GrEffectRef* effect = GrSimpleTextureEffect::Create(texture, matrix, params); |
|
380 this->addCoverageEffect(effect)->unref(); |
|
381 } |
|
382 |
|
383 /** |
|
384 * When this object is destroyed it will remove any effects from the draw state that were added |
|
385 * after its constructor. |
|
386 */ |
|
387 class AutoRestoreEffects : public ::SkNoncopyable { |
|
388 public: |
|
389 AutoRestoreEffects() : fDrawState(NULL), fColorEffectCnt(0), fCoverageEffectCnt(0) {} |
|
390 |
|
391 AutoRestoreEffects(GrDrawState* ds) : fDrawState(NULL), fColorEffectCnt(0), fCoverageEffectCnt(0) { |
|
392 this->set(ds); |
|
393 } |
|
394 |
|
395 ~AutoRestoreEffects() { this->set(NULL); } |
|
396 |
|
397 void set(GrDrawState* ds) { |
|
398 if (NULL != fDrawState) { |
|
399 int n = fDrawState->fColorStages.count() - fColorEffectCnt; |
|
400 SkASSERT(n >= 0); |
|
401 fDrawState->fColorStages.pop_back_n(n); |
|
402 n = fDrawState->fCoverageStages.count() - fCoverageEffectCnt; |
|
403 SkASSERT(n >= 0); |
|
404 fDrawState->fCoverageStages.pop_back_n(n); |
|
405 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;) |
|
406 } |
|
407 fDrawState = ds; |
|
408 if (NULL != ds) { |
|
409 fColorEffectCnt = ds->fColorStages.count(); |
|
410 fCoverageEffectCnt = ds->fCoverageStages.count(); |
|
411 SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;) |
|
412 } |
|
413 } |
|
414 |
|
415 private: |
|
416 GrDrawState* fDrawState; |
|
417 int fColorEffectCnt; |
|
418 int fCoverageEffectCnt; |
|
419 }; |
|
420 |
|
421 int numColorStages() const { return fColorStages.count(); } |
|
422 int numCoverageStages() const { return fCoverageStages.count(); } |
|
423 int numTotalStages() const { return this->numColorStages() + this->numCoverageStages(); } |
|
424 |
|
425 const GrEffectStage& getColorStage(int stageIdx) const { return fColorStages[stageIdx]; } |
|
426 const GrEffectStage& getCoverageStage(int stageIdx) const { return fCoverageStages[stageIdx]; } |
|
427 |
|
428 /** |
|
429 * Checks whether any of the effects will read the dst pixel color. |
|
430 */ |
|
431 bool willEffectReadDstColor() const; |
|
432 |
|
433 /// @} |
|
434 |
|
435 /////////////////////////////////////////////////////////////////////////// |
|
436 /// @name Blending |
|
437 //// |
|
438 |
|
439 /** |
|
440 * Sets the blending function coefficients. |
|
441 * |
|
442 * The blend function will be: |
|
443 * D' = sat(S*srcCoef + D*dstCoef) |
|
444 * |
|
445 * where D is the existing destination color, S is the incoming source |
|
446 * color, and D' is the new destination color that will be written. sat() |
|
447 * is the saturation function. |
|
448 * |
|
449 * @param srcCoef coefficient applied to the src color. |
|
450 * @param dstCoef coefficient applied to the dst color. |
|
451 */ |
|
452 void setBlendFunc(GrBlendCoeff srcCoeff, GrBlendCoeff dstCoeff) { |
|
453 fCommon.fSrcBlend = srcCoeff; |
|
454 fCommon.fDstBlend = dstCoeff; |
|
455 #ifdef SK_DEBUG |
|
456 if (GrBlendCoeffRefsDst(dstCoeff)) { |
|
457 GrPrintf("Unexpected dst blend coeff. Won't work correctly with coverage stages.\n"); |
|
458 } |
|
459 if (GrBlendCoeffRefsSrc(srcCoeff)) { |
|
460 GrPrintf("Unexpected src blend coeff. Won't work correctly with coverage stages.\n"); |
|
461 } |
|
462 #endif |
|
463 } |
|
464 |
|
465 GrBlendCoeff getSrcBlendCoeff() const { return fCommon.fSrcBlend; } |
|
466 GrBlendCoeff getDstBlendCoeff() const { return fCommon.fDstBlend; } |
|
467 |
|
468 void getDstBlendCoeff(GrBlendCoeff* srcBlendCoeff, |
|
469 GrBlendCoeff* dstBlendCoeff) const { |
|
470 *srcBlendCoeff = fCommon.fSrcBlend; |
|
471 *dstBlendCoeff = fCommon.fDstBlend; |
|
472 } |
|
473 |
|
474 /** |
|
475 * Sets the blending function constant referenced by the following blending |
|
476 * coefficients: |
|
477 * kConstC_GrBlendCoeff |
|
478 * kIConstC_GrBlendCoeff |
|
479 * kConstA_GrBlendCoeff |
|
480 * kIConstA_GrBlendCoeff |
|
481 * |
|
482 * @param constant the constant to set |
|
483 */ |
|
484 void setBlendConstant(GrColor constant) { fCommon.fBlendConstant = constant; } |
|
485 |
|
486 /** |
|
487 * Retrieves the last value set by setBlendConstant() |
|
488 * @return the blending constant value |
|
489 */ |
|
490 GrColor getBlendConstant() const { return fCommon.fBlendConstant; } |
|
491 |
|
492 /** |
|
493 * Determines whether multiplying the computed per-pixel color by the pixel's fractional |
|
494 * coverage before the blend will give the correct final destination color. In general it |
|
495 * will not as coverage is applied after blending. |
|
496 */ |
|
497 bool canTweakAlphaForCoverage() const; |
|
498 |
|
499 /** |
|
500 * Optimizations for blending / coverage to that can be applied based on the current state. |
|
501 */ |
|
502 enum BlendOptFlags { |
|
503 /** |
|
504 * No optimization |
|
505 */ |
|
506 kNone_BlendOpt = 0, |
|
507 /** |
|
508 * Don't draw at all |
|
509 */ |
|
510 kSkipDraw_BlendOptFlag = 0x1, |
|
511 /** |
|
512 * Emit the src color, disable HW blending (replace dst with src) |
|
513 */ |
|
514 kDisableBlend_BlendOptFlag = 0x2, |
|
515 /** |
|
516 * The coverage value does not have to be computed separately from alpha, the the output |
|
517 * color can be the modulation of the two. |
|
518 */ |
|
519 kCoverageAsAlpha_BlendOptFlag = 0x4, |
|
520 /** |
|
521 * Instead of emitting a src color, emit coverage in the alpha channel and r,g,b are |
|
522 * "don't cares". |
|
523 */ |
|
524 kEmitCoverage_BlendOptFlag = 0x8, |
|
525 /** |
|
526 * Emit transparent black instead of the src color, no need to compute coverage. |
|
527 */ |
|
528 kEmitTransBlack_BlendOptFlag = 0x10, |
|
529 }; |
|
530 GR_DECL_BITFIELD_OPS_FRIENDS(BlendOptFlags); |
|
531 |
|
532 /** |
|
533 * Determines what optimizations can be applied based on the blend. The coefficients may have |
|
534 * to be tweaked in order for the optimization to work. srcCoeff and dstCoeff are optional |
|
535 * params that receive the tweaked coefficients. Normally the function looks at the current |
|
536 * state to see if coverage is enabled. By setting forceCoverage the caller can speculatively |
|
537 * determine the blend optimizations that would be used if there was partial pixel coverage. |
|
538 * |
|
539 * Subclasses of GrDrawTarget that actually draw (as opposed to those that just buffer for |
|
540 * playback) must call this function and respect the flags that replace the output color. |
|
541 */ |
|
542 BlendOptFlags getBlendOpts(bool forceCoverage = false, |
|
543 GrBlendCoeff* srcCoeff = NULL, |
|
544 GrBlendCoeff* dstCoeff = NULL) const; |
|
545 |
|
546 /// @} |
|
547 |
|
548 /////////////////////////////////////////////////////////////////////////// |
|
549 /// @name View Matrix |
|
550 //// |
|
551 |
|
552 /** |
|
553 * Sets the view matrix to identity and updates any installed effects to compensate for the |
|
554 * coord system change. |
|
555 */ |
|
556 bool setIdentityViewMatrix(); |
|
557 |
|
558 /** |
|
559 * Retrieves the current view matrix |
|
560 * @return the current view matrix. |
|
561 */ |
|
562 const SkMatrix& getViewMatrix() const { return fCommon.fViewMatrix; } |
|
563 |
|
564 /** |
|
565 * Retrieves the inverse of the current view matrix. |
|
566 * |
|
567 * If the current view matrix is invertible, return true, and if matrix |
|
568 * is non-null, copy the inverse into it. If the current view matrix is |
|
569 * non-invertible, return false and ignore the matrix parameter. |
|
570 * |
|
571 * @param matrix if not null, will receive a copy of the current inverse. |
|
572 */ |
|
573 bool getViewInverse(SkMatrix* matrix) const { |
|
574 // TODO: determine whether we really need to leave matrix unmodified |
|
575 // at call sites when inversion fails. |
|
576 SkMatrix inverse; |
|
577 if (fCommon.fViewMatrix.invert(&inverse)) { |
|
578 if (matrix) { |
|
579 *matrix = inverse; |
|
580 } |
|
581 return true; |
|
582 } |
|
583 return false; |
|
584 } |
|
585 |
|
586 //////////////////////////////////////////////////////////////////////////// |
|
587 |
|
588 /** |
|
589 * Preconcats the current view matrix and restores the previous view matrix in the destructor. |
|
590 * Effect matrices are automatically adjusted to compensate and adjusted back in the destructor. |
|
591 */ |
|
592 class AutoViewMatrixRestore : public ::SkNoncopyable { |
|
593 public: |
|
594 AutoViewMatrixRestore() : fDrawState(NULL) {} |
|
595 |
|
596 AutoViewMatrixRestore(GrDrawState* ds, const SkMatrix& preconcatMatrix) { |
|
597 fDrawState = NULL; |
|
598 this->set(ds, preconcatMatrix); |
|
599 } |
|
600 |
|
601 ~AutoViewMatrixRestore() { this->restore(); } |
|
602 |
|
603 /** |
|
604 * Can be called prior to destructor to restore the original matrix. |
|
605 */ |
|
606 void restore(); |
|
607 |
|
608 void set(GrDrawState* drawState, const SkMatrix& preconcatMatrix); |
|
609 |
|
610 /** Sets the draw state's matrix to identity. This can fail because the current view matrix |
|
611 is not invertible. */ |
|
612 bool setIdentity(GrDrawState* drawState); |
|
613 |
|
614 private: |
|
615 void doEffectCoordChanges(const SkMatrix& coordChangeMatrix); |
|
616 |
|
617 GrDrawState* fDrawState; |
|
618 SkMatrix fViewMatrix; |
|
619 int fNumColorStages; |
|
620 SkAutoSTArray<8, GrEffectStage::SavedCoordChange> fSavedCoordChanges; |
|
621 }; |
|
622 |
|
623 /// @} |
|
624 |
|
625 /////////////////////////////////////////////////////////////////////////// |
|
626 /// @name Render Target |
|
627 //// |
|
628 |
|
629 /** |
|
630 * Sets the render-target used at the next drawing call |
|
631 * |
|
632 * @param target The render target to set. |
|
633 */ |
|
634 void setRenderTarget(GrRenderTarget* target) { |
|
635 fRenderTarget.reset(SkSafeRef(target)); |
|
636 } |
|
637 |
|
638 /** |
|
639 * Retrieves the currently set render-target. |
|
640 * |
|
641 * @return The currently set render target. |
|
642 */ |
|
643 const GrRenderTarget* getRenderTarget() const { return fRenderTarget.get(); } |
|
644 GrRenderTarget* getRenderTarget() { return fRenderTarget.get(); } |
|
645 |
|
646 class AutoRenderTargetRestore : public ::SkNoncopyable { |
|
647 public: |
|
648 AutoRenderTargetRestore() : fDrawState(NULL), fSavedTarget(NULL) {} |
|
649 AutoRenderTargetRestore(GrDrawState* ds, GrRenderTarget* newTarget) { |
|
650 fDrawState = NULL; |
|
651 fSavedTarget = NULL; |
|
652 this->set(ds, newTarget); |
|
653 } |
|
654 ~AutoRenderTargetRestore() { this->restore(); } |
|
655 |
|
656 void restore() { |
|
657 if (NULL != fDrawState) { |
|
658 fDrawState->setRenderTarget(fSavedTarget); |
|
659 fDrawState = NULL; |
|
660 } |
|
661 SkSafeSetNull(fSavedTarget); |
|
662 } |
|
663 |
|
664 void set(GrDrawState* ds, GrRenderTarget* newTarget) { |
|
665 this->restore(); |
|
666 |
|
667 if (NULL != ds) { |
|
668 SkASSERT(NULL == fSavedTarget); |
|
669 fSavedTarget = ds->getRenderTarget(); |
|
670 SkSafeRef(fSavedTarget); |
|
671 ds->setRenderTarget(newTarget); |
|
672 fDrawState = ds; |
|
673 } |
|
674 } |
|
675 private: |
|
676 GrDrawState* fDrawState; |
|
677 GrRenderTarget* fSavedTarget; |
|
678 }; |
|
679 |
|
680 /// @} |
|
681 |
|
682 /////////////////////////////////////////////////////////////////////////// |
|
683 /// @name Stencil |
|
684 //// |
|
685 |
|
686 /** |
|
687 * Sets the stencil settings to use for the next draw. |
|
688 * Changing the clip has the side-effect of possibly zeroing |
|
689 * out the client settable stencil bits. So multipass algorithms |
|
690 * using stencil should not change the clip between passes. |
|
691 * @param settings the stencil settings to use. |
|
692 */ |
|
693 void setStencil(const GrStencilSettings& settings) { |
|
694 fCommon.fStencilSettings = settings; |
|
695 } |
|
696 |
|
697 /** |
|
698 * Shortcut to disable stencil testing and ops. |
|
699 */ |
|
700 void disableStencil() { |
|
701 fCommon.fStencilSettings.setDisabled(); |
|
702 } |
|
703 |
|
704 const GrStencilSettings& getStencil() const { return fCommon.fStencilSettings; } |
|
705 |
|
706 GrStencilSettings* stencil() { return &fCommon.fStencilSettings; } |
|
707 |
|
708 /// @} |
|
709 |
|
710 /////////////////////////////////////////////////////////////////////////// |
|
711 /// @name State Flags |
|
712 //// |
|
713 |
|
714 /** |
|
715 * Flags that affect rendering. Controlled using enable/disableState(). All |
|
716 * default to disabled. |
|
717 */ |
|
718 enum StateBits { |
|
719 /** |
|
720 * Perform dithering. TODO: Re-evaluate whether we need this bit |
|
721 */ |
|
722 kDither_StateBit = 0x01, |
|
723 /** |
|
724 * Perform HW anti-aliasing. This means either HW FSAA, if supported by the render target, |
|
725 * or smooth-line rendering if a line primitive is drawn and line smoothing is supported by |
|
726 * the 3D API. |
|
727 */ |
|
728 kHWAntialias_StateBit = 0x02, |
|
729 /** |
|
730 * Draws will respect the clip, otherwise the clip is ignored. |
|
731 */ |
|
732 kClip_StateBit = 0x04, |
|
733 /** |
|
734 * Disables writing to the color buffer. Useful when performing stencil |
|
735 * operations. |
|
736 */ |
|
737 kNoColorWrites_StateBit = 0x08, |
|
738 |
|
739 /** |
|
740 * Usually coverage is applied after color blending. The color is blended using the coeffs |
|
741 * specified by setBlendFunc(). The blended color is then combined with dst using coeffs |
|
742 * of src_coverage, 1-src_coverage. Sometimes we are explicitly drawing a coverage mask. In |
|
743 * this case there is no distinction between coverage and color and the caller needs direct |
|
744 * control over the blend coeffs. When set, there will be a single blend step controlled by |
|
745 * setBlendFunc() which will use coverage*color as the src color. |
|
746 */ |
|
747 kCoverageDrawing_StateBit = 0x10, |
|
748 |
|
749 // Users of the class may add additional bits to the vector |
|
750 kDummyStateBit, |
|
751 kLastPublicStateBit = kDummyStateBit-1, |
|
752 }; |
|
753 |
|
754 void resetStateFlags() { |
|
755 fCommon.fFlagBits = 0; |
|
756 } |
|
757 |
|
758 /** |
|
759 * Enable render state settings. |
|
760 * |
|
761 * @param stateBits bitfield of StateBits specifying the states to enable |
|
762 */ |
|
763 void enableState(uint32_t stateBits) { |
|
764 fCommon.fFlagBits |= stateBits; |
|
765 } |
|
766 |
|
767 /** |
|
768 * Disable render state settings. |
|
769 * |
|
770 * @param stateBits bitfield of StateBits specifying the states to disable |
|
771 */ |
|
772 void disableState(uint32_t stateBits) { |
|
773 fCommon.fFlagBits &= ~(stateBits); |
|
774 } |
|
775 |
|
776 /** |
|
777 * Enable or disable stateBits based on a boolean. |
|
778 * |
|
779 * @param stateBits bitfield of StateBits to enable or disable |
|
780 * @param enable if true enable stateBits, otherwise disable |
|
781 */ |
|
782 void setState(uint32_t stateBits, bool enable) { |
|
783 if (enable) { |
|
784 this->enableState(stateBits); |
|
785 } else { |
|
786 this->disableState(stateBits); |
|
787 } |
|
788 } |
|
789 |
|
790 bool isDitherState() const { |
|
791 return 0 != (fCommon.fFlagBits & kDither_StateBit); |
|
792 } |
|
793 |
|
794 bool isHWAntialiasState() const { |
|
795 return 0 != (fCommon.fFlagBits & kHWAntialias_StateBit); |
|
796 } |
|
797 |
|
798 bool isClipState() const { |
|
799 return 0 != (fCommon.fFlagBits & kClip_StateBit); |
|
800 } |
|
801 |
|
802 bool isColorWriteDisabled() const { |
|
803 return 0 != (fCommon.fFlagBits & kNoColorWrites_StateBit); |
|
804 } |
|
805 |
|
806 bool isCoverageDrawing() const { |
|
807 return 0 != (fCommon.fFlagBits & kCoverageDrawing_StateBit); |
|
808 } |
|
809 |
|
810 bool isStateFlagEnabled(uint32_t stateBit) const { |
|
811 return 0 != (stateBit & fCommon.fFlagBits); |
|
812 } |
|
813 |
|
814 /// @} |
|
815 |
|
816 /////////////////////////////////////////////////////////////////////////// |
|
817 /// @name Face Culling |
|
818 //// |
|
819 |
|
820 enum DrawFace { |
|
821 kInvalid_DrawFace = -1, |
|
822 |
|
823 kBoth_DrawFace, |
|
824 kCCW_DrawFace, |
|
825 kCW_DrawFace, |
|
826 }; |
|
827 |
|
828 /** |
|
829 * Controls whether clockwise, counterclockwise, or both faces are drawn. |
|
830 * @param face the face(s) to draw. |
|
831 */ |
|
832 void setDrawFace(DrawFace face) { |
|
833 SkASSERT(kInvalid_DrawFace != face); |
|
834 fCommon.fDrawFace = face; |
|
835 } |
|
836 |
|
837 /** |
|
838 * Gets whether the target is drawing clockwise, counterclockwise, |
|
839 * or both faces. |
|
840 * @return the current draw face(s). |
|
841 */ |
|
842 DrawFace getDrawFace() const { return fCommon.fDrawFace; } |
|
843 |
|
844 /// @} |
|
845 |
|
846 /////////////////////////////////////////////////////////////////////////// |
|
847 |
|
848 bool operator ==(const GrDrawState& s) const { |
|
849 if (fRenderTarget.get() != s.fRenderTarget.get() || |
|
850 fColorStages.count() != s.fColorStages.count() || |
|
851 fCoverageStages.count() != s.fCoverageStages.count() || |
|
852 fCommon != s.fCommon) { |
|
853 return false; |
|
854 } |
|
855 for (int i = 0; i < fColorStages.count(); i++) { |
|
856 if (fColorStages[i] != s.fColorStages[i]) { |
|
857 return false; |
|
858 } |
|
859 } |
|
860 for (int i = 0; i < fCoverageStages.count(); i++) { |
|
861 if (fCoverageStages[i] != s.fCoverageStages[i]) { |
|
862 return false; |
|
863 } |
|
864 } |
|
865 return true; |
|
866 } |
|
867 bool operator !=(const GrDrawState& s) const { return !(*this == s); } |
|
868 |
|
869 GrDrawState& operator= (const GrDrawState& s) { |
|
870 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages()); |
|
871 this->setRenderTarget(s.fRenderTarget.get()); |
|
872 fCommon = s.fCommon; |
|
873 fColorStages = s.fColorStages; |
|
874 fCoverageStages = s.fCoverageStages; |
|
875 return *this; |
|
876 } |
|
877 |
|
878 private: |
|
879 |
|
880 void onReset(const SkMatrix* initialViewMatrix) { |
|
881 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages()); |
|
882 fColorStages.reset(); |
|
883 fCoverageStages.reset(); |
|
884 |
|
885 fRenderTarget.reset(NULL); |
|
886 |
|
887 this->setDefaultVertexAttribs(); |
|
888 |
|
889 fCommon.fColor = 0xffffffff; |
|
890 if (NULL == initialViewMatrix) { |
|
891 fCommon.fViewMatrix.reset(); |
|
892 } else { |
|
893 fCommon.fViewMatrix = *initialViewMatrix; |
|
894 } |
|
895 fCommon.fSrcBlend = kOne_GrBlendCoeff; |
|
896 fCommon.fDstBlend = kZero_GrBlendCoeff; |
|
897 fCommon.fBlendConstant = 0x0; |
|
898 fCommon.fFlagBits = 0x0; |
|
899 fCommon.fStencilSettings.setDisabled(); |
|
900 fCommon.fCoverage = 0xffffffff; |
|
901 fCommon.fDrawFace = kBoth_DrawFace; |
|
902 } |
|
903 |
|
904 /** Fields that are identical in GrDrawState and GrDrawState::DeferredState. */ |
|
905 struct CommonState { |
|
906 // These fields are roughly sorted by decreasing likelihood of being different in op== |
|
907 GrColor fColor; |
|
908 SkMatrix fViewMatrix; |
|
909 GrBlendCoeff fSrcBlend; |
|
910 GrBlendCoeff fDstBlend; |
|
911 GrColor fBlendConstant; |
|
912 uint32_t fFlagBits; |
|
913 const GrVertexAttrib* fVAPtr; |
|
914 int fVACount; |
|
915 GrStencilSettings fStencilSettings; |
|
916 GrColor fCoverage; |
|
917 DrawFace fDrawFace; |
|
918 |
|
919 // This is simply a different representation of info in fVertexAttribs and thus does |
|
920 // not need to be compared in op==. |
|
921 int fFixedFunctionVertexAttribIndices[kGrFixedFunctionVertexAttribBindingCnt]; |
|
922 |
|
923 bool operator== (const CommonState& other) const { |
|
924 bool result = fColor == other.fColor && |
|
925 fViewMatrix.cheapEqualTo(other.fViewMatrix) && |
|
926 fSrcBlend == other.fSrcBlend && |
|
927 fDstBlend == other.fDstBlend && |
|
928 fBlendConstant == other.fBlendConstant && |
|
929 fFlagBits == other.fFlagBits && |
|
930 fVACount == other.fVACount && |
|
931 !memcmp(fVAPtr, other.fVAPtr, fVACount * sizeof(GrVertexAttrib)) && |
|
932 fStencilSettings == other.fStencilSettings && |
|
933 fCoverage == other.fCoverage && |
|
934 fDrawFace == other.fDrawFace; |
|
935 SkASSERT(!result || 0 == memcmp(fFixedFunctionVertexAttribIndices, |
|
936 other.fFixedFunctionVertexAttribIndices, |
|
937 sizeof(fFixedFunctionVertexAttribIndices))); |
|
938 return result; |
|
939 } |
|
940 bool operator!= (const CommonState& other) const { return !(*this == other); } |
|
941 }; |
|
942 |
|
943 /** GrDrawState uses GrEffectStages to hold stage state which holds a ref on GrEffectRef. |
|
944 DeferredState must directly reference GrEffects, however. */ |
|
945 struct SavedEffectStage { |
|
946 SavedEffectStage() : fEffect(NULL) {} |
|
947 const GrEffect* fEffect; |
|
948 GrEffectStage::SavedCoordChange fCoordChange; |
|
949 }; |
|
950 |
|
951 public: |
|
952 /** |
|
953 * DeferredState contains all of the data of a GrDrawState but does not hold refs on GrResource |
|
954 * objects. Resources are allowed to hit zero ref count while in DeferredStates. Their internal |
|
955 * dispose mechanism returns them to the cache. This allows recycling resources through the |
|
956 * the cache while they are in a deferred draw queue. |
|
957 */ |
|
958 class DeferredState { |
|
959 public: |
|
960 DeferredState() : fRenderTarget(NULL) { |
|
961 SkDEBUGCODE(fInitialized = false;) |
|
962 } |
|
963 // TODO: Remove this when DeferredState no longer holds a ref to the RT |
|
964 ~DeferredState() { SkSafeUnref(fRenderTarget); } |
|
965 |
|
966 void saveFrom(const GrDrawState& drawState) { |
|
967 fCommon = drawState.fCommon; |
|
968 // TODO: Here we will copy the GrRenderTarget pointer without taking a ref. |
|
969 fRenderTarget = drawState.fRenderTarget.get(); |
|
970 SkSafeRef(fRenderTarget); |
|
971 // Here we ref the effects directly rather than the effect-refs. TODO: When the effect- |
|
972 // ref gets fully unref'ed it will cause the underlying effect to unref its resources |
|
973 // and recycle them to the cache (if no one else is holding a ref to the resources). |
|
974 fStages.reset(drawState.fColorStages.count() + drawState.fCoverageStages.count()); |
|
975 fColorStageCnt = drawState.fColorStages.count(); |
|
976 for (int i = 0; i < fColorStageCnt; ++i) { |
|
977 fStages[i].saveFrom(drawState.fColorStages[i]); |
|
978 } |
|
979 for (int i = 0; i < drawState.fCoverageStages.count(); ++i) { |
|
980 fStages[i + fColorStageCnt].saveFrom(drawState.fCoverageStages[i]); |
|
981 } |
|
982 SkDEBUGCODE(fInitialized = true;) |
|
983 } |
|
984 |
|
985 void restoreTo(GrDrawState* drawState) { |
|
986 SkASSERT(fInitialized); |
|
987 drawState->fCommon = fCommon; |
|
988 drawState->setRenderTarget(fRenderTarget); |
|
989 // reinflate color/cov stage arrays. |
|
990 drawState->fColorStages.reset(); |
|
991 for (int i = 0; i < fColorStageCnt; ++i) { |
|
992 SkNEW_APPEND_TO_TARRAY(&drawState->fColorStages, GrEffectStage, (fStages[i])); |
|
993 } |
|
994 int coverageStageCnt = fStages.count() - fColorStageCnt; |
|
995 drawState->fCoverageStages.reset(); |
|
996 for (int i = 0; i < coverageStageCnt; ++i) { |
|
997 SkNEW_APPEND_TO_TARRAY(&drawState->fCoverageStages, |
|
998 GrEffectStage, (fStages[i + fColorStageCnt])); |
|
999 } |
|
1000 } |
|
1001 |
|
1002 bool isEqual(const GrDrawState& state) const { |
|
1003 int numCoverageStages = fStages.count() - fColorStageCnt; |
|
1004 if (fRenderTarget != state.fRenderTarget.get() || |
|
1005 fColorStageCnt != state.fColorStages.count() || |
|
1006 numCoverageStages != state.fCoverageStages.count() || |
|
1007 fCommon != state.fCommon) { |
|
1008 return false; |
|
1009 } |
|
1010 bool explicitLocalCoords = state.hasLocalCoordAttribute(); |
|
1011 for (int i = 0; i < fColorStageCnt; ++i) { |
|
1012 if (!fStages[i].isEqual(state.fColorStages[i], explicitLocalCoords)) { |
|
1013 return false; |
|
1014 } |
|
1015 } |
|
1016 for (int i = 0; i < numCoverageStages; ++i) { |
|
1017 int s = fColorStageCnt + i; |
|
1018 if (!fStages[s].isEqual(state.fCoverageStages[i], explicitLocalCoords)) { |
|
1019 return false; |
|
1020 } |
|
1021 } |
|
1022 return true; |
|
1023 } |
|
1024 |
|
1025 private: |
|
1026 typedef SkAutoSTArray<8, GrEffectStage::DeferredStage> DeferredStageArray; |
|
1027 |
|
1028 GrRenderTarget* fRenderTarget; |
|
1029 CommonState fCommon; |
|
1030 int fColorStageCnt; |
|
1031 DeferredStageArray fStages; |
|
1032 |
|
1033 SkDEBUGCODE(bool fInitialized;) |
|
1034 }; |
|
1035 |
|
1036 private: |
|
1037 |
|
1038 SkAutoTUnref<GrRenderTarget> fRenderTarget; |
|
1039 CommonState fCommon; |
|
1040 |
|
1041 typedef SkSTArray<4, GrEffectStage> EffectStageArray; |
|
1042 EffectStageArray fColorStages; |
|
1043 EffectStageArray fCoverageStages; |
|
1044 |
|
1045 // Some of the auto restore objects assume that no effects are removed during their lifetime. |
|
1046 // This is used to assert that this condition holds. |
|
1047 SkDEBUGCODE(int fBlockEffectRemovalCnt;) |
|
1048 |
|
1049 /** |
|
1050 * Sets vertex attributes for next draw. |
|
1051 * |
|
1052 * @param attribs the array of vertex attributes to set. |
|
1053 * @param count the number of attributes being set, limited to kMaxVertexAttribCnt. |
|
1054 */ |
|
1055 void setVertexAttribs(const GrVertexAttrib attribs[], int count); |
|
1056 |
|
1057 typedef SkRefCnt INHERITED; |
|
1058 }; |
|
1059 |
|
1060 GR_MAKE_BITFIELD_OPS(GrDrawState::BlendOptFlags); |
|
1061 |
|
1062 #endif |