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

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: Rename blendEquationAdvancedIsKHR to mustEnableAdvancedBlendEquations 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
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
(...skipping 473 matching lines...) Expand 10 before | Expand all | Expand 10 after
503 504
504 bool hasSecondaryOutput() const override { return false; } 505 bool hasSecondaryOutput() const override { return false; }
505 506
506 GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI, 507 GrXferProcessor::OptFlags getOptimizations(const GrProcOptInfo& colorPOI,
507 const GrProcOptInfo& coveragePOI, 508 const GrProcOptInfo& coveragePOI,
508 bool doesStencilWrite, 509 bool doesStencilWrite,
509 GrColor* overrideColor, 510 GrColor* overrideColor,
510 const GrDrawTargetCaps& caps) ove rride; 511 const GrDrawTargetCaps& caps) ove rride;
511 512
512 SkXfermode::Mode mode() const { return fMode; } 513 SkXfermode::Mode mode() const { return fMode; }
514 bool hasCoverage() const { return fHasCoverage; }
515 bool hasHWBlendEquation() const { return kInvalid_GrBlendEquation != fHWBlen dEquation; }
516
517 GrBlendEquation hwBlendEquation() const {
518 SkASSERT(this->hasHWBlendEquation());
519 return fHWBlendEquation;
520 }
513 521
514 private: 522 private:
515 CustomXP(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy, bool wi llReadDstColor); 523 CustomXP(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy, bool wi llReadDstColor);
516 524
517 void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) c onst override; 525 void onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder* b) c onst override;
518 526
527 bool onWillNeedXferBarrier(const GrRenderTarget* rt,
528 const GrDrawTargetCaps& caps,
529 GrXferBarrierType* outBarrierType) const override ;
530
531 void onGetBlendInfo(BlendInfo*) const override;
532
519 bool onIsEqual(const GrXferProcessor& xpBase) const override; 533 bool onIsEqual(const GrXferProcessor& xpBase) const override;
520 534
521 SkXfermode::Mode fMode; 535 SkXfermode::Mode fMode;
536 bool fHasCoverage;
537 GrBlendEquation fHWBlendEquation;
522 538
523 typedef GrXferProcessor INHERITED; 539 typedef GrXferProcessor INHERITED;
524 }; 540 };
525 541
526 /////////////////////////////////////////////////////////////////////////////// 542 ///////////////////////////////////////////////////////////////////////////////
527 543
528 GrXPFactory* GrCustomXfermode::CreateXPFactory(SkXfermode::Mode mode) { 544 GrXPFactory* GrCustomXfermode::CreateXPFactory(SkXfermode::Mode mode) {
529 if (!GrCustomXfermode::IsSupportedMode(mode)) { 545 if (!GrCustomXfermode::IsSupportedMode(mode)) {
530 return NULL; 546 return NULL;
531 } else { 547 } else {
532 return SkNEW_ARGS(GrCustomXPFactory, (mode)); 548 return SkNEW_ARGS(GrCustomXPFactory, (mode));
533 } 549 }
534 } 550 }
535 551
536 /////////////////////////////////////////////////////////////////////////////// 552 ///////////////////////////////////////////////////////////////////////////////
537 553
538 class GLCustomXP : public GrGLXferProcessor { 554 class GLCustomXP : public GrGLXferProcessor {
539 public: 555 public:
540 GLCustomXP(const GrXferProcessor&) {} 556 GLCustomXP(const GrXferProcessor&) {}
541 ~GLCustomXP() override {} 557 ~GLCustomXP() override {}
542 558
543 static void GenKey(const GrXferProcessor& proc, const GrGLSLCaps&, GrProcess orKeyBuilder* b) { 559 static void GenKey(const GrXferProcessor& p, const GrGLSLCaps& caps, GrProce ssorKeyBuilder* b) {
544 uint32_t key = proc.numTextures(); 560 const CustomXP& xp = p.cast<CustomXP>();
561 uint32_t key = xp.numTextures();
545 SkASSERT(key <= 1); 562 SkASSERT(key <= 1);
546 key |= proc.cast<CustomXP>().mode() << 1; 563 key |= xp.hasCoverage() << 1;
564 if (!xp.hasHWBlendEquation() || caps.mustEnableAdvancedBlendEquations()) {
egdaniel 2015/05/04 19:51:21 just to confirm, mustEnableAdvBE() means that we n
Chris Dalton 2015/05/04 20:33:12 Yes, that's correct. And we need this check becaus
565 key |= 1 << 2; // Differentiate the shaders that take this branch.
566 key |= xp.hasHWBlendEquation() << 3;
567 key |= xp.mode() << 4;
egdaniel 2015/05/04 19:51:21 When adding the case to switch between all and ind
Chris Dalton 2015/05/05 18:57:58 Done.
568 }
547 b->add32(key); 569 b->add32(key);
548 } 570 }
549 571
550 private: 572 private:
551 void onEmitCode(const EmitArgs& args) override { 573 void onEmitCode(const EmitArgs& args) override {
552 SkXfermode::Mode mode = args.fXP.cast<CustomXP>().mode(); 574 const CustomXP& xp = args.fXP.cast<CustomXP>();
553 GrGLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder(); 575 GrGLXPFragmentBuilder* fsBuilder = args.fPB->getFragmentShaderBuilder();
554 const char* dstColor = fsBuilder->dstColor();
555 576
556 emit_custom_xfermode_code(mode, fsBuilder, args.fOutputPrimary, args.fIn putColor, dstColor); 577 if (xp.hasHWBlendEquation()) {
578 // The blend mode will be implemented in hardware; only output the s rc color.
579 if (args.fPB->gpu()->glCaps().glslCaps()->mustEnableAdvancedBlendEqu ations()) {
580 fsBuilder->enableAdvancedBlendEquation(xp.hwBlendEquation());
581 }
582 if (xp.hasCoverage()) {
583 // Do coverage modulation by multiplying it into the src color b efore blending.
584 // (See canTweakAlphaForCoverage())
585 fsBuilder->codeAppendf("%s = %s * %s;",
586 args.fOutputPrimary, args.fInputCoverage, args.fInputColor);
587 } else {
588 fsBuilder->codeAppendf("%s = %s;", args.fOutputPrimary, args.fIn putColor);
589 }
590 } else {
591 SkXfermode::Mode mode = xp.mode();
592 const char* dstColor = fsBuilder->dstColor();
557 593
558 fsBuilder->codeAppendf("%s = %s * %s + (vec4(1.0) - %s) * %s;", 594 emit_custom_xfermode_code(mode, fsBuilder, args.fOutputPrimary, args .fInputColor, dstColor);
egdaniel 2015/05/04 19:51:21 100 chars
Chris Dalton 2015/05/04 20:33:12 Oops :)
Chris Dalton 2015/05/05 18:57:58 Done.
559 args.fOutputPrimary, args.fOutputPrimary, args.fI nputCoverage, 595
560 args.fInputCoverage, dstColor); 596 if (xp.hasCoverage()) {
597 fsBuilder->codeAppendf("%s = %s * %s + (vec4(1.0) - %s) * %s;",
598 args.fOutputPrimary, args.fOutputPrimary,
599 args.fInputCoverage, args.fInputCoverage, dstColor);
600 }
601 }
561 } 602 }
562 603
563 void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) overri de {} 604 void onSetData(const GrGLProgramDataManager&, const GrXferProcessor&) overri de {}
564 605
565 typedef GrGLFragmentProcessor INHERITED; 606 typedef GrGLFragmentProcessor INHERITED;
566 }; 607 };
567 608
568 /////////////////////////////////////////////////////////////////////////////// 609 ///////////////////////////////////////////////////////////////////////////////
569 610
570 CustomXP::CustomXP(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy, 611 CustomXP::CustomXP(SkXfermode::Mode mode, const GrDeviceCoordTexture* dstCopy,
571 bool willReadDstColor) 612 bool willReadDstColor)
572 : INHERITED(dstCopy, willReadDstColor), fMode(mode) { 613 : INHERITED(dstCopy, willReadDstColor),
614 fMode(mode),
615 fHasCoverage(true),
616 fHWBlendEquation(kInvalid_GrBlendEquation) {
573 this->initClassID<CustomXP>(); 617 this->initClassID<CustomXP>();
574 } 618 }
575 619
576 void CustomXP::onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder * b) const { 620 void CustomXP::onGetGLProcessorKey(const GrGLSLCaps& caps, GrProcessorKeyBuilder * b) const {
577 GLCustomXP::GenKey(*this, caps, b); 621 GLCustomXP::GenKey(*this, caps, b);
578 } 622 }
579 623
580 GrGLXferProcessor* CustomXP::createGLInstance() const { 624 GrGLXferProcessor* CustomXP::createGLInstance() const {
625 SkASSERT(this->willReadDstColor() != this->hasHWBlendEquation());
581 return SkNEW_ARGS(GLCustomXP, (*this)); 626 return SkNEW_ARGS(GLCustomXP, (*this));
582 } 627 }
583 628
584 bool CustomXP::onIsEqual(const GrXferProcessor& other) const { 629 bool CustomXP::onIsEqual(const GrXferProcessor& other) const {
585 const CustomXP& s = other.cast<CustomXP>(); 630 const CustomXP& s = other.cast<CustomXP>();
586 return fMode == s.fMode; 631 return fMode == s.fMode &&
632 fHasCoverage == s.fHasCoverage &&
633 fHWBlendEquation == s.fHWBlendEquation;
587 } 634 }
588 635
589 GrXferProcessor::OptFlags CustomXP::getOptimizations(const GrProcOptInfo& colorP OI, 636 GrXferProcessor::OptFlags CustomXP::getOptimizations(const GrProcOptInfo& colorP OI,
590 const GrProcOptInfo& cove ragePOI, 637 const GrProcOptInfo& cove ragePOI,
591 bool doesStencilWrite, 638 bool doesStencilWrite,
592 GrColor* overrideColor, 639 GrColor* overrideColor,
593 const GrDrawTargetCaps& c aps) { 640 const GrDrawTargetCaps& c aps) {
594 return GrXferProcessor::kNone_Opt; 641 OptFlags flags = kNone_Opt;
642 if (colorPOI.allStagesMultiplyInput()) {
643 flags = flags | kCanTweakAlphaForCoverage_OptFlag;
644 }
645 if (coveragePOI.isSolidWhite()) {
646 flags = flags | kIgnoreCoverage_OptFlag;
647 fHasCoverage = false;
648 }
649 if (caps.advancedBlendEquationSupport() && !coveragePOI.isFourChannelOutput( )) {
650 // This blend mode can be implemented in hardware.
651 enum { kOffset = kOverlay_GrBlendEquation - SkXfermode::kOverlay_Mode };
652 fHWBlendEquation = static_cast<GrBlendEquation>(fMode + kOffset);
653
654 GR_STATIC_ASSERT(kOverlay_GrBlendEquation == SkXfermode::kOverlay_Mode + kOffset);
655 GR_STATIC_ASSERT(kDarken_GrBlendEquation == SkXfermode::kDarken_Mode + k Offset);
656 GR_STATIC_ASSERT(kLighten_GrBlendEquation == SkXfermode::kLighten_Mode + kOffset);
657 GR_STATIC_ASSERT(kColorDodge_GrBlendEquation == SkXfermode::kColorDodge_ Mode + kOffset);
658 GR_STATIC_ASSERT(kColorBurn_GrBlendEquation == SkXfermode::kColorBurn_Mo de + kOffset);
659 GR_STATIC_ASSERT(kHardLight_GrBlendEquation == SkXfermode::kHardLight_Mo de + kOffset);
660 GR_STATIC_ASSERT(kSoftLight_GrBlendEquation == SkXfermode::kSoftLight_Mo de + kOffset);
661 GR_STATIC_ASSERT(kDifference_GrBlendEquation == SkXfermode::kDifference_ Mode + kOffset);
662 GR_STATIC_ASSERT(kExclusion_GrBlendEquation == SkXfermode::kExclusion_Mo de + kOffset);
663 GR_STATIC_ASSERT(kMultiply_GrBlendEquation == SkXfermode::kMultiply_Mode + kOffset);
664 GR_STATIC_ASSERT(kHSLHue_GrBlendEquation == SkXfermode::kHue_Mode + kOff set);
665 GR_STATIC_ASSERT(kHSLSaturation_GrBlendEquation == SkXfermode::kSaturati on_Mode + kOffset);
666 GR_STATIC_ASSERT(kHSLColor_GrBlendEquation == SkXfermode::kColor_Mode + kOffset);
667 GR_STATIC_ASSERT(kHSLLuminosity_GrBlendEquation == SkXfermode::kLuminosi ty_Mode + kOffset);
668 GR_STATIC_ASSERT(kTotalGrBlendEquationCount == SkXfermode::kLastMode + 1 + kOffset);
669 }
670 return flags;
671 }
672
673 bool CustomXP::onWillNeedXferBarrier(const GrRenderTarget* rt,
674 const GrDrawTargetCaps& caps,
675 GrXferBarrierType* outBarrierType) const {
676 if (this->hasHWBlendEquation() &&
677 GrDrawTargetCaps::kAdvancedCoherent_BlendEquationSupport != caps.blendEq uationSupport()) {
678 *outBarrierType = kBlend_GrXferBarrierType;
679 return true;
680 }
681 return false;
682 }
683
684 void CustomXP::onGetBlendInfo(BlendInfo* blendInfo) const {
685 if (this->hasHWBlendEquation()) {
686 blendInfo->fEquation = this->hwBlendEquation();
687 }
595 } 688 }
596 689
597 /////////////////////////////////////////////////////////////////////////////// 690 ///////////////////////////////////////////////////////////////////////////////
598 691
599 GrCustomXPFactory::GrCustomXPFactory(SkXfermode::Mode mode) 692 GrCustomXPFactory::GrCustomXPFactory(SkXfermode::Mode mode)
600 : fMode(mode) { 693 : fMode(mode) {
601 this->initClassID<GrCustomXPFactory>(); 694 this->initClassID<GrCustomXPFactory>();
602 } 695 }
603 696
604 GrXferProcessor* 697 GrXferProcessor*
605 GrCustomXPFactory::onCreateXferProcessor(const GrDrawTargetCaps& caps, 698 GrCustomXPFactory::onCreateXferProcessor(const GrDrawTargetCaps& caps,
606 const GrProcOptInfo& colorPOI, 699 const GrProcOptInfo& colorPOI,
607 const GrProcOptInfo& coveragePOI, 700 const GrProcOptInfo& coveragePOI,
608 const GrDeviceCoordTexture* dstCopy) co nst { 701 const GrDeviceCoordTexture* dstCopy) co nst {
609 return CustomXP::Create(fMode, dstCopy, this->willReadDstColor(caps, colorPO I, coveragePOI)); 702 return CustomXP::Create(fMode, dstCopy, this->willReadDstColor(caps, colorPO I, coveragePOI));
610 } 703 }
611 704
705 bool GrCustomXPFactory::canTweakAlphaForCoverage() const {
egdaniel 2015/05/04 19:51:21 so we actually just removed this function since wi
Chris Dalton 2015/05/05 18:57:58 Done.
706 /*
707 The general SVG blend equation is defined in the spec as follows:
708
709 Dca' = B(Sc, Dc) * Sa * Da + Y * Sca * (1-Da) + Z * Dca * (1-Sa)
710 Da' = X * Sa * Da + Y * Sa * (1-Da) + Z * Da * (1-Sa)
711
712 (Note that Sca, Dca indicate RGB vectors that are premultiplied by alpha,
713 and that B(Sc, Dc) is a mode-specific function that accepts non-multiplied
714 RGB colors.)
715
716 For every blend mode supported by this class, i.e. the "advanced" blend
717 modes, X=Y=Z=1 and this equation reduces to the PDF blend equation.
718
719 It can be shown that when X=Y=Z=1, canTweakAlphaForCoverage() is true.
720
721
722 == Color ==
723
724 We substitute Y=Z=1 and define a blend() function that calculates Dca' in
725 terms of premultiplied alpha only:
726
727 blend(Sca, Dca, Sa, Da) = {Dca : if Sa == 0,
728 Sca : if Da == 0,
729 B(Sca/Sa, Dca/Da) * Sa * Da + Sca * (1-Da) + Dc a * (1-Sa) : if Sa,Da != 0}
730
731 And for coverage modulation, we use a post blend src-over model:
732
733 Dca'' = f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
734
735 (Where f is the fractional coverage.)
736
737 Next we show that canTweakAlphaForCoverage() is true by proving the
738 following relationship:
739
740 blend(f*Sca, Dca, f*Sa, Da) == f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
741
742 General case (f,Sa,Da != 0):
743
744 f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
745 = f * (B(Sca/Sa, Dca/Da) * Sa * Da + Sca * (1-Da) + Dca * (1-Sa)) + (1-f ) * Dca [Sa,Da != 0, definition of blend()]
746 = B(Sca/Sa, Dca/Da) * f*Sa * Da + f*Sca * (1-Da) + f*Dca * (1-Sa) + Dca - f*Dca
747 = B(Sca/Sa, Dca/Da) * f*Sa * Da + f*Sca - f*Sca * Da + f*Dca - f*Dca * S a + Dca - f*Dca
748 = B(Sca/Sa, Dca/Da) * f*Sa * Da + f*Sca - f*Sca * Da - f*Dca * Sa + Dca
749 = B(Sca/Sa, Dca/Da) * f*Sa * Da + f*Sca * (1-Da) - f*Dca * Sa + Dca
750 = B(Sca/Sa, Dca/Da) * f*Sa * Da + f*Sca * (1-Da) + Dca * (1 - f*Sa)
751 = B(f*Sca/f*Sa, Dca/Da) * f*Sa * Da + f*Sca * (1-Da) + Dca * (1 - f*Sa) [f!=0]
752 = blend(f*Sca, Dca, f*Sa, Da) [definition of blend()]
753
754 Corner cases (Sa=0, Da=0, and f=0):
755
756 Sa=0: f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
757 = f * Dca + (1-f) * Dca [Sa=0, definition of blend()]
758 = Dca
759 = blend(0, Dca, 0, Da) [definition of blend()]
760 = blend(f*Sca, Dca, f*Sa, Da) [Sa=0]
761
762 Da=0: f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
763 = f * Sca + (1-f) * Dca [Da=0, definition of blend()]
764 = f * Sca [Da=0]
765 = blend(f*Sca, 0, f*Sa, 0) [definition of blend()]
766 = blend(f*Sca, Dca, f*Sa, Da) [Da=0]
767
768 f=0: f * blend(Sca, Dca, Sa, Da) + (1-f) * Dca
769 = Dca [f=0]
770 = blend(0, Dca, 0, Da) [definition of blend()]
771 = blend(f*Sca, Dca, f*Sa, Da) [f=0]
772
773 == Alpha ==
774
775 We substitute X=Y=Z=1 and define a blend() function that calculates Da':
776
777 blend(Sa, Da) = Sa * Da + Sa * (1-Da) + Da * (1-Sa)
778 = Sa * Da + Sa - Sa * Da + Da - Da * Sa
779 = Sa + Da - Sa * Da
780
781 We use the same model for coverage modulation as we did with color:
782
783 Da'' = f * blend(Sa, Da) + (1-f) * Da
784
785 And show that canTweakAlphaForCoverage() is true by proving the following
786 relationship:
787
788 blend(f*Sa, Da) == f * blend(Sa, Da) + (1-f) * Da
789
790
791 f * blend(Sa, Da) + (1-f) * Da
792 = f * (Sa + Da - Sa * Da) + (1-f) * Da
793 = f*Sa + f*Da - f*Sa * Da + Da - f*Da
794 = f*Sa - f*Sa * Da + Da
795 = f*Sa + Da - f*Sa * Da
796 = blend(f*Sa, Da)
797 */
798
799 return true;
egdaniel 2015/05/04 19:51:21 so I read through the proof on your first path. Of
Chris Dalton 2015/05/04 20:33:12 Yes, it works for the dst read version because it
800 }
801
802 bool GrCustomXPFactory::willReadDstColor(const GrDrawTargetCaps& caps,
803 const GrProcOptInfo& colorPOI,
804 const GrProcOptInfo& coveragePOI) const {
805 if (!caps.advancedBlendEquationSupport()) {
806 // No hardware support for advanced blend modes; we will need to do it i n the shader.
807 return true;
808 }
809 if (coveragePOI.isFourChannelOutput()) {
810 // Hardware blend modes won't work with RGB coverage. For these modes we multiply coverage
811 // into the src color before the blend, but this only works if coverage is a scalar.
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

Powered by Google App Engine
This is Rietveld 408576698