| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2012 Google Inc. | 2 * Copyright 2012 Google Inc. |
| 3 * | 3 * |
| 4 * Use of this source code is governed by a BSD-style license that can be | 4 * Use of this source code is governed by a BSD-style license that can be |
| 5 * found in the LICENSE file. | 5 * found in the LICENSE file. |
| 6 */ | 6 */ |
| 7 | 7 |
| 8 #include "GrDrawState.h" | 8 #include "GrDrawState.h" |
| 9 #include "GrPaint.h" | 9 #include "GrPaint.h" |
| 10 #include "GrDrawTargetCaps.h" |
| 10 | 11 |
| 11 //////////////////////////////////////////////////////////////////////////////s | 12 //////////////////////////////////////////////////////////////////////////////s |
| 12 | 13 |
| 13 bool GrDrawState::State::HaveCompatibleState(const State& a, const State& b, | 14 bool GrDrawState::State::HaveCompatibleState(const State& a, const State& b, |
| 14 bool explicitLocalCoords) { | 15 bool explicitLocalCoords) { |
| 15 if (a.fColorStages.count() != b.fColorStages.count() || | 16 if (a.fColorStages.count() != b.fColorStages.count() || |
| 16 a.fCoverageStages.count() != b.fCoverageStages.count() || | 17 a.fCoverageStages.count() != b.fCoverageStages.count() || |
| 17 a.fSrcBlend != b.fSrcBlend || | 18 a.fSrcBlend != b.fSrcBlend || |
| 18 a.fDstBlend != b.fDstBlend) { | 19 a.fDstBlend != b.fDstBlend) { |
| 19 return false; | 20 return false; |
| 20 } | 21 } |
| 21 for (int i = 0; i < a.fColorStages.count(); i++) { | 22 for (int i = 0; i < a.fColorStages.count(); i++) { |
| 22 if (!GrEffectStage::AreCompatible(a.fColorStages[i], b.fColorStages[i], | 23 if (!GrEffectStage::AreCompatible(a.fColorStages[i], b.fColorStages[i], |
| 23 explicitLocalCoords)) { | 24 explicitLocalCoords)) { |
| 24 return false; | 25 return false; |
| 25 } | 26 } |
| 26 } | 27 } |
| 27 for (int i = 0; i < a.fCoverageStages.count(); i++) { | 28 for (int i = 0; i < a.fCoverageStages.count(); i++) { |
| 28 if (!GrEffectStage::AreCompatible(a.fCoverageStages[i], b.fCoverageStage
s[i], | 29 if (!GrEffectStage::AreCompatible(a.fCoverageStages[i], b.fCoverageStage
s[i], |
| 29 explicitLocalCoords)) { | 30 explicitLocalCoords)) { |
| 30 return false; | 31 return false; |
| 31 } | 32 } |
| 32 } | 33 } |
| 33 return true; | 34 return true; |
| 34 } | 35 } |
| 35 //////////////////////////////////////////////////////////////////////////////s | 36 //////////////////////////////////////////////////////////////////////////////s |
| 36 GrDrawState::CombinedState GrDrawState::CombineIfPossible( | 37 GrDrawState::CombinedState GrDrawState::CombineIfPossible( |
| 37 const GrDrawState& a, const GrDrawState& b) { | 38 const GrDrawState& a, const GrDrawState& b, const GrDrawTargetCaps& caps) { |
| 38 | 39 |
| 39 bool usingVertexColors = a.hasColorVertexAttribute(); | 40 bool usingVertexColors = a.hasColorVertexAttribute(); |
| 40 if (!usingVertexColors && a.fColor != b.fColor) { | 41 if (!usingVertexColors && a.fColor != b.fColor) { |
| 41 return kIncompatible_CombinedState; | 42 return kIncompatible_CombinedState; |
| 42 } | 43 } |
| 43 | 44 |
| 44 if (a.fRenderTarget.get() != b.fRenderTarget.get() || | 45 if (a.fRenderTarget.get() != b.fRenderTarget.get() || |
| 45 !a.fViewMatrix.cheapEqualTo(b.fViewMatrix) || | 46 !a.fViewMatrix.cheapEqualTo(b.fViewMatrix) || |
| 46 a.fBlendConstant != b.fBlendConstant || | 47 a.fBlendConstant != b.fBlendConstant || |
| 47 a.fFlagBits != b.fFlagBits || | 48 a.fFlagBits != b.fFlagBits || |
| (...skipping 10 matching lines...) Expand all Loading... |
| 58 } | 59 } |
| 59 | 60 |
| 60 bool explicitLocalCoords = a.hasLocalCoordAttribute(); | 61 bool explicitLocalCoords = a.hasLocalCoordAttribute(); |
| 61 | 62 |
| 62 SkASSERT(0 == memcmp(a.fFixedFunctionVertexAttribIndices, | 63 SkASSERT(0 == memcmp(a.fFixedFunctionVertexAttribIndices, |
| 63 b.fFixedFunctionVertexAttribIndices, | 64 b.fFixedFunctionVertexAttribIndices, |
| 64 sizeof(a.fFixedFunctionVertexAttribIndices))); | 65 sizeof(a.fFixedFunctionVertexAttribIndices))); |
| 65 if (!State::HaveCompatibleState(a.fState, b.fState, explicitLocalCoords)) { | 66 if (!State::HaveCompatibleState(a.fState, b.fState, explicitLocalCoords)) { |
| 66 return kIncompatible_CombinedState; | 67 return kIncompatible_CombinedState; |
| 67 } | 68 } |
| 69 |
| 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; |
| 79 if (aIsOpaque) { |
| 80 opaque = &a; |
| 81 nonOpaque = &b; |
| 82 } else { |
| 83 opaque = &b; |
| 84 nonOpaque = &a; |
| 85 } |
| 86 if (!opaque->hasSolidCoverage() && opaque->couldApplyCoverage(caps))
{ |
| 87 SkASSERT(!nonOpaque->hasSolidCoverage()); |
| 88 if (!nonOpaque->couldApplyCoverage(caps)) { |
| 89 return kIncompatible_CombinedState; |
| 90 } |
| 91 } |
| 92 return aIsOpaque ? kB_CombinedState : kA_CombinedState; |
| 93 } |
| 94 } |
| 68 return kAOrB_CombinedState; | 95 return kAOrB_CombinedState; |
| 69 } | 96 } |
| 70 | 97 |
| 71 | |
| 72 //////////////////////////////////////////////////////////////////////////////s | 98 //////////////////////////////////////////////////////////////////////////////s |
| 73 | 99 |
| 74 GrDrawState::GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatr
ix) { | 100 GrDrawState::GrDrawState(const GrDrawState& state, const SkMatrix& preConcatMatr
ix) { |
| 75 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;) | 101 SkDEBUGCODE(fBlockEffectRemovalCnt = 0;) |
| 76 *this = state; | 102 *this = state; |
| 77 if (!preConcatMatrix.isIdentity()) { | 103 if (!preConcatMatrix.isIdentity()) { |
| 78 for (int i = 0; i < this->numColorStages(); ++i) { | 104 for (int i = 0; i < this->numColorStages(); ++i) { |
| 79 fState.fColorStages[i].localCoordChange(preConcatMatrix); | 105 fState.fColorStages[i].localCoordChange(preConcatMatrix); |
| 80 } | 106 } |
| 81 for (int i = 0; i < this->numCoverageStages(); ++i) { | 107 for (int i = 0; i < this->numCoverageStages(); ++i) { |
| (...skipping 13 matching lines...) Expand all Loading... |
| 95 fVACount = that.fVACount; | 121 fVACount = that.fVACount; |
| 96 fVAPtr = that.fVAPtr; | 122 fVAPtr = that.fVAPtr; |
| 97 fStencilSettings = that.fStencilSettings; | 123 fStencilSettings = that.fStencilSettings; |
| 98 fCoverage = that.fCoverage; | 124 fCoverage = that.fCoverage; |
| 99 fDrawFace = that.fDrawFace; | 125 fDrawFace = that.fDrawFace; |
| 100 fOptSrcBlend = that.fOptSrcBlend; | 126 fOptSrcBlend = that.fOptSrcBlend; |
| 101 fOptDstBlend = that.fOptDstBlend; | 127 fOptDstBlend = that.fOptDstBlend; |
| 102 fBlendOptFlags = that.fBlendOptFlags; | 128 fBlendOptFlags = that.fBlendOptFlags; |
| 103 | 129 |
| 104 fState = that.fState; | 130 fState = that.fState; |
| 131 fHints = that.fHints; |
| 105 | 132 |
| 106 memcpy(fFixedFunctionVertexAttribIndices, | 133 memcpy(fFixedFunctionVertexAttribIndices, |
| 107 that.fFixedFunctionVertexAttribIndices, | 134 that.fFixedFunctionVertexAttribIndices, |
| 108 sizeof(fFixedFunctionVertexAttribIndices)); | 135 sizeof(fFixedFunctionVertexAttribIndices)); |
| 109 return *this; | 136 return *this; |
| 110 } | 137 } |
| 111 | 138 |
| 112 void GrDrawState::onReset(const SkMatrix* initialViewMatrix) { | 139 void GrDrawState::onReset(const SkMatrix* initialViewMatrix) { |
| 113 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages()); | 140 SkASSERT(0 == fBlockEffectRemovalCnt || 0 == this->numTotalStages()); |
| 114 fState.reset(); | 141 fState.reset(); |
| 115 | 142 |
| 116 fRenderTarget.reset(NULL); | 143 fRenderTarget.reset(NULL); |
| 117 | 144 |
| 118 this->setDefaultVertexAttribs(); | 145 this->setDefaultVertexAttribs(); |
| 119 | 146 |
| 120 fColor = 0xffffffff; | 147 fColor = 0xffffffff; |
| 121 if (NULL == initialViewMatrix) { | 148 if (NULL == initialViewMatrix) { |
| 122 fViewMatrix.reset(); | 149 fViewMatrix.reset(); |
| 123 } else { | 150 } else { |
| 124 fViewMatrix = *initialViewMatrix; | 151 fViewMatrix = *initialViewMatrix; |
| 125 } | 152 } |
| 126 fBlendConstant = 0x0; | 153 fBlendConstant = 0x0; |
| 127 fFlagBits = 0x0; | 154 fFlagBits = 0x0; |
| 128 fStencilSettings.setDisabled(); | 155 fStencilSettings.setDisabled(); |
| 129 fCoverage = 0xffffffff; | 156 fCoverage = 0xffffffff; |
| 130 fDrawFace = kBoth_DrawFace; | 157 fDrawFace = kBoth_DrawFace; |
| 131 | 158 |
| 159 fHints = 0; |
| 160 |
| 132 this->invalidateBlendOptFlags(); | 161 this->invalidateBlendOptFlags(); |
| 133 } | 162 } |
| 134 | 163 |
| 135 bool GrDrawState::setIdentityViewMatrix() { | 164 bool GrDrawState::setIdentityViewMatrix() { |
| 136 if (this->numTotalStages()) { | 165 if (this->numTotalStages()) { |
| 137 SkMatrix invVM; | 166 SkMatrix invVM; |
| 138 if (!fViewMatrix.invert(&invVM)) { | 167 if (!fViewMatrix.invert(&invVM)) { |
| 139 // sad trombone sound | 168 // sad trombone sound |
| 140 return false; | 169 return false; |
| 141 } | 170 } |
| (...skipping 23 matching lines...) Expand all Loading... |
| 165 | 194 |
| 166 this->setRenderTarget(rt); | 195 this->setRenderTarget(rt); |
| 167 | 196 |
| 168 fViewMatrix = vm; | 197 fViewMatrix = vm; |
| 169 | 198 |
| 170 // These have no equivalent in GrPaint, set them to defaults | 199 // These have no equivalent in GrPaint, set them to defaults |
| 171 fBlendConstant = 0x0; | 200 fBlendConstant = 0x0; |
| 172 fDrawFace = kBoth_DrawFace; | 201 fDrawFace = kBoth_DrawFace; |
| 173 fStencilSettings.setDisabled(); | 202 fStencilSettings.setDisabled(); |
| 174 this->resetStateFlags(); | 203 this->resetStateFlags(); |
| 204 fHints = 0; |
| 175 | 205 |
| 176 // Enable the clip bit | 206 // Enable the clip bit |
| 177 this->enableState(GrDrawState::kClip_StateBit); | 207 this->enableState(GrDrawState::kClip_StateBit); |
| 178 | 208 |
| 179 this->setColor(paint.getColor()); | 209 this->setColor(paint.getColor()); |
| 180 this->setState(GrDrawState::kDither_StateBit, paint.isDither()); | 210 this->setState(GrDrawState::kDither_StateBit, paint.isDither()); |
| 181 this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias()); | 211 this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias()); |
| 182 | 212 |
| 183 this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff()); | 213 this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff()); |
| 184 this->setCoverage(paint.getCoverage()); | 214 this->setCoverage(paint.getCoverage()); |
| (...skipping 134 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 319 for (int s = 0; s < this->numCoverageStages(); ++s) { | 349 for (int s = 0; s < this->numCoverageStages(); ++s) { |
| 320 if (this->getCoverageStage(s).getEffect()->willReadDstColor()) { | 350 if (this->getCoverageStage(s).getEffect()->willReadDstColor()) { |
| 321 return true; | 351 return true; |
| 322 } | 352 } |
| 323 } | 353 } |
| 324 return false; | 354 return false; |
| 325 } | 355 } |
| 326 | 356 |
| 327 //////////////////////////////////////////////////////////////////////////////// | 357 //////////////////////////////////////////////////////////////////////////////// |
| 328 | 358 |
| 359 bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const { |
| 360 if (caps.dualSourceBlendingSupport()) { |
| 361 return true; |
| 362 } |
| 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, &dstCo
eff); |
| 369 return GrDrawState::kNone_BlendOpt != flag || |
| 370 (this->willEffectReadDstColor() && |
| 371 kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff); |
| 372 } |
| 373 |
| 329 bool GrDrawState::srcAlphaWillBeOne() const { | 374 bool GrDrawState::srcAlphaWillBeOne() const { |
| 330 uint32_t validComponentFlags; | 375 uint32_t validComponentFlags; |
| 331 GrColor color; | 376 GrColor color; |
| 332 // Check if per-vertex or constant color may have partial alpha | 377 // Check if per-vertex or constant color may have partial alpha |
| 333 if (this->hasColorVertexAttribute()) { | 378 if (this->hasColorVertexAttribute()) { |
| 334 validComponentFlags = 0; | 379 if (fHints & kVertexColorsAreOpaque_Hint) { |
| 335 color = 0; // not strictly necessary but we get false alarms from tools
about uninit. | 380 validComponentFlags = kA_GrColorComponentFlag; |
| 381 color = 0xFF << GrColor_SHIFT_A; |
| 382 } else { |
| 383 validComponentFlags = 0; |
| 384 color = 0; // not strictly necessary but we get false alarms from to
ols about uninit. |
| 385 } |
| 336 } else { | 386 } else { |
| 337 validComponentFlags = kRGBA_GrColorComponentFlags; | 387 validComponentFlags = kRGBA_GrColorComponentFlags; |
| 338 color = this->getColor(); | 388 color = this->getColor(); |
| 339 } | 389 } |
| 340 | 390 |
| 341 // Run through the color stages | 391 // Run through the color stages |
| 342 for (int s = 0; s < this->numColorStages(); ++s) { | 392 for (int s = 0; s < this->numColorStages(); ++s) { |
| 343 const GrEffect* effect = this->getColorStage(s).getEffect(); | 393 const GrEffect* effect = this->getColorStage(s).getEffect(); |
| 344 effect->getConstantColorComponents(&color, &validComponentFlags); | 394 effect->getConstantColorComponents(&color, &validComponentFlags); |
| 345 } | 395 } |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 448 *srcCoeff = kZero_GrBlendCoeff; | 498 *srcCoeff = kZero_GrBlendCoeff; |
| 449 *dstCoeff = kOne_GrBlendCoeff; | 499 *dstCoeff = kOne_GrBlendCoeff; |
| 450 } | 500 } |
| 451 | 501 |
| 452 bool srcAIsOne = this->srcAlphaWillBeOne(); | 502 bool srcAIsOne = this->srcAlphaWillBeOne(); |
| 453 bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff || | 503 bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff || |
| 454 (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne); | 504 (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne); |
| 455 bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff || | 505 bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff || |
| 456 (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne); | 506 (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne); |
| 457 | 507 |
| 458 bool covIsZero = !this->isCoverageDrawing() && | |
| 459 !this->hasCoverageVertexAttribute() && | |
| 460 0 == this->getCoverageColor(); | |
| 461 // When coeffs are (0,1) there is no reason to draw at all, unless | 508 // When coeffs are (0,1) there is no reason to draw at all, unless |
| 462 // stenciling is enabled. Having color writes disabled is effectively | 509 // stenciling is enabled. Having color writes disabled is effectively |
| 463 // (0,1). The same applies when coverage is known to be 0. | 510 // (0,1). |
| 464 if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne) || covIsZero) { | 511 if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne)) { |
| 465 if (this->getStencil().doesWrite()) { | 512 if (this->getStencil().doesWrite()) { |
| 466 return kEmitCoverage_BlendOptFlag; | 513 return kEmitCoverage_BlendOptFlag; |
| 467 } else { | 514 } else { |
| 468 return kSkipDraw_BlendOptFlag; | 515 return kSkipDraw_BlendOptFlag; |
| 469 } | 516 } |
| 470 } | 517 } |
| 471 | 518 |
| 472 // check for coverage due to constant coverage, per-vertex coverage, or cove
rage stage | 519 bool hasCoverage = forceCoverage || !this->hasSolidCoverage(); |
| 473 bool hasCoverage = forceCoverage || | |
| 474 0xffffffff != this->getCoverageColor() || | |
| 475 this->hasCoverageVertexAttribute() || | |
| 476 this->numCoverageStages() > 0; | |
| 477 | 520 |
| 478 // if we don't have coverage we can check whether the dst | 521 // if we don't have coverage we can check whether the dst |
| 479 // has to read at all. If not, we'll disable blending. | 522 // has to read at all. If not, we'll disable blending. |
| 480 if (!hasCoverage) { | 523 if (!hasCoverage) { |
| 481 if (dstCoeffIsZero) { | 524 if (dstCoeffIsZero) { |
| 482 if (kOne_GrBlendCoeff == *srcCoeff) { | 525 if (kOne_GrBlendCoeff == *srcCoeff) { |
| 483 // if there is no coverage and coeffs are (1,0) then we | 526 // if there is no coverage and coeffs are (1,0) then we |
| 484 // won't need to read the dst at all, it gets replaced by src | 527 // won't need to read the dst at all, it gets replaced by src |
| 485 *dstCoeff = kZero_GrBlendCoeff; | 528 *dstCoeff = kZero_GrBlendCoeff; |
| 486 return kNone_BlendOpt; | 529 return kNone_BlendOpt; |
| (...skipping 162 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 649 fDrawState->getColorStage(s).saveCoordChange(&fSavedCoordChanges[i]); | 692 fDrawState->getColorStage(s).saveCoordChange(&fSavedCoordChanges[i]); |
| 650 fDrawState->fState.fColorStages[s].localCoordChange(coordChangeMatrix); | 693 fDrawState->fState.fColorStages[s].localCoordChange(coordChangeMatrix); |
| 651 } | 694 } |
| 652 | 695 |
| 653 int numCoverageStages = fDrawState->numCoverageStages(); | 696 int numCoverageStages = fDrawState->numCoverageStages(); |
| 654 for (int s = 0; s < numCoverageStages; ++s, ++i) { | 697 for (int s = 0; s < numCoverageStages; ++s, ++i) { |
| 655 fDrawState->getCoverageStage(s).saveCoordChange(&fSavedCoordChanges[i]); | 698 fDrawState->getCoverageStage(s).saveCoordChange(&fSavedCoordChanges[i]); |
| 656 fDrawState->fState.fCoverageStages[s].localCoordChange(coordChangeMatrix
); | 699 fDrawState->fState.fCoverageStages[s].localCoordChange(coordChangeMatrix
); |
| 657 } | 700 } |
| 658 } | 701 } |
| OLD | NEW |