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 522 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
533 : INHERITED(dstTexture, true), | 533 : INHERITED(dstTexture, true), |
534 fMode(mode), | 534 fMode(mode), |
535 fHWBlendEquation(static_cast<GrBlendEquation>(-1)) { | 535 fHWBlendEquation(static_cast<GrBlendEquation>(-1)) { |
536 this->initClassID<CustomXP>(); | 536 this->initClassID<CustomXP>(); |
537 } | 537 } |
538 | 538 |
539 const char* name() const override { return "Custom Xfermode"; } | 539 const char* name() const override { return "Custom Xfermode"; } |
540 | 540 |
541 GrGLXferProcessor* createGLInstance() const override; | 541 GrGLXferProcessor* createGLInstance() const override; |
542 | 542 |
543 bool hasSecondaryOutput() const override { return false; } | |
544 | |
545 SkXfermode::Mode mode() const { return fMode; } | 543 SkXfermode::Mode mode() const { return fMode; } |
546 bool hasHWBlendEquation() const { return -1 != static_cast<int>(fHWBlendEqua
tion); } | 544 bool hasHWBlendEquation() const { return -1 != static_cast<int>(fHWBlendEqua
tion); } |
547 | 545 |
548 GrBlendEquation hwBlendEquation() const { | 546 GrBlendEquation hwBlendEquation() const { |
549 SkASSERT(this->hasHWBlendEquation()); | 547 SkASSERT(this->hasHWBlendEquation()); |
550 return fHWBlendEquation; | 548 return fHWBlendEquation; |
551 } | 549 } |
552 | 550 |
553 private: | 551 private: |
554 GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI, | 552 GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI, |
(...skipping 30 matching lines...) Expand all Loading... |
585 | 583 |
586 /////////////////////////////////////////////////////////////////////////////// | 584 /////////////////////////////////////////////////////////////////////////////// |
587 | 585 |
588 class GLCustomXP : public GrGLXferProcessor { | 586 class GLCustomXP : public GrGLXferProcessor { |
589 public: | 587 public: |
590 GLCustomXP(const GrXferProcessor&) {} | 588 GLCustomXP(const GrXferProcessor&) {} |
591 ~GLCustomXP() override {} | 589 ~GLCustomXP() override {} |
592 | 590 |
593 static void GenKey(const GrXferProcessor& p, const GrGLSLCaps& caps, GrProce
ssorKeyBuilder* b) { | 591 static void GenKey(const GrXferProcessor& p, const GrGLSLCaps& caps, GrProce
ssorKeyBuilder* b) { |
594 const CustomXP& xp = p.cast<CustomXP>(); | 592 const CustomXP& xp = p.cast<CustomXP>(); |
595 uint32_t key = xp.numTextures(); | 593 uint32_t key = 0; |
596 SkASSERT(key <= 1); | |
597 key |= xp.readsCoverage() << 1; | |
598 if (xp.hasHWBlendEquation()) { | 594 if (xp.hasHWBlendEquation()) { |
599 SkASSERT(caps.advBlendEqInteraction() > 0); // 0 will mean !xp.hasH
WBlendEquation(). | 595 SkASSERT(caps.advBlendEqInteraction() > 0); // 0 will mean !xp.hasH
WBlendEquation(). |
600 key |= caps.advBlendEqInteraction() << 2; | 596 key |= caps.advBlendEqInteraction(); |
| 597 key |= xp.readsCoverage() << 2; |
| 598 GR_STATIC_ASSERT(GrGLSLCaps::kLast_AdvBlendEqInteraction < 4); |
601 } | 599 } |
602 if (!xp.hasHWBlendEquation() || caps.mustEnableSpecificAdvBlendEqs()) { | 600 if (!xp.hasHWBlendEquation() || caps.mustEnableSpecificAdvBlendEqs()) { |
603 GR_STATIC_ASSERT(GrGLSLCaps::kLast_AdvBlendEqInteraction < 4); | 601 key |= xp.mode() << 3; |
604 key |= xp.mode() << 4; | |
605 } | 602 } |
606 b->add32(key); | 603 b->add32(key); |
607 } | 604 } |
608 | 605 |
609 private: | 606 private: |
610 void onEmitCode(const EmitArgs& args) override { | 607 void emitOutputsForBlendState(const EmitArgs& args) override { |
611 const CustomXP& xp = args.fXP.cast<CustomXP>(); | 608 const CustomXP& xp = args.fXP.cast<CustomXP>(); |
| 609 SkASSERT(xp.hasHWBlendEquation()); |
| 610 |
612 GrGLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); | 611 GrGLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); |
| 612 fsBuilder->enableAdvancedBlendEquationIfNeeded(xp.hwBlendEquation()); |
613 | 613 |
614 if (xp.hasHWBlendEquation()) { | 614 // Apply coverage by multiplying it into the src color before blending. |
615 // The blend mode will be implemented in hardware; only output the s
rc color. | 615 // (See onGetOptimizations()) |
616 fsBuilder->enableAdvancedBlendEquationIfNeeded(xp.hwBlendEquation())
; | 616 if (xp.readsCoverage()) { |
617 if (xp.readsCoverage()) { | 617 fsBuilder->codeAppendf("%s = %s * %s;", |
618 // Do coverage modulation by multiplying it into the src color b
efore blending. | 618 args.fOutputPrimary, args.fInputCoverage, arg
s.fInputColor); |
619 // (See getOptimizations()) | |
620 fsBuilder->codeAppendf("%s = %s * %s;", | |
621 args.fOutputPrimary, args.fInputCoverage,
args.fInputColor); | |
622 } else { | |
623 fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fIn
putColor); | |
624 } | |
625 } else { | 619 } else { |
626 const char* dstColor = fsBuilder->dstColor(); | 620 fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fInputC
olor); |
627 emit_custom_xfermode_code(xp.mode(), fsBuilder, args.fOutputPrimary,
args.fInputColor, | |
628 dstColor); | |
629 if (xp.readsCoverage()) { | |
630 fsBuilder->codeAppendf("%s = %s * %s + (vec4(1.0) - %s) * %s;", | |
631 args.fOutputPrimary, args.fOutputPrimary, | |
632 args.fInputCoverage, args.fInputCoverage,
dstColor); | |
633 } | |
634 } | 621 } |
635 } | 622 } |
636 | 623 |
| 624 void emitBlendCodeForDstRead(GrGLXPBuilder* pb, const char* srcColor, const
char* dstColor, |
| 625 const char* outColor, const GrXferProcessor& pr
oc) override { |
| 626 const CustomXP& xp = proc.cast<CustomXP>(); |
| 627 SkASSERT(!xp.hasHWBlendEquation()); |
| 628 |
| 629 GrGLXPFragmentBuilder* fsBuilder = pb->getFragmentShaderBuilder(); |
| 630 emit_custom_xfermode_code(xp.mode(), fsBuilder, outColor, srcColor, dstC
olor); |
| 631 } |
| 632 |
637 void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) overri
de {} | 633 void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) overri
de {} |
638 | 634 |
639 typedef GrGLFragmentProcessor INHERITED; | 635 typedef GrGLFragmentProcessor INHERITED; |
640 }; | 636 }; |
641 | 637 |
642 /////////////////////////////////////////////////////////////////////////////// | 638 /////////////////////////////////////////////////////////////////////////////// |
643 | 639 |
644 void CustomXP::onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder
* b) const { | 640 void CustomXP::onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder
* b) const { |
645 GLCustomXP::GenKey(*this, caps, b); | 641 GLCustomXP::GenKey(*this, caps, b); |
646 } | 642 } |
(...skipping 106 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
753 = f*Sa + f*Da - f*Sa * Da + Da - f*Da | 749 = f*Sa + f*Da - f*Sa * Da + Da - f*Da |
754 = f*Sa - f*Sa * Da + Da | 750 = f*Sa - f*Sa * Da + Da |
755 = f*Sa + Da - f*Sa * Da | 751 = f*Sa + Da - f*Sa * Da |
756 = blend(f*Sa, Da) | 752 = blend(f*Sa, Da) |
757 */ | 753 */ |
758 | 754 |
759 OptFlags flags = kNone_Opt; | 755 OptFlags flags = kNone_Opt; |
760 if (colorPOI.allStagesMultiplyInput()) { | 756 if (colorPOI.allStagesMultiplyInput()) { |
761 flags |= kCanTweakAlphaForCoverage_OptFlag; | 757 flags |= kCanTweakAlphaForCoverage_OptFlag; |
762 } | 758 } |
763 if (coveragePOI.isSolidWhite()) { | 759 if (this->hasHWBlendEquation() && coveragePOI.isSolidWhite()) { |
764 flags |= kIgnoreCoverage_OptFlag; | 760 flags |= kIgnoreCoverage_OptFlag; |
765 } | 761 } |
766 return flags; | 762 return flags; |
767 } | 763 } |
768 | 764 |
769 bool CustomXP::onWillNeedXferBarrier(const GrRenderTarget* rt, | 765 bool CustomXP::onWillNeedXferBarrier(const GrRenderTarget* rt, |
770 const GrCaps& caps, | 766 const GrCaps& caps, |
771 GrXferBarrierType* outBarrierType) const { | 767 GrXferBarrierType* outBarrierType) const { |
772 if (this->hasHWBlendEquation() && !caps.advancedCoherentBlendEquationSupport
()) { | 768 if (this->hasHWBlendEquation() && !caps.advancedCoherentBlendEquationSupport
()) { |
773 *outBarrierType = kBlend_GrXferBarrierType; | 769 *outBarrierType = kBlend_GrXferBarrierType; |
(...skipping 44 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
818 GR_DEFINE_XP_FACTORY_TEST(GrCustomXPFactory); | 814 GR_DEFINE_XP_FACTORY_TEST(GrCustomXPFactory); |
819 GrXPFactory* GrCustomXPFactory::TestCreate(SkRandom* rand, | 815 GrXPFactory* GrCustomXPFactory::TestCreate(SkRandom* rand, |
820 GrContext*, | 816 GrContext*, |
821 const GrCaps&, | 817 const GrCaps&, |
822 GrTexture*[]) { | 818 GrTexture*[]) { |
823 int mode = rand->nextRangeU(SkXfermode::kLastCoeffMode + 1, SkXfermode::kLas
tSeparableMode); | 819 int mode = rand->nextRangeU(SkXfermode::kLastCoeffMode + 1, SkXfermode::kLas
tSeparableMode); |
824 | 820 |
825 return SkNEW_ARGS(GrCustomXPFactory, (static_cast<SkXfermode::Mode>(mode))); | 821 return SkNEW_ARGS(GrCustomXPFactory, (static_cast<SkXfermode::Mode>(mode))); |
826 } | 822 } |
827 | 823 |
OLD | NEW |