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

Sat, 03 Jan 2015 20:18:00 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Sat, 03 Jan 2015 20:18:00 +0100
branch
TOR_BUG_3246
changeset 7
129ffea94266
permissions
-rw-r--r--

Conditionally enable double key logic according to:
private browsing mode or privacy.thirdparty.isolate preference and
implement in GetCookieStringCommon and FindCookie where it counts...
With some reservations of how to convince FindCookie users to test
condition and pass a nullptr when disabling double key logic.

michael@0 1 /*
michael@0 2 * Copyright 2012 Google Inc.
michael@0 3 *
michael@0 4 * Use of this source code is governed by a BSD-style license that can be
michael@0 5 * found in the LICENSE file.
michael@0 6 */
michael@0 7
michael@0 8 #include "GrDrawState.h"
michael@0 9 #include "GrPaint.h"
michael@0 10
michael@0 11 bool GrDrawState::setIdentityViewMatrix() {
michael@0 12 if (fColorStages.count() || fCoverageStages.count()) {
michael@0 13 SkMatrix invVM;
michael@0 14 if (!fCommon.fViewMatrix.invert(&invVM)) {
michael@0 15 // sad trombone sound
michael@0 16 return false;
michael@0 17 }
michael@0 18 for (int s = 0; s < fColorStages.count(); ++s) {
michael@0 19 fColorStages[s].localCoordChange(invVM);
michael@0 20 }
michael@0 21 for (int s = 0; s < fCoverageStages.count(); ++s) {
michael@0 22 fCoverageStages[s].localCoordChange(invVM);
michael@0 23 }
michael@0 24 }
michael@0 25 fCommon.fViewMatrix.reset();
michael@0 26 return true;
michael@0 27 }
michael@0 28
michael@0 29 void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRenderTarget* rt) {
michael@0 30 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages());
michael@0 31
michael@0 32 fColorStages.reset();
michael@0 33 fCoverageStages.reset();
michael@0 34
michael@0 35 for (int i = 0; i < paint.numColorStages(); ++i) {
michael@0 36 fColorStages.push_back(paint.getColorStage(i));
michael@0 37 }
michael@0 38
michael@0 39 for (int i = 0; i < paint.numCoverageStages(); ++i) {
michael@0 40 fCoverageStages.push_back(paint.getCoverageStage(i));
michael@0 41 }
michael@0 42
michael@0 43 this->setRenderTarget(rt);
michael@0 44
michael@0 45 fCommon.fViewMatrix = vm;
michael@0 46
michael@0 47 // These have no equivalent in GrPaint, set them to defaults
michael@0 48 fCommon.fBlendConstant = 0x0;
michael@0 49 fCommon.fDrawFace = kBoth_DrawFace;
michael@0 50 fCommon.fStencilSettings.setDisabled();
michael@0 51 this->resetStateFlags();
michael@0 52
michael@0 53 // Enable the clip bit
michael@0 54 this->enableState(GrDrawState::kClip_StateBit);
michael@0 55
michael@0 56 this->setColor(paint.getColor());
michael@0 57 this->setState(GrDrawState::kDither_StateBit, paint.isDither());
michael@0 58 this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias());
michael@0 59
michael@0 60 this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff());
michael@0 61 this->setCoverage(paint.getCoverage());
michael@0 62 }
michael@0 63
michael@0 64 ////////////////////////////////////////////////////////////////////////////////
michael@0 65
michael@0 66 static size_t vertex_size(const GrVertexAttrib* attribs, int count) {
michael@0 67 // this works as long as we're 4 byte-aligned
michael@0 68 #ifdef SK_DEBUG
michael@0 69 uint32_t overlapCheck = 0;
michael@0 70 #endif
michael@0 71 SkASSERT(count <= GrDrawState::kMaxVertexAttribCnt);
michael@0 72 size_t size = 0;
michael@0 73 for (int index = 0; index < count; ++index) {
michael@0 74 size_t attribSize = GrVertexAttribTypeSize(attribs[index].fType);
michael@0 75 size += attribSize;
michael@0 76 #ifdef SK_DEBUG
michael@0 77 size_t dwordCount = attribSize >> 2;
michael@0 78 uint32_t mask = (1 << dwordCount)-1;
michael@0 79 size_t offsetShift = attribs[index].fOffset >> 2;
michael@0 80 SkASSERT(!(overlapCheck & (mask << offsetShift)));
michael@0 81 overlapCheck |= (mask << offsetShift);
michael@0 82 #endif
michael@0 83 }
michael@0 84 return size;
michael@0 85 }
michael@0 86
michael@0 87 size_t GrDrawState::getVertexSize() const {
michael@0 88 return vertex_size(fCommon.fVAPtr, fCommon.fVACount);
michael@0 89 }
michael@0 90
michael@0 91 ////////////////////////////////////////////////////////////////////////////////
michael@0 92
michael@0 93 void GrDrawState::setVertexAttribs(const GrVertexAttrib* attribs, int count) {
michael@0 94 SkASSERT(count <= kMaxVertexAttribCnt);
michael@0 95
michael@0 96 fCommon.fVAPtr = attribs;
michael@0 97 fCommon.fVACount = count;
michael@0 98
michael@0 99 // Set all the indices to -1
michael@0 100 memset(fCommon.fFixedFunctionVertexAttribIndices,
michael@0 101 0xff,
michael@0 102 sizeof(fCommon.fFixedFunctionVertexAttribIndices));
michael@0 103 #ifdef SK_DEBUG
michael@0 104 uint32_t overlapCheck = 0;
michael@0 105 #endif
michael@0 106 for (int i = 0; i < count; ++i) {
michael@0 107 if (attribs[i].fBinding < kGrFixedFunctionVertexAttribBindingCnt) {
michael@0 108 // The fixed function attribs can only be specified once
michael@0 109 SkASSERT(-1 == fCommon.fFixedFunctionVertexAttribIndices[attribs[i].fBinding]);
michael@0 110 SkASSERT(GrFixedFunctionVertexAttribVectorCount(attribs[i].fBinding) ==
michael@0 111 GrVertexAttribTypeVectorCount(attribs[i].fType));
michael@0 112 fCommon.fFixedFunctionVertexAttribIndices[attribs[i].fBinding] = i;
michael@0 113 }
michael@0 114 #ifdef SK_DEBUG
michael@0 115 size_t dwordCount = GrVertexAttribTypeSize(attribs[i].fType) >> 2;
michael@0 116 uint32_t mask = (1 << dwordCount)-1;
michael@0 117 size_t offsetShift = attribs[i].fOffset >> 2;
michael@0 118 SkASSERT(!(overlapCheck & (mask << offsetShift)));
michael@0 119 overlapCheck |= (mask << offsetShift);
michael@0 120 #endif
michael@0 121 }
michael@0 122 // Positions must be specified.
michael@0 123 SkASSERT(-1 != fCommon.fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding]);
michael@0 124 }
michael@0 125
michael@0 126 ////////////////////////////////////////////////////////////////////////////////
michael@0 127
michael@0 128 void GrDrawState::setDefaultVertexAttribs() {
michael@0 129 static const GrVertexAttrib kPositionAttrib =
michael@0 130 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding};
michael@0 131
michael@0 132 fCommon.fVAPtr = &kPositionAttrib;
michael@0 133 fCommon.fVACount = 1;
michael@0 134
michael@0 135 // set all the fixed function indices to -1 except position.
michael@0 136 memset(fCommon.fFixedFunctionVertexAttribIndices,
michael@0 137 0xff,
michael@0 138 sizeof(fCommon.fFixedFunctionVertexAttribIndices));
michael@0 139 fCommon.fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding] = 0;
michael@0 140 }
michael@0 141
michael@0 142 ////////////////////////////////////////////////////////////////////////////////
michael@0 143
michael@0 144 bool GrDrawState::validateVertexAttribs() const {
michael@0 145 // check consistency of effects and attributes
michael@0 146 GrSLType slTypes[kMaxVertexAttribCnt];
michael@0 147 for (int i = 0; i < kMaxVertexAttribCnt; ++i) {
michael@0 148 slTypes[i] = static_cast<GrSLType>(-1);
michael@0 149 }
michael@0 150 int totalStages = fColorStages.count() + fCoverageStages.count();
michael@0 151 for (int s = 0; s < totalStages; ++s) {
michael@0 152 int covIdx = s - fColorStages.count();
michael@0 153 const GrEffectStage& stage = covIdx < 0 ? fColorStages[s] : fCoverageStages[covIdx];
michael@0 154 const GrEffectRef* effect = stage.getEffect();
michael@0 155 SkASSERT(NULL != effect);
michael@0 156 // make sure that any attribute indices have the correct binding type, that the attrib
michael@0 157 // type and effect's shader lang type are compatible, and that attributes shared by
michael@0 158 // multiple effects use the same shader lang type.
michael@0 159 const int* attributeIndices = stage.getVertexAttribIndices();
michael@0 160 int numAttributes = stage.getVertexAttribIndexCount();
michael@0 161 for (int i = 0; i < numAttributes; ++i) {
michael@0 162 int attribIndex = attributeIndices[i];
michael@0 163 if (attribIndex >= fCommon.fVACount ||
michael@0 164 kEffect_GrVertexAttribBinding != fCommon.fVAPtr[attribIndex].fBinding) {
michael@0 165 return false;
michael@0 166 }
michael@0 167
michael@0 168 GrSLType effectSLType = (*effect)->vertexAttribType(i);
michael@0 169 GrVertexAttribType attribType = fCommon.fVAPtr[attribIndex].fType;
michael@0 170 int slVecCount = GrSLTypeVectorCount(effectSLType);
michael@0 171 int attribVecCount = GrVertexAttribTypeVectorCount(attribType);
michael@0 172 if (slVecCount != attribVecCount ||
michael@0 173 (static_cast<GrSLType>(-1) != slTypes[attribIndex] &&
michael@0 174 slTypes[attribIndex] != effectSLType)) {
michael@0 175 return false;
michael@0 176 }
michael@0 177 slTypes[attribIndex] = effectSLType;
michael@0 178 }
michael@0 179 }
michael@0 180
michael@0 181 return true;
michael@0 182 }
michael@0 183
michael@0 184 bool GrDrawState::willEffectReadDstColor() const {
michael@0 185 if (!this->isColorWriteDisabled()) {
michael@0 186 for (int s = 0; s < fColorStages.count(); ++s) {
michael@0 187 if ((*fColorStages[s].getEffect())->willReadDstColor()) {
michael@0 188 return true;
michael@0 189 }
michael@0 190 }
michael@0 191 }
michael@0 192 for (int s = 0; s < fCoverageStages.count(); ++s) {
michael@0 193 if ((*fCoverageStages[s].getEffect())->willReadDstColor()) {
michael@0 194 return true;
michael@0 195 }
michael@0 196 }
michael@0 197 return false;
michael@0 198 }
michael@0 199
michael@0 200 ////////////////////////////////////////////////////////////////////////////////
michael@0 201
michael@0 202 bool GrDrawState::srcAlphaWillBeOne() const {
michael@0 203 uint32_t validComponentFlags;
michael@0 204 GrColor color;
michael@0 205 // Check if per-vertex or constant color may have partial alpha
michael@0 206 if (this->hasColorVertexAttribute()) {
michael@0 207 validComponentFlags = 0;
michael@0 208 color = 0; // not strictly necessary but we get false alarms from tools about uninit.
michael@0 209 } else {
michael@0 210 validComponentFlags = kRGBA_GrColorComponentFlags;
michael@0 211 color = this->getColor();
michael@0 212 }
michael@0 213
michael@0 214 // Run through the color stages
michael@0 215 for (int s = 0; s < fColorStages.count(); ++s) {
michael@0 216 const GrEffectRef* effect = fColorStages[s].getEffect();
michael@0 217 (*effect)->getConstantColorComponents(&color, &validComponentFlags);
michael@0 218 }
michael@0 219
michael@0 220 // Check whether coverage is treated as color. If so we run through the coverage computation.
michael@0 221 if (this->isCoverageDrawing()) {
michael@0 222 GrColor coverageColor = this->getCoverageColor();
michael@0 223 GrColor oldColor = color;
michael@0 224 color = 0;
michael@0 225 for (int c = 0; c < 4; ++c) {
michael@0 226 if (validComponentFlags & (1 << c)) {
michael@0 227 U8CPU a = (oldColor >> (c * 8)) & 0xff;
michael@0 228 U8CPU b = (coverageColor >> (c * 8)) & 0xff;
michael@0 229 color |= (SkMulDiv255Round(a, b) << (c * 8));
michael@0 230 }
michael@0 231 }
michael@0 232 for (int s = 0; s < fCoverageStages.count(); ++s) {
michael@0 233 const GrEffectRef* effect = fCoverageStages[s].getEffect();
michael@0 234 (*effect)->getConstantColorComponents(&color, &validComponentFlags);
michael@0 235 }
michael@0 236 }
michael@0 237 return (kA_GrColorComponentFlag & validComponentFlags) && 0xff == GrColorUnpackA(color);
michael@0 238 }
michael@0 239
michael@0 240 bool GrDrawState::hasSolidCoverage() const {
michael@0 241 // If we're drawing coverage directly then coverage is effectively treated as color.
michael@0 242 if (this->isCoverageDrawing()) {
michael@0 243 return true;
michael@0 244 }
michael@0 245
michael@0 246 GrColor coverage;
michael@0 247 uint32_t validComponentFlags;
michael@0 248 // Initialize to an unknown starting coverage if per-vertex coverage is specified.
michael@0 249 if (this->hasCoverageVertexAttribute()) {
michael@0 250 validComponentFlags = 0;
michael@0 251 } else {
michael@0 252 coverage = fCommon.fCoverage;
michael@0 253 validComponentFlags = kRGBA_GrColorComponentFlags;
michael@0 254 }
michael@0 255
michael@0 256 // Run through the coverage stages and see if the coverage will be all ones at the end.
michael@0 257 for (int s = 0; s < fCoverageStages.count(); ++s) {
michael@0 258 const GrEffectRef* effect = fCoverageStages[s].getEffect();
michael@0 259 (*effect)->getConstantColorComponents(&coverage, &validComponentFlags);
michael@0 260 }
michael@0 261 return (kRGBA_GrColorComponentFlags == validComponentFlags) && (0xffffffff == coverage);
michael@0 262 }
michael@0 263
michael@0 264 ////////////////////////////////////////////////////////////////////////////////
michael@0 265
michael@0 266 // Some blend modes allow folding a fractional coverage value into the color's alpha channel, while
michael@0 267 // others will blend incorrectly.
michael@0 268 bool GrDrawState::canTweakAlphaForCoverage() const {
michael@0 269 /*
michael@0 270 The fractional coverage is f.
michael@0 271 The src and dst coeffs are Cs and Cd.
michael@0 272 The dst and src colors are S and D.
michael@0 273 We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D. By tweaking the source color's alpha
michael@0 274 we're replacing S with S'=fS. It's obvious that that first term will always be ok. The second
michael@0 275 term can be rearranged as [1-(1-Cd)f]D. By substituting in the various possibilities for Cd we
michael@0 276 find that only 1, ISA, and ISC produce the correct destination when applied to S' and D.
michael@0 277 Also, if we're directly rendering coverage (isCoverageDrawing) then coverage is treated as
michael@0 278 color by definition.
michael@0 279 */
michael@0 280 return kOne_GrBlendCoeff == fCommon.fDstBlend ||
michael@0 281 kISA_GrBlendCoeff == fCommon.fDstBlend ||
michael@0 282 kISC_GrBlendCoeff == fCommon.fDstBlend ||
michael@0 283 this->isCoverageDrawing();
michael@0 284 }
michael@0 285
michael@0 286 GrDrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage,
michael@0 287 GrBlendCoeff* srcCoeff,
michael@0 288 GrBlendCoeff* dstCoeff) const {
michael@0 289
michael@0 290 GrBlendCoeff bogusSrcCoeff, bogusDstCoeff;
michael@0 291 if (NULL == srcCoeff) {
michael@0 292 srcCoeff = &bogusSrcCoeff;
michael@0 293 }
michael@0 294 *srcCoeff = this->getSrcBlendCoeff();
michael@0 295
michael@0 296 if (NULL == dstCoeff) {
michael@0 297 dstCoeff = &bogusDstCoeff;
michael@0 298 }
michael@0 299 *dstCoeff = this->getDstBlendCoeff();
michael@0 300
michael@0 301 if (this->isColorWriteDisabled()) {
michael@0 302 *srcCoeff = kZero_GrBlendCoeff;
michael@0 303 *dstCoeff = kOne_GrBlendCoeff;
michael@0 304 }
michael@0 305
michael@0 306 bool srcAIsOne = this->srcAlphaWillBeOne();
michael@0 307 bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff ||
michael@0 308 (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne);
michael@0 309 bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff ||
michael@0 310 (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne);
michael@0 311
michael@0 312 bool covIsZero = !this->isCoverageDrawing() &&
michael@0 313 !this->hasCoverageVertexAttribute() &&
michael@0 314 0 == this->getCoverageColor();
michael@0 315 // When coeffs are (0,1) there is no reason to draw at all, unless
michael@0 316 // stenciling is enabled. Having color writes disabled is effectively
michael@0 317 // (0,1). The same applies when coverage is known to be 0.
michael@0 318 if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne) || covIsZero) {
michael@0 319 if (this->getStencil().doesWrite()) {
michael@0 320 return kDisableBlend_BlendOptFlag |
michael@0 321 kEmitCoverage_BlendOptFlag;
michael@0 322 } else {
michael@0 323 return kSkipDraw_BlendOptFlag;
michael@0 324 }
michael@0 325 }
michael@0 326
michael@0 327 // check for coverage due to constant coverage, per-vertex coverage, or coverage stage
michael@0 328 bool hasCoverage = forceCoverage ||
michael@0 329 0xffffffff != this->getCoverageColor() ||
michael@0 330 this->hasCoverageVertexAttribute() ||
michael@0 331 fCoverageStages.count() > 0;
michael@0 332
michael@0 333 // if we don't have coverage we can check whether the dst
michael@0 334 // has to read at all. If not, we'll disable blending.
michael@0 335 if (!hasCoverage) {
michael@0 336 if (dstCoeffIsZero) {
michael@0 337 if (kOne_GrBlendCoeff == *srcCoeff) {
michael@0 338 // if there is no coverage and coeffs are (1,0) then we
michael@0 339 // won't need to read the dst at all, it gets replaced by src
michael@0 340 return kDisableBlend_BlendOptFlag;
michael@0 341 } else if (kZero_GrBlendCoeff == *srcCoeff) {
michael@0 342 // if the op is "clear" then we don't need to emit a color
michael@0 343 // or blend, just write transparent black into the dst.
michael@0 344 *srcCoeff = kOne_GrBlendCoeff;
michael@0 345 *dstCoeff = kZero_GrBlendCoeff;
michael@0 346 return kDisableBlend_BlendOptFlag | kEmitTransBlack_BlendOptFlag;
michael@0 347 }
michael@0 348 }
michael@0 349 } else if (this->isCoverageDrawing()) {
michael@0 350 // we have coverage but we aren't distinguishing it from alpha by request.
michael@0 351 return kCoverageAsAlpha_BlendOptFlag;
michael@0 352 } else {
michael@0 353 // check whether coverage can be safely rolled into alpha
michael@0 354 // of if we can skip color computation and just emit coverage
michael@0 355 if (this->canTweakAlphaForCoverage()) {
michael@0 356 return kCoverageAsAlpha_BlendOptFlag;
michael@0 357 }
michael@0 358 if (dstCoeffIsZero) {
michael@0 359 if (kZero_GrBlendCoeff == *srcCoeff) {
michael@0 360 // the source color is not included in the blend
michael@0 361 // the dst coeff is effectively zero so blend works out to:
michael@0 362 // (c)(0)D + (1-c)D = (1-c)D.
michael@0 363 *dstCoeff = kISA_GrBlendCoeff;
michael@0 364 return kEmitCoverage_BlendOptFlag;
michael@0 365 } else if (srcAIsOne) {
michael@0 366 // the dst coeff is effectively zero so blend works out to:
michael@0 367 // cS + (c)(0)D + (1-c)D = cS + (1-c)D.
michael@0 368 // If Sa is 1 then we can replace Sa with c
michael@0 369 // and set dst coeff to 1-Sa.
michael@0 370 *dstCoeff = kISA_GrBlendCoeff;
michael@0 371 return kCoverageAsAlpha_BlendOptFlag;
michael@0 372 }
michael@0 373 } else if (dstCoeffIsOne) {
michael@0 374 // the dst coeff is effectively one so blend works out to:
michael@0 375 // cS + (c)(1)D + (1-c)D = cS + D.
michael@0 376 *dstCoeff = kOne_GrBlendCoeff;
michael@0 377 return kCoverageAsAlpha_BlendOptFlag;
michael@0 378 }
michael@0 379 }
michael@0 380 if (kOne_GrBlendCoeff == *srcCoeff &&
michael@0 381 kZero_GrBlendCoeff == *dstCoeff &&
michael@0 382 this->willEffectReadDstColor()) {
michael@0 383 // In this case the shader will fully resolve the color, coverage, and dst and we don't
michael@0 384 // need blending.
michael@0 385 return kDisableBlend_BlendOptFlag;
michael@0 386 }
michael@0 387 return kNone_BlendOpt;
michael@0 388 }
michael@0 389
michael@0 390 ////////////////////////////////////////////////////////////////////////////////
michael@0 391
michael@0 392 void GrDrawState::AutoViewMatrixRestore::restore() {
michael@0 393 if (NULL != fDrawState) {
michael@0 394 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;)
michael@0 395 fDrawState->fCommon.fViewMatrix = fViewMatrix;
michael@0 396 SkASSERT(fDrawState->numColorStages() >= fNumColorStages);
michael@0 397 int numCoverageStages = fSavedCoordChanges.count() - fNumColorStages;
michael@0 398 SkASSERT(fDrawState->numCoverageStages() >= numCoverageStages);
michael@0 399
michael@0 400 int i = 0;
michael@0 401 for (int s = 0; s < fNumColorStages; ++s, ++i) {
michael@0 402 fDrawState->fColorStages[s].restoreCoordChange(fSavedCoordChanges[i]);
michael@0 403 }
michael@0 404 for (int s = 0; s < numCoverageStages; ++s, ++i) {
michael@0 405 fDrawState->fCoverageStages[s].restoreCoordChange(fSavedCoordChanges[i]);
michael@0 406 }
michael@0 407 fDrawState = NULL;
michael@0 408 }
michael@0 409 }
michael@0 410
michael@0 411 void GrDrawState::AutoViewMatrixRestore::set(GrDrawState* drawState,
michael@0 412 const SkMatrix& preconcatMatrix) {
michael@0 413 this->restore();
michael@0 414
michael@0 415 SkASSERT(NULL == fDrawState);
michael@0 416 if (NULL == drawState || preconcatMatrix.isIdentity()) {
michael@0 417 return;
michael@0 418 }
michael@0 419 fDrawState = drawState;
michael@0 420
michael@0 421 fViewMatrix = drawState->getViewMatrix();
michael@0 422 drawState->fCommon.fViewMatrix.preConcat(preconcatMatrix);
michael@0 423
michael@0 424 this->doEffectCoordChanges(preconcatMatrix);
michael@0 425 SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
michael@0 426 }
michael@0 427
michael@0 428 bool GrDrawState::AutoViewMatrixRestore::setIdentity(GrDrawState* drawState) {
michael@0 429 this->restore();
michael@0 430
michael@0 431 if (NULL == drawState) {
michael@0 432 return false;
michael@0 433 }
michael@0 434
michael@0 435 if (drawState->getViewMatrix().isIdentity()) {
michael@0 436 return true;
michael@0 437 }
michael@0 438
michael@0 439 fViewMatrix = drawState->getViewMatrix();
michael@0 440 if (0 == drawState->numTotalStages()) {
michael@0 441 drawState->fCommon.fViewMatrix.reset();
michael@0 442 fDrawState = drawState;
michael@0 443 fNumColorStages = 0;
michael@0 444 fSavedCoordChanges.reset(0);
michael@0 445 SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
michael@0 446 return true;
michael@0 447 } else {
michael@0 448 SkMatrix inv;
michael@0 449 if (!fViewMatrix.invert(&inv)) {
michael@0 450 return false;
michael@0 451 }
michael@0 452 drawState->fCommon.fViewMatrix.reset();
michael@0 453 fDrawState = drawState;
michael@0 454 this->doEffectCoordChanges(inv);
michael@0 455 SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
michael@0 456 return true;
michael@0 457 }
michael@0 458 }
michael@0 459
michael@0 460 void GrDrawState::AutoViewMatrixRestore::doEffectCoordChanges(const SkMatrix& coordChangeMatrix) {
michael@0 461 fSavedCoordChanges.reset(fDrawState->numTotalStages());
michael@0 462 int i = 0;
michael@0 463
michael@0 464 fNumColorStages = fDrawState->numColorStages();
michael@0 465 for (int s = 0; s < fNumColorStages; ++s, ++i) {
michael@0 466 fDrawState->fColorStages[s].saveCoordChange(&fSavedCoordChanges[i]);
michael@0 467 fDrawState->fColorStages[s].localCoordChange(coordChangeMatrix);
michael@0 468 }
michael@0 469
michael@0 470 int numCoverageStages = fDrawState->numCoverageStages();
michael@0 471 for (int s = 0; s < numCoverageStages; ++s, ++i) {
michael@0 472 fDrawState->fCoverageStages[s].saveCoordChange(&fSavedCoordChanges[i]);
michael@0 473 fDrawState->fCoverageStages[s].localCoordChange(coordChangeMatrix);
michael@0 474 }
michael@0 475 }

mercurial