gfx/skia/trunk/src/gpu/GrDrawTarget.cpp

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/gpu/GrDrawTarget.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,1081 @@
     1.4 +
     1.5 +/*
     1.6 + * Copyright 2010 Google Inc.
     1.7 + *
     1.8 + * Use of this source code is governed by a BSD-style license that can be
     1.9 + * found in the LICENSE file.
    1.10 + */
    1.11 +
    1.12 +
    1.13 +
    1.14 +#include "GrDrawTarget.h"
    1.15 +#include "GrContext.h"
    1.16 +#include "GrDrawTargetCaps.h"
    1.17 +#include "GrPath.h"
    1.18 +#include "GrRenderTarget.h"
    1.19 +#include "GrTexture.h"
    1.20 +#include "GrVertexBuffer.h"
    1.21 +
    1.22 +#include "SkStrokeRec.h"
    1.23 +
    1.24 +////////////////////////////////////////////////////////////////////////////////
    1.25 +
    1.26 +GrDrawTarget::DrawInfo& GrDrawTarget::DrawInfo::operator =(const DrawInfo& di) {
    1.27 +    fPrimitiveType  = di.fPrimitiveType;
    1.28 +    fStartVertex    = di.fStartVertex;
    1.29 +    fStartIndex     = di.fStartIndex;
    1.30 +    fVertexCount    = di.fVertexCount;
    1.31 +    fIndexCount     = di.fIndexCount;
    1.32 +
    1.33 +    fInstanceCount          = di.fInstanceCount;
    1.34 +    fVerticesPerInstance    = di.fVerticesPerInstance;
    1.35 +    fIndicesPerInstance     = di.fIndicesPerInstance;
    1.36 +
    1.37 +    if (NULL != di.fDevBounds) {
    1.38 +        SkASSERT(di.fDevBounds == &di.fDevBoundsStorage);
    1.39 +        fDevBoundsStorage = di.fDevBoundsStorage;
    1.40 +        fDevBounds = &fDevBoundsStorage;
    1.41 +    } else {
    1.42 +        fDevBounds = NULL;
    1.43 +    }
    1.44 +
    1.45 +    fDstCopy = di.fDstCopy;
    1.46 +
    1.47 +    return *this;
    1.48 +}
    1.49 +
    1.50 +#ifdef SK_DEBUG
    1.51 +bool GrDrawTarget::DrawInfo::isInstanced() const {
    1.52 +    if (fInstanceCount > 0) {
    1.53 +        SkASSERT(0 == fIndexCount % fIndicesPerInstance);
    1.54 +        SkASSERT(0 == fVertexCount % fVerticesPerInstance);
    1.55 +        SkASSERT(fIndexCount / fIndicesPerInstance == fInstanceCount);
    1.56 +        SkASSERT(fVertexCount / fVerticesPerInstance == fInstanceCount);
    1.57 +        // there is no way to specify a non-zero start index to drawIndexedInstances().
    1.58 +        SkASSERT(0 == fStartIndex);
    1.59 +        return true;
    1.60 +    } else {
    1.61 +        SkASSERT(!fVerticesPerInstance);
    1.62 +        SkASSERT(!fIndicesPerInstance);
    1.63 +        return false;
    1.64 +    }
    1.65 +}
    1.66 +#endif
    1.67 +
    1.68 +void GrDrawTarget::DrawInfo::adjustInstanceCount(int instanceOffset) {
    1.69 +    SkASSERT(this->isInstanced());
    1.70 +    SkASSERT(instanceOffset + fInstanceCount >= 0);
    1.71 +    fInstanceCount += instanceOffset;
    1.72 +    fVertexCount = fVerticesPerInstance * fInstanceCount;
    1.73 +    fIndexCount = fIndicesPerInstance * fInstanceCount;
    1.74 +}
    1.75 +
    1.76 +void GrDrawTarget::DrawInfo::adjustStartVertex(int vertexOffset) {
    1.77 +    fStartVertex += vertexOffset;
    1.78 +    SkASSERT(fStartVertex >= 0);
    1.79 +}
    1.80 +
    1.81 +void GrDrawTarget::DrawInfo::adjustStartIndex(int indexOffset) {
    1.82 +    SkASSERT(this->isIndexed());
    1.83 +    fStartIndex += indexOffset;
    1.84 +    SkASSERT(fStartIndex >= 0);
    1.85 +}
    1.86 +
    1.87 +////////////////////////////////////////////////////////////////////////////////
    1.88 +
    1.89 +#define DEBUG_INVAL_BUFFER 0xdeadcafe
    1.90 +#define DEBUG_INVAL_START_IDX -1
    1.91 +
    1.92 +GrDrawTarget::GrDrawTarget(GrContext* context)
    1.93 +    : fClip(NULL)
    1.94 +    , fContext(context)
    1.95 +    , fPushGpuTraceCount(0) {
    1.96 +    SkASSERT(NULL != context);
    1.97 +
    1.98 +    fDrawState = &fDefaultDrawState;
    1.99 +    // We assume that fDrawState always owns a ref to the object it points at.
   1.100 +    fDefaultDrawState.ref();
   1.101 +    GeometrySrcState& geoSrc = fGeoSrcStateStack.push_back();
   1.102 +#ifdef SK_DEBUG
   1.103 +    geoSrc.fVertexCount = DEBUG_INVAL_START_IDX;
   1.104 +    geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
   1.105 +    geoSrc.fIndexCount = DEBUG_INVAL_START_IDX;
   1.106 +    geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
   1.107 +#endif
   1.108 +    geoSrc.fVertexSrc = kNone_GeometrySrcType;
   1.109 +    geoSrc.fIndexSrc  = kNone_GeometrySrcType;
   1.110 +}
   1.111 +
   1.112 +GrDrawTarget::~GrDrawTarget() {
   1.113 +    SkASSERT(1 == fGeoSrcStateStack.count());
   1.114 +    SkDEBUGCODE(GeometrySrcState& geoSrc = fGeoSrcStateStack.back());
   1.115 +    SkASSERT(kNone_GeometrySrcType == geoSrc.fIndexSrc);
   1.116 +    SkASSERT(kNone_GeometrySrcType == geoSrc.fVertexSrc);
   1.117 +    fDrawState->unref();
   1.118 +}
   1.119 +
   1.120 +void GrDrawTarget::releaseGeometry() {
   1.121 +    int popCnt = fGeoSrcStateStack.count() - 1;
   1.122 +    while (popCnt) {
   1.123 +        this->popGeometrySource();
   1.124 +        --popCnt;
   1.125 +    }
   1.126 +    this->resetVertexSource();
   1.127 +    this->resetIndexSource();
   1.128 +}
   1.129 +
   1.130 +void GrDrawTarget::setClip(const GrClipData* clip) {
   1.131 +    clipWillBeSet(clip);
   1.132 +    fClip = clip;
   1.133 +}
   1.134 +
   1.135 +const GrClipData* GrDrawTarget::getClip() const {
   1.136 +    return fClip;
   1.137 +}
   1.138 +
   1.139 +void GrDrawTarget::setDrawState(GrDrawState*  drawState) {
   1.140 +    SkASSERT(NULL != fDrawState);
   1.141 +    if (NULL == drawState) {
   1.142 +        drawState = &fDefaultDrawState;
   1.143 +    }
   1.144 +    if (fDrawState != drawState) {
   1.145 +        fDrawState->unref();
   1.146 +        drawState->ref();
   1.147 +        fDrawState = drawState;
   1.148 +    }
   1.149 +}
   1.150 +
   1.151 +bool GrDrawTarget::reserveVertexSpace(size_t vertexSize,
   1.152 +                                      int vertexCount,
   1.153 +                                      void** vertices) {
   1.154 +    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
   1.155 +    bool acquired = false;
   1.156 +    if (vertexCount > 0) {
   1.157 +        SkASSERT(NULL != vertices);
   1.158 +        this->releasePreviousVertexSource();
   1.159 +        geoSrc.fVertexSrc = kNone_GeometrySrcType;
   1.160 +
   1.161 +        acquired = this->onReserveVertexSpace(vertexSize,
   1.162 +                                              vertexCount,
   1.163 +                                              vertices);
   1.164 +    }
   1.165 +    if (acquired) {
   1.166 +        geoSrc.fVertexSrc = kReserved_GeometrySrcType;
   1.167 +        geoSrc.fVertexCount = vertexCount;
   1.168 +        geoSrc.fVertexSize = vertexSize;
   1.169 +    } else if (NULL != vertices) {
   1.170 +        *vertices = NULL;
   1.171 +    }
   1.172 +    return acquired;
   1.173 +}
   1.174 +
   1.175 +bool GrDrawTarget::reserveIndexSpace(int indexCount,
   1.176 +                                     void** indices) {
   1.177 +    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
   1.178 +    bool acquired = false;
   1.179 +    if (indexCount > 0) {
   1.180 +        SkASSERT(NULL != indices);
   1.181 +        this->releasePreviousIndexSource();
   1.182 +        geoSrc.fIndexSrc = kNone_GeometrySrcType;
   1.183 +
   1.184 +        acquired = this->onReserveIndexSpace(indexCount, indices);
   1.185 +    }
   1.186 +    if (acquired) {
   1.187 +        geoSrc.fIndexSrc = kReserved_GeometrySrcType;
   1.188 +        geoSrc.fIndexCount = indexCount;
   1.189 +    } else if (NULL != indices) {
   1.190 +        *indices = NULL;
   1.191 +    }
   1.192 +    return acquired;
   1.193 +
   1.194 +}
   1.195 +
   1.196 +bool GrDrawTarget::reserveVertexAndIndexSpace(int vertexCount,
   1.197 +                                              int indexCount,
   1.198 +                                              void** vertices,
   1.199 +                                              void** indices) {
   1.200 +    size_t vertexSize = this->drawState()->getVertexSize();
   1.201 +    this->willReserveVertexAndIndexSpace(vertexCount, indexCount);
   1.202 +    if (vertexCount) {
   1.203 +        if (!this->reserveVertexSpace(vertexSize, vertexCount, vertices)) {
   1.204 +            if (indexCount) {
   1.205 +                this->resetIndexSource();
   1.206 +            }
   1.207 +            return false;
   1.208 +        }
   1.209 +    }
   1.210 +    if (indexCount) {
   1.211 +        if (!this->reserveIndexSpace(indexCount, indices)) {
   1.212 +            if (vertexCount) {
   1.213 +                this->resetVertexSource();
   1.214 +            }
   1.215 +            return false;
   1.216 +        }
   1.217 +    }
   1.218 +    return true;
   1.219 +}
   1.220 +
   1.221 +bool GrDrawTarget::geometryHints(int32_t* vertexCount,
   1.222 +                                 int32_t* indexCount) const {
   1.223 +    if (NULL != vertexCount) {
   1.224 +        *vertexCount = -1;
   1.225 +    }
   1.226 +    if (NULL != indexCount) {
   1.227 +        *indexCount = -1;
   1.228 +    }
   1.229 +    return false;
   1.230 +}
   1.231 +
   1.232 +void GrDrawTarget::releasePreviousVertexSource() {
   1.233 +    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
   1.234 +    switch (geoSrc.fVertexSrc) {
   1.235 +        case kNone_GeometrySrcType:
   1.236 +            break;
   1.237 +        case kArray_GeometrySrcType:
   1.238 +            this->releaseVertexArray();
   1.239 +            break;
   1.240 +        case kReserved_GeometrySrcType:
   1.241 +            this->releaseReservedVertexSpace();
   1.242 +            break;
   1.243 +        case kBuffer_GeometrySrcType:
   1.244 +            geoSrc.fVertexBuffer->unref();
   1.245 +#ifdef SK_DEBUG
   1.246 +            geoSrc.fVertexBuffer = (GrVertexBuffer*)DEBUG_INVAL_BUFFER;
   1.247 +#endif
   1.248 +            break;
   1.249 +        default:
   1.250 +            GrCrash("Unknown Vertex Source Type.");
   1.251 +            break;
   1.252 +    }
   1.253 +}
   1.254 +
   1.255 +void GrDrawTarget::releasePreviousIndexSource() {
   1.256 +    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
   1.257 +    switch (geoSrc.fIndexSrc) {
   1.258 +        case kNone_GeometrySrcType:   // these two don't require
   1.259 +            break;
   1.260 +        case kArray_GeometrySrcType:
   1.261 +            this->releaseIndexArray();
   1.262 +            break;
   1.263 +        case kReserved_GeometrySrcType:
   1.264 +            this->releaseReservedIndexSpace();
   1.265 +            break;
   1.266 +        case kBuffer_GeometrySrcType:
   1.267 +            geoSrc.fIndexBuffer->unref();
   1.268 +#ifdef SK_DEBUG
   1.269 +            geoSrc.fIndexBuffer = (GrIndexBuffer*)DEBUG_INVAL_BUFFER;
   1.270 +#endif
   1.271 +            break;
   1.272 +        default:
   1.273 +            GrCrash("Unknown Index Source Type.");
   1.274 +            break;
   1.275 +    }
   1.276 +}
   1.277 +
   1.278 +void GrDrawTarget::setVertexSourceToArray(const void* vertexArray,
   1.279 +                                          int vertexCount) {
   1.280 +    this->releasePreviousVertexSource();
   1.281 +    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
   1.282 +    geoSrc.fVertexSrc = kArray_GeometrySrcType;
   1.283 +    geoSrc.fVertexSize = this->drawState()->getVertexSize();
   1.284 +    geoSrc.fVertexCount = vertexCount;
   1.285 +    this->onSetVertexSourceToArray(vertexArray, vertexCount);
   1.286 +}
   1.287 +
   1.288 +void GrDrawTarget::setIndexSourceToArray(const void* indexArray,
   1.289 +                                         int indexCount) {
   1.290 +    this->releasePreviousIndexSource();
   1.291 +    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
   1.292 +    geoSrc.fIndexSrc = kArray_GeometrySrcType;
   1.293 +    geoSrc.fIndexCount = indexCount;
   1.294 +    this->onSetIndexSourceToArray(indexArray, indexCount);
   1.295 +}
   1.296 +
   1.297 +void GrDrawTarget::setVertexSourceToBuffer(const GrVertexBuffer* buffer) {
   1.298 +    this->releasePreviousVertexSource();
   1.299 +    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
   1.300 +    geoSrc.fVertexSrc    = kBuffer_GeometrySrcType;
   1.301 +    geoSrc.fVertexBuffer = buffer;
   1.302 +    buffer->ref();
   1.303 +    geoSrc.fVertexSize = this->drawState()->getVertexSize();
   1.304 +}
   1.305 +
   1.306 +void GrDrawTarget::setIndexSourceToBuffer(const GrIndexBuffer* buffer) {
   1.307 +    this->releasePreviousIndexSource();
   1.308 +    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
   1.309 +    geoSrc.fIndexSrc     = kBuffer_GeometrySrcType;
   1.310 +    geoSrc.fIndexBuffer  = buffer;
   1.311 +    buffer->ref();
   1.312 +}
   1.313 +
   1.314 +void GrDrawTarget::resetVertexSource() {
   1.315 +    this->releasePreviousVertexSource();
   1.316 +    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
   1.317 +    geoSrc.fVertexSrc = kNone_GeometrySrcType;
   1.318 +}
   1.319 +
   1.320 +void GrDrawTarget::resetIndexSource() {
   1.321 +    this->releasePreviousIndexSource();
   1.322 +    GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
   1.323 +    geoSrc.fIndexSrc = kNone_GeometrySrcType;
   1.324 +}
   1.325 +
   1.326 +void GrDrawTarget::pushGeometrySource() {
   1.327 +    this->geometrySourceWillPush();
   1.328 +    GeometrySrcState& newState = fGeoSrcStateStack.push_back();
   1.329 +    newState.fIndexSrc = kNone_GeometrySrcType;
   1.330 +    newState.fVertexSrc = kNone_GeometrySrcType;
   1.331 +#ifdef SK_DEBUG
   1.332 +    newState.fVertexCount  = ~0;
   1.333 +    newState.fVertexBuffer = (GrVertexBuffer*)~0;
   1.334 +    newState.fIndexCount   = ~0;
   1.335 +    newState.fIndexBuffer = (GrIndexBuffer*)~0;
   1.336 +#endif
   1.337 +}
   1.338 +
   1.339 +void GrDrawTarget::popGeometrySource() {
   1.340 +    // if popping last element then pops are unbalanced with pushes
   1.341 +    SkASSERT(fGeoSrcStateStack.count() > 1);
   1.342 +
   1.343 +    this->geometrySourceWillPop(fGeoSrcStateStack.fromBack(1));
   1.344 +    this->releasePreviousVertexSource();
   1.345 +    this->releasePreviousIndexSource();
   1.346 +    fGeoSrcStateStack.pop_back();
   1.347 +}
   1.348 +
   1.349 +////////////////////////////////////////////////////////////////////////////////
   1.350 +
   1.351 +bool GrDrawTarget::checkDraw(GrPrimitiveType type, int startVertex,
   1.352 +                             int startIndex, int vertexCount,
   1.353 +                             int indexCount) const {
   1.354 +    const GrDrawState& drawState = this->getDrawState();
   1.355 +#ifdef SK_DEBUG
   1.356 +    const GeometrySrcState& geoSrc = fGeoSrcStateStack.back();
   1.357 +    int maxVertex = startVertex + vertexCount;
   1.358 +    int maxValidVertex;
   1.359 +    switch (geoSrc.fVertexSrc) {
   1.360 +        case kNone_GeometrySrcType:
   1.361 +            GrCrash("Attempting to draw without vertex src.");
   1.362 +        case kReserved_GeometrySrcType: // fallthrough
   1.363 +        case kArray_GeometrySrcType:
   1.364 +            maxValidVertex = geoSrc.fVertexCount;
   1.365 +            break;
   1.366 +        case kBuffer_GeometrySrcType:
   1.367 +            maxValidVertex = static_cast<int>(geoSrc.fVertexBuffer->sizeInBytes() / geoSrc.fVertexSize);
   1.368 +            break;
   1.369 +    }
   1.370 +    if (maxVertex > maxValidVertex) {
   1.371 +        GrCrash("Drawing outside valid vertex range.");
   1.372 +    }
   1.373 +    if (indexCount > 0) {
   1.374 +        int maxIndex = startIndex + indexCount;
   1.375 +        int maxValidIndex;
   1.376 +        switch (geoSrc.fIndexSrc) {
   1.377 +            case kNone_GeometrySrcType:
   1.378 +                GrCrash("Attempting to draw indexed geom without index src.");
   1.379 +            case kReserved_GeometrySrcType: // fallthrough
   1.380 +            case kArray_GeometrySrcType:
   1.381 +                maxValidIndex = geoSrc.fIndexCount;
   1.382 +                break;
   1.383 +            case kBuffer_GeometrySrcType:
   1.384 +                maxValidIndex = static_cast<int>(geoSrc.fIndexBuffer->sizeInBytes() / sizeof(uint16_t));
   1.385 +                break;
   1.386 +        }
   1.387 +        if (maxIndex > maxValidIndex) {
   1.388 +            GrCrash("Index reads outside valid index range.");
   1.389 +        }
   1.390 +    }
   1.391 +
   1.392 +    SkASSERT(NULL != drawState.getRenderTarget());
   1.393 +
   1.394 +    for (int s = 0; s < drawState.numColorStages(); ++s) {
   1.395 +        const GrEffectRef& effect = *drawState.getColorStage(s).getEffect();
   1.396 +        int numTextures = effect->numTextures();
   1.397 +        for (int t = 0; t < numTextures; ++t) {
   1.398 +            GrTexture* texture = effect->texture(t);
   1.399 +            SkASSERT(texture->asRenderTarget() != drawState.getRenderTarget());
   1.400 +        }
   1.401 +    }
   1.402 +    for (int s = 0; s < drawState.numCoverageStages(); ++s) {
   1.403 +        const GrEffectRef& effect = *drawState.getCoverageStage(s).getEffect();
   1.404 +        int numTextures = effect->numTextures();
   1.405 +        for (int t = 0; t < numTextures; ++t) {
   1.406 +            GrTexture* texture = effect->texture(t);
   1.407 +            SkASSERT(texture->asRenderTarget() != drawState.getRenderTarget());
   1.408 +        }
   1.409 +    }
   1.410 +
   1.411 +    SkASSERT(drawState.validateVertexAttribs());
   1.412 +#endif
   1.413 +    if (NULL == drawState.getRenderTarget()) {
   1.414 +        return false;
   1.415 +    }
   1.416 +    return true;
   1.417 +}
   1.418 +
   1.419 +bool GrDrawTarget::setupDstReadIfNecessary(GrDeviceCoordTexture* dstCopy, const SkRect* drawBounds) {
   1.420 +    if (this->caps()->dstReadInShaderSupport() || !this->getDrawState().willEffectReadDstColor()) {
   1.421 +        return true;
   1.422 +    }
   1.423 +    GrRenderTarget* rt = this->drawState()->getRenderTarget();
   1.424 +    SkIRect copyRect;
   1.425 +    const GrClipData* clip = this->getClip();
   1.426 +    clip->getConservativeBounds(rt, &copyRect);
   1.427 +
   1.428 +    if (NULL != drawBounds) {
   1.429 +        SkIRect drawIBounds;
   1.430 +        drawBounds->roundOut(&drawIBounds);
   1.431 +        if (!copyRect.intersect(drawIBounds)) {
   1.432 +#ifdef SK_DEBUG
   1.433 +            GrPrintf("Missed an early reject. Bailing on draw from setupDstReadIfNecessary.\n");
   1.434 +#endif
   1.435 +            return false;
   1.436 +        }
   1.437 +    } else {
   1.438 +#ifdef SK_DEBUG
   1.439 +        //GrPrintf("No dev bounds when dst copy is made.\n");
   1.440 +#endif
   1.441 +    }
   1.442 +
   1.443 +    // MSAA consideration: When there is support for reading MSAA samples in the shader we could
   1.444 +    // have per-sample dst values by making the copy multisampled.
   1.445 +    GrTextureDesc desc;
   1.446 +    this->initCopySurfaceDstDesc(rt, &desc);
   1.447 +    desc.fWidth = copyRect.width();
   1.448 +    desc.fHeight = copyRect.height();
   1.449 +
   1.450 +    GrAutoScratchTexture ast(fContext, desc, GrContext::kApprox_ScratchTexMatch);
   1.451 +
   1.452 +    if (NULL == ast.texture()) {
   1.453 +        GrPrintf("Failed to create temporary copy of destination texture.\n");
   1.454 +        return false;
   1.455 +    }
   1.456 +    SkIPoint dstPoint = {0, 0};
   1.457 +    if (this->copySurface(ast.texture(), rt, copyRect, dstPoint)) {
   1.458 +        dstCopy->setTexture(ast.texture());
   1.459 +        dstCopy->setOffset(copyRect.fLeft, copyRect.fTop);
   1.460 +        return true;
   1.461 +    } else {
   1.462 +        return false;
   1.463 +    }
   1.464 +}
   1.465 +
   1.466 +void GrDrawTarget::drawIndexed(GrPrimitiveType type,
   1.467 +                               int startVertex,
   1.468 +                               int startIndex,
   1.469 +                               int vertexCount,
   1.470 +                               int indexCount,
   1.471 +                               const SkRect* devBounds) {
   1.472 +    if (indexCount > 0 && this->checkDraw(type, startVertex, startIndex, vertexCount, indexCount)) {
   1.473 +        DrawInfo info;
   1.474 +        info.fPrimitiveType = type;
   1.475 +        info.fStartVertex   = startVertex;
   1.476 +        info.fStartIndex    = startIndex;
   1.477 +        info.fVertexCount   = vertexCount;
   1.478 +        info.fIndexCount    = indexCount;
   1.479 +
   1.480 +        info.fInstanceCount         = 0;
   1.481 +        info.fVerticesPerInstance   = 0;
   1.482 +        info.fIndicesPerInstance    = 0;
   1.483 +
   1.484 +        if (NULL != devBounds) {
   1.485 +            info.setDevBounds(*devBounds);
   1.486 +        }
   1.487 +        // TODO: We should continue with incorrect blending.
   1.488 +        if (!this->setupDstReadIfNecessary(&info)) {
   1.489 +            return;
   1.490 +        }
   1.491 +        this->onDraw(info);
   1.492 +    }
   1.493 +}
   1.494 +
   1.495 +void GrDrawTarget::drawNonIndexed(GrPrimitiveType type,
   1.496 +                                  int startVertex,
   1.497 +                                  int vertexCount,
   1.498 +                                  const SkRect* devBounds) {
   1.499 +    if (vertexCount > 0 && this->checkDraw(type, startVertex, -1, vertexCount, -1)) {
   1.500 +        DrawInfo info;
   1.501 +        info.fPrimitiveType = type;
   1.502 +        info.fStartVertex   = startVertex;
   1.503 +        info.fStartIndex    = 0;
   1.504 +        info.fVertexCount   = vertexCount;
   1.505 +        info.fIndexCount    = 0;
   1.506 +
   1.507 +        info.fInstanceCount         = 0;
   1.508 +        info.fVerticesPerInstance   = 0;
   1.509 +        info.fIndicesPerInstance    = 0;
   1.510 +
   1.511 +        if (NULL != devBounds) {
   1.512 +            info.setDevBounds(*devBounds);
   1.513 +        }
   1.514 +        // TODO: We should continue with incorrect blending.
   1.515 +        if (!this->setupDstReadIfNecessary(&info)) {
   1.516 +            return;
   1.517 +        }
   1.518 +        this->onDraw(info);
   1.519 +    }
   1.520 +}
   1.521 +
   1.522 +void GrDrawTarget::stencilPath(const GrPath* path, SkPath::FillType fill) {
   1.523 +    // TODO: extract portions of checkDraw that are relevant to path stenciling.
   1.524 +    SkASSERT(NULL != path);
   1.525 +    SkASSERT(this->caps()->pathRenderingSupport());
   1.526 +    SkASSERT(!SkPath::IsInverseFillType(fill));
   1.527 +    this->onStencilPath(path, fill);
   1.528 +}
   1.529 +
   1.530 +void GrDrawTarget::drawPath(const GrPath* path, SkPath::FillType fill) {
   1.531 +    // TODO: extract portions of checkDraw that are relevant to path rendering.
   1.532 +    SkASSERT(NULL != path);
   1.533 +    SkASSERT(this->caps()->pathRenderingSupport());
   1.534 +    const GrDrawState* drawState = &getDrawState();
   1.535 +
   1.536 +    SkRect devBounds;
   1.537 +    if (SkPath::IsInverseFillType(fill)) {
   1.538 +        devBounds = SkRect::MakeWH(SkIntToScalar(drawState->getRenderTarget()->width()),
   1.539 +                                   SkIntToScalar(drawState->getRenderTarget()->height()));
   1.540 +    } else {
   1.541 +        devBounds = path->getBounds();
   1.542 +    }
   1.543 +    SkMatrix viewM = drawState->getViewMatrix();
   1.544 +    viewM.mapRect(&devBounds);
   1.545 +
   1.546 +    GrDeviceCoordTexture dstCopy;
   1.547 +    if (!this->setupDstReadIfNecessary(&dstCopy, &devBounds)) {
   1.548 +        return;
   1.549 +    }
   1.550 +
   1.551 +    this->onDrawPath(path, fill, dstCopy.texture() ? &dstCopy : NULL);
   1.552 +}
   1.553 +
   1.554 +void GrDrawTarget::instantGpuTraceEvent(const char* marker) {
   1.555 +    if (this->caps()->gpuTracingSupport()) {
   1.556 +        this->onInstantGpuTraceEvent(marker);
   1.557 +    }
   1.558 +}
   1.559 +
   1.560 +void GrDrawTarget::pushGpuTraceEvent(const char* marker) {
   1.561 +    SkASSERT(fPushGpuTraceCount >= 0);
   1.562 +    if (this->caps()->gpuTracingSupport()) {
   1.563 +        this->onPushGpuTraceEvent(marker);
   1.564 +        ++fPushGpuTraceCount;
   1.565 +    }
   1.566 +}
   1.567 +
   1.568 +void GrDrawTarget::popGpuTraceEvent() {
   1.569 +    SkASSERT(fPushGpuTraceCount >= 1);
   1.570 +    if (this->caps()->gpuTracingSupport()) {
   1.571 +        this->onPopGpuTraceEvent();
   1.572 +        --fPushGpuTraceCount;
   1.573 +    }
   1.574 +}
   1.575 +
   1.576 +////////////////////////////////////////////////////////////////////////////////
   1.577 +
   1.578 +bool GrDrawTarget::willUseHWAALines() const {
   1.579 +    // There is a conflict between using smooth lines and our use of premultiplied alpha. Smooth
   1.580 +    // lines tweak the incoming alpha value but not in a premul-alpha way. So we only use them when
   1.581 +    // our alpha is 0xff and tweaking the color for partial coverage is OK
   1.582 +    if (!this->caps()->hwAALineSupport() ||
   1.583 +        !this->getDrawState().isHWAntialiasState()) {
   1.584 +        return false;
   1.585 +    }
   1.586 +    GrDrawState::BlendOptFlags opts = this->getDrawState().getBlendOpts();
   1.587 +    return (GrDrawState::kDisableBlend_BlendOptFlag & opts) &&
   1.588 +           (GrDrawState::kCoverageAsAlpha_BlendOptFlag & opts);
   1.589 +}
   1.590 +
   1.591 +bool GrDrawTarget::canApplyCoverage() const {
   1.592 +    // we can correctly apply coverage if a) we have dual source blending
   1.593 +    // or b) one of our blend optimizations applies.
   1.594 +    return this->caps()->dualSourceBlendingSupport() ||
   1.595 +           GrDrawState::kNone_BlendOpt != this->getDrawState().getBlendOpts(true);
   1.596 +}
   1.597 +
   1.598 +////////////////////////////////////////////////////////////////////////////////
   1.599 +
   1.600 +void GrDrawTarget::drawIndexedInstances(GrPrimitiveType type,
   1.601 +                                        int instanceCount,
   1.602 +                                        int verticesPerInstance,
   1.603 +                                        int indicesPerInstance,
   1.604 +                                        const SkRect* devBounds) {
   1.605 +    if (!verticesPerInstance || !indicesPerInstance) {
   1.606 +        return;
   1.607 +    }
   1.608 +
   1.609 +    int maxInstancesPerDraw = this->indexCountInCurrentSource() / indicesPerInstance;
   1.610 +    if (!maxInstancesPerDraw) {
   1.611 +        return;
   1.612 +    }
   1.613 +
   1.614 +    DrawInfo info;
   1.615 +    info.fPrimitiveType = type;
   1.616 +    info.fStartIndex = 0;
   1.617 +    info.fStartVertex = 0;
   1.618 +    info.fIndicesPerInstance = indicesPerInstance;
   1.619 +    info.fVerticesPerInstance = verticesPerInstance;
   1.620 +
   1.621 +    // Set the same bounds for all the draws.
   1.622 +    if (NULL != devBounds) {
   1.623 +        info.setDevBounds(*devBounds);
   1.624 +    }
   1.625 +    // TODO: We should continue with incorrect blending.
   1.626 +    if (!this->setupDstReadIfNecessary(&info)) {
   1.627 +        return;
   1.628 +    }
   1.629 +
   1.630 +    while (instanceCount) {
   1.631 +        info.fInstanceCount = GrMin(instanceCount, maxInstancesPerDraw);
   1.632 +        info.fVertexCount = info.fInstanceCount * verticesPerInstance;
   1.633 +        info.fIndexCount = info.fInstanceCount * indicesPerInstance;
   1.634 +
   1.635 +        if (this->checkDraw(type,
   1.636 +                            info.fStartVertex,
   1.637 +                            info.fStartIndex,
   1.638 +                            info.fVertexCount,
   1.639 +                            info.fIndexCount)) {
   1.640 +            this->onDraw(info);
   1.641 +        }
   1.642 +        info.fStartVertex += info.fVertexCount;
   1.643 +        instanceCount -= info.fInstanceCount;
   1.644 +    }
   1.645 +}
   1.646 +
   1.647 +////////////////////////////////////////////////////////////////////////////////
   1.648 +
   1.649 +namespace {
   1.650 +
   1.651 +// position + (optional) texture coord
   1.652 +extern const GrVertexAttrib gBWRectPosUVAttribs[] = {
   1.653 +    {kVec2f_GrVertexAttribType, 0,               kPosition_GrVertexAttribBinding},
   1.654 +    {kVec2f_GrVertexAttribType, sizeof(GrPoint), kLocalCoord_GrVertexAttribBinding}
   1.655 +};
   1.656 +
   1.657 +void set_vertex_attributes(GrDrawState* drawState, bool hasUVs) {
   1.658 +    if (hasUVs) {
   1.659 +        drawState->setVertexAttribs<gBWRectPosUVAttribs>(2);
   1.660 +    } else {
   1.661 +        drawState->setVertexAttribs<gBWRectPosUVAttribs>(1);
   1.662 +    }
   1.663 +}
   1.664 +
   1.665 +};
   1.666 +
   1.667 +void GrDrawTarget::onDrawRect(const SkRect& rect,
   1.668 +                              const SkMatrix* matrix,
   1.669 +                              const SkRect* localRect,
   1.670 +                              const SkMatrix* localMatrix) {
   1.671 +
   1.672 +    GrDrawState::AutoViewMatrixRestore avmr;
   1.673 +    if (NULL != matrix) {
   1.674 +        avmr.set(this->drawState(), *matrix);
   1.675 +    }
   1.676 +
   1.677 +    set_vertex_attributes(this->drawState(), NULL != localRect);
   1.678 +
   1.679 +    AutoReleaseGeometry geo(this, 4, 0);
   1.680 +    if (!geo.succeeded()) {
   1.681 +        GrPrintf("Failed to get space for vertices!\n");
   1.682 +        return;
   1.683 +    }
   1.684 +
   1.685 +    size_t vsize = this->drawState()->getVertexSize();
   1.686 +    geo.positions()->setRectFan(rect.fLeft, rect.fTop, rect.fRight, rect.fBottom, vsize);
   1.687 +    if (NULL != localRect) {
   1.688 +        GrPoint* coords = GrTCast<GrPoint*>(GrTCast<intptr_t>(geo.vertices()) +
   1.689 +                                            sizeof(GrPoint));
   1.690 +        coords->setRectFan(localRect->fLeft, localRect->fTop,
   1.691 +                           localRect->fRight, localRect->fBottom,
   1.692 +                           vsize);
   1.693 +        if (NULL != localMatrix) {
   1.694 +            localMatrix->mapPointsWithStride(coords, vsize, 4);
   1.695 +        }
   1.696 +    }
   1.697 +    SkRect bounds;
   1.698 +    this->getDrawState().getViewMatrix().mapRect(&bounds, rect);
   1.699 +
   1.700 +    this->drawNonIndexed(kTriangleFan_GrPrimitiveType, 0, 4, &bounds);
   1.701 +}
   1.702 +
   1.703 +void GrDrawTarget::clipWillBeSet(const GrClipData* clipData) {
   1.704 +}
   1.705 +
   1.706 +////////////////////////////////////////////////////////////////////////////////
   1.707 +
   1.708 +GrDrawTarget::AutoStateRestore::AutoStateRestore() {
   1.709 +    fDrawTarget = NULL;
   1.710 +}
   1.711 +
   1.712 +GrDrawTarget::AutoStateRestore::AutoStateRestore(GrDrawTarget* target,
   1.713 +                                                 ASRInit init,
   1.714 +                                                 const SkMatrix* vm) {
   1.715 +    fDrawTarget = NULL;
   1.716 +    this->set(target, init, vm);
   1.717 +}
   1.718 +
   1.719 +GrDrawTarget::AutoStateRestore::~AutoStateRestore() {
   1.720 +    if (NULL != fDrawTarget) {
   1.721 +        fDrawTarget->setDrawState(fSavedState);
   1.722 +        fSavedState->unref();
   1.723 +    }
   1.724 +}
   1.725 +
   1.726 +void GrDrawTarget::AutoStateRestore::set(GrDrawTarget* target, ASRInit init, const SkMatrix* vm) {
   1.727 +    SkASSERT(NULL == fDrawTarget);
   1.728 +    fDrawTarget = target;
   1.729 +    fSavedState = target->drawState();
   1.730 +    SkASSERT(fSavedState);
   1.731 +    fSavedState->ref();
   1.732 +    if (kReset_ASRInit == init) {
   1.733 +        if (NULL == vm) {
   1.734 +            // calls the default cons
   1.735 +            fTempState.init();
   1.736 +        } else {
   1.737 +            SkNEW_IN_TLAZY(&fTempState, GrDrawState, (*vm));
   1.738 +        }
   1.739 +    } else {
   1.740 +        SkASSERT(kPreserve_ASRInit == init);
   1.741 +        if (NULL == vm) {
   1.742 +            fTempState.set(*fSavedState);
   1.743 +        } else {
   1.744 +            SkNEW_IN_TLAZY(&fTempState, GrDrawState, (*fSavedState, *vm));
   1.745 +        }
   1.746 +    }
   1.747 +    target->setDrawState(fTempState.get());
   1.748 +}
   1.749 +
   1.750 +bool GrDrawTarget::AutoStateRestore::setIdentity(GrDrawTarget* target, ASRInit init) {
   1.751 +    SkASSERT(NULL == fDrawTarget);
   1.752 +    fDrawTarget = target;
   1.753 +    fSavedState = target->drawState();
   1.754 +    SkASSERT(fSavedState);
   1.755 +    fSavedState->ref();
   1.756 +    if (kReset_ASRInit == init) {
   1.757 +        // calls the default cons
   1.758 +        fTempState.init();
   1.759 +    } else {
   1.760 +        SkASSERT(kPreserve_ASRInit == init);
   1.761 +        // calls the copy cons
   1.762 +        fTempState.set(*fSavedState);
   1.763 +        if (!fTempState.get()->setIdentityViewMatrix()) {
   1.764 +            // let go of any resources held by the temp
   1.765 +            fTempState.get()->reset();
   1.766 +            fDrawTarget = NULL;
   1.767 +            fSavedState->unref();
   1.768 +            fSavedState = NULL;
   1.769 +            return false;
   1.770 +        }
   1.771 +    }
   1.772 +    target->setDrawState(fTempState.get());
   1.773 +    return true;
   1.774 +}
   1.775 +
   1.776 +////////////////////////////////////////////////////////////////////////////////
   1.777 +
   1.778 +GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry(
   1.779 +                                         GrDrawTarget*  target,
   1.780 +                                         int vertexCount,
   1.781 +                                         int indexCount) {
   1.782 +    fTarget = NULL;
   1.783 +    this->set(target, vertexCount, indexCount);
   1.784 +}
   1.785 +
   1.786 +GrDrawTarget::AutoReleaseGeometry::AutoReleaseGeometry() {
   1.787 +    fTarget = NULL;
   1.788 +}
   1.789 +
   1.790 +GrDrawTarget::AutoReleaseGeometry::~AutoReleaseGeometry() {
   1.791 +    this->reset();
   1.792 +}
   1.793 +
   1.794 +bool GrDrawTarget::AutoReleaseGeometry::set(GrDrawTarget*  target,
   1.795 +                                            int vertexCount,
   1.796 +                                            int indexCount) {
   1.797 +    this->reset();
   1.798 +    fTarget = target;
   1.799 +    bool success = true;
   1.800 +    if (NULL != fTarget) {
   1.801 +        fTarget = target;
   1.802 +        success = target->reserveVertexAndIndexSpace(vertexCount,
   1.803 +                                                     indexCount,
   1.804 +                                                     &fVertices,
   1.805 +                                                     &fIndices);
   1.806 +        if (!success) {
   1.807 +            fTarget = NULL;
   1.808 +            this->reset();
   1.809 +        }
   1.810 +    }
   1.811 +    SkASSERT(success == (NULL != fTarget));
   1.812 +    return success;
   1.813 +}
   1.814 +
   1.815 +void GrDrawTarget::AutoReleaseGeometry::reset() {
   1.816 +    if (NULL != fTarget) {
   1.817 +        if (NULL != fVertices) {
   1.818 +            fTarget->resetVertexSource();
   1.819 +        }
   1.820 +        if (NULL != fIndices) {
   1.821 +            fTarget->resetIndexSource();
   1.822 +        }
   1.823 +        fTarget = NULL;
   1.824 +    }
   1.825 +    fVertices = NULL;
   1.826 +    fIndices = NULL;
   1.827 +}
   1.828 +
   1.829 +GrDrawTarget::AutoClipRestore::AutoClipRestore(GrDrawTarget* target, const SkIRect& newClip) {
   1.830 +    fTarget = target;
   1.831 +    fClip = fTarget->getClip();
   1.832 +    fStack.init();
   1.833 +    fStack.get()->clipDevRect(newClip, SkRegion::kReplace_Op);
   1.834 +    fReplacementClip.fClipStack = fStack.get();
   1.835 +    target->setClip(&fReplacementClip);
   1.836 +}
   1.837 +
   1.838 +namespace {
   1.839 +// returns true if the read/written rect intersects the src/dst and false if not.
   1.840 +bool clip_srcrect_and_dstpoint(const GrSurface* dst,
   1.841 +                               const GrSurface* src,
   1.842 +                               const SkIRect& srcRect,
   1.843 +                               const SkIPoint& dstPoint,
   1.844 +                               SkIRect* clippedSrcRect,
   1.845 +                               SkIPoint* clippedDstPoint) {
   1.846 +    *clippedSrcRect = srcRect;
   1.847 +    *clippedDstPoint = dstPoint;
   1.848 +
   1.849 +    // clip the left edge to src and dst bounds, adjusting dstPoint if necessary
   1.850 +    if (clippedSrcRect->fLeft < 0) {
   1.851 +        clippedDstPoint->fX -= clippedSrcRect->fLeft;
   1.852 +        clippedSrcRect->fLeft = 0;
   1.853 +    }
   1.854 +    if (clippedDstPoint->fX < 0) {
   1.855 +        clippedSrcRect->fLeft -= clippedDstPoint->fX;
   1.856 +        clippedDstPoint->fX = 0;
   1.857 +    }
   1.858 +
   1.859 +    // clip the top edge to src and dst bounds, adjusting dstPoint if necessary
   1.860 +    if (clippedSrcRect->fTop < 0) {
   1.861 +        clippedDstPoint->fY -= clippedSrcRect->fTop;
   1.862 +        clippedSrcRect->fTop = 0;
   1.863 +    }
   1.864 +    if (clippedDstPoint->fY < 0) {
   1.865 +        clippedSrcRect->fTop -= clippedDstPoint->fY;
   1.866 +        clippedDstPoint->fY = 0;
   1.867 +    }
   1.868 +
   1.869 +    // clip the right edge to the src and dst bounds.
   1.870 +    if (clippedSrcRect->fRight > src->width()) {
   1.871 +        clippedSrcRect->fRight = src->width();
   1.872 +    }
   1.873 +    if (clippedDstPoint->fX + clippedSrcRect->width() > dst->width()) {
   1.874 +        clippedSrcRect->fRight = clippedSrcRect->fLeft + dst->width() - clippedDstPoint->fX;
   1.875 +    }
   1.876 +
   1.877 +    // clip the bottom edge to the src and dst bounds.
   1.878 +    if (clippedSrcRect->fBottom > src->height()) {
   1.879 +        clippedSrcRect->fBottom = src->height();
   1.880 +    }
   1.881 +    if (clippedDstPoint->fY + clippedSrcRect->height() > dst->height()) {
   1.882 +        clippedSrcRect->fBottom = clippedSrcRect->fTop + dst->height() - clippedDstPoint->fY;
   1.883 +    }
   1.884 +
   1.885 +    // The above clipping steps may have inverted the rect if it didn't intersect either the src or
   1.886 +    // dst bounds.
   1.887 +    return !clippedSrcRect->isEmpty();
   1.888 +}
   1.889 +}
   1.890 +
   1.891 +bool GrDrawTarget::copySurface(GrSurface* dst,
   1.892 +                               GrSurface* src,
   1.893 +                               const SkIRect& srcRect,
   1.894 +                               const SkIPoint& dstPoint) {
   1.895 +    SkASSERT(NULL != dst);
   1.896 +    SkASSERT(NULL != src);
   1.897 +
   1.898 +    SkIRect clippedSrcRect;
   1.899 +    SkIPoint clippedDstPoint;
   1.900 +    // If the rect is outside the src or dst then we've already succeeded.
   1.901 +    if (!clip_srcrect_and_dstpoint(dst,
   1.902 +                                   src,
   1.903 +                                   srcRect,
   1.904 +                                   dstPoint,
   1.905 +                                   &clippedSrcRect,
   1.906 +                                   &clippedDstPoint)) {
   1.907 +        SkASSERT(this->canCopySurface(dst, src, srcRect, dstPoint));
   1.908 +        return true;
   1.909 +    }
   1.910 +
   1.911 +    bool result = this->onCopySurface(dst, src, clippedSrcRect, clippedDstPoint);
   1.912 +    SkASSERT(result == this->canCopySurface(dst, src, clippedSrcRect, clippedDstPoint));
   1.913 +    return result;
   1.914 +}
   1.915 +
   1.916 +bool GrDrawTarget::canCopySurface(GrSurface* dst,
   1.917 +                                  GrSurface* src,
   1.918 +                                  const SkIRect& srcRect,
   1.919 +                                  const SkIPoint& dstPoint) {
   1.920 +    SkASSERT(NULL != dst);
   1.921 +    SkASSERT(NULL != src);
   1.922 +
   1.923 +    SkIRect clippedSrcRect;
   1.924 +    SkIPoint clippedDstPoint;
   1.925 +    // If the rect is outside the src or dst then we're guaranteed success
   1.926 +    if (!clip_srcrect_and_dstpoint(dst,
   1.927 +                                   src,
   1.928 +                                   srcRect,
   1.929 +                                   dstPoint,
   1.930 +                                   &clippedSrcRect,
   1.931 +                                   &clippedDstPoint)) {
   1.932 +        return true;
   1.933 +    }
   1.934 +    return this->onCanCopySurface(dst, src, clippedSrcRect, clippedDstPoint);
   1.935 +}
   1.936 +
   1.937 +bool GrDrawTarget::onCanCopySurface(GrSurface* dst,
   1.938 +                                    GrSurface* src,
   1.939 +                                    const SkIRect& srcRect,
   1.940 +                                    const SkIPoint& dstPoint) {
   1.941 +    // Check that the read/write rects are contained within the src/dst bounds.
   1.942 +    SkASSERT(!srcRect.isEmpty());
   1.943 +    SkASSERT(SkIRect::MakeWH(src->width(), src->height()).contains(srcRect));
   1.944 +    SkASSERT(dstPoint.fX >= 0 && dstPoint.fY >= 0);
   1.945 +    SkASSERT(dstPoint.fX + srcRect.width() <= dst->width() &&
   1.946 +             dstPoint.fY + srcRect.height() <= dst->height());
   1.947 +
   1.948 +    return !dst->isSameAs(src) && NULL != dst->asRenderTarget() && NULL != src->asTexture();
   1.949 +}
   1.950 +
   1.951 +bool GrDrawTarget::onCopySurface(GrSurface* dst,
   1.952 +                                 GrSurface* src,
   1.953 +                                 const SkIRect& srcRect,
   1.954 +                                 const SkIPoint& dstPoint) {
   1.955 +    if (!GrDrawTarget::onCanCopySurface(dst, src, srcRect, dstPoint)) {
   1.956 +        return false;
   1.957 +    }
   1.958 +
   1.959 +    GrRenderTarget* rt = dst->asRenderTarget();
   1.960 +    GrTexture* tex = src->asTexture();
   1.961 +
   1.962 +    GrDrawTarget::AutoStateRestore asr(this, kReset_ASRInit);
   1.963 +    this->drawState()->setRenderTarget(rt);
   1.964 +    SkMatrix matrix;
   1.965 +    matrix.setTranslate(SkIntToScalar(srcRect.fLeft - dstPoint.fX),
   1.966 +                        SkIntToScalar(srcRect.fTop - dstPoint.fY));
   1.967 +    matrix.postIDiv(tex->width(), tex->height());
   1.968 +    this->drawState()->addColorTextureEffect(tex, matrix);
   1.969 +    SkIRect dstRect = SkIRect::MakeXYWH(dstPoint.fX,
   1.970 +                                        dstPoint.fY,
   1.971 +                                        srcRect.width(),
   1.972 +                                        srcRect.height());
   1.973 +    this->drawSimpleRect(dstRect);
   1.974 +    return true;
   1.975 +}
   1.976 +
   1.977 +void GrDrawTarget::initCopySurfaceDstDesc(const GrSurface* src, GrTextureDesc* desc) {
   1.978 +    // Make the dst of the copy be a render target because the default copySurface draws to the dst.
   1.979 +    desc->fOrigin = kDefault_GrSurfaceOrigin;
   1.980 +    desc->fFlags = kRenderTarget_GrTextureFlagBit | kNoStencil_GrTextureFlagBit;
   1.981 +    desc->fConfig = src->config();
   1.982 +}
   1.983 +
   1.984 +///////////////////////////////////////////////////////////////////////////////
   1.985 +
   1.986 +void GrDrawTargetCaps::reset() {
   1.987 +    f8BitPaletteSupport = false;
   1.988 +    fMipMapSupport = false;
   1.989 +    fNPOTTextureTileSupport = false;
   1.990 +    fTwoSidedStencilSupport = false;
   1.991 +    fStencilWrapOpsSupport = false;
   1.992 +    fHWAALineSupport = false;
   1.993 +    fShaderDerivativeSupport = false;
   1.994 +    fGeometryShaderSupport = false;
   1.995 +    fDualSourceBlendingSupport = false;
   1.996 +    fBufferLockSupport = false;
   1.997 +    fPathRenderingSupport = false;
   1.998 +    fDstReadInShaderSupport = false;
   1.999 +    fReuseScratchTextures = true;
  1.1000 +    fGpuTracingSupport = false;
  1.1001 +
  1.1002 +    fMaxRenderTargetSize = 0;
  1.1003 +    fMaxTextureSize = 0;
  1.1004 +    fMaxSampleCount = 0;
  1.1005 +
  1.1006 +    memset(fConfigRenderSupport, 0, sizeof(fConfigRenderSupport));
  1.1007 +}
  1.1008 +
  1.1009 +GrDrawTargetCaps& GrDrawTargetCaps::operator=(const GrDrawTargetCaps& other) {
  1.1010 +    f8BitPaletteSupport = other.f8BitPaletteSupport;
  1.1011 +    fMipMapSupport = other.fMipMapSupport;
  1.1012 +    fNPOTTextureTileSupport = other.fNPOTTextureTileSupport;
  1.1013 +    fTwoSidedStencilSupport = other.fTwoSidedStencilSupport;
  1.1014 +    fStencilWrapOpsSupport = other.fStencilWrapOpsSupport;
  1.1015 +    fHWAALineSupport = other.fHWAALineSupport;
  1.1016 +    fShaderDerivativeSupport = other.fShaderDerivativeSupport;
  1.1017 +    fGeometryShaderSupport = other.fGeometryShaderSupport;
  1.1018 +    fDualSourceBlendingSupport = other.fDualSourceBlendingSupport;
  1.1019 +    fBufferLockSupport = other.fBufferLockSupport;
  1.1020 +    fPathRenderingSupport = other.fPathRenderingSupport;
  1.1021 +    fDstReadInShaderSupport = other.fDstReadInShaderSupport;
  1.1022 +    fReuseScratchTextures = other.fReuseScratchTextures;
  1.1023 +    fGpuTracingSupport = other.fGpuTracingSupport;
  1.1024 +
  1.1025 +    fMaxRenderTargetSize = other.fMaxRenderTargetSize;
  1.1026 +    fMaxTextureSize = other.fMaxTextureSize;
  1.1027 +    fMaxSampleCount = other.fMaxSampleCount;
  1.1028 +
  1.1029 +    memcpy(fConfigRenderSupport, other.fConfigRenderSupport, sizeof(fConfigRenderSupport));
  1.1030 +
  1.1031 +    return *this;
  1.1032 +}
  1.1033 +
  1.1034 +SkString GrDrawTargetCaps::dump() const {
  1.1035 +    SkString r;
  1.1036 +    static const char* gNY[] = {"NO", "YES"};
  1.1037 +    r.appendf("8 Bit Palette Support       : %s\n", gNY[f8BitPaletteSupport]);
  1.1038 +    r.appendf("MIP Map Support             : %s\n", gNY[fMipMapSupport]);
  1.1039 +    r.appendf("NPOT Texture Tile Support   : %s\n", gNY[fNPOTTextureTileSupport]);
  1.1040 +    r.appendf("Two Sided Stencil Support   : %s\n", gNY[fTwoSidedStencilSupport]);
  1.1041 +    r.appendf("Stencil Wrap Ops  Support   : %s\n", gNY[fStencilWrapOpsSupport]);
  1.1042 +    r.appendf("HW AA Lines Support         : %s\n", gNY[fHWAALineSupport]);
  1.1043 +    r.appendf("Shader Derivative Support   : %s\n", gNY[fShaderDerivativeSupport]);
  1.1044 +    r.appendf("Geometry Shader Support     : %s\n", gNY[fGeometryShaderSupport]);
  1.1045 +    r.appendf("Dual Source Blending Support: %s\n", gNY[fDualSourceBlendingSupport]);
  1.1046 +    r.appendf("Buffer Lock Support         : %s\n", gNY[fBufferLockSupport]);
  1.1047 +    r.appendf("Path Rendering Support      : %s\n", gNY[fPathRenderingSupport]);
  1.1048 +    r.appendf("Dst Read In Shader Support  : %s\n", gNY[fDstReadInShaderSupport]);
  1.1049 +    r.appendf("Reuse Scratch Textures      : %s\n", gNY[fReuseScratchTextures]);
  1.1050 +    r.appendf("Gpu Tracing Support         : %s\n", gNY[fGpuTracingSupport]);
  1.1051 +    r.appendf("Max Texture Size            : %d\n", fMaxTextureSize);
  1.1052 +    r.appendf("Max Render Target Size      : %d\n", fMaxRenderTargetSize);
  1.1053 +    r.appendf("Max Sample Count            : %d\n", fMaxSampleCount);
  1.1054 +
  1.1055 +    static const char* kConfigNames[] = {
  1.1056 +        "Unknown",  // kUnknown_GrPixelConfig
  1.1057 +        "Alpha8",   // kAlpha_8_GrPixelConfig,
  1.1058 +        "Index8",   // kIndex_8_GrPixelConfig,
  1.1059 +        "RGB565",   // kRGB_565_GrPixelConfig,
  1.1060 +        "RGBA444",  // kRGBA_4444_GrPixelConfig,
  1.1061 +        "RGBA8888", // kRGBA_8888_GrPixelConfig,
  1.1062 +        "BGRA8888", // kBGRA_8888_GrPixelConfig,
  1.1063 +    };
  1.1064 +    GR_STATIC_ASSERT(0 == kUnknown_GrPixelConfig);
  1.1065 +    GR_STATIC_ASSERT(1 == kAlpha_8_GrPixelConfig);
  1.1066 +    GR_STATIC_ASSERT(2 == kIndex_8_GrPixelConfig);
  1.1067 +    GR_STATIC_ASSERT(3 == kRGB_565_GrPixelConfig);
  1.1068 +    GR_STATIC_ASSERT(4 == kRGBA_4444_GrPixelConfig);
  1.1069 +    GR_STATIC_ASSERT(5 == kRGBA_8888_GrPixelConfig);
  1.1070 +    GR_STATIC_ASSERT(6 == kBGRA_8888_GrPixelConfig);
  1.1071 +    GR_STATIC_ASSERT(SK_ARRAY_COUNT(kConfigNames) == kGrPixelConfigCnt);
  1.1072 +
  1.1073 +    SkASSERT(!fConfigRenderSupport[kUnknown_GrPixelConfig][0]);
  1.1074 +    SkASSERT(!fConfigRenderSupport[kUnknown_GrPixelConfig][1]);
  1.1075 +    for (size_t i = 0; i < SK_ARRAY_COUNT(kConfigNames); ++i)  {
  1.1076 +        if (i != kUnknown_GrPixelConfig) {
  1.1077 +            r.appendf("%s is renderable: %s, with MSAA: %s\n",
  1.1078 +                     kConfigNames[i],
  1.1079 +                     gNY[fConfigRenderSupport[i][0]],
  1.1080 +                     gNY[fConfigRenderSupport[i][1]]);
  1.1081 +        }
  1.1082 +    }
  1.1083 +    return r;
  1.1084 +}

mercurial