| OLD | NEW |
| 1 /* | 1 /* |
| 2 * Copyright 2015 Google Inc. | 2 * Copyright 2015 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 "effects/GrCustomXfermode.h" | 8 #include "effects/GrCustomXfermode.h" |
| 9 #include "effects/GrCustomXfermodePriv.h" | 9 #include "effects/GrCustomXfermodePriv.h" |
| 10 | 10 |
| (...skipping 507 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 518 } | 518 } |
| 519 | 519 |
| 520 ~CustomXP() override {}; | 520 ~CustomXP() override {}; |
| 521 | 521 |
| 522 const char* name() const override { return "Custom Xfermode"; } | 522 const char* name() const override { return "Custom Xfermode"; } |
| 523 | 523 |
| 524 GrGLXferProcessor* createGLInstance() const override; | 524 GrGLXferProcessor* createGLInstance() const override; |
| 525 | 525 |
| 526 bool hasSecondaryOutput() const override { return false; } | 526 bool hasSecondaryOutput() const override { return false; } |
| 527 | 527 |
| 528 GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI, | |
| 529 const GrProcOptInfo& coveragePOI, | |
| 530 bool doesStencilWrite, | |
| 531 GrColor* overrideColor, | |
| 532 const GrDrawTargetCaps& caps) ove
rride; | |
| 533 | |
| 534 SkXfermode::Mode mode() const { return fMode; } | 528 SkXfermode::Mode mode() const { return fMode; } |
| 535 bool hasCoverage() const { return fHasCoverage; } | |
| 536 bool hasHWBlendEquation() const { return kInvalid_GrBlendEquation != fHWBlen
dEquation; } | 529 bool hasHWBlendEquation() const { return kInvalid_GrBlendEquation != fHWBlen
dEquation; } |
| 537 | 530 |
| 538 GrBlendEquation hwBlendEquation() const { | 531 GrBlendEquation hwBlendEquation() const { |
| 539 SkASSERT(this->hasHWBlendEquation()); | 532 SkASSERT(this->hasHWBlendEquation()); |
| 540 return fHWBlendEquation; | 533 return fHWBlendEquation; |
| 541 } | 534 } |
| 542 | 535 |
| 543 private: | 536 private: |
| 544 CustomXP(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy, bool wi
llReadDstColor); | 537 CustomXP(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy, bool wi
llReadDstColor); |
| 545 | 538 |
| 539 GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI, |
| 540 const GrProcOptInfo& coveragePO
I, |
| 541 bool doesStencilWrite, |
| 542 GrColor* overrideColor, |
| 543 const GrDrawTargetCaps& caps) o
verride; |
| 544 |
| 546 void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) c
onst override; | 545 void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) c
onst override; |
| 547 | 546 |
| 548 bool onWillNeedXferBarrier(const GrRenderTarget* rt, | 547 bool onWillNeedXferBarrier(const GrRenderTarget* rt, |
| 549 const GrDrawTargetCaps& caps, | 548 const GrDrawTargetCaps& caps, |
| 550 GrXferBarrierType* outBarrierType) const override
; | 549 GrXferBarrierType* outBarrierType) const override
; |
| 551 | 550 |
| 552 void onGetBlendInfo(BlendInfo*) const override; | 551 void onGetBlendInfo(BlendInfo*) const override; |
| 553 | 552 |
| 554 bool onIsEqual(const GrXferProcessor& xpBase) const override; | 553 bool onIsEqual(const GrXferProcessor& xpBase) const override; |
| 555 | 554 |
| 556 SkXfermode::Mode fMode; | 555 SkXfermode::Mode fMode; |
| 557 bool fHasCoverage; | |
| 558 GrBlendEquation fHWBlendEquation; | 556 GrBlendEquation fHWBlendEquation; |
| 559 | 557 |
| 560 typedef GrXferProcessor INHERITED; | 558 typedef GrXferProcessor INHERITED; |
| 561 }; | 559 }; |
| 562 | 560 |
| 563 /////////////////////////////////////////////////////////////////////////////// | 561 /////////////////////////////////////////////////////////////////////////////// |
| 564 | 562 |
| 565 GrXPFactory* GrCustomXfermode::CreateXPFactory(SkXfermode::Mode mode) { | 563 GrXPFactory* GrCustomXfermode::CreateXPFactory(SkXfermode::Mode mode) { |
| 566 if (!GrCustomXfermode::IsSupportedMode(mode)) { | 564 if (!GrCustomXfermode::IsSupportedMode(mode)) { |
| 567 return NULL; | 565 return NULL; |
| 568 } else { | 566 } else { |
| 569 return SkNEW_ARGS(GrCustomXPFactory, (mode)); | 567 return SkNEW_ARGS(GrCustomXPFactory, (mode)); |
| 570 } | 568 } |
| 571 } | 569 } |
| 572 | 570 |
| 573 /////////////////////////////////////////////////////////////////////////////// | 571 /////////////////////////////////////////////////////////////////////////////// |
| 574 | 572 |
| 575 class GLCustomXP : public GrGLXferProcessor { | 573 class GLCustomXP : public GrGLXferProcessor { |
| 576 public: | 574 public: |
| 577 GLCustomXP(const GrXferProcessor&) {} | 575 GLCustomXP(const GrXferProcessor&) {} |
| 578 ~GLCustomXP() override {} | 576 ~GLCustomXP() override {} |
| 579 | 577 |
| 580 static void GenKey(const GrXferProcessor& p, const GrGLSLCaps& caps, GrProce
ssorKeyBuilder* b) { | 578 static void GenKey(const GrXferProcessor& p, const GrGLSLCaps& caps, GrProce
ssorKeyBuilder* b) { |
| 581 const CustomXP& xp = p.cast<CustomXP>(); | 579 const CustomXP& xp = p.cast<CustomXP>(); |
| 582 uint32_t key = xp.numTextures(); | 580 uint32_t key = xp.numTextures(); |
| 583 SkASSERT(key <= 1); | 581 SkASSERT(key <= 1); |
| 584 key |= xp.hasCoverage() << 1; | 582 key |= xp.readsCoverage() << 1; |
| 585 if (xp.hasHWBlendEquation()) { | 583 if (xp.hasHWBlendEquation()) { |
| 586 SkASSERT(caps.advBlendEqInteraction() > 0); // 0 will mean !xp.hasH
WBlendEquation(). | 584 SkASSERT(caps.advBlendEqInteraction() > 0); // 0 will mean !xp.hasH
WBlendEquation(). |
| 587 key |= caps.advBlendEqInteraction() << 2; | 585 key |= caps.advBlendEqInteraction() << 2; |
| 588 } | 586 } |
| 589 if (!xp.hasHWBlendEquation() || caps.mustEnableSpecificAdvBlendEqs()) { | 587 if (!xp.hasHWBlendEquation() || caps.mustEnableSpecificAdvBlendEqs()) { |
| 590 GR_STATIC_ASSERT(GrGLSLCaps::kLast_AdvBlendEqInteraction < 4); | 588 GR_STATIC_ASSERT(GrGLSLCaps::kLast_AdvBlendEqInteraction < 4); |
| 591 key |= xp.mode() << 4; | 589 key |= xp.mode() << 4; |
| 592 } | 590 } |
| 593 b->add32(key); | 591 b->add32(key); |
| 594 } | 592 } |
| 595 | 593 |
| 596 private: | 594 private: |
| 597 void onEmitCode(const EmitArgs& args) override { | 595 void onEmitCode(const EmitArgs& args) override { |
| 598 const CustomXP& xp = args.fXP.cast<CustomXP>(); | 596 const CustomXP& xp = args.fXP.cast<CustomXP>(); |
| 599 GrGLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); | 597 GrGLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); |
| 600 | 598 |
| 601 if (xp.hasHWBlendEquation()) { | 599 if (xp.hasHWBlendEquation()) { |
| 602 // The blend mode will be implemented in hardware; only output the s
rc color. | 600 // The blend mode will be implemented in hardware; only output the s
rc color. |
| 603 fsBuilder->enableAdvancedBlendEquationIfNeeded(xp.hwBlendEquation())
; | 601 fsBuilder->enableAdvancedBlendEquationIfNeeded(xp.hwBlendEquation())
; |
| 604 if (xp.hasCoverage()) { | 602 if (xp.readsCoverage()) { |
| 605 // Do coverage modulation by multiplying it into the src color b
efore blending. | 603 // Do coverage modulation by multiplying it into the src color b
efore blending. |
| 606 // (See getOptimizations()) | 604 // (See getOptimizations()) |
| 607 fsBuilder->codeAppendf("%s = %s * %s;", | 605 fsBuilder->codeAppendf("%s = %s * %s;", |
| 608 args.fOutputPrimary, args.fInputCoverage,
args.fInputColor); | 606 args.fOutputPrimary, args.fInputCoverage,
args.fInputColor); |
| 609 } else { | 607 } else { |
| 610 fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fIn
putColor); | 608 fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fIn
putColor); |
| 611 } | 609 } |
| 612 } else { | 610 } else { |
| 613 const char* dstColor = fsBuilder->dstColor(); | 611 const char* dstColor = fsBuilder->dstColor(); |
| 614 emit_custom_xfermode_code(xp.mode(), fsBuilder, args.fOutputPrimary,
args.fInputColor, | 612 emit_custom_xfermode_code(xp.mode(), fsBuilder, args.fOutputPrimary,
args.fInputColor, |
| 615 dstColor); | 613 dstColor); |
| 616 if (xp.hasCoverage()) { | 614 if (xp.readsCoverage()) { |
| 617 fsBuilder->codeAppendf("%s = %s * %s + (vec4(1.0) - %s) * %s;", | 615 fsBuilder->codeAppendf("%s = %s * %s + (vec4(1.0) - %s) * %s;", |
| 618 args.fOutputPrimary, args.fOutputPrimary, | 616 args.fOutputPrimary, args.fOutputPrimary, |
| 619 args.fInputCoverage, args.fInputCoverage,
dstColor); | 617 args.fInputCoverage, args.fInputCoverage,
dstColor); |
| 620 } | 618 } |
| 621 } | 619 } |
| 622 } | 620 } |
| 623 | 621 |
| 624 void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) overri
de {} | 622 void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) overri
de {} |
| 625 | 623 |
| 626 typedef GrGLFragmentProcessor INHERITED; | 624 typedef GrGLFragmentProcessor INHERITED; |
| 627 }; | 625 }; |
| 628 | 626 |
| 629 /////////////////////////////////////////////////////////////////////////////// | 627 /////////////////////////////////////////////////////////////////////////////// |
| 630 | 628 |
| 631 CustomXP::CustomXP(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy, | 629 CustomXP::CustomXP(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy, |
| 632 bool willReadDstColor) | 630 bool willReadDstColor) |
| 633 : INHERITED(dstCopy, willReadDstColor), | 631 : INHERITED(dstCopy, willReadDstColor), |
| 634 fMode(mode), | 632 fMode(mode), |
| 635 fHasCoverage(true), | |
| 636 fHWBlendEquation(kInvalid_GrBlendEquation) { | 633 fHWBlendEquation(kInvalid_GrBlendEquation) { |
| 637 this->initClassID<CustomXP>(); | 634 this->initClassID<CustomXP>(); |
| 638 } | 635 } |
| 639 | 636 |
| 640 void CustomXP::onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder
* b) const { | 637 void CustomXP::onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder
* b) const { |
| 641 GLCustomXP::GenKey(*this, caps, b); | 638 GLCustomXP::GenKey(*this, caps, b); |
| 642 } | 639 } |
| 643 | 640 |
| 644 GrGLXferProcessor* CustomXP::createGLInstance() const { | 641 GrGLXferProcessor* CustomXP::createGLInstance() const { |
| 645 SkASSERT(this->willReadDstColor() != this->hasHWBlendEquation()); | 642 SkASSERT(this->willReadDstColor() != this->hasHWBlendEquation()); |
| 646 return SkNEW_ARGS(GLCustomXP, (*this)); | 643 return SkNEW_ARGS(GLCustomXP, (*this)); |
| 647 } | 644 } |
| 648 | 645 |
| 649 bool CustomXP::onIsEqual(const GrXferProcessor& other) const { | 646 bool CustomXP::onIsEqual(const GrXferProcessor& other) const { |
| 650 const CustomXP& s = other.cast<CustomXP>(); | 647 const CustomXP& s = other.cast<CustomXP>(); |
| 651 return fMode == s.fMode && | 648 return fMode == s.fMode && fHWBlendEquation == s.fHWBlendEquation; |
| 652 fHasCoverage == s.fHasCoverage && | |
| 653 fHWBlendEquation == s.fHWBlendEquation; | |
| 654 } | 649 } |
| 655 | 650 |
| 656 GrXferProcessor::OptFlags CustomXP::getOptimizations(const GrProcOptInfo& colorP
OI, | 651 GrXferProcessor::OptFlags CustomXP::onGetOptimizations(const GrProcOptInfo& colo
rPOI, |
| 657 const GrProcOptInfo& cove
ragePOI, | 652 const GrProcOptInfo& cove
ragePOI, |
| 658 bool doesStencilWrite, | 653 bool doesStencilWrite, |
| 659 GrColor* overrideColor, | 654 GrColor* overrideColor, |
| 660 const GrDrawTargetCaps& c
aps) { | 655 const GrDrawTargetCaps& c
aps) { |
| 661 /* | 656 /* |
| 662 Most the optimizations we do here are based on tweaking alpha for coverage. | 657 Most the optimizations we do here are based on tweaking alpha for coverage. |
| 663 | 658 |
| 664 The general SVG blend equation is defined in the spec as follows: | 659 The general SVG blend equation is defined in the spec as follows: |
| 665 | 660 |
| 666 Dca' = B(Sc, Dc) * Sa * Da + Y * Sca * (1-Da) + Z * Dca * (1-Sa) | 661 Dca' = B(Sc, Dc) * Sa * Da + Y * Sca * (1-Da) + Z * Dca * (1-Sa) |
| (...skipping 86 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 753 = f*Sa + Da - f*Sa * Da | 748 = f*Sa + Da - f*Sa * Da |
| 754 = blend(f*Sa, Da) | 749 = blend(f*Sa, Da) |
| 755 */ | 750 */ |
| 756 | 751 |
| 757 OptFlags flags = kNone_Opt; | 752 OptFlags flags = kNone_Opt; |
| 758 if (colorPOI.allStagesMultiplyInput()) { | 753 if (colorPOI.allStagesMultiplyInput()) { |
| 759 flags = flags | kCanTweakAlphaForCoverage_OptFlag; | 754 flags = flags | kCanTweakAlphaForCoverage_OptFlag; |
| 760 } | 755 } |
| 761 if (coveragePOI.isSolidWhite()) { | 756 if (coveragePOI.isSolidWhite()) { |
| 762 flags = flags | kIgnoreCoverage_OptFlag; | 757 flags = flags | kIgnoreCoverage_OptFlag; |
| 763 fHasCoverage = false; | |
| 764 } | 758 } |
| 765 if (caps.advancedBlendEquationSupport() && !coveragePOI.isFourChannelOutput(
)) { | 759 if (caps.advancedBlendEquationSupport() && !coveragePOI.isFourChannelOutput(
)) { |
| 766 // This blend mode can be implemented in hardware. | 760 // This blend mode can be implemented in hardware. |
| 767 fHWBlendEquation = hw_blend_equation(fMode); | 761 fHWBlendEquation = hw_blend_equation(fMode); |
| 768 } | 762 } |
| 769 return flags; | 763 return flags; |
| 770 } | 764 } |
| 771 | 765 |
| 772 bool CustomXP::onWillNeedXferBarrier(const GrRenderTarget* rt, | 766 bool CustomXP::onWillNeedXferBarrier(const GrRenderTarget* rt, |
| 773 const GrDrawTargetCaps& caps, | 767 const GrDrawTargetCaps& caps, |
| (...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 824 GR_DEFINE_XP_FACTORY_TEST(GrCustomXPFactory); | 818 GR_DEFINE_XP_FACTORY_TEST(GrCustomXPFactory); |
| 825 GrXPFactory* GrCustomXPFactory::TestCreate(SkRandom* rand, | 819 GrXPFactory* GrCustomXPFactory::TestCreate(SkRandom* rand, |
| 826 GrContext*, | 820 GrContext*, |
| 827 const GrDrawTargetCaps&, | 821 const GrDrawTargetCaps&, |
| 828 GrTexture*[]) { | 822 GrTexture*[]) { |
| 829 int mode = rand->nextRangeU(SkXfermode::kLastCoeffMode + 1, SkXfermode::kLas
tSeparableMode); | 823 int mode = rand->nextRangeU(SkXfermode::kLastCoeffMode + 1, SkXfermode::kLas
tSeparableMode); |
| 830 | 824 |
| 831 return SkNEW_ARGS(GrCustomXPFactory, (static_cast<SkXfermode::Mode>(mode))); | 825 return SkNEW_ARGS(GrCustomXPFactory, (static_cast<SkXfermode::Mode>(mode))); |
| 832 } | 826 } |
| 833 | 827 |
| OLD | NEW |