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

changeset 0
6474c204b198
     1.1 --- /dev/null	Thu Jan 01 00:00:00 1970 +0000
     1.2 +++ b/gfx/skia/trunk/src/gpu/GrDrawState.cpp	Wed Dec 31 06:09:35 2014 +0100
     1.3 @@ -0,0 +1,475 @@
     1.4 +/*
     1.5 + * Copyright 2012 Google Inc.
     1.6 + *
     1.7 + * Use of this source code is governed by a BSD-style license that can be
     1.8 + * found in the LICENSE file.
     1.9 + */
    1.10 +
    1.11 +#include "GrDrawState.h"
    1.12 +#include "GrPaint.h"
    1.13 +
    1.14 +bool GrDrawState::setIdentityViewMatrix()  {
    1.15 +    if (fColorStages.count() || fCoverageStages.count()) {
    1.16 +        SkMatrix invVM;
    1.17 +        if (!fCommon.fViewMatrix.invert(&invVM)) {
    1.18 +            // sad trombone sound
    1.19 +            return false;
    1.20 +        }
    1.21 +        for (int s = 0; s < fColorStages.count(); ++s) {
    1.22 +            fColorStages[s].localCoordChange(invVM);
    1.23 +        }
    1.24 +        for (int s = 0; s < fCoverageStages.count(); ++s) {
    1.25 +            fCoverageStages[s].localCoordChange(invVM);
    1.26 +        }
    1.27 +    }
    1.28 +    fCommon.fViewMatrix.reset();
    1.29 +    return true;
    1.30 +}
    1.31 +
    1.32 +void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRenderTarget* rt) {
    1.33 +    SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages());
    1.34 +
    1.35 +    fColorStages.reset();
    1.36 +    fCoverageStages.reset();
    1.37 +
    1.38 +    for (int i = 0; i < paint.numColorStages(); ++i) {
    1.39 +        fColorStages.push_back(paint.getColorStage(i));
    1.40 +    }
    1.41 +
    1.42 +    for (int i = 0; i < paint.numCoverageStages(); ++i) {
    1.43 +        fCoverageStages.push_back(paint.getCoverageStage(i));
    1.44 +    }
    1.45 +
    1.46 +    this->setRenderTarget(rt);
    1.47 +
    1.48 +    fCommon.fViewMatrix = vm;
    1.49 +
    1.50 +    // These have no equivalent in GrPaint, set them to defaults
    1.51 +    fCommon.fBlendConstant = 0x0;
    1.52 +    fCommon.fDrawFace = kBoth_DrawFace;
    1.53 +    fCommon.fStencilSettings.setDisabled();
    1.54 +    this->resetStateFlags();
    1.55 +
    1.56 +    // Enable the clip bit
    1.57 +    this->enableState(GrDrawState::kClip_StateBit);
    1.58 +
    1.59 +    this->setColor(paint.getColor());
    1.60 +    this->setState(GrDrawState::kDither_StateBit, paint.isDither());
    1.61 +    this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias());
    1.62 +
    1.63 +    this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff());
    1.64 +    this->setCoverage(paint.getCoverage());
    1.65 +}
    1.66 +
    1.67 +////////////////////////////////////////////////////////////////////////////////
    1.68 +
    1.69 +static size_t vertex_size(const GrVertexAttrib* attribs, int count) {
    1.70 +    // this works as long as we're 4 byte-aligned
    1.71 +#ifdef SK_DEBUG
    1.72 +    uint32_t overlapCheck = 0;
    1.73 +#endif
    1.74 +    SkASSERT(count <= GrDrawState::kMaxVertexAttribCnt);
    1.75 +    size_t size = 0;
    1.76 +    for (int index = 0; index < count; ++index) {
    1.77 +        size_t attribSize = GrVertexAttribTypeSize(attribs[index].fType);
    1.78 +        size += attribSize;
    1.79 +#ifdef SK_DEBUG
    1.80 +        size_t dwordCount = attribSize >> 2;
    1.81 +        uint32_t mask = (1 << dwordCount)-1;
    1.82 +        size_t offsetShift = attribs[index].fOffset >> 2;
    1.83 +        SkASSERT(!(overlapCheck & (mask << offsetShift)));
    1.84 +        overlapCheck |= (mask << offsetShift);
    1.85 +#endif
    1.86 +    }
    1.87 +    return size;
    1.88 +}
    1.89 +
    1.90 +size_t GrDrawState::getVertexSize() const {
    1.91 +    return vertex_size(fCommon.fVAPtr, fCommon.fVACount);
    1.92 +}
    1.93 +
    1.94 +////////////////////////////////////////////////////////////////////////////////
    1.95 +
    1.96 +void GrDrawState::setVertexAttribs(const GrVertexAttrib* attribs, int count) {
    1.97 +    SkASSERT(count <= kMaxVertexAttribCnt);
    1.98 +
    1.99 +    fCommon.fVAPtr = attribs;
   1.100 +    fCommon.fVACount = count;
   1.101 +
   1.102 +    // Set all the indices to -1
   1.103 +    memset(fCommon.fFixedFunctionVertexAttribIndices,
   1.104 +           0xff,
   1.105 +           sizeof(fCommon.fFixedFunctionVertexAttribIndices));
   1.106 +#ifdef SK_DEBUG
   1.107 +    uint32_t overlapCheck = 0;
   1.108 +#endif
   1.109 +    for (int i = 0; i < count; ++i) {
   1.110 +        if (attribs[i].fBinding < kGrFixedFunctionVertexAttribBindingCnt) {
   1.111 +            // The fixed function attribs can only be specified once
   1.112 +            SkASSERT(-1 == fCommon.fFixedFunctionVertexAttribIndices[attribs[i].fBinding]);
   1.113 +            SkASSERT(GrFixedFunctionVertexAttribVectorCount(attribs[i].fBinding) ==
   1.114 +                     GrVertexAttribTypeVectorCount(attribs[i].fType));
   1.115 +            fCommon.fFixedFunctionVertexAttribIndices[attribs[i].fBinding] = i;
   1.116 +        }
   1.117 +#ifdef SK_DEBUG
   1.118 +        size_t dwordCount = GrVertexAttribTypeSize(attribs[i].fType) >> 2;
   1.119 +        uint32_t mask = (1 << dwordCount)-1;
   1.120 +        size_t offsetShift = attribs[i].fOffset >> 2;
   1.121 +        SkASSERT(!(overlapCheck & (mask << offsetShift)));
   1.122 +        overlapCheck |= (mask << offsetShift);
   1.123 +#endif
   1.124 +    }
   1.125 +    // Positions must be specified.
   1.126 +    SkASSERT(-1 != fCommon.fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding]);
   1.127 +}
   1.128 +
   1.129 +////////////////////////////////////////////////////////////////////////////////
   1.130 +
   1.131 +void GrDrawState::setDefaultVertexAttribs() {
   1.132 +    static const GrVertexAttrib kPositionAttrib =
   1.133 +        {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding};
   1.134 +
   1.135 +    fCommon.fVAPtr = &kPositionAttrib;
   1.136 +    fCommon.fVACount = 1;
   1.137 +
   1.138 +    // set all the fixed function indices to -1 except position.
   1.139 +    memset(fCommon.fFixedFunctionVertexAttribIndices,
   1.140 +           0xff,
   1.141 +           sizeof(fCommon.fFixedFunctionVertexAttribIndices));
   1.142 +    fCommon.fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding] = 0;
   1.143 +}
   1.144 +
   1.145 +////////////////////////////////////////////////////////////////////////////////
   1.146 +
   1.147 +bool GrDrawState::validateVertexAttribs() const {
   1.148 +    // check consistency of effects and attributes
   1.149 +    GrSLType slTypes[kMaxVertexAttribCnt];
   1.150 +    for (int i = 0; i < kMaxVertexAttribCnt; ++i) {
   1.151 +        slTypes[i] = static_cast<GrSLType>(-1);
   1.152 +    }
   1.153 +    int totalStages = fColorStages.count() + fCoverageStages.count();
   1.154 +    for (int s = 0; s < totalStages; ++s) {
   1.155 +        int covIdx = s - fColorStages.count();
   1.156 +        const GrEffectStage& stage = covIdx < 0 ? fColorStages[s] : fCoverageStages[covIdx];
   1.157 +        const GrEffectRef* effect = stage.getEffect();
   1.158 +        SkASSERT(NULL != effect);
   1.159 +        // make sure that any attribute indices have the correct binding type, that the attrib
   1.160 +        // type and effect's shader lang type are compatible, and that attributes shared by
   1.161 +        // multiple effects use the same shader lang type.
   1.162 +        const int* attributeIndices = stage.getVertexAttribIndices();
   1.163 +        int numAttributes = stage.getVertexAttribIndexCount();
   1.164 +        for (int i = 0; i < numAttributes; ++i) {
   1.165 +            int attribIndex = attributeIndices[i];
   1.166 +            if (attribIndex >= fCommon.fVACount ||
   1.167 +                kEffect_GrVertexAttribBinding != fCommon.fVAPtr[attribIndex].fBinding) {
   1.168 +                return false;
   1.169 +            }
   1.170 +
   1.171 +            GrSLType effectSLType = (*effect)->vertexAttribType(i);
   1.172 +            GrVertexAttribType attribType = fCommon.fVAPtr[attribIndex].fType;
   1.173 +            int slVecCount = GrSLTypeVectorCount(effectSLType);
   1.174 +            int attribVecCount = GrVertexAttribTypeVectorCount(attribType);
   1.175 +            if (slVecCount != attribVecCount ||
   1.176 +                (static_cast<GrSLType>(-1) != slTypes[attribIndex] &&
   1.177 +                    slTypes[attribIndex] != effectSLType)) {
   1.178 +                return false;
   1.179 +            }
   1.180 +            slTypes[attribIndex] = effectSLType;
   1.181 +        }
   1.182 +    }
   1.183 +
   1.184 +    return true;
   1.185 +}
   1.186 +
   1.187 +bool GrDrawState::willEffectReadDstColor() const {
   1.188 +    if (!this->isColorWriteDisabled()) {
   1.189 +        for (int s = 0; s < fColorStages.count(); ++s) {
   1.190 +            if ((*fColorStages[s].getEffect())->willReadDstColor()) {
   1.191 +                return true;
   1.192 +            }
   1.193 +        }
   1.194 +    }
   1.195 +    for (int s = 0; s < fCoverageStages.count(); ++s) {
   1.196 +        if ((*fCoverageStages[s].getEffect())->willReadDstColor()) {
   1.197 +            return true;
   1.198 +        }
   1.199 +    }
   1.200 +    return false;
   1.201 +}
   1.202 +
   1.203 +////////////////////////////////////////////////////////////////////////////////
   1.204 +
   1.205 +bool GrDrawState::srcAlphaWillBeOne() const {
   1.206 +    uint32_t validComponentFlags;
   1.207 +    GrColor color;
   1.208 +    // Check if per-vertex or constant color may have partial alpha
   1.209 +    if (this->hasColorVertexAttribute()) {
   1.210 +        validComponentFlags = 0;
   1.211 +        color = 0; // not strictly necessary but we get false alarms from tools about uninit.
   1.212 +    } else {
   1.213 +        validComponentFlags = kRGBA_GrColorComponentFlags;
   1.214 +        color = this->getColor();
   1.215 +    }
   1.216 +
   1.217 +    // Run through the color stages
   1.218 +    for (int s = 0; s < fColorStages.count(); ++s) {
   1.219 +        const GrEffectRef* effect = fColorStages[s].getEffect();
   1.220 +        (*effect)->getConstantColorComponents(&color, &validComponentFlags);
   1.221 +    }
   1.222 +
   1.223 +    // Check whether coverage is treated as color. If so we run through the coverage computation.
   1.224 +    if (this->isCoverageDrawing()) {
   1.225 +        GrColor coverageColor = this->getCoverageColor();
   1.226 +        GrColor oldColor = color;
   1.227 +        color = 0;
   1.228 +        for (int c = 0; c < 4; ++c) {
   1.229 +            if (validComponentFlags & (1 << c)) {
   1.230 +                U8CPU a = (oldColor >> (c * 8)) & 0xff;
   1.231 +                U8CPU b = (coverageColor >> (c * 8)) & 0xff;
   1.232 +                color |= (SkMulDiv255Round(a, b) << (c * 8));
   1.233 +            }
   1.234 +        }
   1.235 +        for (int s = 0; s < fCoverageStages.count(); ++s) {
   1.236 +            const GrEffectRef* effect = fCoverageStages[s].getEffect();
   1.237 +            (*effect)->getConstantColorComponents(&color, &validComponentFlags);
   1.238 +        }
   1.239 +    }
   1.240 +    return (kA_GrColorComponentFlag & validComponentFlags) && 0xff == GrColorUnpackA(color);
   1.241 +}
   1.242 +
   1.243 +bool GrDrawState::hasSolidCoverage() const {
   1.244 +    // If we're drawing coverage directly then coverage is effectively treated as color.
   1.245 +    if (this->isCoverageDrawing()) {
   1.246 +        return true;
   1.247 +    }
   1.248 +
   1.249 +    GrColor coverage;
   1.250 +    uint32_t validComponentFlags;
   1.251 +    // Initialize to an unknown starting coverage if per-vertex coverage is specified.
   1.252 +    if (this->hasCoverageVertexAttribute()) {
   1.253 +        validComponentFlags = 0;
   1.254 +    } else {
   1.255 +        coverage = fCommon.fCoverage;
   1.256 +        validComponentFlags = kRGBA_GrColorComponentFlags;
   1.257 +    }
   1.258 +
   1.259 +    // Run through the coverage stages and see if the coverage will be all ones at the end.
   1.260 +    for (int s = 0; s < fCoverageStages.count(); ++s) {
   1.261 +        const GrEffectRef* effect = fCoverageStages[s].getEffect();
   1.262 +        (*effect)->getConstantColorComponents(&coverage, &validComponentFlags);
   1.263 +    }
   1.264 +    return (kRGBA_GrColorComponentFlags == validComponentFlags) && (0xffffffff == coverage);
   1.265 +}
   1.266 +
   1.267 +////////////////////////////////////////////////////////////////////////////////
   1.268 +
   1.269 +// Some blend modes allow folding a fractional coverage value into the color's alpha channel, while
   1.270 +// others will blend incorrectly.
   1.271 +bool GrDrawState::canTweakAlphaForCoverage() const {
   1.272 +    /*
   1.273 +     The fractional coverage is f.
   1.274 +     The src and dst coeffs are Cs and Cd.
   1.275 +     The dst and src colors are S and D.
   1.276 +     We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D. By tweaking the source color's alpha
   1.277 +     we're replacing S with S'=fS. It's obvious that that first term will always be ok. The second
   1.278 +     term can be rearranged as [1-(1-Cd)f]D. By substituting in the various possibilities for Cd we
   1.279 +     find that only 1, ISA, and ISC produce the correct destination when applied to S' and D.
   1.280 +     Also, if we're directly rendering coverage (isCoverageDrawing) then coverage is treated as
   1.281 +     color by definition.
   1.282 +     */
   1.283 +    return kOne_GrBlendCoeff == fCommon.fDstBlend ||
   1.284 +           kISA_GrBlendCoeff == fCommon.fDstBlend ||
   1.285 +           kISC_GrBlendCoeff == fCommon.fDstBlend ||
   1.286 +           this->isCoverageDrawing();
   1.287 +}
   1.288 +
   1.289 +GrDrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage,
   1.290 +                                                     GrBlendCoeff* srcCoeff,
   1.291 +                                                     GrBlendCoeff* dstCoeff) const {
   1.292 +
   1.293 +    GrBlendCoeff bogusSrcCoeff, bogusDstCoeff;
   1.294 +    if (NULL == srcCoeff) {
   1.295 +        srcCoeff = &bogusSrcCoeff;
   1.296 +    }
   1.297 +    *srcCoeff = this->getSrcBlendCoeff();
   1.298 +
   1.299 +    if (NULL == dstCoeff) {
   1.300 +        dstCoeff = &bogusDstCoeff;
   1.301 +    }
   1.302 +    *dstCoeff = this->getDstBlendCoeff();
   1.303 +
   1.304 +    if (this->isColorWriteDisabled()) {
   1.305 +        *srcCoeff = kZero_GrBlendCoeff;
   1.306 +        *dstCoeff = kOne_GrBlendCoeff;
   1.307 +    }
   1.308 +
   1.309 +    bool srcAIsOne = this->srcAlphaWillBeOne();
   1.310 +    bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff ||
   1.311 +                         (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne);
   1.312 +    bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff ||
   1.313 +                         (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne);
   1.314 +
   1.315 +    bool covIsZero = !this->isCoverageDrawing() &&
   1.316 +                     !this->hasCoverageVertexAttribute() &&
   1.317 +                     0 == this->getCoverageColor();
   1.318 +    // When coeffs are (0,1) there is no reason to draw at all, unless
   1.319 +    // stenciling is enabled. Having color writes disabled is effectively
   1.320 +    // (0,1). The same applies when coverage is known to be 0.
   1.321 +    if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne) || covIsZero) {
   1.322 +        if (this->getStencil().doesWrite()) {
   1.323 +            return kDisableBlend_BlendOptFlag |
   1.324 +                   kEmitCoverage_BlendOptFlag;
   1.325 +        } else {
   1.326 +            return kSkipDraw_BlendOptFlag;
   1.327 +        }
   1.328 +    }
   1.329 +
   1.330 +    // check for coverage due to constant coverage, per-vertex coverage, or coverage stage
   1.331 +    bool hasCoverage = forceCoverage ||
   1.332 +                       0xffffffff != this->getCoverageColor() ||
   1.333 +                       this->hasCoverageVertexAttribute() ||
   1.334 +                       fCoverageStages.count() > 0;
   1.335 +
   1.336 +    // if we don't have coverage we can check whether the dst
   1.337 +    // has to read at all. If not, we'll disable blending.
   1.338 +    if (!hasCoverage) {
   1.339 +        if (dstCoeffIsZero) {
   1.340 +            if (kOne_GrBlendCoeff == *srcCoeff) {
   1.341 +                // if there is no coverage and coeffs are (1,0) then we
   1.342 +                // won't need to read the dst at all, it gets replaced by src
   1.343 +                return kDisableBlend_BlendOptFlag;
   1.344 +            } else if (kZero_GrBlendCoeff == *srcCoeff) {
   1.345 +                // if the op is "clear" then we don't need to emit a color
   1.346 +                // or blend, just write transparent black into the dst.
   1.347 +                *srcCoeff = kOne_GrBlendCoeff;
   1.348 +                *dstCoeff = kZero_GrBlendCoeff;
   1.349 +                return kDisableBlend_BlendOptFlag | kEmitTransBlack_BlendOptFlag;
   1.350 +            }
   1.351 +        }
   1.352 +    } else if (this->isCoverageDrawing()) {
   1.353 +        // we have coverage but we aren't distinguishing it from alpha by request.
   1.354 +        return kCoverageAsAlpha_BlendOptFlag;
   1.355 +    } else {
   1.356 +        // check whether coverage can be safely rolled into alpha
   1.357 +        // of if we can skip color computation and just emit coverage
   1.358 +        if (this->canTweakAlphaForCoverage()) {
   1.359 +            return kCoverageAsAlpha_BlendOptFlag;
   1.360 +        }
   1.361 +        if (dstCoeffIsZero) {
   1.362 +            if (kZero_GrBlendCoeff == *srcCoeff) {
   1.363 +                // the source color is not included in the blend
   1.364 +                // the dst coeff is effectively zero so blend works out to:
   1.365 +                // (c)(0)D + (1-c)D = (1-c)D.
   1.366 +                *dstCoeff = kISA_GrBlendCoeff;
   1.367 +                return  kEmitCoverage_BlendOptFlag;
   1.368 +            } else if (srcAIsOne) {
   1.369 +                // the dst coeff is effectively zero so blend works out to:
   1.370 +                // cS + (c)(0)D + (1-c)D = cS + (1-c)D.
   1.371 +                // If Sa is 1 then we can replace Sa with c
   1.372 +                // and set dst coeff to 1-Sa.
   1.373 +                *dstCoeff = kISA_GrBlendCoeff;
   1.374 +                return  kCoverageAsAlpha_BlendOptFlag;
   1.375 +            }
   1.376 +        } else if (dstCoeffIsOne) {
   1.377 +            // the dst coeff is effectively one so blend works out to:
   1.378 +            // cS + (c)(1)D + (1-c)D = cS + D.
   1.379 +            *dstCoeff = kOne_GrBlendCoeff;
   1.380 +            return  kCoverageAsAlpha_BlendOptFlag;
   1.381 +        }
   1.382 +    }
   1.383 +    if (kOne_GrBlendCoeff == *srcCoeff &&
   1.384 +        kZero_GrBlendCoeff == *dstCoeff &&
   1.385 +        this->willEffectReadDstColor()) {
   1.386 +        // In this case the shader will fully resolve the color, coverage, and dst and we don't
   1.387 +        // need blending.
   1.388 +        return kDisableBlend_BlendOptFlag;
   1.389 +    }
   1.390 +    return kNone_BlendOpt;
   1.391 +}
   1.392 +
   1.393 +////////////////////////////////////////////////////////////////////////////////
   1.394 +
   1.395 +void GrDrawState::AutoViewMatrixRestore::restore() {
   1.396 +    if (NULL != fDrawState) {
   1.397 +        SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;)
   1.398 +        fDrawState->fCommon.fViewMatrix = fViewMatrix;
   1.399 +        SkASSERT(fDrawState->numColorStages() >= fNumColorStages);
   1.400 +        int numCoverageStages = fSavedCoordChanges.count() - fNumColorStages;
   1.401 +        SkASSERT(fDrawState->numCoverageStages() >= numCoverageStages);
   1.402 +
   1.403 +        int i = 0;
   1.404 +        for (int s = 0; s < fNumColorStages; ++s, ++i) {
   1.405 +            fDrawState->fColorStages[s].restoreCoordChange(fSavedCoordChanges[i]);
   1.406 +        }
   1.407 +        for (int s = 0; s < numCoverageStages; ++s, ++i) {
   1.408 +            fDrawState->fCoverageStages[s].restoreCoordChange(fSavedCoordChanges[i]);
   1.409 +        }
   1.410 +        fDrawState = NULL;
   1.411 +    }
   1.412 +}
   1.413 +
   1.414 +void GrDrawState::AutoViewMatrixRestore::set(GrDrawState* drawState,
   1.415 +                                             const SkMatrix& preconcatMatrix) {
   1.416 +    this->restore();
   1.417 +
   1.418 +    SkASSERT(NULL == fDrawState);
   1.419 +    if (NULL == drawState || preconcatMatrix.isIdentity()) {
   1.420 +        return;
   1.421 +    }
   1.422 +    fDrawState = drawState;
   1.423 +
   1.424 +    fViewMatrix = drawState->getViewMatrix();
   1.425 +    drawState->fCommon.fViewMatrix.preConcat(preconcatMatrix);
   1.426 +
   1.427 +    this->doEffectCoordChanges(preconcatMatrix);
   1.428 +    SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
   1.429 +}
   1.430 +
   1.431 +bool GrDrawState::AutoViewMatrixRestore::setIdentity(GrDrawState* drawState) {
   1.432 +    this->restore();
   1.433 +
   1.434 +    if (NULL == drawState) {
   1.435 +        return false;
   1.436 +    }
   1.437 +
   1.438 +    if (drawState->getViewMatrix().isIdentity()) {
   1.439 +        return true;
   1.440 +    }
   1.441 +
   1.442 +    fViewMatrix = drawState->getViewMatrix();
   1.443 +    if (0 == drawState->numTotalStages()) {
   1.444 +        drawState->fCommon.fViewMatrix.reset();
   1.445 +        fDrawState = drawState;
   1.446 +        fNumColorStages = 0;
   1.447 +        fSavedCoordChanges.reset(0);
   1.448 +        SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
   1.449 +        return true;
   1.450 +    } else {
   1.451 +        SkMatrix inv;
   1.452 +        if (!fViewMatrix.invert(&inv)) {
   1.453 +            return false;
   1.454 +        }
   1.455 +        drawState->fCommon.fViewMatrix.reset();
   1.456 +        fDrawState = drawState;
   1.457 +        this->doEffectCoordChanges(inv);
   1.458 +        SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
   1.459 +        return true;
   1.460 +    }
   1.461 +}
   1.462 +
   1.463 +void GrDrawState::AutoViewMatrixRestore::doEffectCoordChanges(const SkMatrix& coordChangeMatrix) {
   1.464 +    fSavedCoordChanges.reset(fDrawState->numTotalStages());
   1.465 +    int i = 0;
   1.466 +
   1.467 +    fNumColorStages = fDrawState->numColorStages();
   1.468 +    for (int s = 0; s < fNumColorStages; ++s, ++i) {
   1.469 +        fDrawState->fColorStages[s].saveCoordChange(&fSavedCoordChanges[i]);
   1.470 +        fDrawState->fColorStages[s].localCoordChange(coordChangeMatrix);
   1.471 +    }
   1.472 +
   1.473 +    int numCoverageStages = fDrawState->numCoverageStages();
   1.474 +    for (int s = 0; s < numCoverageStages; ++s, ++i) {
   1.475 +        fDrawState->fCoverageStages[s].saveCoordChange(&fSavedCoordChanges[i]);
   1.476 +        fDrawState->fCoverageStages[s].localCoordChange(coordChangeMatrix);
   1.477 +    }
   1.478 +}

mercurial