| 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 33 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 Loading... |
| 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 |
| OLD | NEW |