• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright 2012 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 #include "GrDrawState.h"
9 
10 #include "GrGpuVertex.h"
11 #include "GrPaint.h"
12 
setFromPaint(const GrPaint & paint)13 void GrDrawState::setFromPaint(const GrPaint& paint) {
14     for (int i = 0; i < GrPaint::kMaxColorStages; ++i) {
15         int s = i + GrPaint::kFirstColorStage;
16         if (paint.isColorStageEnabled(i)) {
17             fStages[s] = paint.getColorStage(i);
18         } else {
19             fStages[s].setEffect(NULL);
20         }
21     }
22 
23     this->setFirstCoverageStage(GrPaint::kFirstCoverageStage);
24 
25     for (int i = 0; i < GrPaint::kMaxCoverageStages; ++i) {
26         int s = i + GrPaint::kFirstCoverageStage;
27         if (paint.isCoverageStageEnabled(i)) {
28             fStages[s] = paint.getCoverageStage(i);
29         } else {
30             fStages[s].setEffect(NULL);
31         }
32     }
33 
34     // disable all stages not accessible via the paint
35     for (int s = GrPaint::kTotalStages; s < GrDrawState::kNumStages; ++s) {
36         this->disableStage(s);
37     }
38 
39     this->setColor(paint.getColor());
40 
41     this->setState(GrDrawState::kDither_StateBit, paint.isDither());
42     this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias());
43 
44     this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff());
45     this->setColorFilter(paint.getColorFilterColor(), paint.getColorFilterMode());
46     this->setCoverage(paint.getCoverage());
47 }
48 
49 ////////////////////////////////////////////////////////////////////////////////
50 
51 namespace {
52 
53 /**
54  * This function generates some masks that we like to have known at compile
55  * time. When the number of stages or tex coords is bumped or the way bits
56  * are defined in GrDrawState.h changes this function should be rerun to
57  * generate the new masks. (We attempted to force the compiler to generate the
58  * masks using recursive templates but always wound up with static initializers
59  * under gcc, even if they were just a series of immediate->memory moves.)
60  *
61  */
gen_mask_arrays(GrVertexLayout * stageTexCoordMasks,GrVertexLayout * texCoordMasks)62 void gen_mask_arrays(GrVertexLayout* stageTexCoordMasks,
63                      GrVertexLayout* texCoordMasks) {
64     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
65         stageTexCoordMasks[s] = 0;
66         for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
67             stageTexCoordMasks[s] |= GrDrawState::StageTexCoordVertexLayoutBit(s, t);
68         }
69     }
70     for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
71         texCoordMasks[t] = 0;
72         for (int s = 0; s < GrDrawState::kNumStages; ++s) {
73             texCoordMasks[t] |= GrDrawState::StageTexCoordVertexLayoutBit(s, t);
74         }
75     }
76 }
77 
78 /**
79  * Uncomment and run the gen_globals function to generate
80  * the code that declares the global masks.
81  *
82  * #if 0'ed out to avoid unused function warning.
83  */
84 
85 #if 0
86 void gen_globals() {
87     GrVertexLayout stageTexCoordMasks[GrDrawState::kNumStages];
88     GrVertexLayout texCoordMasks[GrDrawState::kMaxTexCoords];
89     gen_mask_arrays(stageTexCoordMasks, texCoordMasks);
90 
91     GrPrintf("const GrVertexLayout gStageTexCoordMasks[] = {\n");
92     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
93         GrPrintf("    0x%x,\n", stageTexCoordMasks[s]);
94     }
95     GrPrintf("};\n");
96     GrPrintf("GR_STATIC_ASSERT(GrDrawState::kNumStages == GR_ARRAY_COUNT(gStageTexCoordMasks));\n\n");
97     GrPrintf("const GrVertexLayout gTexCoordMasks[] = {\n");
98     for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
99         GrPrintf("    0x%x,\n", texCoordMasks[t]);
100     }
101     GrPrintf("};\n");
102     GrPrintf("GR_STATIC_ASSERT(GrDrawState::kMaxTexCoords == GR_ARRAY_COUNT(gTexCoordMasks));\n");
103 }
104 #endif
105 
106 /* These values were generated by the above function */
107 
108 const GrVertexLayout gStageTexCoordMasks[] = {
109     0x108421,
110     0x210842,
111     0x421084,
112     0x842108,
113     0x1084210,
114 };
115 GR_STATIC_ASSERT(GrDrawState::kNumStages == GR_ARRAY_COUNT(gStageTexCoordMasks));
116 
117 const GrVertexLayout gTexCoordMasks[] = {
118     0x1f,
119     0x3e0,
120     0x7c00,
121     0xf8000,
122     0x1f00000,
123 };
124 GR_STATIC_ASSERT(GrDrawState::kMaxTexCoords == GR_ARRAY_COUNT(gTexCoordMasks));
125 
126 #ifdef SK_DEBUG
check_layout(GrVertexLayout layout)127 bool check_layout(GrVertexLayout layout) {
128     // can only have 1 or 0 bits set for each stage.
129     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
130         int stageBits = layout & gStageTexCoordMasks[s];
131         if (stageBits && !GrIsPow2(stageBits)) {
132             return false;
133         }
134     }
135     return true;
136 }
137 #endif
138 
num_tex_coords(GrVertexLayout layout)139 int num_tex_coords(GrVertexLayout layout) {
140     int cnt = 0;
141     // figure out how many tex coordinates are present
142     for (int t = 0; t < GrDrawState::kMaxTexCoords; ++t) {
143         if (gTexCoordMasks[t] & layout) {
144             ++cnt;
145         }
146     }
147     return cnt;
148 }
149 
150 } //unnamed namespace
151 
VertexSize(GrVertexLayout vertexLayout)152 size_t GrDrawState::VertexSize(GrVertexLayout vertexLayout) {
153     GrAssert(check_layout(vertexLayout));
154 
155     size_t vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
156                         sizeof(GrGpuTextVertex) :
157                         sizeof(GrPoint);
158 
159     size_t size = vecSize; // position
160     size += num_tex_coords(vertexLayout) * vecSize;
161     if (vertexLayout & kColor_VertexLayoutBit) {
162         size += sizeof(GrColor);
163     }
164     if (vertexLayout & kCoverage_VertexLayoutBit) {
165         size += sizeof(GrColor);
166     }
167     if (vertexLayout & kEdge_VertexLayoutBit) {
168         size += 4 * sizeof(SkScalar);
169     }
170     return size;
171 }
172 
173 ////////////////////////////////////////////////////////////////////////////////
174 
175 /**
176  * Functions for computing offsets of various components from the layout
177  * bitfield.
178  *
179  * Order of vertex components:
180  * Position
181  * Tex Coord 0
182  * ...
183  * Tex Coord GrDrawState::kMaxTexCoords-1
184  * Color
185  * Coverage
186  */
187 
VertexStageCoordOffset(int stageIdx,GrVertexLayout vertexLayout)188 int GrDrawState::VertexStageCoordOffset(int stageIdx, GrVertexLayout vertexLayout) {
189     GrAssert(check_layout(vertexLayout));
190 
191     if (!StageUsesTexCoords(vertexLayout, stageIdx)) {
192         return 0;
193     }
194     int tcIdx = VertexTexCoordsForStage(stageIdx, vertexLayout);
195     if (tcIdx >= 0) {
196 
197         int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
198                                     sizeof(GrGpuTextVertex) :
199                                     sizeof(GrPoint);
200         int offset = vecSize; // position
201         // figure out how many tex coordinates are present and precede this one.
202         for (int t = 0; t < tcIdx; ++t) {
203             if (gTexCoordMasks[t] & vertexLayout) {
204                 offset += vecSize;
205             }
206         }
207         return offset;
208     }
209 
210     return -1;
211 }
212 
VertexColorOffset(GrVertexLayout vertexLayout)213 int GrDrawState::VertexColorOffset(GrVertexLayout vertexLayout) {
214     GrAssert(check_layout(vertexLayout));
215 
216     if (vertexLayout & kColor_VertexLayoutBit) {
217         int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
218                                     sizeof(GrGpuTextVertex) :
219                                     sizeof(GrPoint);
220         return vecSize * (num_tex_coords(vertexLayout) + 1); //+1 for pos
221     }
222     return -1;
223 }
224 
VertexCoverageOffset(GrVertexLayout vertexLayout)225 int GrDrawState::VertexCoverageOffset(GrVertexLayout vertexLayout) {
226     GrAssert(check_layout(vertexLayout));
227 
228     if (vertexLayout & kCoverage_VertexLayoutBit) {
229         int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
230                                     sizeof(GrGpuTextVertex) :
231                                     sizeof(GrPoint);
232 
233         int offset = vecSize * (num_tex_coords(vertexLayout) + 1);
234         if (vertexLayout & kColor_VertexLayoutBit) {
235             offset += sizeof(GrColor);
236         }
237         return offset;
238     }
239     return -1;
240 }
241 
VertexEdgeOffset(GrVertexLayout vertexLayout)242 int GrDrawState::VertexEdgeOffset(GrVertexLayout vertexLayout) {
243     GrAssert(check_layout(vertexLayout));
244 
245     // edge pts are after the pos, tex coords, and color
246     if (vertexLayout & kEdge_VertexLayoutBit) {
247         int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
248                                     sizeof(GrGpuTextVertex) :
249                                     sizeof(GrPoint);
250         int offset = vecSize * (num_tex_coords(vertexLayout) + 1); //+1 for pos
251         if (vertexLayout & kColor_VertexLayoutBit) {
252             offset += sizeof(GrColor);
253         }
254         if (vertexLayout & kCoverage_VertexLayoutBit) {
255             offset += sizeof(GrColor);
256         }
257         return offset;
258     }
259     return -1;
260 }
261 
VertexSizeAndOffsetsByIdx(GrVertexLayout vertexLayout,int texCoordOffsetsByIdx[kMaxTexCoords],int * colorOffset,int * coverageOffset,int * edgeOffset)262 int GrDrawState::VertexSizeAndOffsetsByIdx(
263         GrVertexLayout vertexLayout,
264         int texCoordOffsetsByIdx[kMaxTexCoords],
265         int* colorOffset,
266         int* coverageOffset,
267         int* edgeOffset) {
268     GrAssert(check_layout(vertexLayout));
269 
270     int vecSize = (vertexLayout & kTextFormat_VertexLayoutBit) ?
271                                                     sizeof(GrGpuTextVertex) :
272                                                     sizeof(GrPoint);
273     int size = vecSize; // position
274 
275     for (int t = 0; t < kMaxTexCoords; ++t) {
276         if (gTexCoordMasks[t] & vertexLayout) {
277             if (NULL != texCoordOffsetsByIdx) {
278                 texCoordOffsetsByIdx[t] = size;
279             }
280             size += vecSize;
281         } else {
282             if (NULL != texCoordOffsetsByIdx) {
283                 texCoordOffsetsByIdx[t] = -1;
284             }
285         }
286     }
287     if (kColor_VertexLayoutBit & vertexLayout) {
288         if (NULL != colorOffset) {
289             *colorOffset = size;
290         }
291         size += sizeof(GrColor);
292     } else {
293         if (NULL != colorOffset) {
294             *colorOffset = -1;
295         }
296     }
297     if (kCoverage_VertexLayoutBit & vertexLayout) {
298         if (NULL != coverageOffset) {
299             *coverageOffset = size;
300         }
301         size += sizeof(GrColor);
302     } else {
303         if (NULL != coverageOffset) {
304             *coverageOffset = -1;
305         }
306     }
307     if (kEdge_VertexLayoutBit & vertexLayout) {
308         if (NULL != edgeOffset) {
309             *edgeOffset = size;
310         }
311         size += 4 * sizeof(SkScalar);
312     } else {
313         if (NULL != edgeOffset) {
314             *edgeOffset = -1;
315         }
316     }
317     return size;
318 }
319 
VertexSizeAndOffsetsByStage(GrVertexLayout vertexLayout,int texCoordOffsetsByStage[GrDrawState::kNumStages],int * colorOffset,int * coverageOffset,int * edgeOffset)320 int GrDrawState::VertexSizeAndOffsetsByStage(
321         GrVertexLayout vertexLayout,
322         int texCoordOffsetsByStage[GrDrawState::kNumStages],
323         int* colorOffset,
324         int* coverageOffset,
325         int* edgeOffset) {
326     GrAssert(check_layout(vertexLayout));
327 
328     int texCoordOffsetsByIdx[kMaxTexCoords];
329     int size = VertexSizeAndOffsetsByIdx(vertexLayout,
330                                          (NULL == texCoordOffsetsByStage) ?
331                                                NULL :
332                                                texCoordOffsetsByIdx,
333                                          colorOffset,
334                                          coverageOffset,
335                                          edgeOffset);
336     if (NULL != texCoordOffsetsByStage) {
337         for (int s = 0; s < GrDrawState::kNumStages; ++s) {
338             int tcIdx = VertexTexCoordsForStage(s, vertexLayout);
339             texCoordOffsetsByStage[s] =
340                 tcIdx < 0 ? 0 : texCoordOffsetsByIdx[tcIdx];
341         }
342     }
343     return size;
344 }
345 
346 ////////////////////////////////////////////////////////////////////////////////
347 
VertexUsesTexCoordIdx(int coordIndex,GrVertexLayout vertexLayout)348 bool GrDrawState::VertexUsesTexCoordIdx(int coordIndex,
349                                          GrVertexLayout vertexLayout) {
350     GrAssert(coordIndex < kMaxTexCoords);
351     GrAssert(check_layout(vertexLayout));
352     return !!(gTexCoordMasks[coordIndex] & vertexLayout);
353 }
354 
VertexTexCoordsForStage(int stageIdx,GrVertexLayout vertexLayout)355 int GrDrawState::VertexTexCoordsForStage(int stageIdx,
356                                           GrVertexLayout vertexLayout) {
357     GrAssert(stageIdx < GrDrawState::kNumStages);
358     GrAssert(check_layout(vertexLayout));
359     int bit = vertexLayout & gStageTexCoordMasks[stageIdx];
360     if (bit) {
361         // figure out which set of texture coordates is used
362         // bits are ordered T0S0, T0S1, T0S2, ..., T1S0, T1S1, ...
363         // and start at bit 0.
364         GR_STATIC_ASSERT(sizeof(GrVertexLayout) <= sizeof(uint32_t));
365         return (32 - SkCLZ(bit) - 1) / GrDrawState::kNumStages;
366     }
367     return -1;
368 }
369 
370 ////////////////////////////////////////////////////////////////////////////////
371 
VertexLayoutUnitTest()372 void GrDrawState::VertexLayoutUnitTest() {
373     // Ensure that our globals mask arrays are correct
374     GrVertexLayout stageTexCoordMasks[GrDrawState::kNumStages];
375     GrVertexLayout texCoordMasks[kMaxTexCoords];
376     gen_mask_arrays(stageTexCoordMasks, texCoordMasks);
377     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
378         GrAssert(stageTexCoordMasks[s] == gStageTexCoordMasks[s]);
379     }
380     for (int t = 0; t < kMaxTexCoords; ++t) {
381         GrAssert(texCoordMasks[t] == gTexCoordMasks[t]);
382     }
383 
384     // not necessarily exhaustive
385     static bool run;
386     if (!run) {
387         run = true;
388         for (int s = 0; s < GrDrawState::kNumStages; ++s) {
389 
390             GrVertexLayout stageMask = 0;
391             for (int t = 0; t < kMaxTexCoords; ++t) {
392                 stageMask |= StageTexCoordVertexLayoutBit(s,t);
393             }
394             GrAssert(1 == kMaxTexCoords ||
395                      !check_layout(stageMask));
396             GrAssert(gStageTexCoordMasks[s] == stageMask);
397             GrAssert(!check_layout(stageMask));
398         }
399         for (int t = 0; t < kMaxTexCoords; ++t) {
400             GrVertexLayout tcMask = 0;
401             GrAssert(!VertexUsesTexCoordIdx(t, 0));
402             for (int s = 0; s < GrDrawState::kNumStages; ++s) {
403                 tcMask |= StageTexCoordVertexLayoutBit(s,t);
404                 GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
405                 GrAssert(VertexUsesTexCoordIdx(t, tcMask));
406                 GrAssert(2*sizeof(GrPoint) == VertexSize(tcMask));
407                 GrAssert(t == VertexTexCoordsForStage(s, tcMask));
408                 for (int s2 = s + 1; s2 < GrDrawState::kNumStages; ++s2) {
409                     GrAssert(-1 == VertexTexCoordsForStage(s2, tcMask));
410 
411                 #if GR_DEBUG
412                     GrVertexLayout posAsTex = tcMask;
413                 #endif
414                     GrAssert(0 == VertexStageCoordOffset(s2, posAsTex));
415                     GrAssert(2*sizeof(GrPoint) == VertexSize(posAsTex));
416                     GrAssert(-1 == VertexTexCoordsForStage(s2, posAsTex));
417                     GrAssert(-1 == VertexEdgeOffset(posAsTex));
418                 }
419                 GrAssert(-1 == VertexEdgeOffset(tcMask));
420                 GrAssert(-1 == VertexColorOffset(tcMask));
421                 GrAssert(-1 == VertexCoverageOffset(tcMask));
422             #if GR_DEBUG
423                 GrVertexLayout withColor = tcMask | kColor_VertexLayoutBit;
424             #endif
425                 GrAssert(-1 == VertexCoverageOffset(withColor));
426                 GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColor));
427                 GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColor));
428             #if GR_DEBUG
429                 GrVertexLayout withEdge = tcMask | kEdge_VertexLayoutBit;
430             #endif
431                 GrAssert(-1 == VertexColorOffset(withEdge));
432                 GrAssert(2*sizeof(GrPoint) == VertexEdgeOffset(withEdge));
433                 GrAssert(4*sizeof(GrPoint) == VertexSize(withEdge));
434             #if GR_DEBUG
435                 GrVertexLayout withColorAndEdge = withColor | kEdge_VertexLayoutBit;
436             #endif
437                 GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withColorAndEdge));
438                 GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexEdgeOffset(withColorAndEdge));
439                 GrAssert(4*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withColorAndEdge));
440             #if GR_DEBUG
441                 GrVertexLayout withCoverage = tcMask | kCoverage_VertexLayoutBit;
442             #endif
443                 GrAssert(-1 == VertexColorOffset(withCoverage));
444                 GrAssert(2*sizeof(GrPoint) == VertexCoverageOffset(withCoverage));
445                 GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexSize(withCoverage));
446             #if GR_DEBUG
447                 GrVertexLayout withCoverageAndColor = tcMask | kCoverage_VertexLayoutBit |
448                                                       kColor_VertexLayoutBit;
449             #endif
450                 GrAssert(2*sizeof(GrPoint) == VertexColorOffset(withCoverageAndColor));
451                 GrAssert(2*sizeof(GrPoint) + sizeof(GrColor) == VertexCoverageOffset(withCoverageAndColor));
452                 GrAssert(2*sizeof(GrPoint) + 2 * sizeof(GrColor) == VertexSize(withCoverageAndColor));
453             }
454             GrAssert(gTexCoordMasks[t] == tcMask);
455             GrAssert(check_layout(tcMask));
456 
457             int stageOffsets[GrDrawState::kNumStages];
458             int colorOffset;
459             int edgeOffset;
460             int coverageOffset;
461             int size;
462             size = VertexSizeAndOffsetsByStage(tcMask,
463                                                stageOffsets, &colorOffset,
464                                                &coverageOffset, &edgeOffset);
465             GrAssert(2*sizeof(GrPoint) == size);
466             GrAssert(-1 == colorOffset);
467             GrAssert(-1 == coverageOffset);
468             GrAssert(-1 == edgeOffset);
469             for (int s = 0; s < GrDrawState::kNumStages; ++s) {
470                 GrAssert(sizeof(GrPoint) == stageOffsets[s]);
471                 GrAssert(sizeof(GrPoint) == VertexStageCoordOffset(s, tcMask));
472             }
473         }
474     }
475 }
476 
477 ////////////////////////////////////////////////////////////////////////////////
478 
StageUsesTexCoords(GrVertexLayout layout,int stageIdx)479 bool GrDrawState::StageUsesTexCoords(GrVertexLayout layout, int stageIdx) {
480     return SkToBool(layout & gStageTexCoordMasks[stageIdx]);
481 }
482 
srcAlphaWillBeOne(GrVertexLayout layout) const483 bool GrDrawState::srcAlphaWillBeOne(GrVertexLayout layout) const {
484 
485     uint32_t validComponentFlags;
486     GrColor  color;
487     // Check if per-vertex or constant color may have partial alpha
488     if (layout & kColor_VertexLayoutBit) {
489         validComponentFlags = 0;
490     } else {
491         validComponentFlags = GrEffect::kAll_ValidComponentFlags;
492         color = this->getColor();
493     }
494 
495     // Run through the color stages
496     int stageCnt = getFirstCoverageStage();
497     for (int s = 0; s < stageCnt; ++s) {
498         const GrEffectRef* effect = this->getStage(s).getEffect();
499         if (NULL != effect) {
500             (*effect)->getConstantColorComponents(&color, &validComponentFlags);
501         }
502     }
503 
504     // Check if the color filter could introduce an alpha.
505     // We could skip the above work when this is true, but it is rare and the right fix is to make
506     // the color filter a GrEffect and implement getConstantColorComponents() for it.
507     if (SkXfermode::kDst_Mode != this->getColorFilterMode()) {
508         validComponentFlags = 0;
509     }
510 
511     // Check whether coverage is treated as color. If so we run through the coverage computation.
512     if (this->isCoverageDrawing()) {
513         GrColor coverageColor = this->getCoverage();
514         GrColor oldColor = color;
515         color = 0;
516         for (int c = 0; c < 4; ++c) {
517             if (validComponentFlags & (1 << c)) {
518                 U8CPU a = (oldColor >> (c * 8)) & 0xff;
519                 U8CPU b = (coverageColor >> (c * 8)) & 0xff;
520                 color |= (SkMulDiv255Round(a, b) << (c * 8));
521             }
522         }
523         for (int s = this->getFirstCoverageStage(); s < GrDrawState::kNumStages; ++s) {
524             const GrEffectRef* effect = this->getStage(s).getEffect();
525             if (NULL != effect) {
526                 (*effect)->getConstantColorComponents(&color, &validComponentFlags);
527             }
528         }
529     }
530     return (GrEffect::kA_ValidComponentFlag & validComponentFlags) && 0xff == GrColorUnpackA(color);
531 }
532 
hasSolidCoverage(GrVertexLayout layout) const533 bool GrDrawState::hasSolidCoverage(GrVertexLayout layout) const {
534     // If we're drawing coverage directly then coverage is effectively treated as color.
535     if (this->isCoverageDrawing()) {
536         return true;
537     }
538 
539     GrColor coverage;
540     uint32_t validComponentFlags;
541     // Initialize to an unknown starting coverage if per-vertex coverage is specified.
542     if (layout & kCoverage_VertexLayoutBit) {
543         validComponentFlags = 0;
544     } else {
545         coverage = fCommon.fCoverage;
546         validComponentFlags = GrEffect::kAll_ValidComponentFlags;
547     }
548 
549     // Run through the coverage stages and see if the coverage will be all ones at the end.
550     for (int s = this->getFirstCoverageStage(); s < GrDrawState::kNumStages; ++s) {
551         const GrEffectRef* effect = this->getStage(s).getEffect();
552         if (NULL != effect) {
553             (*effect)->getConstantColorComponents(&coverage, &validComponentFlags);
554         }
555     }
556     return (GrEffect::kAll_ValidComponentFlags == validComponentFlags)  && (0xffffffff == coverage);
557 }
558 
559 ////////////////////////////////////////////////////////////////////////////////
560 
restore()561 void GrDrawState::AutoViewMatrixRestore::restore() {
562     if (NULL != fDrawState) {
563         fDrawState->setViewMatrix(fViewMatrix);
564         for (int s = 0; s < GrDrawState::kNumStages; ++s) {
565             if (fRestoreMask & (1 << s)) {
566                 fDrawState->fStages[s].restoreCoordChange(fSavedCoordChanges[s]);
567             }
568         }
569     }
570     fDrawState = NULL;
571 }
572 
set(GrDrawState * drawState,const SkMatrix & preconcatMatrix,uint32_t explicitCoordStageMask)573 void GrDrawState::AutoViewMatrixRestore::set(GrDrawState* drawState,
574                                              const SkMatrix& preconcatMatrix,
575                                              uint32_t explicitCoordStageMask) {
576     this->restore();
577 
578     fDrawState = drawState;
579     if (NULL == drawState) {
580         return;
581     }
582 
583     fRestoreMask = 0;
584     fViewMatrix = drawState->getViewMatrix();
585     drawState->preConcatViewMatrix(preconcatMatrix);
586     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
587         if (!(explicitCoordStageMask & (1 << s)) && drawState->isStageEnabled(s)) {
588             fRestoreMask |= (1 << s);
589             fDrawState->fStages[s].saveCoordChange(&fSavedCoordChanges[s]);
590             drawState->fStages[s].preConcatCoordChange(preconcatMatrix);
591         }
592     }
593 }
594 
595 ////////////////////////////////////////////////////////////////////////////////
596 
restore()597 void GrDrawState::AutoDeviceCoordDraw::restore() {
598     if (NULL != fDrawState) {
599         fDrawState->setViewMatrix(fViewMatrix);
600         for (int s = 0; s < GrDrawState::kNumStages; ++s) {
601             if (fRestoreMask & (1 << s)) {
602                 fDrawState->fStages[s].restoreCoordChange(fSavedCoordChanges[s]);
603             }
604         }
605     }
606     fDrawState = NULL;
607 }
608 
set(GrDrawState * drawState,uint32_t explicitCoordStageMask)609 bool GrDrawState::AutoDeviceCoordDraw::set(GrDrawState* drawState,
610                                            uint32_t explicitCoordStageMask) {
611     GrAssert(NULL != drawState);
612 
613     this->restore();
614 
615     fDrawState = drawState;
616     if (NULL == fDrawState) {
617         return false;
618     }
619 
620     fViewMatrix = drawState->getViewMatrix();
621     fRestoreMask = 0;
622     SkMatrix invVM;
623     bool inverted = false;
624 
625     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
626         if (!(explicitCoordStageMask & (1 << s)) && drawState->isStageEnabled(s)) {
627             if (!inverted && !fViewMatrix.invert(&invVM)) {
628                 // sad trombone sound
629                 fDrawState = NULL;
630                 return false;
631             } else {
632                 inverted = true;
633             }
634             fRestoreMask |= (1 << s);
635             GrEffectStage* stage = drawState->fStages + s;
636             stage->saveCoordChange(&fSavedCoordChanges[s]);
637             stage->preConcatCoordChange(invVM);
638         }
639     }
640     drawState->viewMatrix()->reset();
641     return true;
642 }
643