Home | History | Annotate | Download | only in gpu
      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 
     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  */
     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
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    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 
    479 bool GrDrawState::StageUsesTexCoords(GrVertexLayout layout, int stageIdx) {
    480     return SkToBool(layout & gStageTexCoordMasks[stageIdx]);
    481 }
    482 
    483 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 
    533 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 
    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 
    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 
    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 
    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