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

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

Issue 1455273006: Make specialized SrcOver XPFactory (Closed) Base URL: https://skia.googlesource.com/skia.git@master
Patch Set: Created 5 years, 1 month 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/effects/GrCustomXfermode.cpp ('k') | tests/GrPorterDuffTest.cpp » ('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 2014 Google Inc. 2 * Copyright 2014 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/GrPorterDuffXferProcessor.h" 8 #include "effects/GrPorterDuffXferProcessor.h"
9 9
10 #include "GrBlend.h" 10 #include "GrBlend.h"
(...skipping 673 matching lines...) Expand 10 before | Expand all | Expand 10 after
684 // We want to force our primary output to be alpha * Coverage, where alp ha is the alpha 684 // We want to force our primary output to be alpha * Coverage, where alp ha is the alpha
685 // value of the blend the constant. We should already have valid blend c oeff's if we are at 685 // value of the blend the constant. We should already have valid blend c oeff's if we are at
686 // a point where we have RGB coverage. We don't need any color stages si nce the known color 686 // a point where we have RGB coverage. We don't need any color stages si nce the known color
687 // output is already baked into the blendConstant. 687 // output is already baked into the blendConstant.
688 *overrideColor = GrColorPackRGBA(fAlpha, fAlpha, fAlpha, fAlpha); 688 *overrideColor = GrColorPackRGBA(fAlpha, fAlpha, fAlpha, fAlpha);
689 return GrXferProcessor::kOverrideColor_OptFlag; 689 return GrXferProcessor::kOverrideColor_OptFlag;
690 } 690 }
691 691
692 /////////////////////////////////////////////////////////////////////////////// 692 ///////////////////////////////////////////////////////////////////////////////
693 693
694 GrPorterDuffXPFactory::GrPorterDuffXPFactory(SkXfermode::Mode xfermode) 694 GrPDXPFactory::GrPDXPFactory(SkXfermode::Mode xfermode)
695 : fXfermode(xfermode) { 695 : fXfermode(xfermode) {
696 SkASSERT(fXfermode <= SkXfermode::kLastCoeffMode); 696 SkASSERT(fXfermode <= SkXfermode::kLastCoeffMode);
697 this->initClassID<GrPorterDuffXPFactory>(); 697 this->initClassID<GrPDXPFactory>();
698 } 698 }
699 699
700 GrXPFactory* GrPorterDuffXPFactory::Create(SkXfermode::Mode xfermode) { 700 const GrXPFactory* GrPDXPFactory::Create(SkXfermode::Mode xfermode) {
701 static GrPorterDuffXPFactory gClearPDXPF(SkXfermode::kClear_Mode); 701 static const GrPDXPFactory gClearPDXPF(SkXfermode::kClear_Mode);
702 static GrPorterDuffXPFactory gSrcPDXPF(SkXfermode::kSrc_Mode); 702 static const GrPDXPFactory gSrcPDXPF(SkXfermode::kSrc_Mode);
703 static GrPorterDuffXPFactory gDstPDXPF(SkXfermode::kDst_Mode); 703 static const GrPDXPFactory gDstPDXPF(SkXfermode::kDst_Mode);
704 static GrPorterDuffXPFactory gSrcOverPDXPF(SkXfermode::kSrcOver_Mode); 704 static const GrPDXPFactory gSrcOverPDXPF(SkXfermode::kSrcOver_Mode);
705 static GrPorterDuffXPFactory gDstOverPDXPF(SkXfermode::kDstOver_Mode); 705 static const GrPDXPFactory gDstOverPDXPF(SkXfermode::kDstOver_Mode);
706 static GrPorterDuffXPFactory gSrcInPDXPF(SkXfermode::kSrcIn_Mode); 706 static const GrPDXPFactory gSrcInPDXPF(SkXfermode::kSrcIn_Mode);
707 static GrPorterDuffXPFactory gDstInPDXPF(SkXfermode::kDstIn_Mode); 707 static const GrPDXPFactory gDstInPDXPF(SkXfermode::kDstIn_Mode);
708 static GrPorterDuffXPFactory gSrcOutPDXPF(SkXfermode::kSrcOut_Mode); 708 static const GrPDXPFactory gSrcOutPDXPF(SkXfermode::kSrcOut_Mode);
709 static GrPorterDuffXPFactory gDstOutPDXPF(SkXfermode::kDstOut_Mode); 709 static const GrPDXPFactory gDstOutPDXPF(SkXfermode::kDstOut_Mode);
710 static GrPorterDuffXPFactory gSrcATopPDXPF(SkXfermode::kSrcATop_Mode); 710 static const GrPDXPFactory gSrcATopPDXPF(SkXfermode::kSrcATop_Mode);
711 static GrPorterDuffXPFactory gDstATopPDXPF(SkXfermode::kDstATop_Mode); 711 static const GrPDXPFactory gDstATopPDXPF(SkXfermode::kDstATop_Mode);
712 static GrPorterDuffXPFactory gXorPDXPF(SkXfermode::kXor_Mode); 712 static const GrPDXPFactory gXorPDXPF(SkXfermode::kXor_Mode);
713 static GrPorterDuffXPFactory gPlusPDXPF(SkXfermode::kPlus_Mode); 713 static const GrPDXPFactory gPlusPDXPF(SkXfermode::kPlus_Mode);
714 static GrPorterDuffXPFactory gModulatePDXPF(SkXfermode::kModulate_Mode); 714 static const GrPDXPFactory gModulatePDXPF(SkXfermode::kModulate_Mode);
715 static GrPorterDuffXPFactory gScreenPDXPF(SkXfermode::kScreen_Mode); 715 static const GrPDXPFactory gScreenPDXPF(SkXfermode::kScreen_Mode);
716 716
717 static GrPorterDuffXPFactory* gFactories[] = { 717 static const GrPDXPFactory* gFactories[] = {
718 &gClearPDXPF, &gSrcPDXPF, &gDstPDXPF, &gSrcOverPDXPF, &gDstOverPDXPF, &g SrcInPDXPF, 718 &gClearPDXPF, &gSrcPDXPF, &gDstPDXPF, &gSrcOverPDXPF, &gDstOverPDXPF, &g SrcInPDXPF,
719 &gDstInPDXPF, &gSrcOutPDXPF, &gDstOutPDXPF, &gSrcATopPDXPF, &gDstATopPDX PF, &gXorPDXPF, 719 &gDstInPDXPF, &gSrcOutPDXPF, &gDstOutPDXPF, &gSrcATopPDXPF, &gDstATopPDX PF, &gXorPDXPF,
720 &gPlusPDXPF, &gModulatePDXPF, &gScreenPDXPF 720 &gPlusPDXPF, &gModulatePDXPF, &gScreenPDXPF
721 }; 721 };
722 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gFactories) == SkXfermode::kLastCoeffMode + 1); 722 GR_STATIC_ASSERT(SK_ARRAY_COUNT(gFactories) == SkXfermode::kLastCoeffMode + 1);
723 723
724 if (xfermode < 0 || xfermode > SkXfermode::kLastCoeffMode) { 724 if (xfermode < 0 || xfermode > SkXfermode::kLastCoeffMode) {
725 return nullptr; 725 return nullptr;
726 } 726 }
727 return SkRef(gFactories[xfermode]); 727 return SkRef(gFactories[xfermode]);
728 } 728 }
729 729
730 GrXferProcessor* 730 GrXferProcessor*
731 GrPorterDuffXPFactory::onCreateXferProcessor(const GrCaps& caps, 731 GrPDXPFactory::onCreateXferProcessor(const GrCaps& caps,
732 const GrProcOptInfo& colorPOI, 732 const GrProcOptInfo& colorPOI,
733 const GrProcOptInfo& covPOI, 733 const GrProcOptInfo& covPOI,
734 bool hasMixedSamples, 734 bool hasMixedSamples,
735 const DstTexture* dstTexture) const { 735 const DstTexture* dstTexture) const {
736 BlendFormula blendFormula; 736 BlendFormula blendFormula;
737 if (covPOI.isFourChannelOutput()) { 737 if (covPOI.isFourChannelOutput()) {
738 if (SkXfermode::kSrcOver_Mode == fXfermode && 738 if (SkXfermode::kSrcOver_Mode == fXfermode &&
739 kRGBA_GrColorComponentFlags == colorPOI.validFlags() && 739 kRGBA_GrColorComponentFlags == colorPOI.validFlags() &&
740 !caps.shaderCaps()->dualSourceBlendingSupport() && 740 !caps.shaderCaps()->dualSourceBlendingSupport() &&
741 !caps.shaderCaps()->dstReadInShaderSupport()) { 741 !caps.shaderCaps()->dstReadInShaderSupport()) {
742 // If we don't have dual source blending or in shader dst reads, we fall back to this 742 // If we don't have dual source blending or in shader dst reads, we fall back to this
743 // trick for rendering SrcOver LCD text instead of doing a dst copy. 743 // trick for rendering SrcOver LCD text instead of doing a dst copy.
744 SkASSERT(!dstTexture || !dstTexture->texture()); 744 SkASSERT(!dstTexture || !dstTexture->texture());
745 return PDLCDXferProcessor::Create(fXfermode, colorPOI); 745 return PDLCDXferProcessor::Create(fXfermode, colorPOI);
746 } 746 }
747 blendFormula = get_lcd_blend_formula(covPOI, fXfermode); 747 blendFormula = get_lcd_blend_formula(covPOI, fXfermode);
748 } else { 748 } else {
749 blendFormula = get_blend_formula(colorPOI, covPOI, hasMixedSamples, fXfe rmode); 749 blendFormula = get_blend_formula(colorPOI, covPOI, hasMixedSamples, fXfe rmode);
750 } 750 }
751 751
752 if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlend ingSupport()) { 752 if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlend ingSupport()) {
753 return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, fXfermode) ; 753 return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, fXfermode) ;
754 } 754 }
755 755
756 SkASSERT(!dstTexture || !dstTexture->texture()); 756 SkASSERT(!dstTexture || !dstTexture->texture());
757 return new PorterDuffXferProcessor(blendFormula); 757 return new PorterDuffXferProcessor(blendFormula);
758 } 758 }
759 759
760 void GrPorterDuffXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorP OI, 760 void GrPDXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorPOI,
761 InvariantBlendedColor* blen dedColor) const { 761 InvariantBlendedColor* blen dedColor) const {
762 // Find the blended color info based on the formula that does not have cover age. 762 // Find the blended color info based on the formula that does not have cover age.
763 BlendFormula colorFormula = gBlendTable[colorPOI.isOpaque()][0][fXfermode]; 763 BlendFormula colorFormula = gBlendTable[colorPOI.isOpaque()][0][fXfermode];
764 if (colorFormula.usesDstColor()) { 764 if (colorFormula.usesDstColor()) {
765 blendedColor->fWillBlendWithDst = true; 765 blendedColor->fWillBlendWithDst = true;
766 blendedColor->fKnownColorFlags = kNone_GrColorComponentFlags; 766 blendedColor->fKnownColorFlags = kNone_GrColorComponentFlags;
767 return; 767 return;
768 } 768 }
769 769
770 blendedColor->fWillBlendWithDst = false; 770 blendedColor->fWillBlendWithDst = false;
(...skipping 10 matching lines...) Expand all
781 blendedColor->fKnownColor = colorPOI.color(); 781 blendedColor->fKnownColor = colorPOI.color();
782 blendedColor->fKnownColorFlags = colorPOI.validFlags(); 782 blendedColor->fKnownColorFlags = colorPOI.validFlags();
783 return; 783 return;
784 784
785 default: 785 default:
786 blendedColor->fKnownColorFlags = kNone_GrColorComponentFlags; 786 blendedColor->fKnownColorFlags = kNone_GrColorComponentFlags;
787 return; 787 return;
788 } 788 }
789 } 789 }
790 790
791 bool GrPorterDuffXPFactory::willReadDstColor(const GrCaps& caps, 791 bool GrPDXPFactory::willReadDstColor(const GrCaps& caps,
792 const GrProcOptInfo& colorPOI, 792 const GrProcOptInfo& colorPOI,
793 const GrProcOptInfo& covPOI, 793 const GrProcOptInfo& covPOI,
794 bool hasMixedSamples) const { 794 bool hasMixedSamples) const {
795 if (caps.shaderCaps()->dualSourceBlendingSupport()) { 795 if (caps.shaderCaps()->dualSourceBlendingSupport()) {
796 return false; 796 return false;
797 } 797 }
798 798
799 // When we have four channel coverage we always need to read the dst in orde r to correctly 799 // When we have four channel coverage we always need to read the dst in orde r to correctly
800 // blend. The one exception is when we are using srcover mode and we know th e input color into 800 // blend. The one exception is when we are using srcover mode and we know th e input color into
801 // the XP. 801 // the XP.
802 if (covPOI.isFourChannelOutput()) { 802 if (covPOI.isFourChannelOutput()) {
803 if (SkXfermode::kSrcOver_Mode == fXfermode && 803 if (SkXfermode::kSrcOver_Mode == fXfermode &&
804 kRGBA_GrColorComponentFlags == colorPOI.validFlags() && 804 kRGBA_GrColorComponentFlags == colorPOI.validFlags() &&
805 !caps.shaderCaps()->dstReadInShaderSupport()) { 805 !caps.shaderCaps()->dstReadInShaderSupport()) {
806 return false; 806 return false;
807 } 807 }
808 return get_lcd_blend_formula(covPOI, fXfermode).hasSecondaryOutput(); 808 return get_lcd_blend_formula(covPOI, fXfermode).hasSecondaryOutput();
809 } 809 }
810 // We fallback on the shader XP when the blend formula would use dual source blending but we 810 // We fallback on the shader XP when the blend formula would use dual source blending but we
811 // don't have support for it. 811 // don't have support for it.
812 return get_blend_formula(colorPOI, covPOI, hasMixedSamples, fXfermode).hasSe condaryOutput(); 812 return get_blend_formula(colorPOI, covPOI, hasMixedSamples, fXfermode).hasSe condaryOutput();
813 } 813 }
814 814
815 GR_DEFINE_XP_FACTORY_TEST(GrPorterDuffXPFactory); 815 GR_DEFINE_XP_FACTORY_TEST(GrPDXPFactory);
816 816
817 const GrXPFactory* GrPorterDuffXPFactory::TestCreate(GrProcessorTestData* d) { 817 const GrXPFactory* GrPDXPFactory::TestCreate(GrProcessorTestData* d) {
818 SkXfermode::Mode mode = SkXfermode::Mode(d->fRandom->nextULessThan(SkXfermod e::kLastCoeffMode)); 818 SkXfermode::Mode mode = SkXfermode::Mode(d->fRandom->nextULessThan(SkXfermod e::kLastCoeffMode));
819 return GrPorterDuffXPFactory::Create(mode); 819 return GrPDXPFactory::Create(mode);
820 } 820 }
821 821
822 void GrPorterDuffXPFactory::TestGetXPOutputTypes(const GrXferProcessor* xp, 822 void GrPDXPFactory::TestGetXPOutputTypes(const GrXferProcessor* xp,
823 int* outPrimary, 823 int* outPrimary,
824 int* outSecondary) { 824 int* outSecondary) {
825 if (!!strcmp(xp->name(), "Porter Duff")) { 825 if (!!strcmp(xp->name(), "Porter Duff")) {
826 *outPrimary = *outSecondary = -1; 826 *outPrimary = *outSecondary = -1;
827 return; 827 return;
828 } 828 }
829 BlendFormula blendFormula = static_cast<const PorterDuffXferProcessor*>(xp)- >getBlendFormula(); 829 BlendFormula blendFormula = static_cast<const PorterDuffXferProcessor*>(xp)- >getBlendFormula();
830 *outPrimary = blendFormula.fPrimaryOutputType; 830 *outPrimary = blendFormula.fPrimaryOutputType;
831 *outSecondary = blendFormula.fSecondaryOutputType; 831 *outSecondary = blendFormula.fSecondaryOutputType;
832 } 832 }
833
834 ////////////////////////////////////////////////////////////////////////////////
835
836 GrSrcOverPDXPFactory::GrSrcOverPDXPFactory() {
837 this->initClassID<GrSrcOverPDXPFactory>();
838 }
839
840 GrXferProcessor*
841 GrSrcOverPDXPFactory::onCreateXferProcessor(const GrCaps& caps,
842 const GrProcOptInfo& colorPOI,
843 const GrProcOptInfo& covPOI,
844 bool hasMixedSamples,
845 const DstTexture* dstTexture) const {
846 BlendFormula blendFormula;
847 if (covPOI.isFourChannelOutput()) {
848 if (kRGBA_GrColorComponentFlags == colorPOI.validFlags() &&
849 !caps.shaderCaps()->dualSourceBlendingSupport() &&
850 !caps.shaderCaps()->dstReadInShaderSupport()) {
851 // If we don't have dual source blending or in shader dst reads, we fall back to this
852 // trick for rendering SrcOver LCD text instead of doing a dst copy.
853 SkASSERT(!dstTexture || !dstTexture->texture());
854 return PDLCDXferProcessor::Create(SkXfermode::kSrcOver_Mode, colorPO I);
855 }
856 blendFormula = get_lcd_blend_formula(covPOI, SkXfermode::kSrcOver_Mode);
857 } else {
858 blendFormula = get_blend_formula(colorPOI, covPOI, hasMixedSamples,
859 SkXfermode::kSrcOver_Mode);
860 }
861
862 if (blendFormula.hasSecondaryOutput() && !caps.shaderCaps()->dualSourceBlend ingSupport()) {
863 return new ShaderPDXferProcessor(dstTexture, hasMixedSamples, SkXfermode ::kSrcOver_Mode);
864 }
865
866 SkASSERT(!dstTexture || !dstTexture->texture());
867 return new PorterDuffXferProcessor(blendFormula);
868 }
869
870 void GrSrcOverPDXPFactory::getInvariantBlendedColor(const GrProcOptInfo& colorPO I,
871 InvariantBlendedColor* blend edColor) const {
872 if (!colorPOI.isOpaque()) {
873 blendedColor->fWillBlendWithDst = true;
874 blendedColor->fKnownColorFlags = kNone_GrColorComponentFlags;
875 return;
876 }
877
878 blendedColor->fWillBlendWithDst = false;
879
880 blendedColor->fKnownColor = colorPOI.color();
881 blendedColor->fKnownColorFlags = colorPOI.validFlags();
882 }
883
884 bool GrSrcOverPDXPFactory::willReadDstColor(const GrCaps& caps,
885 const GrProcOptInfo& colorPOI,
886 const GrProcOptInfo& covPOI,
887 bool hasMixedSamples) const {
888 if (caps.shaderCaps()->dualSourceBlendingSupport()) {
889 return false;
890 }
891
892 // When we have four channel coverage we always need to read the dst in orde r to correctly
893 // blend. The one exception is when we are using srcover mode and we know th e input color into
894 // the XP.
895 if (covPOI.isFourChannelOutput()) {
896 if (kRGBA_GrColorComponentFlags == colorPOI.validFlags() &&
897 !caps.shaderCaps()->dstReadInShaderSupport()) {
898 return false;
899 }
900 return get_lcd_blend_formula(covPOI, SkXfermode::kSrcOver_Mode).hasSecon daryOutput();
901 }
902 // We fallback on the shader XP when the blend formula would use dual source blending but we
903 // don't have support for it.
904 return get_blend_formula(colorPOI, covPOI,
905 hasMixedSamples, SkXfermode::kSrcOver_Mode).hasSeco ndaryOutput();
906 }
907
908 GR_DEFINE_XP_FACTORY_TEST(GrSrcOverPDXPFactory);
909
910 const GrXPFactory* GrSrcOverPDXPFactory::TestCreate(GrProcessorTestData* d) {
911 return SkRef(&GrPorterDuffXPFactory::gSrcOverPDXPFactory);
912 }
913
OLDNEW
« no previous file with comments | « src/gpu/effects/GrCustomXfermode.cpp ('k') | tests/GrPorterDuffTest.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698