2 * Copyright 2012 Google Inc.
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
8 #include "GrDrawState.h"
10 #include "GrDrawTargetCaps.h"
12 //////////////////////////////////////////////////////////////////////////////s
14 bool GrDrawState::State::HaveCompatibleState(const State& a, const State& b,
15 bool explicitLocalCoords) {
16 if (a.fColorStages.count() != b.fColorStages.count() ||
17 a.fCoverageStages.count() != b.fCoverageStages.count() ||
18 a.fSrcBlend != b.fSrcBlend ||
19 a.fDstBlend != b.fDstBlend) {
22 for (int i = 0; i < a.fColorStages.count(); i++) {
23 if (!GrEffectStage::AreCompatible(a.fColorStages[i], b.fColorStages[i],
24 explicitLocalCoords)) {
28 for (int i = 0; i < a.fCoverageStages.count(); i++) {
29 if (!GrEffectStage::AreCompatible(a.fCoverageStages[i], b.fCoverageStages[i],
30 explicitLocalCoords)) {
36 //////////////////////////////////////////////////////////////////////////////s
37 GrDrawState::CombinedState GrDrawState::CombineIfPossible(
38 const GrDrawState& a, const GrDrawState& b, const GrDrawTargetCaps& caps) {
40 bool usingVertexColors = a.hasColorVertexAttribute();
41 if (!usingVertexColors && a.fColor != b.fColor) {
42 return kIncompatible_CombinedState;
45 if (a.fRenderTarget.get() != b.fRenderTarget.get() ||
46 !a.fViewMatrix.cheapEqualTo(b.fViewMatrix) ||
47 a.fBlendConstant != b.fBlendConstant ||
48 a.fFlagBits != b.fFlagBits ||
49 a.fVACount != b.fVACount ||
50 memcmp(a.fVAPtr, b.fVAPtr, a.fVACount * sizeof(GrVertexAttrib)) ||
51 a.fStencilSettings != b.fStencilSettings ||
52 a.fDrawFace != b.fDrawFace) {
53 return kIncompatible_CombinedState;
56 bool usingVertexCoverage = a.hasCoverageVertexAttribute();
57 if (!usingVertexCoverage && a.fCoverage != b.fCoverage) {
58 return kIncompatible_CombinedState;
61 bool explicitLocalCoords = a.hasLocalCoordAttribute();
63 SkASSERT(0 == memcmp(a.fFixedFunctionVertexAttribIndices,
64 b.fFixedFunctionVertexAttribIndices,
65 sizeof(a.fFixedFunctionVertexAttribIndices)));
66 if (!State::HaveCompatibleState(a.fState, b.fState, explicitLocalCoords)) {
67 return kIncompatible_CombinedState;
70 if (usingVertexColors) {
71 // If one is opaque and the other is not then the combined state is not opaque. Moreover,
72 // if the opaqueness affects the ability to get color/coverage blending correct then we
73 // don't combine the draw states.
74 bool aIsOpaque = (kVertexColorsAreOpaque_Hint & a.fHints);
75 bool bIsOpaque = (kVertexColorsAreOpaque_Hint & b.fHints);
76 if (aIsOpaque != bIsOpaque) {
77 const GrDrawState* opaque;
78 const GrDrawState* nonOpaque;
86 if (!opaque->hasSolidCoverage() && opaque->couldApplyCoverage(caps)) {
87 SkASSERT(!nonOpaque->hasSolidCoverage());
88 if (!nonOpaque->couldApplyCoverage(caps)) {
89 return kIncompatible_CombinedState;
92 return aIsOpaque ? kB_CombinedState : kA_CombinedState;
95 return kAOrB_CombinedState;
98 //////////////////////////////////////////////////////////////////////////////s
100 GrDrawState::GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatrix) {
101 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;)
103 if (!preConcatMatrix.isIdentity()) {
104 for (int i = 0; i < this->numColorStages(); ++i) {
105 fState.fColorStages[i].localCoordChange(preConcatMatrix);
107 for (int i = 0; i < this->numCoverageStages(); ++i) {
108 fState.fCoverageStages[i].localCoordChange(preConcatMatrix);
110 this->invalidateBlendOptFlags();
114 GrDrawState& GrDrawState::operator=(const GrDrawState& that) {
115 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages());
116 this->setRenderTarget(that.fRenderTarget.get());
117 fColor = that.fColor;
118 fViewMatrix = that.fViewMatrix;
119 fBlendConstant = that.fBlendConstant;
120 fFlagBits = that.fFlagBits;
121 fVACount = that.fVACount;
122 fVAPtr = that.fVAPtr;
123 fStencilSettings = that.fStencilSettings;
124 fCoverage = that.fCoverage;
125 fDrawFace = that.fDrawFace;
126 fOptSrcBlend = that.fOptSrcBlend;
127 fOptDstBlend = that.fOptDstBlend;
128 fBlendOptFlags = that.fBlendOptFlags;
130 fState = that.fState;
131 fHints = that.fHints;
133 memcpy(fFixedFunctionVertexAttribIndices,
134 that.fFixedFunctionVertexAttribIndices,
135 sizeof(fFixedFunctionVertexAttribIndices));
139 void GrDrawState::onReset(const SkMatrix* initialViewMatrix) {
140 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages());
143 fRenderTarget.reset(NULL);
145 this->setDefaultVertexAttribs();
148 if (NULL == initialViewMatrix) {
151 fViewMatrix = *initialViewMatrix;
153 fBlendConstant = 0x0;
155 fStencilSettings.setDisabled();
156 fCoverage = 0xffffffff;
157 fDrawFace = kBoth_DrawFace;
161 this->invalidateBlendOptFlags();
164 bool GrDrawState::setIdentityViewMatrix() {
165 if (this->numTotalStages()) {
167 if (!fViewMatrix.invert(&invVM)) {
168 // sad trombone sound
171 for (int s = 0; s < this->numColorStages(); ++s) {
172 fState.fColorStages[s].localCoordChange(invVM);
174 for (int s = 0; s < this->numCoverageStages(); ++s) {
175 fState.fCoverageStages[s].localCoordChange(invVM);
182 void GrDrawState::setFromPaint(const GrPaint& paint, const SkMatrix& vm, GrRenderTarget* rt) {
183 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages());
187 for (int i = 0; i < paint.numColorStages(); ++i) {
188 fState.fColorStages.push_back(paint.getColorStage(i));
191 for (int i = 0; i < paint.numCoverageStages(); ++i) {
192 fState.fCoverageStages.push_back(paint.getCoverageStage(i));
195 this->setRenderTarget(rt);
199 // These have no equivalent in GrPaint, set them to defaults
200 fBlendConstant = 0x0;
201 fDrawFace = kBoth_DrawFace;
202 fStencilSettings.setDisabled();
203 this->resetStateFlags();
206 // Enable the clip bit
207 this->enableState(GrDrawState::kClip_StateBit);
209 this->setColor(paint.getColor());
210 this->setState(GrDrawState::kDither_StateBit, paint.isDither());
211 this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias());
213 this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff());
214 this->setCoverage(paint.getCoverage());
215 this->invalidateBlendOptFlags();
218 ////////////////////////////////////////////////////////////////////////////////
220 static size_t vertex_size(const GrVertexAttrib* attribs, int count) {
221 // this works as long as we're 4 byte-aligned
223 uint32_t overlapCheck = 0;
225 SkASSERT(count <= GrDrawState::kMaxVertexAttribCnt);
227 for (int index = 0; index < count; ++index) {
228 size_t attribSize = GrVertexAttribTypeSize(attribs[index].fType);
231 size_t dwordCount = attribSize >> 2;
232 uint32_t mask = (1 << dwordCount)-1;
233 size_t offsetShift = attribs[index].fOffset >> 2;
234 SkASSERT(!(overlapCheck & (mask << offsetShift)));
235 overlapCheck |= (mask << offsetShift);
241 size_t GrDrawState::getVertexSize() const {
242 return vertex_size(fVAPtr, fVACount);
245 ////////////////////////////////////////////////////////////////////////////////
247 void GrDrawState::setVertexAttribs(const GrVertexAttrib* attribs, int count) {
248 SkASSERT(count <= kMaxVertexAttribCnt);
253 // Set all the indices to -1
254 memset(fFixedFunctionVertexAttribIndices,
256 sizeof(fFixedFunctionVertexAttribIndices));
258 uint32_t overlapCheck = 0;
260 for (int i = 0; i < count; ++i) {
261 if (attribs[i].fBinding < kGrFixedFunctionVertexAttribBindingCnt) {
262 // The fixed function attribs can only be specified once
263 SkASSERT(-1 == fFixedFunctionVertexAttribIndices[attribs[i].fBinding]);
264 SkASSERT(GrFixedFunctionVertexAttribVectorCount(attribs[i].fBinding) ==
265 GrVertexAttribTypeVectorCount(attribs[i].fType));
266 fFixedFunctionVertexAttribIndices[attribs[i].fBinding] = i;
269 size_t dwordCount = GrVertexAttribTypeSize(attribs[i].fType) >> 2;
270 uint32_t mask = (1 << dwordCount)-1;
271 size_t offsetShift = attribs[i].fOffset >> 2;
272 SkASSERT(!(overlapCheck & (mask << offsetShift)));
273 overlapCheck |= (mask << offsetShift);
276 this->invalidateBlendOptFlags();
277 // Positions must be specified.
278 SkASSERT(-1 != fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding]);
281 ////////////////////////////////////////////////////////////////////////////////
283 void GrDrawState::setDefaultVertexAttribs() {
284 static const GrVertexAttrib kPositionAttrib =
285 {kVec2f_GrVertexAttribType, 0, kPosition_GrVertexAttribBinding};
287 fVAPtr = &kPositionAttrib;
290 // set all the fixed function indices to -1 except position.
291 memset(fFixedFunctionVertexAttribIndices,
293 sizeof(fFixedFunctionVertexAttribIndices));
294 fFixedFunctionVertexAttribIndices[kPosition_GrVertexAttribBinding] = 0;
295 this->invalidateBlendOptFlags();
298 ////////////////////////////////////////////////////////////////////////////////
300 bool GrDrawState::validateVertexAttribs() const {
301 // check consistency of effects and attributes
302 GrSLType slTypes[kMaxVertexAttribCnt];
303 for (int i = 0; i < kMaxVertexAttribCnt; ++i) {
304 slTypes[i] = static_cast<GrSLType>(-1);
306 int totalStages = this->numTotalStages();
307 for (int s = 0; s < totalStages; ++s) {
308 int covIdx = s - this->numColorStages();
309 const GrEffectStage& stage = covIdx < 0 ? this->getColorStage(s) :
310 this->getCoverageStage(covIdx);
311 const GrEffect* effect = stage.getEffect();
312 SkASSERT(NULL != effect);
313 // make sure that any attribute indices have the correct binding type, that the attrib
314 // type and effect's shader lang type are compatible, and that attributes shared by
315 // multiple effects use the same shader lang type.
316 const int* attributeIndices = stage.getVertexAttribIndices();
317 int numAttributes = stage.getVertexAttribIndexCount();
318 for (int i = 0; i < numAttributes; ++i) {
319 int attribIndex = attributeIndices[i];
320 if (attribIndex >= fVACount ||
321 kEffect_GrVertexAttribBinding != fVAPtr[attribIndex].fBinding) {
325 GrSLType effectSLType = effect->vertexAttribType(i);
326 GrVertexAttribType attribType = fVAPtr[attribIndex].fType;
327 int slVecCount = GrSLTypeVectorCount(effectSLType);
328 int attribVecCount = GrVertexAttribTypeVectorCount(attribType);
329 if (slVecCount != attribVecCount ||
330 (static_cast<GrSLType>(-1) != slTypes[attribIndex] &&
331 slTypes[attribIndex] != effectSLType)) {
334 slTypes[attribIndex] = effectSLType;
341 bool GrDrawState::willEffectReadDstColor() const {
342 if (!this->isColorWriteDisabled()) {
343 for (int s = 0; s < this->numColorStages(); ++s) {
344 if (this->getColorStage(s).getEffect()->willReadDstColor()) {
349 for (int s = 0; s < this->numCoverageStages(); ++s) {
350 if (this->getCoverageStage(s).getEffect()->willReadDstColor()) {
357 ////////////////////////////////////////////////////////////////////////////////
359 bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const {
360 if (caps.dualSourceBlendingSupport()) {
363 // we can correctly apply coverage if a) we have dual source blending
364 // or b) one of our blend optimizations applies
365 // or c) the src, dst blend coeffs are 1,0 and we will read Dst Color
366 GrBlendCoeff srcCoeff;
367 GrBlendCoeff dstCoeff;
368 GrDrawState::BlendOptFlags flag = this->getBlendOpts(true, &srcCoeff, &dstCoeff);
369 return GrDrawState::kNone_BlendOpt != flag ||
370 (this->willEffectReadDstColor() &&
371 kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff);
374 bool GrDrawState::srcAlphaWillBeOne() const {
375 uint32_t validComponentFlags;
377 // Check if per-vertex or constant color may have partial alpha
378 if (this->hasColorVertexAttribute()) {
379 if (fHints & kVertexColorsAreOpaque_Hint) {
380 validComponentFlags = kA_GrColorComponentFlag;
381 color = 0xFF << GrColor_SHIFT_A;
383 validComponentFlags = 0;
384 color = 0; // not strictly necessary but we get false alarms from tools about uninit.
387 validComponentFlags = kRGBA_GrColorComponentFlags;
388 color = this->getColor();
391 // Run through the color stages
392 for (int s = 0; s < this->numColorStages(); ++s) {
393 const GrEffect* effect = this->getColorStage(s).getEffect();
394 effect->getConstantColorComponents(&color, &validComponentFlags);
397 // Check whether coverage is treated as color. If so we run through the coverage computation.
398 if (this->isCoverageDrawing()) {
399 GrColor coverageColor = this->getCoverageColor();
400 GrColor oldColor = color;
402 for (int c = 0; c < 4; ++c) {
403 if (validComponentFlags & (1 << c)) {
404 U8CPU a = (oldColor >> (c * 8)) & 0xff;
405 U8CPU b = (coverageColor >> (c * 8)) & 0xff;
406 color |= (SkMulDiv255Round(a, b) << (c * 8));
409 for (int s = 0; s < this->numCoverageStages(); ++s) {
410 const GrEffect* effect = this->getCoverageStage(s).getEffect();
411 effect->getConstantColorComponents(&color, &validComponentFlags);
414 return (kA_GrColorComponentFlag & validComponentFlags) && 0xff == GrColorUnpackA(color);
417 bool GrDrawState::hasSolidCoverage() const {
418 // If we're drawing coverage directly then coverage is effectively treated as color.
419 if (this->isCoverageDrawing()) {
424 uint32_t validComponentFlags;
425 // Initialize to an unknown starting coverage if per-vertex coverage is specified.
426 if (this->hasCoverageVertexAttribute()) {
427 validComponentFlags = 0;
429 coverage = fCoverage;
430 validComponentFlags = kRGBA_GrColorComponentFlags;
433 // Run through the coverage stages and see if the coverage will be all ones at the end.
434 for (int s = 0; s < this->numCoverageStages(); ++s) {
435 const GrEffect* effect = this->getCoverageStage(s).getEffect();
436 effect->getConstantColorComponents(&coverage, &validComponentFlags);
438 return (kRGBA_GrColorComponentFlags == validComponentFlags) && (0xffffffff == coverage);
441 ////////////////////////////////////////////////////////////////////////////////
443 // Some blend modes allow folding a fractional coverage value into the color's alpha channel, while
444 // others will blend incorrectly.
445 bool GrDrawState::canTweakAlphaForCoverage() const {
447 The fractional coverage is f.
448 The src and dst coeffs are Cs and Cd.
449 The dst and src colors are S and D.
450 We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D. By tweaking the source color's alpha
451 we're replacing S with S'=fS. It's obvious that that first term will always be ok. The second
452 term can be rearranged as [1-(1-Cd)f]D. By substituting in the various possibilities for Cd we
453 find that only 1, ISA, and ISC produce the correct destination when applied to S' and D.
454 Also, if we're directly rendering coverage (isCoverageDrawing) then coverage is treated as
457 return kOne_GrBlendCoeff == fState.fDstBlend ||
458 kISA_GrBlendCoeff == fState.fDstBlend ||
459 kISC_GrBlendCoeff == fState.fDstBlend ||
460 this->isCoverageDrawing();
463 GrDrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage,
464 GrBlendCoeff* srcCoeff,
465 GrBlendCoeff* dstCoeff) const {
466 GrBlendCoeff bogusSrcCoeff, bogusDstCoeff;
467 if (NULL == srcCoeff) {
468 srcCoeff = &bogusSrcCoeff;
470 if (NULL == dstCoeff) {
471 dstCoeff = &bogusDstCoeff;
475 return this->calcBlendOpts(true, srcCoeff, dstCoeff);
478 if (0 == (fBlendOptFlags & kInvalid_BlendOptFlag)) {
479 *srcCoeff = fOptSrcBlend;
480 *dstCoeff = fOptDstBlend;
481 return fBlendOptFlags;
484 fBlendOptFlags = this->calcBlendOpts(forceCoverage, srcCoeff, dstCoeff);
485 fOptSrcBlend = *srcCoeff;
486 fOptDstBlend = *dstCoeff;
488 return fBlendOptFlags;
491 GrDrawState::BlendOptFlags GrDrawState::calcBlendOpts(bool forceCoverage,
492 GrBlendCoeff* srcCoeff,
493 GrBlendCoeff* dstCoeff) const {
494 *srcCoeff = this->getSrcBlendCoeff();
495 *dstCoeff = this->getDstBlendCoeff();
497 if (this->isColorWriteDisabled()) {
498 *srcCoeff = kZero_GrBlendCoeff;
499 *dstCoeff = kOne_GrBlendCoeff;
502 bool srcAIsOne = this->srcAlphaWillBeOne();
503 bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff ||
504 (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne);
505 bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff ||
506 (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne);
508 // When coeffs are (0,1) there is no reason to draw at all, unless
509 // stenciling is enabled. Having color writes disabled is effectively
511 if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne)) {
512 if (this->getStencil().doesWrite()) {
513 return kEmitCoverage_BlendOptFlag;
515 return kSkipDraw_BlendOptFlag;
519 bool hasCoverage = forceCoverage || !this->hasSolidCoverage();
521 // if we don't have coverage we can check whether the dst
522 // has to read at all. If not, we'll disable blending.
524 if (dstCoeffIsZero) {
525 if (kOne_GrBlendCoeff == *srcCoeff) {
526 // if there is no coverage and coeffs are (1,0) then we
527 // won't need to read the dst at all, it gets replaced by src
528 *dstCoeff = kZero_GrBlendCoeff;
529 return kNone_BlendOpt;
530 } else if (kZero_GrBlendCoeff == *srcCoeff) {
531 // if the op is "clear" then we don't need to emit a color
532 // or blend, just write transparent black into the dst.
533 *srcCoeff = kOne_GrBlendCoeff;
534 *dstCoeff = kZero_GrBlendCoeff;
535 return kEmitTransBlack_BlendOptFlag;
538 } else if (this->isCoverageDrawing()) {
539 // we have coverage but we aren't distinguishing it from alpha by request.
540 return kCoverageAsAlpha_BlendOptFlag;
542 // check whether coverage can be safely rolled into alpha
543 // of if we can skip color computation and just emit coverage
544 if (this->canTweakAlphaForCoverage()) {
545 return kCoverageAsAlpha_BlendOptFlag;
547 if (dstCoeffIsZero) {
548 if (kZero_GrBlendCoeff == *srcCoeff) {
549 // the source color is not included in the blend
550 // the dst coeff is effectively zero so blend works out to:
551 // (c)(0)D + (1-c)D = (1-c)D.
552 *dstCoeff = kISA_GrBlendCoeff;
553 return kEmitCoverage_BlendOptFlag;
554 } else if (srcAIsOne) {
555 // the dst coeff is effectively zero so blend works out to:
556 // cS + (c)(0)D + (1-c)D = cS + (1-c)D.
557 // If Sa is 1 then we can replace Sa with c
558 // and set dst coeff to 1-Sa.
559 *dstCoeff = kISA_GrBlendCoeff;
560 return kCoverageAsAlpha_BlendOptFlag;
562 } else if (dstCoeffIsOne) {
563 // the dst coeff is effectively one so blend works out to:
564 // cS + (c)(1)D + (1-c)D = cS + D.
565 *dstCoeff = kOne_GrBlendCoeff;
566 return kCoverageAsAlpha_BlendOptFlag;
570 return kNone_BlendOpt;
573 bool GrDrawState::canIgnoreColorAttribute() const {
574 if (fBlendOptFlags & kInvalid_BlendOptFlag) {
575 this->getBlendOpts();
577 return SkToBool(fBlendOptFlags & (GrDrawState::kEmitTransBlack_BlendOptFlag |
578 GrDrawState::kEmitCoverage_BlendOptFlag));
581 //////////////////////////////////////////////////////////////////////////////
583 GrDrawState::AutoVertexAttribRestore::AutoVertexAttribRestore(
584 GrDrawState* drawState) {
585 SkASSERT(NULL != drawState);
586 fDrawState = drawState;
587 fVAPtr = drawState->fVAPtr;
588 fVACount = drawState->fVACount;
589 fDrawState->setDefaultVertexAttribs();
592 //////////////////////////////////////////////////////////////////////////////s
594 void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) {
595 if (NULL != fDrawState) {
596 int m = fDrawState->numColorStages() - fColorEffectCnt;
598 fDrawState->fState.fColorStages.pop_back_n(m);
600 int n = fDrawState->numCoverageStages() - fCoverageEffectCnt;
602 fDrawState->fState.fCoverageStages.pop_back_n(n);
604 fDrawState->invalidateBlendOptFlags();
606 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;)
610 fColorEffectCnt = ds->numColorStages();
611 fCoverageEffectCnt = ds->numCoverageStages();
612 SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;)
616 ////////////////////////////////////////////////////////////////////////////////
618 void GrDrawState::AutoViewMatrixRestore::restore() {
619 if (NULL != fDrawState) {
620 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;)
621 fDrawState->fViewMatrix = fViewMatrix;
622 SkASSERT(fDrawState->numColorStages() >= fNumColorStages);
623 int numCoverageStages = fSavedCoordChanges.count() - fNumColorStages;
624 SkASSERT(fDrawState->numCoverageStages() >= numCoverageStages);
627 for (int s = 0; s < fNumColorStages; ++s, ++i) {
628 fDrawState->fState.fColorStages[s].restoreCoordChange(fSavedCoordChanges[i]);
630 for (int s = 0; s < numCoverageStages; ++s, ++i) {
631 fDrawState->fState.fCoverageStages[s].restoreCoordChange(fSavedCoordChanges[i]);
637 void GrDrawState::AutoViewMatrixRestore::set(GrDrawState* drawState,
638 const SkMatrix& preconcatMatrix) {
641 SkASSERT(NULL == fDrawState);
642 if (NULL == drawState || preconcatMatrix.isIdentity()) {
645 fDrawState = drawState;
647 fViewMatrix = drawState->getViewMatrix();
648 drawState->fViewMatrix.preConcat(preconcatMatrix);
650 this->doEffectCoordChanges(preconcatMatrix);
651 SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
654 bool GrDrawState::AutoViewMatrixRestore::setIdentity(GrDrawState* drawState) {
657 if (NULL == drawState) {
661 if (drawState->getViewMatrix().isIdentity()) {
665 fViewMatrix = drawState->getViewMatrix();
666 if (0 == drawState->numTotalStages()) {
667 drawState->fViewMatrix.reset();
668 fDrawState = drawState;
670 fSavedCoordChanges.reset(0);
671 SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
675 if (!fViewMatrix.invert(&inv)) {
678 drawState->fViewMatrix.reset();
679 fDrawState = drawState;
680 this->doEffectCoordChanges(inv);
681 SkDEBUGCODE(++fDrawState->fBlockEffectRemovalCnt;)
686 void GrDrawState::AutoViewMatrixRestore::doEffectCoordChanges(const SkMatrix& coordChangeMatrix) {
687 fSavedCoordChanges.reset(fDrawState->numTotalStages());
690 fNumColorStages = fDrawState->numColorStages();
691 for (int s = 0; s < fNumColorStages; ++s, ++i) {
692 fDrawState->getColorStage(s).saveCoordChange(&fSavedCoordChanges[i]);
693 fDrawState->fState.fColorStages[s].localCoordChange(coordChangeMatrix);
696 int numCoverageStages = fDrawState->numCoverageStages();
697 for (int s = 0; s < numCoverageStages; ++s, ++i) {
698 fDrawState->getCoverageStage(s).saveCoordChange(&fSavedCoordChanges[i]);
699 fDrawState->fState.fCoverageStages[s].localCoordChange(coordChangeMatrix);