| 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 "GrBlend.h" | 10 #include "GrBlend.h" |
| (...skipping 176 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 187 } | 187 } |
| 188 | 188 |
| 189 this->setRenderTarget(rt); | 189 this->setRenderTarget(rt); |
| 190 | 190 |
| 191 fViewMatrix = vm; | 191 fViewMatrix = vm; |
| 192 | 192 |
| 193 // These have no equivalent in GrPaint, set them to defaults | 193 // These have no equivalent in GrPaint, set them to defaults |
| 194 fBlendConstant = 0x0; | 194 fBlendConstant = 0x0; |
| 195 fDrawFace = kBoth_DrawFace; | 195 fDrawFace = kBoth_DrawFace; |
| 196 fStencilSettings.setDisabled(); | 196 fStencilSettings.setDisabled(); |
| 197 this->resetStateFlags(); | 197 fFlagBits = 0; |
| 198 fHints = 0; | 198 fHints = 0; |
| 199 | 199 |
| 200 // Enable the clip bit | 200 // Enable the clip bit |
| 201 this->enableState(GrDrawState::kClip_StateBit); | 201 this->enableState(GrDrawState::kClip_StateBit); |
| 202 | 202 |
| 203 this->setColor(paint.getColor()); | 203 this->setColor(paint.getColor()); |
| 204 this->setState(GrDrawState::kDither_StateBit, paint.isDither()); | 204 this->setState(GrDrawState::kDither_StateBit, paint.isDither()); |
| 205 this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias()); | 205 this->setState(GrDrawState::kHWAntialias_StateBit, paint.isAntiAlias()); |
| 206 | 206 |
| 207 this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff()); | 207 this->setBlendFunc(paint.getSrcBlendCoeff(), paint.getDstBlendCoeff()); |
| (...skipping 126 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 334 | 334 |
| 335 bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const { | 335 bool GrDrawState::couldApplyCoverage(const GrDrawTargetCaps& caps) const { |
| 336 if (caps.dualSourceBlendingSupport()) { | 336 if (caps.dualSourceBlendingSupport()) { |
| 337 return true; | 337 return true; |
| 338 } | 338 } |
| 339 // we can correctly apply coverage if a) we have dual source blending | 339 // we can correctly apply coverage if a) we have dual source blending |
| 340 // or b) one of our blend optimizations applies | 340 // or b) one of our blend optimizations applies |
| 341 // or c) the src, dst blend coeffs are 1,0 and we will read Dst Color | 341 // or c) the src, dst blend coeffs are 1,0 and we will read Dst Color |
| 342 GrBlendCoeff srcCoeff; | 342 GrBlendCoeff srcCoeff; |
| 343 GrBlendCoeff dstCoeff; | 343 GrBlendCoeff dstCoeff; |
| 344 BlendOptFlags flag = this->getBlendOpts(true, &srcCoeff, &dstCoeff); | 344 BlendOpt opt = this->getBlendOpt(true, &srcCoeff, &dstCoeff); |
| 345 return GrDrawState::kNone_BlendOpt != flag || | 345 return GrDrawState::kNone_BlendOpt != opt || |
| 346 (this->willEffectReadDstColor() && | 346 (this->willEffectReadDstColor() && |
| 347 kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff); | 347 kOne_GrBlendCoeff == srcCoeff && kZero_GrBlendCoeff == dstCoeff); |
| 348 } | 348 } |
| 349 | 349 |
| 350 bool GrDrawState::hasSolidCoverage() const { | 350 bool GrDrawState::hasSolidCoverage() const { |
| 351 // If we're drawing coverage directly then coverage is effectively treated a
s color. | 351 // If we're drawing coverage directly then coverage is effectively treated a
s color. |
| 352 if (this->isCoverageDrawing()) { | 352 if (this->isCoverageDrawing()) { |
| 353 return true; | 353 return true; |
| 354 } | 354 } |
| 355 | 355 |
| (...skipping 175 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 531 } | 531 } |
| 532 | 532 |
| 533 //////////////////////////////////////////////////////////////////////////////// | 533 //////////////////////////////////////////////////////////////////////////////// |
| 534 | 534 |
| 535 GrDrawState::~GrDrawState() { | 535 GrDrawState::~GrDrawState() { |
| 536 SkASSERT(0 == fBlockEffectRemovalCnt); | 536 SkASSERT(0 == fBlockEffectRemovalCnt); |
| 537 } | 537 } |
| 538 | 538 |
| 539 //////////////////////////////////////////////////////////////////////////////// | 539 //////////////////////////////////////////////////////////////////////////////// |
| 540 | 540 |
| 541 GrDrawState::BlendOptFlags GrDrawState::getBlendOpts(bool forceCoverage, | 541 GrDrawState::BlendOpt GrDrawState::getBlendOpt(bool forceCoverage, |
| 542 GrBlendCoeff* srcCoeff, | 542 GrBlendCoeff* srcCoeff, |
| 543 GrBlendCoeff* dstCoeff) con
st { | 543 GrBlendCoeff* dstCoeff) const { |
| 544 GrBlendCoeff bogusSrcCoeff, bogusDstCoeff; | 544 GrBlendCoeff bogusSrcCoeff, bogusDstCoeff; |
| 545 if (NULL == srcCoeff) { | 545 if (NULL == srcCoeff) { |
| 546 srcCoeff = &bogusSrcCoeff; | 546 srcCoeff = &bogusSrcCoeff; |
| 547 } | 547 } |
| 548 if (NULL == dstCoeff) { | 548 if (NULL == dstCoeff) { |
| 549 dstCoeff = &bogusDstCoeff; | 549 dstCoeff = &bogusDstCoeff; |
| 550 } | 550 } |
| 551 | 551 |
| 552 *srcCoeff = this->getSrcBlendCoeff(); | 552 *srcCoeff = this->getSrcBlendCoeff(); |
| 553 *dstCoeff = this->getDstBlendCoeff(); | 553 *dstCoeff = this->getDstBlendCoeff(); |
| 554 | 554 |
| 555 if (this->isColorWriteDisabled()) { | 555 if (this->isColorWriteDisabled()) { |
| 556 *srcCoeff = kZero_GrBlendCoeff; | 556 *srcCoeff = kZero_GrBlendCoeff; |
| 557 *dstCoeff = kOne_GrBlendCoeff; | 557 *dstCoeff = kOne_GrBlendCoeff; |
| 558 } | 558 } |
| 559 | 559 |
| 560 bool srcAIsOne = this->srcAlphaWillBeOne(); | 560 bool srcAIsOne = this->srcAlphaWillBeOne(); |
| 561 bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff || | 561 bool dstCoeffIsOne = kOne_GrBlendCoeff == *dstCoeff || |
| 562 (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne); | 562 (kSA_GrBlendCoeff == *dstCoeff && srcAIsOne); |
| 563 bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff || | 563 bool dstCoeffIsZero = kZero_GrBlendCoeff == *dstCoeff || |
| 564 (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne); | 564 (kISA_GrBlendCoeff == *dstCoeff && srcAIsOne); |
| 565 | 565 |
| 566 // When coeffs are (0,1) there is no reason to draw at all, unless | 566 // When coeffs are (0,1) there is no reason to draw at all, unless |
| 567 // stenciling is enabled. Having color writes disabled is effectively | 567 // stenciling is enabled. Having color writes disabled is effectively |
| 568 // (0,1). | 568 // (0,1). |
| 569 if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne)) { | 569 if ((kZero_GrBlendCoeff == *srcCoeff && dstCoeffIsOne)) { |
| 570 if (this->getStencil().doesWrite()) { | 570 if (this->getStencil().doesWrite()) { |
| 571 return kEmitCoverage_BlendOptFlag; | 571 return kEmitCoverage_BlendOpt; |
| 572 } else { | 572 } else { |
| 573 *dstCoeff = kOne_GrBlendCoeff; | 573 *dstCoeff = kOne_GrBlendCoeff; |
| 574 return kSkipDraw_BlendOptFlag; | 574 return kSkipDraw_BlendOpt; |
| 575 } | 575 } |
| 576 } | 576 } |
| 577 | 577 |
| 578 bool hasCoverage = forceCoverage || !this->hasSolidCoverage(); | 578 bool hasCoverage = forceCoverage || !this->hasSolidCoverage(); |
| 579 | 579 |
| 580 // if we don't have coverage we can check whether the dst | 580 // if we don't have coverage we can check whether the dst |
| 581 // has to read at all. If not, we'll disable blending. | 581 // has to read at all. If not, we'll disable blending. |
| 582 if (!hasCoverage) { | 582 if (!hasCoverage) { |
| 583 if (dstCoeffIsZero) { | 583 if (dstCoeffIsZero) { |
| 584 if (kOne_GrBlendCoeff == *srcCoeff) { | 584 if (kOne_GrBlendCoeff == *srcCoeff) { |
| 585 // if there is no coverage and coeffs are (1,0) then we | 585 // if there is no coverage and coeffs are (1,0) then we |
| 586 // won't need to read the dst at all, it gets replaced by src | 586 // won't need to read the dst at all, it gets replaced by src |
| 587 *dstCoeff = kZero_GrBlendCoeff; | 587 *dstCoeff = kZero_GrBlendCoeff; |
| 588 return kNone_BlendOpt; | 588 return kNone_BlendOpt; |
| 589 } else if (kZero_GrBlendCoeff == *srcCoeff) { | 589 } else if (kZero_GrBlendCoeff == *srcCoeff) { |
| 590 // if the op is "clear" then we don't need to emit a color | 590 // if the op is "clear" then we don't need to emit a color |
| 591 // or blend, just write transparent black into the dst. | 591 // or blend, just write transparent black into the dst. |
| 592 *srcCoeff = kOne_GrBlendCoeff; | 592 *srcCoeff = kOne_GrBlendCoeff; |
| 593 *dstCoeff = kZero_GrBlendCoeff; | 593 *dstCoeff = kZero_GrBlendCoeff; |
| 594 return kEmitTransBlack_BlendOptFlag; | 594 return kEmitTransBlack_BlendOpt; |
| 595 } | 595 } |
| 596 } | 596 } |
| 597 } else if (this->isCoverageDrawing()) { | 597 } else if (this->isCoverageDrawing()) { |
| 598 // we have coverage but we aren't distinguishing it from alpha by reques
t. | 598 // we have coverage but we aren't distinguishing it from alpha by reques
t. |
| 599 return kCoverageAsAlpha_BlendOptFlag; | 599 return kCoverageAsAlpha_BlendOpt; |
| 600 } else { | 600 } else { |
| 601 // check whether coverage can be safely rolled into alpha | 601 // check whether coverage can be safely rolled into alpha |
| 602 // of if we can skip color computation and just emit coverage | 602 // of if we can skip color computation and just emit coverage |
| 603 if (this->canTweakAlphaForCoverage()) { | 603 if (this->canTweakAlphaForCoverage()) { |
| 604 return kCoverageAsAlpha_BlendOptFlag; | 604 return kCoverageAsAlpha_BlendOpt; |
| 605 } | 605 } |
| 606 if (dstCoeffIsZero) { | 606 if (dstCoeffIsZero) { |
| 607 if (kZero_GrBlendCoeff == *srcCoeff) { | 607 if (kZero_GrBlendCoeff == *srcCoeff) { |
| 608 // the source color is not included in the blend | 608 // the source color is not included in the blend |
| 609 // the dst coeff is effectively zero so blend works out to: | 609 // the dst coeff is effectively zero so blend works out to: |
| 610 // (c)(0)D + (1-c)D = (1-c)D. | 610 // (c)(0)D + (1-c)D = (1-c)D. |
| 611 *dstCoeff = kISA_GrBlendCoeff; | 611 *dstCoeff = kISA_GrBlendCoeff; |
| 612 return kEmitCoverage_BlendOptFlag; | 612 return kEmitCoverage_BlendOpt; |
| 613 } else if (srcAIsOne) { | 613 } else if (srcAIsOne) { |
| 614 // the dst coeff is effectively zero so blend works out to: | 614 // the dst coeff is effectively zero so blend works out to: |
| 615 // cS + (c)(0)D + (1-c)D = cS + (1-c)D. | 615 // cS + (c)(0)D + (1-c)D = cS + (1-c)D. |
| 616 // If Sa is 1 then we can replace Sa with c | 616 // If Sa is 1 then we can replace Sa with c |
| 617 // and set dst coeff to 1-Sa. | 617 // and set dst coeff to 1-Sa. |
| 618 *dstCoeff = kISA_GrBlendCoeff; | 618 *dstCoeff = kISA_GrBlendCoeff; |
| 619 return kCoverageAsAlpha_BlendOptFlag; | 619 return kCoverageAsAlpha_BlendOpt; |
| 620 } | 620 } |
| 621 } else if (dstCoeffIsOne) { | 621 } else if (dstCoeffIsOne) { |
| 622 // the dst coeff is effectively one so blend works out to: | 622 // the dst coeff is effectively one so blend works out to: |
| 623 // cS + (c)(1)D + (1-c)D = cS + D. | 623 // cS + (c)(1)D + (1-c)D = cS + D. |
| 624 *dstCoeff = kOne_GrBlendCoeff; | 624 *dstCoeff = kOne_GrBlendCoeff; |
| 625 return kCoverageAsAlpha_BlendOptFlag; | 625 return kCoverageAsAlpha_BlendOpt; |
| 626 } | 626 } |
| 627 } | 627 } |
| 628 | 628 |
| 629 return kNone_BlendOpt; | 629 return kNone_BlendOpt; |
| 630 } | 630 } |
| 631 | 631 |
| 632 bool GrDrawState::srcAlphaWillBeOne() const { | 632 bool GrDrawState::srcAlphaWillBeOne() const { |
| 633 this->calcColorInvariantOutput(); | 633 this->calcColorInvariantOutput(); |
| 634 if (this->isCoverageDrawing()) { | 634 if (this->isCoverageDrawing()) { |
| 635 this->calcCoverageInvariantOutput(); | 635 this->calcCoverageInvariantOutput(); |
| (...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 693 } else { | 693 } else { |
| 694 flags = kRGBA_GrColorComponentFlags; | 694 flags = kRGBA_GrColorComponentFlags; |
| 695 color = this->getCoverageColor(); | 695 color = this->getCoverageColor(); |
| 696 } | 696 } |
| 697 fCoverageProcInfo.calcWithInitialValues(fCoverageStages.begin(), this->n
umCoverageStages(), | 697 fCoverageProcInfo.calcWithInitialValues(fCoverageStages.begin(), this->n
umCoverageStages(), |
| 698 color, flags, true, fGeometryPro
cessor.get()); | 698 color, flags, true, fGeometryPro
cessor.get()); |
| 699 fCoverageProcInfoValid = true; | 699 fCoverageProcInfoValid = true; |
| 700 } | 700 } |
| 701 } | 701 } |
| 702 | 702 |
| OLD | NEW |