Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(19)

Side by Side Diff: src/gpu/effects/GrCustomXfermode.cpp

Issue 1161913003: Opt for advanced blend at creation time in CrCustomXfermode (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « no previous file | src/gpu/effects/GrCustomXfermodePriv.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after
44 GR_STATIC_ASSERT(kDifference_GrBlendEquation == SkXfermode::kDifference_Mode + kOffset); 44 GR_STATIC_ASSERT(kDifference_GrBlendEquation == SkXfermode::kDifference_Mode + kOffset);
45 GR_STATIC_ASSERT(kExclusion_GrBlendEquation == SkXfermode::kExclusion_Mode + kOffset); 45 GR_STATIC_ASSERT(kExclusion_GrBlendEquation == SkXfermode::kExclusion_Mode + kOffset);
46 GR_STATIC_ASSERT(kMultiply_GrBlendEquation == SkXfermode::kMultiply_Mode + k Offset); 46 GR_STATIC_ASSERT(kMultiply_GrBlendEquation == SkXfermode::kMultiply_Mode + k Offset);
47 GR_STATIC_ASSERT(kHSLHue_GrBlendEquation == SkXfermode::kHue_Mode + kOffset) ; 47 GR_STATIC_ASSERT(kHSLHue_GrBlendEquation == SkXfermode::kHue_Mode + kOffset) ;
48 GR_STATIC_ASSERT(kHSLSaturation_GrBlendEquation == SkXfermode::kSaturation_M ode + kOffset); 48 GR_STATIC_ASSERT(kHSLSaturation_GrBlendEquation == SkXfermode::kSaturation_M ode + kOffset);
49 GR_STATIC_ASSERT(kHSLColor_GrBlendEquation == SkXfermode::kColor_Mode + kOff set); 49 GR_STATIC_ASSERT(kHSLColor_GrBlendEquation == SkXfermode::kColor_Mode + kOff set);
50 GR_STATIC_ASSERT(kHSLLuminosity_GrBlendEquation == SkXfermode::kLuminosity_M ode + kOffset); 50 GR_STATIC_ASSERT(kHSLLuminosity_GrBlendEquation == SkXfermode::kLuminosity_M ode + kOffset);
51 GR_STATIC_ASSERT(kGrBlendEquationCnt == SkXfermode::kLastMode + 1 + kOffset) ; 51 GR_STATIC_ASSERT(kGrBlendEquationCnt == SkXfermode::kLastMode + 1 + kOffset) ;
52 } 52 }
53 53
54 static bool can_use_hw_blend_equation(const GrProcOptInfo& coveragePOI, const Gr Caps& caps) {
55 if (!caps.advancedBlendEquationSupport()) {
56 return false;
57 }
58 if (coveragePOI.isFourChannelOutput()) {
59 return false; // LCD coverage must be applied after the blend equation.
60 }
61 return true;
62 }
63
54 static void hard_light(GrGLFragmentBuilder* fsBuilder, 64 static void hard_light(GrGLFragmentBuilder* fsBuilder,
55 const char* final, 65 const char* final,
56 const char* src, 66 const char* src,
57 const char* dst) { 67 const char* dst) {
58 static const char kComponents[] = {'r', 'g', 'b'}; 68 static const char kComponents[] = {'r', 'g', 'b'};
59 for (size_t i = 0; i < SK_ARRAY_COUNT(kComponents); ++i) { 69 for (size_t i = 0; i < SK_ARRAY_COUNT(kComponents); ++i) {
60 char component = kComponents[i]; 70 char component = kComponents[i];
61 fsBuilder->codeAppendf("if (2.0 * %s.%c <= %s.a) {", src, component, src ); 71 fsBuilder->codeAppendf("if (2.0 * %s.%c <= %s.a) {", src, component, src );
62 fsBuilder->codeAppendf("%s.%c = 2.0 * %s.%c * %s.%c;", 72 fsBuilder->codeAppendf("%s.%c = 2.0 * %s.%c * %s.%c;",
63 final, component, src, component, dst, component) ; 73 final, component, src, component, dst, component) ;
(...skipping 437 matching lines...) Expand 10 before | Expand all | Expand 10 after
501 511
502 return SkNEW_ARGS(GrCustomXferFP, (static_cast<SkXfermode::Mode>(mode), text ures[0])); 512 return SkNEW_ARGS(GrCustomXferFP, (static_cast<SkXfermode::Mode>(mode), text ures[0]));
503 } 513 }
504 514
505 /////////////////////////////////////////////////////////////////////////////// 515 ///////////////////////////////////////////////////////////////////////////////
506 // Xfer Processor 516 // Xfer Processor
507 /////////////////////////////////////////////////////////////////////////////// 517 ///////////////////////////////////////////////////////////////////////////////
508 518
509 class CustomXP : public GrXferProcessor { 519 class CustomXP : public GrXferProcessor {
510 public: 520 public:
511 static GrXferProcessor* Create(SkXfermode::Mode mode, const DstTexture* dstT exture, 521 CustomXP(SkXfermode::Mode mode, GrBlendEquation hwBlendEquation)
512 bool willReadDstColor) { 522 : fMode(mode),
513 if (!GrCustomXfermode::IsSupportedMode(mode)) { 523 fHWBlendEquation(hwBlendEquation) {
514 return NULL; 524 this->initClassID<CustomXP>();
515 } else {
516 return SkNEW_ARGS(CustomXP, (mode, dstTexture, willReadDstColor));
517 }
518 } 525 }
519 526
520 ~CustomXP() override {}; 527 CustomXP(SkXfermode::Mode mode, const DstTexture* dstTexture)
528 : INHERITED(dstTexture, true),
529 fMode(mode),
530 fHWBlendEquation(static_cast<GrBlendEquation>(-1)) {
531 this->initClassID<CustomXP>();
532 }
521 533
522 const char* name() const override { return "Custom Xfermode"; } 534 const char* name() const override { return "Custom Xfermode"; }
523 535
524 GrGLXferProcessor* createGLInstance() const override; 536 GrGLXferProcessor* createGLInstance() const override;
525 537
526 bool hasSecondaryOutput() const override { return false; } 538 bool hasSecondaryOutput() const override { return false; }
527 539
528 SkXfermode::Mode mode() const { return fMode; } 540 SkXfermode::Mode mode() const { return fMode; }
529 bool hasHWBlendEquation() const { return -1 != static_cast<int>(fHWBlendEqua tion); } 541 bool hasHWBlendEquation() const { return -1 != static_cast<int>(fHWBlendEqua tion); }
530 542
531 GrBlendEquation hwBlendEquation() const { 543 GrBlendEquation hwBlendEquation() const {
532 SkASSERT(this->hasHWBlendEquation()); 544 SkASSERT(this->hasHWBlendEquation());
533 return fHWBlendEquation; 545 return fHWBlendEquation;
534 } 546 }
535 547
536 private: 548 private:
537 CustomXP(SkXfermode::Mode mode, const DstTexture*, bool willReadDstColor);
538
539 GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI, 549 GrXferProcessor::OptFlags onGetOptimizations(const GrProcOptInfo& colorPOI,
540 const GrProcOptInfo& coveragePO I, 550 const GrProcOptInfo& coveragePO I,
541 bool doesStencilWrite, 551 bool doesStencilWrite,
542 GrColor* overrideColor, 552 GrColor* overrideColor,
543 const GrCaps& caps) override; 553 const GrCaps& caps) override;
544 554
545 void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) c onst override; 555 void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) c onst override;
546 556
547 bool onWillNeedXferBarrier(const GrRenderTarget* rt, 557 bool onWillNeedXferBarrier(const GrRenderTarget* rt,
548 const GrCaps& caps, 558 const GrCaps& caps,
549 GrXferBarrierType* outBarrierType) const override ; 559 GrXferBarrierType* outBarrierType) const override ;
550 560
551 void onGetBlendInfo(BlendInfo*) const override; 561 void onGetBlendInfo(BlendInfo*) const override;
552 562
553 bool onIsEqual(const GrXferProcessor& xpBase) const override; 563 bool onIsEqual(const GrXferProcessor& xpBase) const override;
554 564
555 SkXfermode::Mode fMode; 565 const SkXfermode::Mode fMode;
556 GrBlendEquation fHWBlendEquation; 566 const GrBlendEquation fHWBlendEquation;
557 567
558 typedef GrXferProcessor INHERITED; 568 typedef GrXferProcessor INHERITED;
559 }; 569 };
560 570
561 /////////////////////////////////////////////////////////////////////////////// 571 ///////////////////////////////////////////////////////////////////////////////
562 572
563 GrXPFactory* GrCustomXfermode::CreateXPFactory(SkXfermode::Mode mode) { 573 GrXPFactory* GrCustomXfermode::CreateXPFactory(SkXfermode::Mode mode) {
564 if (!GrCustomXfermode::IsSupportedMode(mode)) { 574 if (!GrCustomXfermode::IsSupportedMode(mode)) {
565 return NULL; 575 return NULL;
566 } else { 576 } else {
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
619 } 629 }
620 } 630 }
621 631
622 void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) overri de {} 632 void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) overri de {}
623 633
624 typedef GrGLFragmentProcessor INHERITED; 634 typedef GrGLFragmentProcessor INHERITED;
625 }; 635 };
626 636
627 /////////////////////////////////////////////////////////////////////////////// 637 ///////////////////////////////////////////////////////////////////////////////
628 638
629 CustomXP::CustomXP(SkXfermode::Mode mode, const DstTexture* dstTexture, bool wil lReadDstColor)
630 : INHERITED(dstTexture, willReadDstColor),
631 fMode(mode),
632 fHWBlendEquation(static_cast<GrBlendEquation>(-1)) {
633 this->initClassID<CustomXP>();
634 }
635
636 void CustomXP::onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder * b) const { 639 void CustomXP::onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder * b) const {
637 GLCustomXP::GenKey(*this, caps, b); 640 GLCustomXP::GenKey(*this, caps, b);
638 } 641 }
639 642
640 GrGLXferProcessor* CustomXP::createGLInstance() const { 643 GrGLXferProcessor* CustomXP::createGLInstance() const {
641 SkASSERT(this->willReadDstColor() != this->hasHWBlendEquation()); 644 SkASSERT(this->willReadDstColor() != this->hasHWBlendEquation());
642 return SkNEW_ARGS(GLCustomXP, (*this)); 645 return SkNEW_ARGS(GLCustomXP, (*this));
643 } 646 }
644 647
645 bool CustomXP::onIsEqual(const GrXferProcessor& other) const { 648 bool CustomXP::onIsEqual(const GrXferProcessor& other) const {
(...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after
748 = blend(f*Sa, Da) 751 = blend(f*Sa, Da)
749 */ 752 */
750 753
751 OptFlags flags = kNone_Opt; 754 OptFlags flags = kNone_Opt;
752 if (colorPOI.allStagesMultiplyInput()) { 755 if (colorPOI.allStagesMultiplyInput()) {
753 flags |= kCanTweakAlphaForCoverage_OptFlag; 756 flags |= kCanTweakAlphaForCoverage_OptFlag;
754 } 757 }
755 if (coveragePOI.isSolidWhite()) { 758 if (coveragePOI.isSolidWhite()) {
756 flags |= kIgnoreCoverage_OptFlag; 759 flags |= kIgnoreCoverage_OptFlag;
757 } 760 }
758 if (caps.advancedBlendEquationSupport() && !coveragePOI.isFourChannelOutput( )) {
759 // This blend mode can be implemented in hardware.
760 fHWBlendEquation = hw_blend_equation(fMode);
761 }
762 return flags; 761 return flags;
763 } 762 }
764 763
765 bool CustomXP::onWillNeedXferBarrier(const GrRenderTarget* rt, 764 bool CustomXP::onWillNeedXferBarrier(const GrRenderTarget* rt,
766 const GrCaps& caps, 765 const GrCaps& caps,
767 GrXferBarrierType* outBarrierType) const { 766 GrXferBarrierType* outBarrierType) const {
768 if (this->hasHWBlendEquation() && !caps.advancedCoherentBlendEquationSupport ()) { 767 if (this->hasHWBlendEquation() && !caps.advancedCoherentBlendEquationSupport ()) {
769 *outBarrierType = kBlend_GrXferBarrierType; 768 *outBarrierType = kBlend_GrXferBarrierType;
770 return true; 769 return true;
771 } 770 }
772 return false; 771 return false;
773 } 772 }
774 773
775 void CustomXP::onGetBlendInfo(BlendInfo* blendInfo) const { 774 void CustomXP::onGetBlendInfo(BlendInfo* blendInfo) const {
776 if (this->hasHWBlendEquation()) { 775 if (this->hasHWBlendEquation()) {
777 blendInfo->fEquation = this->hwBlendEquation(); 776 blendInfo->fEquation = this->hwBlendEquation();
778 } 777 }
779 } 778 }
780 779
781 /////////////////////////////////////////////////////////////////////////////// 780 ///////////////////////////////////////////////////////////////////////////////
782 781
783 GrCustomXPFactory::GrCustomXPFactory(SkXfermode::Mode mode) 782 GrCustomXPFactory::GrCustomXPFactory(SkXfermode::Mode mode)
784 : fMode(mode) { 783 : fMode(mode),
784 fHWBlendEquation(hw_blend_equation(mode)) {
785 SkASSERT(GrCustomXfermode::IsSupportedMode(fMode));
785 this->initClassID<GrCustomXPFactory>(); 786 this->initClassID<GrCustomXPFactory>();
786 } 787 }
787 788
788 GrXferProcessor* 789 GrXferProcessor*
789 GrCustomXPFactory::onCreateXferProcessor(const GrCaps& caps, 790 GrCustomXPFactory::onCreateXferProcessor(const GrCaps& caps,
790 const GrProcOptInfo& colorPOI, 791 const GrProcOptInfo& colorPOI,
791 const GrProcOptInfo& coveragePOI, 792 const GrProcOptInfo& coveragePOI,
792 const DstTexture* dstTexture) const { 793 const DstTexture* dstTexture) const {
793 return CustomXP::Create(fMode, dstTexture, this->willReadDstColor(caps, colo rPOI, coveragePOI)); 794 if (can_use_hw_blend_equation(coveragePOI, caps)) {
795 SkASSERT(!dstTexture || !dstTexture->texture());
796 return SkNEW_ARGS(CustomXP, (fMode, fHWBlendEquation));
797 }
798 return SkNEW_ARGS(CustomXP, (fMode, dstTexture));
794 } 799 }
795 800
796 bool GrCustomXPFactory::willReadDstColor(const GrCaps& caps, 801 bool GrCustomXPFactory::willReadDstColor(const GrCaps& caps,
797 const GrProcOptInfo& colorPOI, 802 const GrProcOptInfo& colorPOI,
798 const GrProcOptInfo& coveragePOI) const { 803 const GrProcOptInfo& coveragePOI) const {
799 if (!caps.advancedBlendEquationSupport()) { 804 return !can_use_hw_blend_equation(coveragePOI, caps);
800 // No hardware support for advanced blend equations; we will need to do it in the shader.
801 return true;
802 }
803 if (coveragePOI.isFourChannelOutput()) {
804 // Advanced blend equations can't tweak alpha for RGB coverage.
805 return true;
806 }
807 return false;
808 } 805 }
809 806
810 void GrCustomXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorPOI, 807 void GrCustomXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorPOI,
811 InvariantBlendedColor* blendedC olor) const { 808 InvariantBlendedColor* blendedC olor) const {
812 blendedColor->fWillBlendWithDst = true; 809 blendedColor->fWillBlendWithDst = true;
813 blendedColor->fKnownColorFlags = kNone_GrColorComponentFlags; 810 blendedColor->fKnownColorFlags = kNone_GrColorComponentFlags;
814 } 811 }
815 812
816 GR_DEFINE_XP_FACTORY_TEST(GrCustomXPFactory); 813 GR_DEFINE_XP_FACTORY_TEST(GrCustomXPFactory);
817 GrXPFactory* GrCustomXPFactory::TestCreate(SkRandom* rand, 814 GrXPFactory* GrCustomXPFactory::TestCreate(SkRandom* rand,
818 GrContext*, 815 GrContext*,
819 const GrCaps&, 816 const GrCaps&,
820 GrTexture*[]) { 817 GrTexture*[]) {
821 int mode = rand->nextRangeU(SkXfermode::kLastCoeffMode + 1, SkXfermode::kLas tSeparableMode); 818 int mode = rand->nextRangeU(SkXfermode::kLastCoeffMode + 1, SkXfermode::kLas tSeparableMode);
822 819
823 return SkNEW_ARGS(GrCustomXPFactory, (static_cast<SkXfermode::Mode>(mode))); 820 return SkNEW_ARGS(GrCustomXPFactory, (static_cast<SkXfermode::Mode>(mode)));
824 } 821 }
825 822
OLDNEW
« no previous file with comments | « no previous file | src/gpu/effects/GrCustomXfermodePriv.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698