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

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

Issue 1037123003: Implement support for KHR_blend_equation_advanced (Closed) Base URL: https://skia.googlesource.com/skia.git@upload_zzz2_barriers
Patch Set: Compiler warning Created 5 years, 7 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 | « src/gpu/GrXferProcessor.cpp ('k') | 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
11 #include "GrCoordTransform.h" 11 #include "GrCoordTransform.h"
12 #include "GrContext.h" 12 #include "GrContext.h"
13 #include "GrFragmentProcessor.h" 13 #include "GrFragmentProcessor.h"
14 #include "GrInvariantOutput.h" 14 #include "GrInvariantOutput.h"
15 #include "GrProcessor.h" 15 #include "GrProcessor.h"
16 #include "GrTexture.h" 16 #include "GrTexture.h"
17 #include "GrTextureAccess.h" 17 #include "GrTextureAccess.h"
18 #include "SkXfermode.h" 18 #include "SkXfermode.h"
19 #include "gl/GrGLCaps.h" 19 #include "gl/GrGLCaps.h"
20 #include "gl/GrGLGpu.h"
20 #include "gl/GrGLProcessor.h" 21 #include "gl/GrGLProcessor.h"
21 #include "gl/GrGLProgramDataManager.h" 22 #include "gl/GrGLProgramDataManager.h"
22 #include "gl/builders/GrGLProgramBuilder.h" 23 #include "gl/builders/GrGLProgramBuilder.h"
23 24
24 bool GrCustomXfermode::IsSupportedMode(SkXfermode::Mode mode) { 25 bool GrCustomXfermode::IsSupportedMode(SkXfermode::Mode mode) {
25 return mode > SkXfermode::kLastCoeffMode && mode <= SkXfermode::kLastMode; 26 return mode > SkXfermode::kLastCoeffMode && mode <= SkXfermode::kLastMode;
26 } 27 }
27 28
28 /////////////////////////////////////////////////////////////////////////////// 29 ///////////////////////////////////////////////////////////////////////////////
29 // Static helpers 30 // Static helpers
30 /////////////////////////////////////////////////////////////////////////////// 31 ///////////////////////////////////////////////////////////////////////////////
31 32
33 static GrBlendEquation hw_blend_equation(SkXfermode::Mode mode) {
34 enum { kOffset = kOverlay_GrBlendEquation - SkXfermode::kOverlay_Mode };
35 return static_cast<GrBlendEquation>(mode + kOffset);
36
37 GR_STATIC_ASSERT(kOverlay_GrBlendEquation == SkXfermode::kOverlay_Mode + kOf fset);
38 GR_STATIC_ASSERT(kDarken_GrBlendEquation == SkXfermode::kDarken_Mode + kOffs et);
39 GR_STATIC_ASSERT(kLighten_GrBlendEquation == SkXfermode::kLighten_Mode + kOf fset);
40 GR_STATIC_ASSERT(kColorDodge_GrBlendEquation == SkXfermode::kColorDodge_Mode + kOffset);
41 GR_STATIC_ASSERT(kColorBurn_GrBlendEquation == SkXfermode::kColorBurn_Mode + kOffset);
42 GR_STATIC_ASSERT(kHardLight_GrBlendEquation == SkXfermode::kHardLight_Mode + kOffset);
43 GR_STATIC_ASSERT(kSoftLight_GrBlendEquation == SkXfermode::kSoftLight_Mode + kOffset);
44 GR_STATIC_ASSERT(kDifference_GrBlendEquation == SkXfermode::kDifference_Mode + kOffset);
45 GR_STATIC_ASSERT(kExclusion_GrBlendEquation == SkXfermode::kExclusion_Mode + kOffset);
46 GR_STATIC_ASSERT(kMultiply_GrBlendEquation == SkXfermode::kMultiply_Mode + k Offset);
47 GR_STATIC_ASSERT(kHSLHue_GrBlendEquation == SkXfermode::kHue_Mode + kOffset) ;
48 GR_STATIC_ASSERT(kHSLSaturation_GrBlendEquation == SkXfermode::kSaturation_M ode + kOffset);
49 GR_STATIC_ASSERT(kHSLColor_GrBlendEquation == SkXfermode::kColor_Mode + kOff set);
50 GR_STATIC_ASSERT(kHSLLuminosity_GrBlendEquation == SkXfermode::kLuminosity_M ode + kOffset);
51 GR_STATIC_ASSERT(kTotalGrBlendEquationCount == SkXfermode::kLastMode + 1 + k Offset);
52 }
53
32 static void hard_light(GrGLFragmentBuilder* fsBuilder, 54 static void hard_light(GrGLFragmentBuilder* fsBuilder,
33 const char* final, 55 const char* final,
34 const char* src, 56 const char* src,
35 const char* dst) { 57 const char* dst) {
36 static const char kComponents[] = {'r', 'g', 'b'}; 58 static const char kComponents[] = {'r', 'g', 'b'};
37 for (size_t i = 0; i < SK_ARRAY_COUNT(kComponents); ++i) { 59 for (size_t i = 0; i < SK_ARRAY_COUNT(kComponents); ++i) {
38 char component = kComponents[i]; 60 char component = kComponents[i];
39 fsBuilder->codeAppendf("if (2.0 * %s.%c <= %s.a) {", src, component, src ); 61 fsBuilder->codeAppendf("if (2.0 * %s.%c <= %s.a) {", src, component, src );
40 fsBuilder->codeAppendf("%s.%c = 2.0 * %s.%c * %s.%c;", 62 fsBuilder->codeAppendf("%s.%c = 2.0 * %s.%c * %s.%c;",
41 final, component, src, component, dst, component) ; 63 final, component, src, component, dst, component) ;
(...skipping 461 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 525
504 bool hasSecondaryOutput() const override { return false; } 526 bool hasSecondaryOutput() const override { return false; }
505 527
506 GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI, 528 GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI,
507 const GrProcOptInfo& coveragePOI, 529 const GrProcOptInfo& coveragePOI,
508 bool doesStencilWrite, 530 bool doesStencilWrite,
509 GrColor* overrideColor, 531 GrColor* overrideColor,
510 const GrDrawTargetCaps& caps) ove rride; 532 const GrDrawTargetCaps& caps) ove rride;
511 533
512 SkXfermode::Mode mode() const { return fMode; } 534 SkXfermode::Mode mode() const { return fMode; }
535 bool hasCoverage() const { return fHasCoverage; }
536 bool hasHWBlendEquation() const { return kInvalid_GrBlendEquation != fHWBlen dEquation; }
537
538 GrBlendEquation hwBlendEquation() const {
539 SkASSERT(this->hasHWBlendEquation());
540 return fHWBlendEquation;
541 }
513 542
514 private: 543 private:
515 CustomXP(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy, bool wi llReadDstColor); 544 CustomXP(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy, bool wi llReadDstColor);
516 545
517 void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) c onst override; 546 void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) c onst override;
518 547
548 bool onWillNeedXferBarrier(const GrRenderTarget* rt,
549 const GrDrawTargetCaps& caps,
550 GrXferBarrierType* outBarrierType) const override ;
551
552 void onGetBlendInfo(BlendInfo*) const override;
553
519 bool onIsEqual(const GrXferProcessor& xpBase) const override; 554 bool onIsEqual(const GrXferProcessor& xpBase) const override;
520 555
521 SkXfermode::Mode fMode; 556 SkXfermode::Mode fMode;
557 bool fHasCoverage;
558 GrBlendEquation fHWBlendEquation;
522 559
523 typedef GrXferProcessor INHERITED; 560 typedef GrXferProcessor INHERITED;
524 }; 561 };
525 562
526 /////////////////////////////////////////////////////////////////////////////// 563 ///////////////////////////////////////////////////////////////////////////////
527 564
528 GrXPFactory* GrCustomXfermode::CreateXPFactory(SkXfermode::Mode mode) { 565 GrXPFactory* GrCustomXfermode::CreateXPFactory(SkXfermode::Mode mode) {
529 if (!GrCustomXfermode::IsSupportedMode(mode)) { 566 if (!GrCustomXfermode::IsSupportedMode(mode)) {
530 return NULL; 567 return NULL;
531 } else { 568 } else {
532 return SkNEW_ARGS(GrCustomXPFactory, (mode)); 569 return SkNEW_ARGS(GrCustomXPFactory, (mode));
533 } 570 }
534 } 571 }
535 572
536 /////////////////////////////////////////////////////////////////////////////// 573 ///////////////////////////////////////////////////////////////////////////////
537 574
538 class GLCustomXP : public GrGLXferProcessor { 575 class GLCustomXP : public GrGLXferProcessor {
539 public: 576 public:
540 GLCustomXP(const GrXferProcessor&) {} 577 GLCustomXP(const GrXferProcessor&) {}
541 ~GLCustomXP() override {} 578 ~GLCustomXP() override {}
542 579
543 static void GenKey(const GrXferProcessor& proc, const GrGLSLCaps&, GrProcess orKeyBuilder* b) { 580 static void GenKey(const GrXferProcessor& p, const GrGLSLCaps& caps, GrProce ssorKeyBuilder* b) {
544 uint32_t key = proc.numTextures(); 581 const CustomXP& xp = p.cast<CustomXP>();
582 uint32_t key = xp.numTextures();
545 SkASSERT(key <= 1); 583 SkASSERT(key <= 1);
546 key |= proc.cast<CustomXP>().mode() << 1; 584 key |= xp.hasCoverage() << 1;
585 if (xp.hasHWBlendEquation()) {
586 SkASSERT(caps.advBlendEqInteraction() > 0); // 0 will mean !xp.hasH WBlendEquation().
587 key |= caps.advBlendEqInteraction() << 2;
588 }
589 if (!xp.hasHWBlendEquation() || caps.mustEnableSpecificAdvBlendEqs()) {
590 GR_STATIC_ASSERT(GrGLSLCaps::kLast_AdvBlendEqInteraction < 4);
591 key |= xp.mode() << 4;
592 }
547 b->add32(key); 593 b->add32(key);
548 } 594 }
549 595
550 private: 596 private:
551 void onEmitCode(const EmitArgs& args) override { 597 void onEmitCode(const EmitArgs& args) override {
552 SkXfermode::Mode mode = args.fXP.cast<CustomXP>().mode(); 598 const CustomXP& xp = args.fXP.cast<CustomXP>();
553 GrGLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); 599 GrGLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
554 const char* dstColor = fsBuilder->dstColor();
555 600
556 emit_custom_xfermode_code(mode, fsBuilder, args.fOutputPrimary, args.fIn putColor, dstColor); 601 if (xp.hasHWBlendEquation()) {
557 602 // The blend mode will be implemented in hardware; only output the s rc color.
558 fsBuilder->codeAppendf("%s = %s * %s + (vec4(1.0) - %s) * %s;", 603 fsBuilder->enableAdvancedBlendEquationIfNeeded(xp.hwBlendEquation()) ;
559 args.fOutputPrimary, args.fOutputPrimary, args.fI nputCoverage, 604 if (xp.hasCoverage()) {
560 args.fInputCoverage, dstColor); 605 // Do coverage modulation by multiplying it into the src color b efore blending.
606 // (See getOptimizations())
607 fsBuilder->codeAppendf("%s = %s * %s;",
608 args.fOutputPrimary, args.fInputCoverage, args.fInputColor);
609 } else {
610 fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fIn putColor);
611 }
612 } else {
613 const char* dstColor = fsBuilder->dstColor();
614 emit_custom_xfermode_code(xp.mode(), fsBuilder, args.fOutputPrimary, args.fInputColor,
615 dstColor);
616 if (xp.hasCoverage()) {
617 fsBuilder->codeAppendf("%s = %s * %s + (vec4(1.0) - %s) * %s;",
618 args.fOutputPrimary, args.fOutputPrimary,
619 args.fInputCoverage, args.fInputCoverage, dstColor);
620 }
621 }
561 } 622 }
562 623
563 void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) overri de {} 624 void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) overri de {}
564 625
565 typedef GrGLFragmentProcessor INHERITED; 626 typedef GrGLFragmentProcessor INHERITED;
566 }; 627 };
567 628
568 /////////////////////////////////////////////////////////////////////////////// 629 ///////////////////////////////////////////////////////////////////////////////
569 630
570 CustomXP::CustomXP(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy, 631 CustomXP::CustomXP(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy,
571 bool willReadDstColor) 632 bool willReadDstColor)
572 : INHERITED(dstCopy, willReadDstColor), fMode(mode) { 633 : INHERITED(dstCopy, willReadDstColor),
634 fMode(mode),
635 fHasCoverage(true),
636 fHWBlendEquation(kInvalid_GrBlendEquation) {
573 this->initClassID<CustomXP>(); 637 this->initClassID<CustomXP>();
574 } 638 }
575 639
576 void CustomXP::onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder * b) const { 640 void CustomXP::onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder * b) const {
577 GLCustomXP::GenKey(*this, caps, b); 641 GLCustomXP::GenKey(*this, caps, b);
578 } 642 }
579 643
580 GrGLXferProcessor* CustomXP::createGLInstance() const { 644 GrGLXferProcessor* CustomXP::createGLInstance() const {
645 SkASSERT(this->willReadDstColor() != this->hasHWBlendEquation());
581 return SkNEW_ARGS(GLCustomXP, (*this)); 646 return SkNEW_ARGS(GLCustomXP, (*this));
582 } 647 }
583 648
584 bool CustomXP::onIsEqual(const GrXferProcessor& other) const { 649 bool CustomXP::onIsEqual(const GrXferProcessor& other) const {
585 const CustomXP& s = other.cast<CustomXP>(); 650 const CustomXP& s = other.cast<CustomXP>();
586 return fMode == s.fMode; 651 return fMode == s.fMode &&
652 fHasCoverage == s.fHasCoverage &&
653 fHWBlendEquation == s.fHWBlendEquation;
587 } 654 }
588 655
589 GrXferProcessor::OptFlags CustomXP::getOptimizations(const GrProcOptInfo& colorP OI, 656 GrXferProcessor::OptFlags CustomXP::getOptimizations(const GrProcOptInfo& colorP OI,
590 const GrProcOptInfo& cove ragePOI, 657 const GrProcOptInfo& cove ragePOI,
591 bool doesStencilWrite, 658 bool doesStencilWrite,
592 GrColor* overrideColor, 659 GrColor* overrideColor,
593 const GrDrawTargetCaps& c aps) { 660 const GrDrawTargetCaps& c aps) {
594 return GrXferProcessor::kNone_Opt; 661 /*
662 Most the optimizations we do here are based on tweaking alpha for coverage.
663
664 The general SVG blend equation is defined in the spec as follows:
665
666 Dca' = B(Sc, Dc) * Sa * Da + Y * Sca * (1-Da) + Z * Dca * (1-Sa)
667 Da' = X * Sa * Da + Y * Sa * (1-Da) + Z * Da * (1-Sa)
668
669 (Note that Sca, Dca indicate RGB vectors that are premultiplied by alpha,
670 and that B(Sc, Dc) is a mode-specific function that accepts non-multiplied
671 RGB colors.)
672
673 For every blend mode supported by this class, i.e. the "advanced" blend
674 modes, X=Y=Z=1 and this equation reduces to the PDF blend equation.
675
676 It can be shown that when X=Y=Z=1, these equations can modulate alpha for
677 coverage.
678
679
680 == Color ==
681
682 We substitute Y=Z=1 and define a blend() function that calculates Dca' in
683 terms of premultiplied alpha only:
684
685 blend(Sca, Dca, Sa, Da) = {Dca : if Sa == 0,
686 Sca : if Da == 0,
687 B(Sca/Sa, Dca/Da) * Sa * Da + Sca * (1-Da) + Dc a * (1-Sa) : if Sa,Da != 0}
688
689 And for coverage modulation, we use a post blend src-over model:
690
691 Dca'' = f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
692
693 (Where f is the fractional coverage.)
694
695 Next we show that canTweakAlphaForCoverage() is true by proving the
696 following relationship:
697
698 blend(f*Sca, Dca, f*Sa, Da) == f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
699
700 General case (f,Sa,Da != 0):
701
702 f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
703 = f * (B(Sca/Sa, Dca/Da) * Sa * Da + Sca * (1-Da) + Dca * (1-Sa)) + (1-f ) * Dca [Sa,Da != 0, definition of blend()]
704 = B(Sca/Sa, Dca/Da) * f*Sa * Da + f*Sca * (1-Da) + f*Dca * (1-Sa) + Dca - f*Dca
705 = B(Sca/Sa, Dca/Da) * f*Sa * Da + f*Sca - f*Sca * Da + f*Dca - f*Dca * S a + Dca - f*Dca
706 = B(Sca/Sa, Dca/Da) * f*Sa * Da + f*Sca - f*Sca * Da - f*Dca * Sa + Dca
707 = B(Sca/Sa, Dca/Da) * f*Sa * Da + f*Sca * (1-Da) - f*Dca * Sa + Dca
708 = B(Sca/Sa, Dca/Da) * f*Sa * Da + f*Sca * (1-Da) + Dca * (1 - f*Sa)
709 = B(f*Sca/f*Sa, Dca/Da) * f*Sa * Da + f*Sca * (1-Da) + Dca * (1 - f*Sa) [f!=0]
710 = blend(f*Sca, Dca, f*Sa, Da) [definition of blend()]
711
712 Corner cases (Sa=0, Da=0, and f=0):
713
714 Sa=0: f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
715 = f * Dca + (1-f) * Dca [Sa=0, definition of blend()]
716 = Dca
717 = blend(0, Dca, 0, Da) [definition of blend()]
718 = blend(f*Sca, Dca, f*Sa, Da) [Sa=0]
719
720 Da=0: f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
721 = f * Sca + (1-f) * Dca [Da=0, definition of blend()]
722 = f * Sca [Da=0]
723 = blend(f*Sca, 0, f*Sa, 0) [definition of blend()]
724 = blend(f*Sca, Dca, f*Sa, Da) [Da=0]
725
726 f=0: f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
727 = Dca [f=0]
728 = blend(0, Dca, 0, Da) [definition of blend()]
729 = blend(f*Sca, Dca, f*Sa, Da) [f=0]
730
731 == Alpha ==
732
733 We substitute X=Y=Z=1 and define a blend() function that calculates Da':
734
735 blend(Sa, Da) = Sa * Da + Sa * (1-Da) + Da * (1-Sa)
736 = Sa * Da + Sa - Sa * Da + Da - Da * Sa
737 = Sa + Da - Sa * Da
738
739 We use the same model for coverage modulation as we did with color:
740
741 Da'' = f * blend(Sa, Da) + (1-f) * Da
742
743 And show that canTweakAlphaForCoverage() is true by proving the following
744 relationship:
745
746 blend(f*Sa, Da) == f * blend(Sa, Da) + (1-f) * Da
747
748
749 f * blend(Sa, Da) + (1-f) * Da
750 = f * (Sa + Da - Sa * Da) + (1-f) * Da
751 = f*Sa + f*Da - f*Sa * Da + Da - f*Da
752 = f*Sa - f*Sa * Da + Da
753 = f*Sa + Da - f*Sa * Da
754 = blend(f*Sa, Da)
755 */
756
757 OptFlags flags = kNone_Opt;
758 if (colorPOI.allStagesMultiplyInput()) {
759 flags = flags | kCanTweakAlphaForCoverage_OptFlag;
760 }
761 if (coveragePOI.isSolidWhite()) {
762 flags = flags | kIgnoreCoverage_OptFlag;
763 fHasCoverage = false;
764 }
765 if (caps.advancedBlendEquationSupport() && !coveragePOI.isFourChannelOutput( )) {
766 // This blend mode can be implemented in hardware.
767 fHWBlendEquation = hw_blend_equation(fMode);
768 }
769 return flags;
770 }
771
772 bool CustomXP::onWillNeedXferBarrier(const GrRenderTarget* rt,
773 const GrDrawTargetCaps& caps,
774 GrXferBarrierType* outBarrierType) const {
775 if (this->hasHWBlendEquation() && !caps.advancedCoherentBlendEquationSupport ()) {
776 *outBarrierType = kBlend_GrXferBarrierType;
777 return true;
778 }
779 return false;
780 }
781
782 void CustomXP::onGetBlendInfo(BlendInfo* blendInfo) const {
783 if (this->hasHWBlendEquation()) {
784 blendInfo->fEquation = this->hwBlendEquation();
785 }
595 } 786 }
596 787
597 /////////////////////////////////////////////////////////////////////////////// 788 ///////////////////////////////////////////////////////////////////////////////
598 789
599 GrCustomXPFactory::GrCustomXPFactory(SkXfermode::Mode mode) 790 GrCustomXPFactory::GrCustomXPFactory(SkXfermode::Mode mode)
600 : fMode(mode) { 791 : fMode(mode) {
601 this->initClassID<GrCustomXPFactory>(); 792 this->initClassID<GrCustomXPFactory>();
602 } 793 }
603 794
604 GrXferProcessor* 795 GrXferProcessor*
605 GrCustomXPFactory::onCreateXferProcessor(const GrDrawTargetCaps& caps, 796 GrCustomXPFactory::onCreateXferProcessor(const GrDrawTargetCaps& caps,
606 const GrProcOptInfo& colorPOI, 797 const GrProcOptInfo& colorPOI,
607 const GrProcOptInfo& coveragePOI, 798 const GrProcOptInfo& coveragePOI,
608 const GrDeviceCoordTexture* dstCopy) co nst { 799 const GrDeviceCoordTexture* dstCopy) co nst {
609 return CustomXP::Create(fMode, dstCopy, this->willReadDstColor(caps, colorPO I, coveragePOI)); 800 return CustomXP::Create(fMode, dstCopy, this->willReadDstColor(caps, colorPO I, coveragePOI));
610 } 801 }
611 802
803 bool GrCustomXPFactory::willReadDstColor(const GrDrawTargetCaps& caps,
804 const GrProcOptInfo& colorPOI,
805 const GrProcOptInfo& coveragePOI) const {
806 if (!caps.advancedBlendEquationSupport()) {
807 // No hardware support for advanced blend equations; we will need to do it in the shader.
808 return true;
809 }
810 if (coveragePOI.isFourChannelOutput()) {
811 // Advanced blend equations can't tweak alpha for RGB coverage.
812 return true;
813 }
814 return false;
815 }
612 816
613 void GrCustomXPFactory::getInvariantOutput(const GrProcOptInfo& colorPOI, 817 void GrCustomXPFactory::getInvariantOutput(const GrProcOptInfo& colorPOI,
614 const GrProcOptInfo& coveragePOI, 818 const GrProcOptInfo& coveragePOI,
615 GrXPFactory::InvariantOutput* out put) const { 819 GrXPFactory::InvariantOutput* out put) const {
616 output->fWillBlendWithDst = true; 820 output->fWillBlendWithDst = true;
617 output->fBlendedColorFlags = 0; 821 output->fBlendedColorFlags = 0;
618 } 822 }
619 823
620 GR_DEFINE_XP_FACTORY_TEST(GrCustomXPFactory); 824 GR_DEFINE_XP_FACTORY_TEST(GrCustomXPFactory);
621 GrXPFactory* GrCustomXPFactory::TestCreate(SkRandom* rand, 825 GrXPFactory* GrCustomXPFactory::TestCreate(SkRandom* rand,
622 GrContext*, 826 GrContext*,
623 const GrDrawTargetCaps&, 827 const GrDrawTargetCaps&,
624 GrTexture*[]) { 828 GrTexture*[]) {
625 int mode = rand->nextRangeU(SkXfermode::kLastCoeffMode + 1, SkXfermode::kLas tSeparableMode); 829 int mode = rand->nextRangeU(SkXfermode::kLastCoeffMode + 1, SkXfermode::kLas tSeparableMode);
626 830
627 return SkNEW_ARGS(GrCustomXPFactory, (static_cast<SkXfermode::Mode>(mode))); 831 return SkNEW_ARGS(GrCustomXPFactory, (static_cast<SkXfermode::Mode>(mode)));
628 } 832 }
629 833
OLDNEW
« no previous file with comments | « src/gpu/GrXferProcessor.cpp ('k') | src/gpu/effects/GrCustomXfermodePriv.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698