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 |