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 | 9 |
10 #include "GrOptDrawState.h" | 10 #include "GrOptDrawState.h" |
11 #include "GrPaint.h" | 11 #include "GrPaint.h" |
12 | 12 |
13 //////////////////////////////////////////////////////////////////////////////s | 13 //////////////////////////////////////////////////////////////////////////////s |
14 | 14 |
15 GrOptDrawState* GrDrawState::createOptState(const GrDrawTargetCaps& caps) const
{ | 15 GrOptDrawState* GrDrawState::createOptState(const GrDrawTargetCaps& caps) const
{ |
16 if (NULL == fCachedOptState || caps.getUniqueID() != fCachedCapsID) { | 16 if (NULL == fCachedOptState || caps.getUniqueID() != fCachedCapsID) { |
17 GrBlendCoeff srcCoeff; | 17 GrBlendCoeff srcCoeff; |
18 GrBlendCoeff dstCoeff; | 18 GrBlendCoeff dstCoeff; |
19 BlendOptFlags blendFlags = this->getBlendOpts(false, &srcCoeff, &dstCoef
f); | 19 GrOptDrawState::BlendOptFlags blendFlags = |
| 20 (GrOptDrawState::BlendOptFlags) this->getBlendOpts(false, &srcCoeff,
&dstCoeff); |
20 fCachedOptState = SkNEW_ARGS(GrOptDrawState, (*this, blendFlags, srcCoef
f, dstCoeff, caps)); | 21 fCachedOptState = SkNEW_ARGS(GrOptDrawState, (*this, blendFlags, srcCoef
f, dstCoeff, caps)); |
21 fCachedCapsID = caps.getUniqueID(); | 22 fCachedCapsID = caps.getUniqueID(); |
22 } else { | 23 } else { |
23 #ifdef SK_DEBUG | 24 #ifdef SK_DEBUG |
24 GrBlendCoeff srcCoeff; | 25 GrBlendCoeff srcCoeff; |
25 GrBlendCoeff dstCoeff; | 26 GrBlendCoeff dstCoeff; |
26 BlendOptFlags blendFlags = this->getBlendOpts(false, &srcCoeff, &dstCoef
f); | 27 GrOptDrawState::BlendOptFlags blendFlags = |
| 28 (GrOptDrawState::BlendOptFlags) this->getBlendOpts(false, &srcCoeff,
&dstCoeff); |
27 SkASSERT(GrOptDrawState(*this, blendFlags, srcCoeff, dstCoeff, caps) ==
*fCachedOptState); | 29 SkASSERT(GrOptDrawState(*this, blendFlags, srcCoeff, dstCoeff, caps) ==
*fCachedOptState); |
28 #endif | 30 #endif |
29 } | 31 } |
30 fCachedOptState->ref(); | 32 fCachedOptState->ref(); |
31 return fCachedOptState; | 33 return fCachedOptState; |
32 } | 34 } |
33 | 35 |
34 //////////////////////////////////////////////////////////////////////////////s | 36 //////////////////////////////////////////////////////////////////////////////s |
35 | 37 |
| 38 bool GrDrawState::isEqual(const GrDrawState& that) const { |
| 39 bool usingVertexColors = this->hasColorVertexAttribute(); |
| 40 if (!usingVertexColors && this->fColor != that.fColor) { |
| 41 return false; |
| 42 } |
| 43 |
| 44 if (this->getRenderTarget() != that.getRenderTarget() || |
| 45 this->fColorStages.count() != that.fColorStages.count() || |
| 46 this->fCoverageStages.count() != that.fCoverageStages.count() || |
| 47 !this->fViewMatrix.cheapEqualTo(that.fViewMatrix) || |
| 48 this->fSrcBlend != that.fSrcBlend || |
| 49 this->fDstBlend != that.fDstBlend || |
| 50 this->fBlendConstant != that.fBlendConstant || |
| 51 this->fFlagBits != that.fFlagBits || |
| 52 this->fVACount != that.fVACount || |
| 53 this->fVAStride != that.fVAStride || |
| 54 memcmp(this->fVAPtr, that.fVAPtr, this->fVACount * sizeof(GrVertexAttrib
)) || |
| 55 this->fStencilSettings != that.fStencilSettings || |
| 56 this->fDrawFace != that.fDrawFace) { |
| 57 return false; |
| 58 } |
| 59 |
| 60 bool usingVertexCoverage = this->hasCoverageVertexAttribute(); |
| 61 if (!usingVertexCoverage && this->fCoverage != that.fCoverage) { |
| 62 return false; |
| 63 } |
| 64 |
| 65 bool explicitLocalCoords = this->hasLocalCoordAttribute(); |
| 66 if (this->hasGeometryProcessor()) { |
| 67 if (!that.hasGeometryProcessor()) { |
| 68 return false; |
| 69 } else if (!GrProcessorStage::AreCompatible(*this->getGeometryProcessor(
), |
| 70 *that.getGeometryProcessor()
, |
| 71 explicitLocalCoords)) { |
| 72 return false; |
| 73 } |
| 74 } else if (that.hasGeometryProcessor()) { |
| 75 return false; |
| 76 } |
| 77 |
| 78 for (int i = 0; i < this->numColorStages(); i++) { |
| 79 if (!GrProcessorStage::AreCompatible(this->getColorStage(i), that.getCol
orStage(i), |
| 80 explicitLocalCoords)) { |
| 81 return false; |
| 82 } |
| 83 } |
| 84 for (int i = 0; i < this->numCoverageStages(); i++) { |
| 85 if (!GrProcessorStage::AreCompatible(this->getCoverageStage(i), that.get
CoverageStage(i), |
| 86 explicitLocalCoords)) { |
| 87 return false; |
| 88 } |
| 89 } |
| 90 |
| 91 SkASSERT(0 == memcmp(this->fFixedFunctionVertexAttribIndices, |
| 92 that.fFixedFunctionVertexAttribIndices, |
| 93 sizeof(this->fFixedFunctionVertexAttribIndices))); |
| 94 |
| 95 return true; |
| 96 } |
| 97 |
36 GrDrawState::CombinedState GrDrawState::CombineIfPossible( | 98 GrDrawState::CombinedState GrDrawState::CombineIfPossible( |
37 const GrDrawState& a, const GrDrawState& b, const GrDrawTargetCaps& caps) { | 99 const GrDrawState& a, const GrDrawState& b, const GrDrawTargetCaps& caps) { |
38 | 100 |
39 if (!a.isEqual(b)) { | 101 if (!a.isEqual(b)) { |
40 return kIncompatible_CombinedState; | 102 return kIncompatible_CombinedState; |
41 } | 103 } |
42 | 104 |
43 // If the general draw states are equal (from check above) we know hasColorV
ertexAttribute() | 105 // If the general draw states are equal (from check above) we know hasColorV
ertexAttribute() |
44 // is equivalent for both a and b | 106 // is equivalent for both a and b |
45 if (a.hasColorVertexAttribute()) { | 107 if (a.hasColorVertexAttribute()) { |
(...skipping 165 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
211 this->setState(GrDrawState::kDither_StateBit, paint.isDither()); | 273 this->setState(GrDrawState::kDither_StateBit, paint.isDither()); |
212 this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias()); | 274 this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias()); |
213 | 275 |
214 this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff()); | 276 this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff()); |
215 this->setCoverage(paint.getCoverage()); | 277 this->setCoverage(paint.getCoverage()); |
216 this->invalidateOptState(); | 278 this->invalidateOptState(); |
217 } | 279 } |
218 | 280 |
219 //////////////////////////////////////////////////////////////////////////////// | 281 //////////////////////////////////////////////////////////////////////////////// |
220 | 282 |
| 283 bool GrDrawState::validateVertexAttribs() const { |
| 284 // check consistency of effects and attributes |
| 285 GrSLType slTypes[kMaxVertexAttribCnt]; |
| 286 for (int i = 0; i < kMaxVertexAttribCnt; ++i) { |
| 287 slTypes[i] = static_cast<GrSLType>(-1); |
| 288 } |
| 289 |
| 290 if (this->hasGeometryProcessor()) { |
| 291 const GrGeometryStage& stage = *this->getGeometryProcessor(); |
| 292 const GrGeometryProcessor* gp = stage.getGeometryProcessor(); |
| 293 SkASSERT(gp); |
| 294 // make sure that any attribute indices have the correct binding type, t
hat the attrib |
| 295 // type and effect's shader lang type are compatible, and that attribute
s shared by |
| 296 // multiple effects use the same shader lang type. |
| 297 const GrGeometryProcessor::VertexAttribArray& s = gp->getVertexAttribs()
; |
| 298 |
| 299 int effectIndex = 0; |
| 300 for (int index = 0; index < fVACount; index++) { |
| 301 if (kGeometryProcessor_GrVertexAttribBinding != fVAPtr[index].fBindi
ng) { |
| 302 // we only care about effect bindings |
| 303 continue; |
| 304 } |
| 305 SkASSERT(effectIndex < s.count()); |
| 306 GrSLType effectSLType = s[effectIndex].getType(); |
| 307 GrVertexAttribType attribType = fVAPtr[index].fType; |
| 308 int slVecCount = GrSLTypeVectorCount(effectSLType); |
| 309 int attribVecCount = GrVertexAttribTypeVectorCount(attribType); |
| 310 if (slVecCount != attribVecCount || |
| 311 (static_cast<GrSLType>(-1) != slTypes[index] && slTypes[index] !
= effectSLType)) { |
| 312 return false; |
| 313 } |
| 314 slTypes[index] = effectSLType; |
| 315 effectIndex++; |
| 316 } |
| 317 // Make sure all attributes are consumed and we were able to find everyt
hing |
| 318 SkASSERT(s.count() == effectIndex); |
| 319 } |
| 320 |
| 321 return true; |
| 322 } |
| 323 |
| 324 //////////////////////////////////////////////////////////////////////////////// |
| 325 |
221 static void validate_vertex_attribs(const GrVertexAttrib* attribs, int count, si
ze_t stride) { | 326 static void validate_vertex_attribs(const GrVertexAttrib* attribs, int count, si
ze_t stride) { |
222 // this works as long as we're 4 byte-aligned | 327 // this works as long as we're 4 byte-aligned |
223 #ifdef SK_DEBUG | 328 #ifdef SK_DEBUG |
224 uint32_t overlapCheck = 0; | 329 uint32_t overlapCheck = 0; |
225 SkASSERT(count <= GrRODrawState::kMaxVertexAttribCnt); | 330 SkASSERT(count <= GrDrawState::kMaxVertexAttribCnt); |
226 for (int index = 0; index < count; ++index) { | 331 for (int index = 0; index < count; ++index) { |
227 size_t attribSize = GrVertexAttribTypeSize(attribs[index].fType); | 332 size_t attribSize = GrVertexAttribTypeSize(attribs[index].fType); |
228 size_t attribOffset = attribs[index].fOffset; | 333 size_t attribOffset = attribs[index].fOffset; |
229 SkASSERT(attribOffset + attribSize <= stride); | 334 SkASSERT(attribOffset + attribSize <= stride); |
230 size_t dwordCount = attribSize >> 2; | 335 size_t dwordCount = attribSize >> 2; |
231 uint32_t mask = (1 << dwordCount)-1; | 336 uint32_t mask = (1 << dwordCount)-1; |
232 size_t offsetShift = attribOffset >> 2; | 337 size_t offsetShift = attribOffset >> 2; |
233 SkASSERT(!(overlapCheck & (mask << offsetShift))); | 338 SkASSERT(!(overlapCheck & (mask << offsetShift))); |
234 overlapCheck |= (mask << offsetShift); | 339 overlapCheck |= (mask << offsetShift); |
235 } | 340 } |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
298 bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const { | 403 bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const { |
299 if (caps.dualSourceBlendingSupport()) { | 404 if (caps.dualSourceBlendingSupport()) { |
300 return true; | 405 return true; |
301 } | 406 } |
302 // we can correctly apply coverage if a) we have dual source blending | 407 // we can correctly apply coverage if a) we have dual source blending |
303 // or b) one of our blend optimizations applies | 408 // or b) one of our blend optimizations applies |
304 // or c) the src, dst blend coeffs are 1,0 and we will read Dst Color | 409 // or c) the src, dst blend coeffs are 1,0 and we will read Dst Color |
305 GrBlendCoeff srcCoeff; | 410 GrBlendCoeff srcCoeff; |
306 GrBlendCoeff dstCoeff; | 411 GrBlendCoeff dstCoeff; |
307 BlendOptFlags flag = this->getBlendOpts(true, &srcCoeff, &dstCoeff); | 412 BlendOptFlags flag = this->getBlendOpts(true, &srcCoeff, &dstCoeff); |
308 return GrRODrawState::kNone_BlendOpt != flag || | 413 return GrDrawState::kNone_BlendOpt != flag || |
309 (this->willEffectReadDstColor() && | 414 (this->willEffectReadDstColor() && |
310 kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff); | 415 kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff); |
311 } | 416 } |
312 | 417 |
| 418 bool GrDrawState::hasSolidCoverage() const { |
| 419 // If we're drawing coverage directly then coverage is effectively treated a
s color. |
| 420 if (this->isCoverageDrawing()) { |
| 421 return true; |
| 422 } |
| 423 |
| 424 GrColor coverage; |
| 425 uint32_t validComponentFlags; |
| 426 // Initialize to an unknown starting coverage if per-vertex coverage is spec
ified. |
| 427 if (this->hasCoverageVertexAttribute()) { |
| 428 validComponentFlags = 0; |
| 429 } else { |
| 430 coverage = fCoverage; |
| 431 validComponentFlags = kRGBA_GrColorComponentFlags; |
| 432 } |
| 433 |
| 434 // Run through the coverage stages and see if the coverage will be all ones
at the end. |
| 435 if (this->hasGeometryProcessor()) { |
| 436 const GrGeometryProcessor* gp = fGeometryProcessor->getGeometryProcessor
(); |
| 437 gp->getConstantColorComponents(&coverage, &validComponentFlags); |
| 438 } |
| 439 for (int s = 0; s < this->numCoverageStages(); ++s) { |
| 440 const GrProcessor* processor = this->getCoverageStage(s).getProcessor(); |
| 441 processor->getConstantColorComponents(&coverage, &validComponentFlags); |
| 442 } |
| 443 return (kRGBA_GrColorComponentFlags == validComponentFlags) && (0xffffffff =
= coverage); |
| 444 } |
| 445 |
313 ////////////////////////////////////////////////////////////////////////////// | 446 ////////////////////////////////////////////////////////////////////////////// |
314 | 447 |
315 GrDrawState::AutoVertexAttribRestore::AutoVertexAttribRestore(GrDrawState* drawS
tate) { | 448 GrDrawState::AutoVertexAttribRestore::AutoVertexAttribRestore(GrDrawState* drawS
tate) { |
316 SkASSERT(drawState); | 449 SkASSERT(drawState); |
317 fDrawState = drawState; | 450 fDrawState = drawState; |
318 fVAPtr = drawState->fVAPtr; | 451 fVAPtr = drawState->fVAPtr; |
319 fVACount = drawState->fVACount; | 452 fVACount = drawState->fVACount; |
320 fVAStride = drawState->fVAStride; | 453 fVAStride = drawState->fVAStride; |
321 fDrawState->setDefaultVertexAttribs(); | 454 fDrawState->setDefaultVertexAttribs(); |
322 } | 455 } |
323 | 456 |
324 //////////////////////////////////////////////////////////////////////////////s | 457 //////////////////////////////////////////////////////////////////////////////s |
325 | 458 |
| 459 bool GrDrawState::willEffectReadDstColor() const { |
| 460 if (!this->isColorWriteDisabled()) { |
| 461 for (int s = 0; s < this->numColorStages(); ++s) { |
| 462 if (this->getColorStage(s).getFragmentProcessor()->willReadDstColor(
)) { |
| 463 return true; |
| 464 } |
| 465 } |
| 466 } |
| 467 for (int s = 0; s < this->numCoverageStages(); ++s) { |
| 468 if (this->getCoverageStage(s).getFragmentProcessor()->willReadDstColor()
) { |
| 469 return true; |
| 470 } |
| 471 } |
| 472 return false; |
| 473 } |
| 474 |
326 void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) { | 475 void GrDrawState::AutoRestoreEffects::set(GrDrawState* ds) { |
327 if (fDrawState) { | 476 if (fDrawState) { |
328 // See the big comment on the class definition about GPs. | 477 // See the big comment on the class definition about GPs. |
329 if (SK_InvalidUniqueID == fOriginalGPID) { | 478 if (SK_InvalidUniqueID == fOriginalGPID) { |
330 fDrawState->fGeometryProcessor.reset(NULL); | 479 fDrawState->fGeometryProcessor.reset(NULL); |
331 } else { | 480 } else { |
332 SkASSERT(fDrawState->getGeometryProcessor()->getProcessor()->getUniq
ueID() == | 481 SkASSERT(fDrawState->getGeometryProcessor()->getProcessor()->getUniq
ueID() == |
333 fOriginalGPID); | 482 fOriginalGPID); |
334 fOriginalGPID = SK_InvalidUniqueID; | 483 fOriginalGPID = SK_InvalidUniqueID; |
335 } | 484 } |
(...skipping 17 matching lines...) Expand all Loading... |
353 fOriginalGPID = ds->getGeometryProcessor()->getProcessor()->getUniqu
eID(); | 502 fOriginalGPID = ds->getGeometryProcessor()->getProcessor()->getUniqu
eID(); |
354 } | 503 } |
355 fColorEffectCnt = ds->numColorStages(); | 504 fColorEffectCnt = ds->numColorStages(); |
356 fCoverageEffectCnt = ds->numCoverageStages(); | 505 fCoverageEffectCnt = ds->numCoverageStages(); |
357 SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;) | 506 SkDEBUGCODE(++ds->fBlockEffectRemovalCnt;) |
358 } | 507 } |
359 } | 508 } |
360 | 509 |
361 //////////////////////////////////////////////////////////////////////////////// | 510 //////////////////////////////////////////////////////////////////////////////// |
362 | 511 |
| 512 // Some blend modes allow folding a fractional coverage value into the color's a
lpha channel, while |
| 513 // others will blend incorrectly. |
| 514 bool GrDrawState::canTweakAlphaForCoverage() const { |
| 515 /* |
| 516 The fractional coverage is f. |
| 517 The src and dst coeffs are Cs and Cd. |
| 518 The dst and src colors are S and D. |
| 519 We want the blend to compute: f*Cs*S + (f*Cd + (1-f))D. By tweaking the sou
rce color's alpha |
| 520 we're replacing S with S'=fS. It's obvious that that first term will always
be ok. The second |
| 521 term can be rearranged as [1-(1-Cd)f]D. By substituting in the various poss
ibilities for Cd we |
| 522 find that only 1, ISA, and ISC produce the correct destination when applied
to S' and D. |
| 523 Also, if we're directly rendering coverage (isCoverageDrawing) then coverag
e is treated as |
| 524 color by definition. |
| 525 */ |
| 526 return kOne_GrBlendCoeff == fDstBlend || |
| 527 kISA_GrBlendCoeff == fDstBlend || |
| 528 kISC_GrBlendCoeff == fDstBlend || |
| 529 this->isCoverageDrawing(); |
| 530 } |
| 531 |
| 532 //////////////////////////////////////////////////////////////////////////////// |
| 533 |
363 void GrDrawState::AutoViewMatrixRestore::restore() { | 534 void GrDrawState::AutoViewMatrixRestore::restore() { |
364 if (fDrawState) { | 535 if (fDrawState) { |
365 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;) | 536 SkDEBUGCODE(--fDrawState->fBlockEffectRemovalCnt;) |
366 fDrawState->fViewMatrix = fViewMatrix; | 537 fDrawState->fViewMatrix = fViewMatrix; |
367 SkASSERT(fDrawState->numColorStages() >= fNumColorStages); | 538 SkASSERT(fDrawState->numColorStages() >= fNumColorStages); |
368 int numCoverageStages = fSavedCoordChanges.count() - fNumColorStages; | 539 int numCoverageStages = fSavedCoordChanges.count() - fNumColorStages; |
369 SkASSERT(fDrawState->numCoverageStages() >= numCoverageStages); | 540 SkASSERT(fDrawState->numCoverageStages() >= numCoverageStages); |
370 | 541 |
371 int i = 0; | 542 int i = 0; |
372 if (fHasGeometryProcessor) { | 543 if (fHasGeometryProcessor) { |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
455 | 626 |
456 int numCoverageStages = fDrawState->numCoverageStages(); | 627 int numCoverageStages = fDrawState->numCoverageStages(); |
457 for (int s = 0; s < numCoverageStages; ++s, ++i) { | 628 for (int s = 0; s < numCoverageStages; ++s, ++i) { |
458 fDrawState->getCoverageStage(s).saveCoordChange(&fSavedCoordChanges[i]); | 629 fDrawState->getCoverageStage(s).saveCoordChange(&fSavedCoordChanges[i]); |
459 fDrawState->fCoverageStages[s].localCoordChange(coordChangeMatrix); | 630 fDrawState->fCoverageStages[s].localCoordChange(coordChangeMatrix); |
460 } | 631 } |
461 } | 632 } |
462 | 633 |
463 //////////////////////////////////////////////////////////////////////////////// | 634 //////////////////////////////////////////////////////////////////////////////// |
464 | 635 |
| 636 void GrDrawState::convertToPendingExec() { |
| 637 fRenderTarget.markPendingIO(); |
| 638 fRenderTarget.removeRef(); |
| 639 for (int i = 0; i < fColorStages.count(); ++i) { |
| 640 fColorStages[i].convertToPendingExec(); |
| 641 } |
| 642 if (fGeometryProcessor) { |
| 643 fGeometryProcessor->convertToPendingExec(); |
| 644 } |
| 645 for (int i = 0; i < fCoverageStages.count(); ++i) { |
| 646 fCoverageStages[i].convertToPendingExec(); |
| 647 } |
| 648 } |
| 649 |
| 650 //////////////////////////////////////////////////////////////////////////////// |
| 651 |
465 void GrDrawState::invalidateOptState() const { | 652 void GrDrawState::invalidateOptState() const { |
466 SkSafeSetNull(fCachedOptState); | 653 SkSafeSetNull(fCachedOptState); |
467 } | 654 } |
468 | 655 |
469 //////////////////////////////////////////////////////////////////////////////// | 656 //////////////////////////////////////////////////////////////////////////////// |
470 | 657 |
471 GrDrawState::~GrDrawState() { | 658 GrDrawState::~GrDrawState() { |
472 SkSafeUnref(fCachedOptState); | 659 SkSafeUnref(fCachedOptState); |
473 SkASSERT(0 == fBlockEffectRemovalCnt); | 660 SkASSERT(0 == fBlockEffectRemovalCnt); |
474 } | 661 } |
475 | 662 |
| 663 //////////////////////////////////////////////////////////////////////////////// |
| 664 |
| 665 GrDrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage, |
| 666 GrBlendCoeff* srcCoeff, |
| 667 GrBlendCoeff* dstCoeff)
const { |
| 668 GrBlendCoeff bogusSrcCoeff, bogusDstCoeff; |
| 669 if (NULL == srcCoeff) { |
| 670 srcCoeff = &bogusSrcCoeff; |
| 671 } |
| 672 if (NULL == dstCoeff) { |
| 673 dstCoeff = &bogusDstCoeff; |
| 674 } |
| 675 |
| 676 *srcCoeff = this->getSrcBlendCoeff(); |
| 677 *dstCoeff = this->getDstBlendCoeff(); |
| 678 |
| 679 if (this->isColorWriteDisabled()) { |
| 680 *srcCoeff = kZero_GrBlendCoeff; |
| 681 *dstCoeff = kOne_GrBlendCoeff; |
| 682 } |
| 683 |
| 684 bool srcAIsOne = this->srcAlphaWillBeOne(); |
| 685 bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff || |
| 686 (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne); |
| 687 bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff || |
| 688 (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne); |
| 689 |
| 690 // When coeffs are (0,1) there is no reason to draw at all, unless |
| 691 // stenciling is enabled. Having color writes disabled is effectively |
| 692 // (0,1). |
| 693 if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne)) { |
| 694 if (this->getStencil().doesWrite()) { |
| 695 return kEmitCoverage_BlendOptFlag; |
| 696 } else { |
| 697 *dstCoeff = kOne_GrBlendCoeff; |
| 698 return kSkipDraw_BlendOptFlag; |
| 699 } |
| 700 } |
| 701 |
| 702 bool hasCoverage = forceCoverage || !this->hasSolidCoverage(); |
| 703 |
| 704 // if we don't have coverage we can check whether the dst |
| 705 // has to read at all. If not, we'll disable blending. |
| 706 if (!hasCoverage) { |
| 707 if (dstCoeffIsZero) { |
| 708 if (kOne_GrBlendCoeff == *srcCoeff) { |
| 709 // if there is no coverage and coeffs are (1,0) then we |
| 710 // won't need to read the dst at all, it gets replaced by src |
| 711 *dstCoeff = kZero_GrBlendCoeff; |
| 712 return kNone_BlendOpt; |
| 713 } else if (kZero_GrBlendCoeff == *srcCoeff) { |
| 714 // if the op is "clear" then we don't need to emit a color |
| 715 // or blend, just write transparent black into the dst. |
| 716 *srcCoeff = kOne_GrBlendCoeff; |
| 717 *dstCoeff = kZero_GrBlendCoeff; |
| 718 return kEmitTransBlack_BlendOptFlag; |
| 719 } |
| 720 } |
| 721 } else if (this->isCoverageDrawing()) { |
| 722 // we have coverage but we aren't distinguishing it from alpha by reques
t. |
| 723 return kCoverageAsAlpha_BlendOptFlag; |
| 724 } else { |
| 725 // check whether coverage can be safely rolled into alpha |
| 726 // of if we can skip color computation and just emit coverage |
| 727 if (this->canTweakAlphaForCoverage()) { |
| 728 return kCoverageAsAlpha_BlendOptFlag; |
| 729 } |
| 730 if (dstCoeffIsZero) { |
| 731 if (kZero_GrBlendCoeff == *srcCoeff) { |
| 732 // the source color is not included in the blend |
| 733 // the dst coeff is effectively zero so blend works out to: |
| 734 // (c)(0)D + (1-c)D = (1-c)D. |
| 735 *dstCoeff = kISA_GrBlendCoeff; |
| 736 return kEmitCoverage_BlendOptFlag; |
| 737 } else if (srcAIsOne) { |
| 738 // the dst coeff is effectively zero so blend works out to: |
| 739 // cS + (c)(0)D + (1-c)D = cS + (1-c)D. |
| 740 // If Sa is 1 then we can replace Sa with c |
| 741 // and set dst coeff to 1-Sa. |
| 742 *dstCoeff = kISA_GrBlendCoeff; |
| 743 return kCoverageAsAlpha_BlendOptFlag; |
| 744 } |
| 745 } else if (dstCoeffIsOne) { |
| 746 // the dst coeff is effectively one so blend works out to: |
| 747 // cS + (c)(1)D + (1-c)D = cS + D. |
| 748 *dstCoeff = kOne_GrBlendCoeff; |
| 749 return kCoverageAsAlpha_BlendOptFlag; |
| 750 } |
| 751 } |
| 752 |
| 753 return kNone_BlendOpt; |
| 754 } |
| 755 |
| 756 |
| 757 bool GrDrawState::srcAlphaWillBeOne() const { |
| 758 uint32_t validComponentFlags; |
| 759 GrColor color; |
| 760 // Check if per-vertex or constant color may have partial alpha |
| 761 if (this->hasColorVertexAttribute()) { |
| 762 if (fHints & kVertexColorsAreOpaque_Hint) { |
| 763 validComponentFlags = kA_GrColorComponentFlag; |
| 764 color = 0xFF << GrColor_SHIFT_A; |
| 765 } else { |
| 766 validComponentFlags = 0; |
| 767 color = 0; // not strictly necessary but we get false alarms from to
ols about uninit. |
| 768 } |
| 769 } else { |
| 770 validComponentFlags = kRGBA_GrColorComponentFlags; |
| 771 color = this->getColor(); |
| 772 } |
| 773 |
| 774 // Run through the color stages |
| 775 for (int s = 0; s < this->numColorStages(); ++s) { |
| 776 const GrProcessor* processor = this->getColorStage(s).getProcessor(); |
| 777 processor->getConstantColorComponents(&color, &validComponentFlags); |
| 778 } |
| 779 |
| 780 // Check whether coverage is treated as color. If so we run through the cove
rage computation. |
| 781 if (this->isCoverageDrawing()) { |
| 782 // The shader generated for coverage drawing runs the full coverage comp
utation and then |
| 783 // makes the shader output be the multiplication of color and coverage.
We mirror that here. |
| 784 GrColor coverage; |
| 785 uint32_t coverageComponentFlags; |
| 786 if (this->hasCoverageVertexAttribute()) { |
| 787 coverageComponentFlags = 0; |
| 788 coverage = 0; // suppresses any warnings. |
| 789 } else { |
| 790 coverageComponentFlags = kRGBA_GrColorComponentFlags; |
| 791 coverage = this->getCoverageColor(); |
| 792 } |
| 793 |
| 794 // Run through the coverage stages |
| 795 for (int s = 0; s < this->numCoverageStages(); ++s) { |
| 796 const GrProcessor* processor = this->getCoverageStage(s).getProcesso
r(); |
| 797 processor->getConstantColorComponents(&coverage, &coverageComponentF
lags); |
| 798 } |
| 799 |
| 800 // Since the shader will multiply coverage and color, the only way the f
inal A==1 is if |
| 801 // coverage and color both have A==1. |
| 802 return (kA_GrColorComponentFlag & validComponentFlags & coverageComponen
tFlags) && |
| 803 0xFF == GrColorUnpackA(color) && 0xFF == GrColorUnpackA(coverage
); |
| 804 |
| 805 } |
| 806 |
| 807 return (kA_GrColorComponentFlag & validComponentFlags) && 0xFF == GrColorUnp
ackA(color); |
| 808 } |
| 809 |
OLD | NEW |