Home | History | Annotate | Download | only in gpu
      1 
      2 /*
      3  * Copyright 2010 Google Inc.
      4  *
      5  * Use of this source code is governed by a BSD-style license that can be
      6  * found in the LICENSE file.
      7  */
      8 
      9 
     10 
     11 #include "GrDrawTarget.h"
     12 #include "GrRenderTarget.h"
     13 #include "GrTexture.h"
     14 #include "GrVertexBuffer.h"
     15 
     16 #include "SkStrokeRec.h"
     17 
     18 SK_DEFINE_INST_COUNT(GrDrawTarget)
     19 
     20 ////////////////////////////////////////////////////////////////////////////////
     21 
     22 GrDrawTarget::DrawInfo& GrDrawTarget::DrawInfo::operator =(const DrawInfo& di) {
     23     fPrimitiveType  = di.fPrimitiveType;
     24     fStartVertex    = di.fStartVertex;
     25     fStartIndex     = di.fStartIndex;
     26     fVertexCount    = di.fVertexCount;
     27     fIndexCount     = di.fIndexCount;
     28 
     29     fInstanceCount          = di.fInstanceCount;
     30     fVerticesPerInstance    = di.fVerticesPerInstance;
     31     fIndicesPerInstance     = di.fIndicesPerInstance;
     32 
     33     if (NULL != di.fDevBounds) {
     34         GrAssert(di.fDevBounds == &di.fDevBoundsStorage);
     35         fDevBoundsStorage = di.fDevBoundsStorage;
     36         fDevBounds = &fDevBoundsStorage;
     37     } else {
     38         fDevBounds = NULL;
     39     }
     40     return *this;
     41 }
     42 
     43 #if GR_DEBUG
     44 bool GrDrawTarget::DrawInfo::isInstanced() const {
     45     if (fInstanceCount > 0) {
     46         GrAssert(0 == fIndexCount % fIndicesPerInstance);
     47         GrAssert(0 == fVertexCount % fVerticesPerInstance);
     48         GrAssert(fIndexCount / fIndicesPerInstance == fInstanceCount);
     49         GrAssert(fVertexCount / fVerticesPerInstance == fInstanceCount);
     50         // there is no way to specify a non-zero start index to drawIndexedInstances().
     51         GrAssert(0 == fStartIndex);
     52         return true;
     53     } else {
     54         GrAssert(!fVerticesPerInstance);
     55         GrAssert(!fIndicesPerInstance);
     56         return false;
     57     }
     58 }
     59 #endif
     60 
     61 void GrDrawTarget::DrawInfo::adjustInstanceCount(int instanceOffset) {
     62     GrAssert(this->isInstanced());
     63     GrAssert(instanceOffset + fInstanceCount >= 0);
     64     fInstanceCount += instanceOffset;
     65     fVertexCount = fVerticesPerInstance * fInstanceCount;
     66     fIndexCount = fIndicesPerInstance * fInstanceCount;
     67 }
     68 
     69 void GrDrawTarget::DrawInfo::adjustStartVertex(int vertexOffset) {
     70     fStartVertex += vertexOffset;
     71     GrAssert(fStartVertex >= 0);
     72 }
     73 
     74 void GrDrawTarget::DrawInfo::adjustStartIndex(int indexOffset) {
     75     GrAssert(this->isIndexed());
     76     fStartIndex += indexOffset;
     77     GrAssert(fStartIndex >= 0);
     78 }
     79 
     80 ////////////////////////////////////////////////////////////////////////////////
     81 
     82 #define DEBUG_INVAL_BUFFER 0xdeadcafe
     83 #define DEBUG_INVAL_START_IDX -1
     84 
     85 GrDrawTarget::GrDrawTarget() : fClip(NULL) {
     86     fDrawState = &fDefaultDrawState;
     87     // We assume that fDrawState always owns a ref to the object it points at.
     88     fDefaultDrawState.ref();
     89     GeometrySrcState& geoSrc = fGeoSrcStateStack.push_back();
     90 #if GR_DEBUG
     91     geoSrc.fVertexCount = DEBUG_INVAL_START_IDX;
     92     geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
     93     geoSrc.fIndexCount = DEBUG_INVAL_START_IDX;
     94     geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
     95 #endif
     96     geoSrc.fVertexSrc = kNone_GeometrySrcType;
     97     geoSrc.fIndexSrc  = kNone_GeometrySrcType;
     98 }
     99 
    100 GrDrawTarget::~GrDrawTarget() {
    101     GrAssert(1 == fGeoSrcStateStack.count());
    102     SkDEBUGCODE(GeometrySrcState& geoSrc = fGeoSrcStateStack.back());
    103     GrAssert(kNone_GeometrySrcType == geoSrc.fIndexSrc);
    104     GrAssert(kNone_GeometrySrcType == geoSrc.fVertexSrc);
    105     fDrawState->unref();
    106 }
    107 
    108 void GrDrawTarget::releaseGeometry() {
    109     int popCnt = fGeoSrcStateStack.count() - 1;
    110     while (popCnt) {
    111         this->popGeometrySource();
    112         --popCnt;
    113     }
    114     this->resetVertexSource();
    115     this->resetIndexSource();
    116 }
    117 
    118 void GrDrawTarget::setClip(const GrClipData* clip) {
    119     clipWillBeSet(clip);
    120     fClip = clip;
    121 }
    122 
    123 const GrClipData* GrDrawTarget::getClip() const {
    124     return fClip;
    125 }
    126 
    127 void GrDrawTarget::setDrawState(GrDrawState*  drawState) {
    128     GrAssert(NULL != fDrawState);
    129     if (NULL == drawState) {
    130         drawState = &fDefaultDrawState;
    131     }
    132     if (fDrawState != drawState) {
    133         fDrawState->unref();
    134         drawState->ref();
    135         fDrawState = drawState;
    136     }
    137 }
    138 
    139 bool GrDrawTarget::reserveVertexSpace(GrVertexLayout vertexLayout,
    140                                       int vertexCount,
    141                                       void** vertices) {
    142     GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
    143     bool acquired = false;
    144     if (vertexCount > 0) {
    145         GrAssert(NULL != vertices);
    146         this->releasePreviousVertexSource();
    147         geoSrc.fVertexSrc = kNone_GeometrySrcType;
    148 
    149         acquired = this->onReserveVertexSpace(GrDrawState::VertexSize(vertexLayout),
    150                                               vertexCount,
    151                                               vertices);
    152     }
    153     if (acquired) {
    154         geoSrc.fVertexSrc = kReserved_GeometrySrcType;
    155         geoSrc.fVertexCount = vertexCount;
    156         geoSrc.fVertexLayout = vertexLayout;
    157     } else if (NULL != vertices) {
    158         *vertices = NULL;
    159     }
    160     return acquired;
    161 }
    162 
    163 bool GrDrawTarget::reserveIndexSpace(int indexCount,
    164                                      void** indices) {
    165     GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
    166     bool acquired = false;
    167     if (indexCount > 0) {
    168         GrAssert(NULL != indices);
    169         this->releasePreviousIndexSource();
    170         geoSrc.fIndexSrc = kNone_GeometrySrcType;
    171 
    172         acquired = this->onReserveIndexSpace(indexCount, indices);
    173     }
    174     if (acquired) {
    175         geoSrc.fIndexSrc = kReserved_GeometrySrcType;
    176         geoSrc.fIndexCount = indexCount;
    177     } else if (NULL != indices) {
    178         *indices = NULL;
    179     }
    180     return acquired;
    181 
    182 }
    183 
    184 bool GrDrawTarget::reserveVertexAndIndexSpace(GrVertexLayout vertexLayout,
    185                                               int vertexCount,
    186                                               int indexCount,
    187                                               void** vertices,
    188                                               void** indices) {
    189     this->willReserveVertexAndIndexSpace(GrDrawState::VertexSize(vertexLayout), vertexCount, indexCount);
    190     if (vertexCount) {
    191         if (!this->reserveVertexSpace(vertexLayout, vertexCount, vertices)) {
    192             if (indexCount) {
    193                 this->resetIndexSource();
    194             }
    195             return false;
    196         }
    197     }
    198     if (indexCount) {
    199         if (!this->reserveIndexSpace(indexCount, indices)) {
    200             if (vertexCount) {
    201                 this->resetVertexSource();
    202             }
    203             return false;
    204         }
    205     }
    206     return true;
    207 }
    208 
    209 bool GrDrawTarget::geometryHints(size_t vertexSize,
    210                                  int32_t* vertexCount,
    211                                  int32_t* indexCount) const {
    212     if (NULL != vertexCount) {
    213         *vertexCount = -1;
    214     }
    215     if (NULL != indexCount) {
    216         *indexCount = -1;
    217     }
    218     return false;
    219 }
    220 
    221 void GrDrawTarget::releasePreviousVertexSource() {
    222     GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
    223     switch (geoSrc.fVertexSrc) {
    224         case kNone_GeometrySrcType:
    225             break;
    226         case kArray_GeometrySrcType:
    227             this->releaseVertexArray();
    228             break;
    229         case kReserved_GeometrySrcType:
    230             this->releaseReservedVertexSpace();
    231             break;
    232         case kBuffer_GeometrySrcType:
    233             geoSrc.fVertexBuffer->unref();
    234 #if GR_DEBUG
    235             geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
    236 #endif
    237             break;
    238         default:
    239             GrCrash("Unknown Vertex Source Type.");
    240             break;
    241     }
    242 }
    243 
    244 void GrDrawTarget::releasePreviousIndexSource() {
    245     GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
    246     switch (geoSrc.fIndexSrc) {
    247         case kNone_GeometrySrcType:   // these two don't require
    248             break;
    249         case kArray_GeometrySrcType:
    250             this->releaseIndexArray();
    251             break;
    252         case kReserved_GeometrySrcType:
    253             this->releaseReservedIndexSpace();
    254             break;
    255         case kBuffer_GeometrySrcType:
    256             geoSrc.fIndexBuffer->unref();
    257 #if GR_DEBUG
    258             geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
    259 #endif
    260             break;
    261         default:
    262             GrCrash("Unknown Index Source Type.");
    263             break;
    264     }
    265 }
    266 
    267 void GrDrawTarget::setVertexSourceToArray(GrVertexLayout vertexLayout,
    268                                           const void* vertexArray,
    269                                           int vertexCount) {
    270     this->releasePreviousVertexSource();
    271     GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
    272     geoSrc.fVertexSrc = kArray_GeometrySrcType;
    273     geoSrc.fVertexLayout = vertexLayout;
    274     geoSrc.fVertexCount = vertexCount;
    275     this->onSetVertexSourceToArray(vertexArray, vertexCount);
    276 }
    277 
    278 void GrDrawTarget::setIndexSourceToArray(const void* indexArray,
    279                                          int indexCount) {
    280     this->releasePreviousIndexSource();
    281     GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
    282     geoSrc.fIndexSrc = kArray_GeometrySrcType;
    283     geoSrc.fIndexCount = indexCount;
    284     this->onSetIndexSourceToArray(indexArray, indexCount);
    285 }
    286 
    287 void GrDrawTarget::setVertexSourceToBuffer(GrVertexLayout vertexLayout,
    288                                            const GrVertexBuffer* buffer) {
    289     this->releasePreviousVertexSource();
    290     GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
    291     geoSrc.fVertexSrc    = kBuffer_GeometrySrcType;
    292     geoSrc.fVertexBuffer = buffer;
    293     buffer->ref();
    294     geoSrc.fVertexLayout = vertexLayout;
    295 }
    296 
    297 void GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) {
    298     this->releasePreviousIndexSource();
    299     GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
    300     geoSrc.fIndexSrc     = kBuffer_GeometrySrcType;
    301     geoSrc.fIndexBuffer  = buffer;
    302     buffer->ref();
    303 }
    304 
    305 void GrDrawTarget::resetVertexSource() {
    306     this->releasePreviousVertexSource();
    307     GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
    308     geoSrc.fVertexSrc = kNone_GeometrySrcType;
    309 }
    310 
    311 void GrDrawTarget::resetIndexSource() {
    312     this->releasePreviousIndexSource();
    313     GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
    314     geoSrc.fIndexSrc = kNone_GeometrySrcType;
    315 }
    316 
    317 void GrDrawTarget::pushGeometrySource() {
    318     this->geometrySourceWillPush();
    319     GeometrySrcState& newState = fGeoSrcStateStack.push_back();
    320     newState.fIndexSrc = kNone_GeometrySrcType;
    321     newState.fVertexSrc = kNone_GeometrySrcType;
    322 #if GR_DEBUG
    323     newState.fVertexCount  = ~0;
    324     newState.fVertexBuffer = (GrVertexBuffer*)~0;
    325     newState.fIndexCount   = ~0;
    326     newState.fIndexBuffer = (GrIndexBuffer*)~0;
    327 #endif
    328 }
    329 
    330 void GrDrawTarget::popGeometrySource() {
    331     // if popping last element then pops are unbalanced with pushes
    332     GrAssert(fGeoSrcStateStack.count() > 1);
    333 
    334     this->geometrySourceWillPop(fGeoSrcStateStack.fromBack(1));
    335     this->releasePreviousVertexSource();
    336     this->releasePreviousIndexSource();
    337     fGeoSrcStateStack.pop_back();
    338 }
    339 
    340 ////////////////////////////////////////////////////////////////////////////////
    341 
    342 bool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex,
    343                              int startIndex, int vertexCount,
    344                              int indexCount) const {
    345     const GrDrawState& drawState = this->getDrawState();
    346 #if GR_DEBUG
    347     const GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
    348     int maxVertex = startVertex + vertexCount;
    349     int maxValidVertex;
    350     switch (geoSrc.fVertexSrc) {
    351         case kNone_GeometrySrcType:
    352             GrCrash("Attempting to draw without vertex src.");
    353         case kReserved_GeometrySrcType: // fallthrough
    354         case kArray_GeometrySrcType:
    355             maxValidVertex = geoSrc.fVertexCount;
    356             break;
    357         case kBuffer_GeometrySrcType:
    358             maxValidVertex = geoSrc.fVertexBuffer->sizeInBytes() / GrDrawState::VertexSize(geoSrc.fVertexLayout);
    359             break;
    360     }
    361     if (maxVertex > maxValidVertex) {
    362         GrCrash("Drawing outside valid vertex range.");
    363     }
    364     if (indexCount > 0) {
    365         int maxIndex = startIndex + indexCount;
    366         int maxValidIndex;
    367         switch (geoSrc.fIndexSrc) {
    368             case kNone_GeometrySrcType:
    369                 GrCrash("Attempting to draw indexed geom without index src.");
    370             case kReserved_GeometrySrcType: // fallthrough
    371             case kArray_GeometrySrcType:
    372                 maxValidIndex = geoSrc.fIndexCount;
    373                 break;
    374             case kBuffer_GeometrySrcType:
    375                 maxValidIndex = geoSrc.fIndexBuffer->sizeInBytes() / sizeof(uint16_t);
    376                 break;
    377         }
    378         if (maxIndex > maxValidIndex) {
    379             GrCrash("Index reads outside valid index range.");
    380         }
    381     }
    382 
    383     GrAssert(NULL != drawState.getRenderTarget());
    384     for (int s = 0; s < GrDrawState::kNumStages; ++s) {
    385         if (drawState.isStageEnabled(s)) {
    386             const GrEffectRef& effect = *drawState.getStage(s).getEffect();
    387             int numTextures = effect->numTextures();
    388             for (int t = 0; t < numTextures; ++t) {
    389                 GrTexture* texture = effect->texture(t);
    390                 GrAssert(texture->asRenderTarget() != drawState.getRenderTarget());
    391             }
    392         }
    393     }
    394 #endif
    395     if (NULL == drawState.getRenderTarget()) {
    396         return false;
    397     }
    398     return true;
    399 }
    400 
    401 void GrDrawTarget::drawIndexed(GrPrimitiveType type,
    402                                int startVertex,
    403                                int startIndex,
    404                                int vertexCount,
    405                                int indexCount,
    406                                const SkRect* devBounds) {
    407     if (indexCount > 0 && this->checkDraw(type, startVertex, startIndex, vertexCount, indexCount)) {
    408         DrawInfo info;
    409         info.fPrimitiveType = type;
    410         info.fStartVertex   = startVertex;
    411         info.fStartIndex    = startIndex;
    412         info.fVertexCount   = vertexCount;
    413         info.fIndexCount    = indexCount;
    414 
    415         info.fInstanceCount         = 0;
    416         info.fVerticesPerInstance   = 0;
    417         info.fIndicesPerInstance    = 0;
    418 
    419         if (NULL != devBounds) {
    420             info.setDevBounds(*devBounds);
    421         }
    422         this->onDraw(info);
    423     }
    424 }
    425 
    426 void GrDrawTarget::drawNonIndexed(GrPrimitiveType type,
    427                                   int startVertex,
    428                                   int vertexCount,
    429                                   const SkRect* devBounds) {
    430     if (vertexCount > 0 && this->checkDraw(type, startVertex, -1, vertexCount, -1)) {
    431         DrawInfo info;
    432         info.fPrimitiveType = type;
    433         info.fStartVertex   = startVertex;
    434         info.fStartIndex    = 0;
    435         info.fVertexCount   = vertexCount;
    436         info.fIndexCount    = 0;
    437 
    438         info.fInstanceCount         = 0;
    439         info.fVerticesPerInstance   = 0;
    440         info.fIndicesPerInstance    = 0;
    441 
    442         if (NULL != devBounds) {
    443             info.setDevBounds(*devBounds);
    444         }
    445         this->onDraw(info);
    446     }
    447 }
    448 
    449 void GrDrawTarget::stencilPath(const GrPath* path, const SkStrokeRec& stroke, SkPath::FillType fill) {
    450     // TODO: extract portions of checkDraw that are relevant to path stenciling.
    451     GrAssert(NULL != path);
    452     GrAssert(fCaps.pathStencilingSupport());
    453     GrAssert(!stroke.isHairlineStyle());
    454     GrAssert(!SkPath::IsInverseFillType(fill));
    455     this->onStencilPath(path, stroke, fill);
    456 }
    457 
    458 ////////////////////////////////////////////////////////////////////////////////
    459 
    460 // Some blend modes allow folding a partial coverage value into the color's
    461 // alpha channel, while others will blend incorrectly.
    462 bool GrDrawTarget::canTweakAlphaForCoverage() const {
    463     /**
    464      * The fractional coverage is f
    465      * The src and dst coeffs are Cs and Cd
    466      * The dst and src colors are S and D
    467      * We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D
    468      * By tweaking the source color's alpha we're replacing S with S'=fS. It's
    469      * obvious that that first term will always be ok. The second term can be
    470      * rearranged as [1-(1-Cd)f]D. By substituting in the various possibilities
    471      * for Cd we find that only 1, ISA, and ISC produce the correct depth
    472      * coefficient in terms of S' and D.
    473      */
    474     GrBlendCoeff dstCoeff = this->getDrawState().getDstBlendCoeff();
    475     return kOne_GrBlendCoeff == dstCoeff ||
    476            kISA_GrBlendCoeff == dstCoeff ||
    477            kISC_GrBlendCoeff == dstCoeff ||
    478            this->getDrawState().isCoverageDrawing();
    479 }
    480 
    481 namespace {
    482 GrVertexLayout default_blend_opts_vertex_layout() {
    483     GrVertexLayout layout = 0;
    484     return layout;
    485 }
    486 }
    487 
    488 GrDrawTarget::BlendOptFlags
    489 GrDrawTarget::getBlendOpts(bool forceCoverage,
    490                            GrBlendCoeff* srcCoeff,
    491                            GrBlendCoeff* dstCoeff) const {
    492 
    493     GrVertexLayout layout;
    494     if (kNone_GeometrySrcType == this->getGeomSrc().fVertexSrc) {
    495         layout = default_blend_opts_vertex_layout();
    496     } else {
    497         layout = this->getVertexLayout();
    498     }
    499 
    500     const GrDrawState& drawState = this->getDrawState();
    501 
    502     GrBlendCoeff bogusSrcCoeff, bogusDstCoeff;
    503     if (NULL == srcCoeff) {
    504         srcCoeff = &bogusSrcCoeff;
    505     }
    506     *srcCoeff = drawState.getSrcBlendCoeff();
    507 
    508     if (NULL == dstCoeff) {
    509         dstCoeff = &bogusDstCoeff;
    510     }
    511     *dstCoeff = drawState.getDstBlendCoeff();
    512 
    513     if (drawState.isColorWriteDisabled()) {
    514         *srcCoeff = kZero_GrBlendCoeff;
    515         *dstCoeff = kOne_GrBlendCoeff;
    516     }
    517 
    518     bool srcAIsOne = drawState.srcAlphaWillBeOne(layout);
    519     bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff ||
    520                          (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne);
    521     bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff ||
    522                          (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne);
    523 
    524     bool covIsZero = !drawState.isCoverageDrawing() &&
    525                      !(layout & GrDrawState::kCoverage_VertexLayoutBit) &&
    526                      0 == drawState.getCoverage();
    527     // When coeffs are (0,1) there is no reason to draw at all, unless
    528     // stenciling is enabled. Having color writes disabled is effectively
    529     // (0,1). The same applies when coverage is known to be 0.
    530     if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne) || covIsZero) {
    531         if (drawState.getStencil().doesWrite()) {
    532             return kDisableBlend_BlendOptFlag |
    533                    kEmitTransBlack_BlendOptFlag;
    534         } else {
    535             return kSkipDraw_BlendOptFlag;
    536         }
    537     }
    538 
    539     // check for coverage due to constant coverage, per-vertex coverage,
    540     // edge aa or coverage stage
    541     bool hasCoverage = forceCoverage ||
    542                        0xffffffff != drawState.getCoverage() ||
    543                        (layout & GrDrawState::kCoverage_VertexLayoutBit) ||
    544                        (layout & GrDrawState::kEdge_VertexLayoutBit);
    545     for (int s = drawState.getFirstCoverageStage();
    546          !hasCoverage && s < GrDrawState::kNumStages;
    547          ++s) {
    548         if (drawState.isStageEnabled(s)) {
    549             hasCoverage = true;
    550         }
    551     }
    552 
    553     // if we don't have coverage we can check whether the dst
    554     // has to read at all. If not, we'll disable blending.
    555     if (!hasCoverage) {
    556         if (dstCoeffIsZero) {
    557             if (kOne_GrBlendCoeff == *srcCoeff) {
    558                 // if there is no coverage and coeffs are (1,0) then we
    559                 // won't need to read the dst at all, it gets replaced by src
    560                 return kDisableBlend_BlendOptFlag;
    561             } else if (kZero_GrBlendCoeff == *srcCoeff) {
    562                 // if the op is "clear" then we don't need to emit a color
    563                 // or blend, just write transparent black into the dst.
    564                 *srcCoeff = kOne_GrBlendCoeff;
    565                 *dstCoeff = kZero_GrBlendCoeff;
    566                 return kDisableBlend_BlendOptFlag | kEmitTransBlack_BlendOptFlag;
    567             }
    568         }
    569     } else if (drawState.isCoverageDrawing()) {
    570         // we have coverage but we aren't distinguishing it from alpha by request.
    571         return kCoverageAsAlpha_BlendOptFlag;
    572     } else {
    573         // check whether coverage can be safely rolled into alpha
    574         // of if we can skip color computation and just emit coverage
    575         if (this->canTweakAlphaForCoverage()) {
    576             return kCoverageAsAlpha_BlendOptFlag;
    577         }
    578         if (dstCoeffIsZero) {
    579             if (kZero_GrBlendCoeff == *srcCoeff) {
    580                 // the source color is not included in the blend
    581                 // the dst coeff is effectively zero so blend works out to:
    582                 // (c)(0)D + (1-c)D = (1-c)D.
    583                 *dstCoeff = kISA_GrBlendCoeff;
    584                 return  kEmitCoverage_BlendOptFlag;
    585             } else if (srcAIsOne) {
    586                 // the dst coeff is effectively zero so blend works out to:
    587                 // cS + (c)(0)D + (1-c)D = cS + (1-c)D.
    588                 // If Sa is 1 then we can replace Sa with c
    589                 // and set dst coeff to 1-Sa.
    590                 *dstCoeff = kISA_GrBlendCoeff;
    591                 return  kCoverageAsAlpha_BlendOptFlag;
    592             }
    593         } else if (dstCoeffIsOne) {
    594             // the dst coeff is effectively one so blend works out to:
    595             // cS + (c)(1)D + (1-c)D = cS + D.
    596             *dstCoeff = kOne_GrBlendCoeff;
    597             return  kCoverageAsAlpha_BlendOptFlag;
    598         }
    599     }
    600     return kNone_BlendOpt;
    601 }
    602 
    603 bool GrDrawTarget::willUseHWAALines() const {
    604     // there is a conflict between using smooth lines and our use of
    605     // premultiplied alpha. Smooth lines tweak the incoming alpha value
    606     // but not in a premul-alpha way. So we only use them when our alpha
    607     // is 0xff and tweaking the color for partial coverage is OK
    608     if (!fCaps.hwAALineSupport() ||
    609         !this->getDrawState().isHWAntialiasState()) {
    610         return false;
    611     }
    612     BlendOptFlags opts = this->getBlendOpts();
    613     return (kDisableBlend_BlendOptFlag & opts) &&
    614            (kCoverageAsAlpha_BlendOptFlag & opts);
    615 }
    616 
    617 bool GrDrawTarget::canApplyCoverage() const {
    618     // we can correctly apply coverage if a) we have dual source blending
    619     // or b) one of our blend optimizations applies.
    620     return this->getCaps().dualSourceBlendingSupport() ||
    621            kNone_BlendOpt != this->getBlendOpts(true);
    622 }
    623 
    624 ////////////////////////////////////////////////////////////////////////////////
    625 
    626 void GrDrawTarget::drawIndexedInstances(GrPrimitiveType type,
    627                                         int instanceCount,
    628                                         int verticesPerInstance,
    629                                         int indicesPerInstance,
    630                                         const SkRect* devBounds) {
    631     if (!verticesPerInstance || !indicesPerInstance) {
    632         return;
    633     }
    634 
    635     int maxInstancesPerDraw = this->indexCountInCurrentSource() / indicesPerInstance;
    636     if (!maxInstancesPerDraw) {
    637         return;
    638     }
    639 
    640     DrawInfo info;
    641     info.fPrimitiveType = type;
    642     info.fStartIndex = 0;
    643     info.fStartVertex = 0;
    644     info.fIndicesPerInstance = indicesPerInstance;
    645     info.fVerticesPerInstance = verticesPerInstance;
    646 
    647     // Set the same bounds for all the draws.
    648     if (NULL != devBounds) {
    649         info.setDevBounds(*devBounds);
    650     }
    651 
    652     while (instanceCount) {
    653         info.fInstanceCount = GrMin(instanceCount, maxInstancesPerDraw);
    654         info.fVertexCount = info.fInstanceCount * verticesPerInstance;
    655         info.fIndexCount = info.fInstanceCount * indicesPerInstance;
    656 
    657         if (this->checkDraw(type,
    658                             info.fStartVertex,
    659                             info.fStartIndex,
    660                             info.fVertexCount,
    661                             info.fIndexCount)) {
    662             this->onDraw(info);
    663         }
    664         info.fStartVertex += info.fVertexCount;
    665         instanceCount -= info.fInstanceCount;
    666     }
    667 }
    668 
    669 ////////////////////////////////////////////////////////////////////////////////
    670 
    671 void GrDrawTarget::drawRect(const GrRect& rect,
    672                             const SkMatrix* matrix,
    673                             const GrRect* srcRects[],
    674                             const SkMatrix* srcMatrices[]) {
    675     GrVertexLayout layout = 0;
    676     uint32_t explicitCoordMask = 0;
    677 
    678     if (NULL != srcRects) {
    679         for (int s = 0; s < GrDrawState::kNumStages; ++s) {
    680             int numTC = 0;
    681             if (NULL != srcRects[s]) {
    682                 layout |= GrDrawState::StageTexCoordVertexLayoutBit(s, numTC);
    683                 explicitCoordMask |= (1 << s);
    684                 ++numTC;
    685             }
    686         }
    687     }
    688 
    689     GrDrawState::AutoViewMatrixRestore avmr;
    690     if (NULL != matrix) {
    691         avmr.set(this->drawState(), *matrix, explicitCoordMask);
    692     }
    693 
    694     AutoReleaseGeometry geo(this, layout, 4, 0);
    695     if (!geo.succeeded()) {
    696         GrPrintf("Failed to get space for vertices!\n");
    697         return;
    698     }
    699 
    700     int stageOffsets[GrDrawState::kNumStages];
    701     int vsize = GrDrawState::VertexSizeAndOffsetsByStage(layout, stageOffsets,  NULL, NULL, NULL);
    702     geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vsize);
    703 
    704     for (int i = 0; i < GrDrawState::kNumStages; ++i) {
    705         if (explicitCoordMask & (1 << i)) {
    706             GrAssert(0 != stageOffsets[i]);
    707             GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(geo.vertices()) +
    708                                                 stageOffsets[i]);
    709             coords->setRectFan(srcRects[i]->fLeft, srcRects[i]->fTop,
    710                                srcRects[i]->fRight, srcRects[i]->fBottom,
    711                                vsize);
    712             if (NULL != srcMatrices && NULL != srcMatrices[i]) {
    713                 srcMatrices[i]->mapPointsWithStride(coords, vsize, 4);
    714             }
    715         } else {
    716             GrAssert(0 == stageOffsets[i]);
    717         }
    718     }
    719 
    720     this->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4);
    721 }
    722 
    723 void GrDrawTarget::clipWillBeSet(const GrClipData* clipData) {
    724 }
    725 
    726 ////////////////////////////////////////////////////////////////////////////////
    727 
    728 GrDrawTarget::AutoStateRestore::AutoStateRestore() {
    729     fDrawTarget = NULL;
    730 }
    731 
    732 GrDrawTarget::AutoStateRestore::AutoStateRestore(GrDrawTarget* target,
    733                                                  ASRInit init) {
    734     fDrawTarget = NULL;
    735     this->set(target, init);
    736 }
    737 
    738 GrDrawTarget::AutoStateRestore::~AutoStateRestore() {
    739     if (NULL != fDrawTarget) {
    740         fDrawTarget->setDrawState(fSavedState);
    741         fSavedState->unref();
    742     }
    743 }
    744 
    745 void GrDrawTarget::AutoStateRestore::set(GrDrawTarget* target, ASRInit init) {
    746     GrAssert(NULL == fDrawTarget);
    747     fDrawTarget = target;
    748     fSavedState = target->drawState();
    749     GrAssert(fSavedState);
    750     fSavedState->ref();
    751     if (kReset_ASRInit == init) {
    752         // calls the default cons
    753         fTempState.init();
    754     } else {
    755         GrAssert(kPreserve_ASRInit == init);
    756         // calls the copy cons
    757         fTempState.set(*fSavedState);
    758     }
    759     target->setDrawState(fTempState.get());
    760 }
    761 
    762 ////////////////////////////////////////////////////////////////////////////////
    763 
    764 GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry(
    765                                          GrDrawTarget*  target,
    766                                          GrVertexLayout vertexLayout,
    767                                          int vertexCount,
    768                                          int indexCount) {
    769     fTarget = NULL;
    770     this->set(target, vertexLayout, vertexCount, indexCount);
    771 }
    772 
    773 GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry() {
    774     fTarget = NULL;
    775 }
    776 
    777 GrDrawTarget::AutoReleaseGeometry::~AutoReleaseGeometry() {
    778     this->reset();
    779 }
    780 
    781 bool GrDrawTarget::AutoReleaseGeometry::set(GrDrawTarget*  target,
    782                                             GrVertexLayout vertexLayout,
    783                                             int vertexCount,
    784                                             int indexCount) {
    785     this->reset();
    786     fTarget = target;
    787     bool success = true;
    788     if (NULL != fTarget) {
    789         fTarget = target;
    790         success = target->reserveVertexAndIndexSpace(vertexLayout,
    791                                                      vertexCount,
    792                                                      indexCount,
    793                                                      &fVertices,
    794                                                      &fIndices);
    795         if (!success) {
    796             fTarget = NULL;
    797             this->reset();
    798         }
    799     }
    800     GrAssert(success == (NULL != fTarget));
    801     return success;
    802 }
    803 
    804 void GrDrawTarget::AutoReleaseGeometry::reset() {
    805     if (NULL != fTarget) {
    806         if (NULL != fVertices) {
    807             fTarget->resetVertexSource();
    808         }
    809         if (NULL != fIndices) {
    810             fTarget->resetIndexSource();
    811         }
    812         fTarget = NULL;
    813     }
    814     fVertices = NULL;
    815     fIndices = NULL;
    816 }
    817 
    818 GrDrawTarget::AutoClipRestore::AutoClipRestore(GrDrawTarget* target, const SkIRect& newClip) {
    819     fTarget = target;
    820     fClip = fTarget->getClip();
    821     fStack.init();
    822     fStack.get()->clipDevRect(newClip, SkRegion::kReplace_Op);
    823     fReplacementClip.fClipStack = fStack.get();
    824     target->setClip(&fReplacementClip);
    825 }
    826 
    827 void GrDrawTarget::Caps::print() const {
    828     static const char* gNY[] = {"NO", "YES"};
    829     GrPrintf("8 Bit Palette Support       : %s\n", gNY[fInternals.f8BitPaletteSupport]);
    830     GrPrintf("NPOT Texture Tile Support   : %s\n", gNY[fInternals.fNPOTTextureTileSupport]);
    831     GrPrintf("Two Sided Stencil Support   : %s\n", gNY[fInternals.fTwoSidedStencilSupport]);
    832     GrPrintf("Stencil Wrap Ops  Support   : %s\n", gNY[fInternals.fStencilWrapOpsSupport]);
    833     GrPrintf("HW AA Lines Support         : %s\n", gNY[fInternals.fHWAALineSupport]);
    834     GrPrintf("Shader Derivative Support   : %s\n", gNY[fInternals.fShaderDerivativeSupport]);
    835     GrPrintf("Geometry Shader Support     : %s\n", gNY[fInternals.fGeometryShaderSupport]);
    836     GrPrintf("FSAA Support                : %s\n", gNY[fInternals.fFSAASupport]);
    837     GrPrintf("Dual Source Blending Support: %s\n", gNY[fInternals.fDualSourceBlendingSupport]);
    838     GrPrintf("Buffer Lock Support         : %s\n", gNY[fInternals.fBufferLockSupport]);
    839     GrPrintf("Path Stenciling Support     : %s\n", gNY[fInternals.fPathStencilingSupport]);
    840     GrPrintf("Max Texture Size            : %d\n", fInternals.fMaxTextureSize);
    841     GrPrintf("Max Render Target Size      : %d\n", fInternals.fMaxRenderTargetSize);
    842 }
    843