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

Side by Side Diff: src/core/SkXfermode.cpp

Issue 844913003: Move XferEffects class to GrCustomXfermode file (Closed) Base URL: https://skia.googlesource.com/skia.git@arithXP
Patch Set: Fix build Created 5 years, 11 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 | « include/gpu/effects/GrCustomXfermode.h ('k') | src/gpu/effects/GrCustomXfermode.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 /* 2 /*
3 * Copyright 2006 The Android Open Source Project 3 * Copyright 2006 The Android Open Source Project
4 * 4 *
5 * Use of this source code is governed by a BSD-style license that can be 5 * Use of this source code is governed by a BSD-style license that can be
6 * found in the LICENSE file. 6 * found in the LICENSE file.
7 */ 7 */
8 8
9 #include "SkXfermode.h" 9 #include "SkXfermode.h"
10 #include "SkXfermode_opts_SSE2.h" 10 #include "SkXfermode_opts_SSE2.h"
(...skipping 777 matching lines...) Expand 10 before | Expand all | Expand 10 after
788 (SkPMColor)(dstA << SK_A32_SHIFT))); 788 (SkPMColor)(dstA << SK_A32_SHIFT)));
789 if (0xFF != a) { 789 if (0xFF != a) {
790 A = SkAlphaBlend(A, dstA, SkAlpha255To256(a)); 790 A = SkAlphaBlend(A, dstA, SkAlpha255To256(a));
791 } 791 }
792 dst[i] = SkToU8(A); 792 dst[i] = SkToU8(A);
793 } 793 }
794 } 794 }
795 } 795 }
796 } 796 }
797 797
798 //////////////////////////////////////////////////////////////////////////////
799
800 #if SK_SUPPORT_GPU
801
802 #include "GrFragmentProcessor.h"
803 #include "GrCoordTransform.h"
804 #include "GrInvariantOutput.h"
805 #include "GrProcessorUnitTest.h"
806 #include "gl/GrGLProcessor.h"
807 #include "gl/builders/GrGLProgramBuilder.h"
808
809 /**
810 * GrProcessor that implements the all the separable xfer modes that cannot be e xpressed as Coeffs.
811 */
812 class XferEffect : public GrFragmentProcessor {
813 public:
814 static bool IsSupportedMode(SkXfermode::Mode mode) {
815 return mode > SkXfermode::kLastCoeffMode && mode <= SkXfermode::kLastMod e;
816 }
817
818 static GrFragmentProcessor* Create(SkXfermode::Mode mode, GrTexture* backgro und) {
819 if (!IsSupportedMode(mode)) {
820 return NULL;
821 } else {
822 return SkNEW_ARGS(XferEffect, (mode, background));
823 }
824 }
825
826 virtual void getGLProcessorKey(const GrGLCaps& caps,
827 GrProcessorKeyBuilder* b) const SK_OVERRIDE {
828 GLProcessor::GenKey(*this, caps, b);
829 }
830
831 GrGLFragmentProcessor* createGLInstance() const SK_OVERRIDE {
832 return SkNEW_ARGS(GLProcessor, (*this));
833 }
834
835 const char* name() const SK_OVERRIDE { return "XferEffect"; }
836
837 SkXfermode::Mode mode() const { return fMode; }
838 const GrTextureAccess& backgroundAccess() const { return fBackgroundAccess; }
839
840 class GLProcessor : public GrGLFragmentProcessor {
841 public:
842 GLProcessor(const GrFragmentProcessor&) {}
843
844 virtual void emitCode(GrGLFPBuilder* builder,
845 const GrFragmentProcessor& fp,
846 const char* outputColor,
847 const char* inputColor,
848 const TransformedCoordsArray& coords,
849 const TextureSamplerArray& samplers) SK_OVERRIDE {
850 SkXfermode::Mode mode = fp.cast<XferEffect>().mode();
851 const GrTexture* backgroundTex =
852 fp.cast<XferEffect>().backgroundAccess().getTexture();
853 GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder ();
854 const char* dstColor;
855 if (backgroundTex) {
856 dstColor = "bgColor";
857 fsBuilder->codeAppendf("\t\tvec4 %s = ", dstColor);
858 fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), c oords[0].getType());
859 fsBuilder->codeAppendf(";\n");
860 } else {
861 dstColor = fsBuilder->dstColor();
862 }
863 SkASSERT(dstColor);
864
865 // We don't try to optimize for this case at all
866 if (NULL == inputColor) {
867 fsBuilder->codeAppendf("\t\tconst vec4 ones = vec4(1);\n");
868 inputColor = "ones";
869 }
870 fsBuilder->codeAppendf("\t\t// SkXfermode::Mode: %s\n", SkXfermode:: ModeName(mode));
871
872 // These all perform src-over on the alpha channel.
873 fsBuilder->codeAppendf("\t\t%s.a = %s.a + (1.0 - %s.a) * %s.a;\n",
874 outputColor, inputColor, inputColor, dstColo r);
875
876 switch (mode) {
877 case SkXfermode::kOverlay_Mode:
878 // Overlay is Hard-Light with the src and dst reversed
879 HardLight(fsBuilder, outputColor, dstColor, inputColor);
880 break;
881 case SkXfermode::kDarken_Mode:
882 fsBuilder->codeAppendf("\t\t%s.rgb = min((1.0 - %s.a) * %s.r gb + %s.rgb, "
883 "(1.0 - %s.a) * %s.r gb + %s.rgb);\n",
884 outputColor,
885 inputColor, dstColor, inputColor,
886 dstColor, inputColor, dstColor);
887 break;
888 case SkXfermode::kLighten_Mode:
889 fsBuilder->codeAppendf("\t\t%s.rgb = max((1.0 - %s.a) * %s.r gb + %s.rgb, "
890 "(1.0 - %s.a) * %s.r gb + %s.rgb);\n",
891 outputColor,
892 inputColor, dstColor, inputColor,
893 dstColor, inputColor, dstColor);
894 break;
895 case SkXfermode::kColorDodge_Mode:
896 ColorDodgeComponent(fsBuilder, outputColor, inputColor, dstC olor, 'r');
897 ColorDodgeComponent(fsBuilder, outputColor, inputColor, dstC olor, 'g');
898 ColorDodgeComponent(fsBuilder, outputColor, inputColor, dstC olor, 'b');
899 break;
900 case SkXfermode::kColorBurn_Mode:
901 ColorBurnComponent(fsBuilder, outputColor, inputColor, dstCo lor, 'r');
902 ColorBurnComponent(fsBuilder, outputColor, inputColor, dstCo lor, 'g');
903 ColorBurnComponent(fsBuilder, outputColor, inputColor, dstCo lor, 'b');
904 break;
905 case SkXfermode::kHardLight_Mode:
906 HardLight(fsBuilder, outputColor, inputColor, dstColor);
907 break;
908 case SkXfermode::kSoftLight_Mode:
909 fsBuilder->codeAppendf("\t\tif (0.0 == %s.a) {\n", dstColor) ;
910 fsBuilder->codeAppendf("\t\t\t%s.rgba = %s;\n", outputColor, inputColor);
911 fsBuilder->codeAppendf("\t\t} else {\n");
912 SoftLightComponentPosDstAlpha(fsBuilder, outputColor, inputC olor, dstColor, 'r');
913 SoftLightComponentPosDstAlpha(fsBuilder, outputColor, inputC olor, dstColor, 'g');
914 SoftLightComponentPosDstAlpha(fsBuilder, outputColor, inputC olor, dstColor, 'b');
915 fsBuilder->codeAppendf("\t\t}\n");
916 break;
917 case SkXfermode::kDifference_Mode:
918 fsBuilder->codeAppendf("\t\t%s.rgb = %s.rgb + %s.rgb -"
919 "2.0 * min(%s.rgb * %s.a, %s.rgb * %s.a);\n",
920 outputColor, inputColor, dstColor, in putColor, dstColor,
921 dstColor, inputColor);
922 break;
923 case SkXfermode::kExclusion_Mode:
924 fsBuilder->codeAppendf("\t\t%s.rgb = %s.rgb + %s.rgb - "
925 "2.0 * %s.rgb * %s.rgb;\ n",
926 outputColor, dstColor, inputColor, ds tColor, inputColor);
927 break;
928 case SkXfermode::kMultiply_Mode:
929 fsBuilder->codeAppendf("\t\t%s.rgb = (1.0 - %s.a) * %s.rgb + "
930 "(1.0 - %s.a) * %s.rgb + "
931 "%s.rgb * %s.rgb;\n",
932 outputColor, inputColor, dstColor, ds tColor, inputColor,
933 inputColor, dstColor);
934 break;
935 case SkXfermode::kHue_Mode: {
936 // SetLum(SetSat(S * Da, Sat(D * Sa)), Sa*Da, D*Sa) + (1 - Sa) * D + (1 - Da) * S
937 SkString setSat, setLum;
938 AddSatFunction(fsBuilder, &setSat);
939 AddLumFunction(fsBuilder, &setLum);
940 fsBuilder->codeAppendf("\t\tvec4 dstSrcAlpha = %s * %s.a;\n" ,
941 dstColor, inputColor);
942 fsBuilder->codeAppendf("\t\t%s.rgb = %s(%s(%s.rgb * %s.a, ds tSrcAlpha.rgb), dstSrcAlpha.a, dstSrcAlpha.rgb);\n",
943 outputColor, setLum.c_str(), setSat.c _str(), inputColor,
944 dstColor);
945 fsBuilder->codeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n",
946 outputColor, inputColor, dstColor, ds tColor, inputColor);
947 break;
948 }
949 case SkXfermode::kSaturation_Mode: {
950 // SetLum(SetSat(D * Sa, Sat(S * Da)), Sa*Da, D*Sa)) + (1 - Sa) * D + (1 - Da) * S
951 SkString setSat, setLum;
952 AddSatFunction(fsBuilder, &setSat);
953 AddLumFunction(fsBuilder, &setLum);
954 fsBuilder->codeAppendf("\t\tvec4 dstSrcAlpha = %s * %s.a;\n" ,
955 dstColor, inputColor);
956 fsBuilder->codeAppendf("\t\t%s.rgb = %s(%s(dstSrcAlpha.rgb, %s.rgb * %s.a), dstSrcAlpha.a, dstSrcAlpha.rgb);\n",
957 outputColor, setLum.c_str(), setSat.c _str(), inputColor,
958 dstColor);
959 fsBuilder->codeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n",
960 outputColor, inputColor, dstColor, ds tColor, inputColor);
961 break;
962 }
963 case SkXfermode::kColor_Mode: {
964 // SetLum(S * Da, Sa* Da, D * Sa) + (1 - Sa) * D + (1 - Da) * S
965 SkString setLum;
966 AddLumFunction(fsBuilder, &setLum);
967 fsBuilder->codeAppendf("\t\tvec4 srcDstAlpha = %s * %s.a;\n" ,
968 inputColor, dstColor);
969 fsBuilder->codeAppendf("\t\t%s.rgb = %s(srcDstAlpha.rgb, src DstAlpha.a, %s.rgb * %s.a);\n",
970 outputColor, setLum.c_str(), dstColor , inputColor);
971 fsBuilder->codeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n",
972 outputColor, inputColor, dstColor, ds tColor, inputColor);
973 break;
974 }
975 case SkXfermode::kLuminosity_Mode: {
976 // SetLum(D * Sa, Sa* Da, S * Da) + (1 - Sa) * D + (1 - Da) * S
977 SkString setLum;
978 AddLumFunction(fsBuilder, &setLum);
979 fsBuilder->codeAppendf("\t\tvec4 srcDstAlpha = %s * %s.a;\n" ,
980 inputColor, dstColor);
981 fsBuilder->codeAppendf("\t\t%s.rgb = %s(%s.rgb * %s.a, srcDs tAlpha.a, srcDstAlpha.rgb);\n",
982 outputColor, setLum.c_str(), dstColor , inputColor);
983 fsBuilder->codeAppendf("\t\t%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s.a) * %s.rgb;\n",
984 outputColor, inputColor, dstColor, ds tColor, inputColor);
985 break;
986 }
987 default:
988 SkFAIL("Unknown XferEffect mode.");
989 break;
990 }
991 }
992
993 static inline void GenKey(const GrProcessor& proc, const GrGLCaps&,
994 GrProcessorKeyBuilder* b) {
995 // The background may come from the dst or from a texture.
996 uint32_t key = proc.numTextures();
997 SkASSERT(key <= 1);
998 key |= proc.cast<XferEffect>().mode() << 1;
999 b->add32(key);
1000 }
1001
1002 private:
1003 static void HardLight(GrGLFPFragmentBuilder* fsBuilder,
1004 const char* final,
1005 const char* src,
1006 const char* dst) {
1007 static const char kComponents[] = {'r', 'g', 'b'};
1008 for (size_t i = 0; i < SK_ARRAY_COUNT(kComponents); ++i) {
1009 char component = kComponents[i];
1010 fsBuilder->codeAppendf("\t\tif (2.0 * %s.%c <= %s.a) {\n", src, component, src);
1011 fsBuilder->codeAppendf("\t\t\t%s.%c = 2.0 * %s.%c * %s.%c;\n", f inal, component, src, component, dst, component);
1012 fsBuilder->codeAppend("\t\t} else {\n");
1013 fsBuilder->codeAppendf("\t\t\t%s.%c = %s.a * %s.a - 2.0 * (%s.a - %s.%c) * (%s.a - %s.%c);\n",
1014 final, component, src, dst, dst, dst, com ponent, src, src, component);
1015 fsBuilder->codeAppend("\t\t}\n");
1016 }
1017 fsBuilder->codeAppendf("\t\t%s.rgb += %s.rgb * (1.0 - %s.a) + %s.rgb * (1.0 - %s.a);\n",
1018 final, src, dst, dst, src);
1019 }
1020
1021 // Does one component of color-dodge
1022 static void ColorDodgeComponent(GrGLFPFragmentBuilder* fsBuilder,
1023 const char* final,
1024 const char* src,
1025 const char* dst,
1026 const char component) {
1027 fsBuilder->codeAppendf("\t\tif (0.0 == %s.%c) {\n", dst, component);
1028 fsBuilder->codeAppendf("\t\t\t%s.%c = %s.%c * (1.0 - %s.a);\n",
1029 final, component, src, component, dst);
1030 fsBuilder->codeAppend("\t\t} else {\n");
1031 fsBuilder->codeAppendf("\t\t\tfloat d = %s.a - %s.%c;\n", src, src, component);
1032 fsBuilder->codeAppend("\t\t\tif (0.0 == d) {\n");
1033 fsBuilder->codeAppendf("\t\t\t\t%s.%c = %s.a * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);\n",
1034 final, component, src, dst, src, component, d st, dst, component,
1035 src);
1036 fsBuilder->codeAppend("\t\t\t} else {\n");
1037 fsBuilder->codeAppendf("\t\t\t\td = min(%s.a, %s.%c * %s.a / d);\n",
1038 dst, dst, component, src);
1039 fsBuilder->codeAppendf("\t\t\t\t%s.%c = d * %s.a + %s.%c * (1.0 - %s .a) + %s.%c * (1.0 - %s.a);\n",
1040 final, component, src, src, component, dst, d st, component, src);
1041 fsBuilder->codeAppend("\t\t\t}\n");
1042 fsBuilder->codeAppend("\t\t}\n");
1043 }
1044
1045 // Does one component of color-burn
1046 static void ColorBurnComponent(GrGLFPFragmentBuilder* fsBuilder,
1047 const char* final,
1048 const char* src,
1049 const char* dst,
1050 const char component) {
1051 fsBuilder->codeAppendf("\t\tif (%s.a == %s.%c) {\n", dst, dst, compo nent);
1052 fsBuilder->codeAppendf("\t\t\t%s.%c = %s.a * %s.a + %s.%c * (1.0 - % s.a) + %s.%c * (1.0 - %s.a);\n",
1053 final, component, src, dst, src, component, d st, dst, component,
1054 src);
1055 fsBuilder->codeAppendf("\t\t} else if (0.0 == %s.%c) {\n", src, comp onent);
1056 fsBuilder->codeAppendf("\t\t\t%s.%c = %s.%c * (1.0 - %s.a);\n",
1057 final, component, dst, component, src);
1058 fsBuilder->codeAppend("\t\t} else {\n");
1059 fsBuilder->codeAppendf("\t\t\tfloat d = max(0.0, %s.a - (%s.a - %s.% c) * %s.a / %s.%c);\n",
1060 dst, dst, dst, component, src, src, component );
1061 fsBuilder->codeAppendf("\t\t\t%s.%c = %s.a * d + %s.%c * (1.0 - %s.a ) + %s.%c * (1.0 - %s.a);\n",
1062 final, component, src, src, component, dst, d st, component, src);
1063 fsBuilder->codeAppend("\t\t}\n");
1064 }
1065
1066 // Does one component of soft-light. Caller should have already checked that dst alpha > 0.
1067 static void SoftLightComponentPosDstAlpha(GrGLFPFragmentBuilder* fsBuild er,
1068 const char* final,
1069 const char* src,
1070 const char* dst,
1071 const char component) {
1072 // if (2S < Sa)
1073 fsBuilder->codeAppendf("\t\t\tif (2.0 * %s.%c <= %s.a) {\n", src, co mponent, src);
1074 // (D^2 (Sa-2 S))/Da+(1-Da) S+D (-Sa+2 S+1)
1075 fsBuilder->codeAppendf("\t\t\t\t%s.%c = (%s.%c*%s.%c*(%s.a - 2.0*%s. %c)) / %s.a + (1.0 - %s.a) * %s.%c + %s.%c*(-%s.a + 2.0*%s.%c + 1.0);\n",
1076 final, component, dst, component, dst, compon ent, src, src,
1077 component, dst, dst, src, component, dst, com ponent, src, src,
1078 component);
1079 // else if (4D < Da)
1080 fsBuilder->codeAppendf("\t\t\t} else if (4.0 * %s.%c <= %s.a) {\n",
1081 dst, component, dst);
1082 fsBuilder->codeAppendf("\t\t\t\tfloat DSqd = %s.%c * %s.%c;\n",
1083 dst, component, dst, component);
1084 fsBuilder->codeAppendf("\t\t\t\tfloat DCub = DSqd * %s.%c;\n", dst, component);
1085 fsBuilder->codeAppendf("\t\t\t\tfloat DaSqd = %s.a * %s.a;\n", dst, dst);
1086 fsBuilder->codeAppendf("\t\t\t\tfloat DaCub = DaSqd * %s.a;\n", dst) ;
1087 // (Da^3 (-S)+Da^2 (S-D (3 Sa-6 S-1))+12 Da D^2 (Sa-2 S)-16 D^3 (Sa- 2 S))/Da^2
1088 fsBuilder->codeAppendf("\t\t\t\t%s.%c = (-DaCub*%s.%c + DaSqd*(%s.%c - %s.%c * (3.0*%s.a - 6.0*%s.%c - 1.0)) + 12.0*%s.a*DSqd*(%s.a - 2.0*%s.%c) - 1 6.0*DCub * (%s.a - 2.0*%s.%c)) / DaSqd;\n",
1089 final, component, src, component, src, compon ent, dst, component,
1090 src, src, component, dst, src, src, component , src, src,
1091 component);
1092 fsBuilder->codeAppendf("\t\t\t} else {\n");
1093 // -sqrt(Da * D) (Sa-2 S)-Da S+D (Sa-2 S+1)+S
1094 fsBuilder->codeAppendf("\t\t\t\t%s.%c = -sqrt(%s.a*%s.%c)*(%s.a - 2. 0*%s.%c) - %s.a*%s.%c + %s.%c*(%s.a - 2.0*%s.%c + 1.0) + %s.%c;\n",
1095 final, component, dst, dst, component, src, src, component, dst,
1096 src, component, dst, component, src, src, co mponent, src,
1097 component);
1098 fsBuilder->codeAppendf("\t\t\t}\n");
1099 }
1100
1101 // Adds a function that takes two colors and an alpha as input. It produ ces a color with the
1102 // hue and saturation of the first color, the luminosity of the second c olor, and the input
1103 // alpha. It has this signature:
1104 // vec3 set_luminance(vec3 hueSatColor, float alpha, vec3 lumColor) .
1105 static void AddLumFunction(GrGLFPFragmentBuilder* fsBuilder, SkString* s etLumFunction) {
1106 // Emit a helper that gets the luminance of a color.
1107 SkString getFunction;
1108 GrGLShaderVar getLumArgs[] = {
1109 GrGLShaderVar("color", kVec3f_GrSLType),
1110 };
1111 SkString getLumBody("\treturn dot(vec3(0.3, 0.59, 0.11), color);\n") ;
1112 fsBuilder->emitFunction(kFloat_GrSLType,
1113 "luminance",
1114 SK_ARRAY_COUNT(getLumArgs), getLumArgs,
1115 getLumBody.c_str(),
1116 &getFunction);
1117
1118 // Emit the set luminance function.
1119 GrGLShaderVar setLumArgs[] = {
1120 GrGLShaderVar("hueSat", kVec3f_GrSLType),
1121 GrGLShaderVar("alpha", kFloat_GrSLType),
1122 GrGLShaderVar("lumColor", kVec3f_GrSLType),
1123 };
1124 SkString setLumBody;
1125 setLumBody.printf("\tfloat diff = %s(lumColor - hueSat);\n", getFunc tion.c_str());
1126 setLumBody.append("\tvec3 outColor = hueSat + diff;\n");
1127 setLumBody.appendf("\tfloat outLum = %s(outColor);\n", getFunction.c _str());
1128 setLumBody.append("\tfloat minComp = min(min(outColor.r, outColor.g) , outColor.b);\n"
1129 "\tfloat maxComp = max(max(outColor.r, outColor.g) , outColor.b);\n"
1130 "\tif (minComp < 0.0 && outLum != minComp) {\n"
1131 "\t\toutColor = outLum + ((outColor - vec3(outLum, outLum, outLum)) * outLum) / (outLum - minComp);\n"
1132 "\t}\n"
1133 "\tif (maxComp > alpha && maxComp != outLum) {\n"
1134 "\t\toutColor = outLum + ((outColor - vec3(outLum, outLum, outLum)) * (alpha - outLum)) / (maxComp - outLum);\n"
1135 "\t}\n"
1136 "\treturn outColor;\n");
1137 fsBuilder->emitFunction(kVec3f_GrSLType,
1138 "set_luminance",
1139 SK_ARRAY_COUNT(setLumArgs), setLumArgs,
1140 setLumBody.c_str(),
1141 setLumFunction);
1142 }
1143
1144 // Adds a function that creates a color with the hue and luminosity of o ne input color and
1145 // the saturation of another color. It will have this signature:
1146 // float set_saturation(vec3 hueLumColor, vec3 satColor)
1147 static void AddSatFunction(GrGLFPFragmentBuilder* fsBuilder, SkString* s etSatFunction) {
1148 // Emit a helper that gets the saturation of a color
1149 SkString getFunction;
1150 GrGLShaderVar getSatArgs[] = { GrGLShaderVar("color", kVec3f_GrSLTyp e) };
1151 SkString getSatBody;
1152 getSatBody.printf("\treturn max(max(color.r, color.g), color.b) - "
1153 "min(min(color.r, color.g), color.b);\n");
1154 fsBuilder->emitFunction(kFloat_GrSLType,
1155 "saturation",
1156 SK_ARRAY_COUNT(getSatArgs), getSatArgs,
1157 getSatBody.c_str(),
1158 &getFunction);
1159
1160 // Emit a helper that sets the saturation given sorted input channel s. This used
1161 // to use inout params for min, mid, and max components but that see ms to cause
1162 // problems on PowerVR drivers. So instead it returns a vec3 where r , g ,b are the
1163 // adjusted min, mid, and max inputs, respectively.
1164 SkString helperFunction;
1165 GrGLShaderVar helperArgs[] = {
1166 GrGLShaderVar("minComp", kFloat_GrSLType),
1167 GrGLShaderVar("midComp", kFloat_GrSLType),
1168 GrGLShaderVar("maxComp", kFloat_GrSLType),
1169 GrGLShaderVar("sat", kFloat_GrSLType),
1170 };
1171 static const char kHelperBody[] = "\tif (minComp < maxComp) {\n"
1172 "\t\tvec3 result;\n"
1173 "\t\tresult.r = 0.0;\n"
1174 "\t\tresult.g = sat * (midComp - m inComp) / (maxComp - minComp);\n"
1175 "\t\tresult.b = sat;\n"
1176 "\t\treturn result;\n"
1177 "\t} else {\n"
1178 "\t\treturn vec3(0, 0, 0);\n"
1179 "\t}\n";
1180 fsBuilder->emitFunction(kVec3f_GrSLType,
1181 "set_saturation_helper",
1182 SK_ARRAY_COUNT(helperArgs), helperArgs,
1183 kHelperBody,
1184 &helperFunction);
1185
1186 GrGLShaderVar setSatArgs[] = {
1187 GrGLShaderVar("hueLumColor", kVec3f_GrSLType),
1188 GrGLShaderVar("satColor", kVec3f_GrSLType),
1189 };
1190 const char* helpFunc = helperFunction.c_str();
1191 SkString setSatBody;
1192 setSatBody.appendf("\tfloat sat = %s(satColor);\n"
1193 "\tif (hueLumColor.r <= hueLumColor.g) {\n"
1194 "\t\tif (hueLumColor.g <= hueLumColor.b) {\n"
1195 "\t\t\thueLumColor.rgb = %s(hueLumColor.r, hueLum Color.g, hueLumColor.b, sat);\n"
1196 "\t\t} else if (hueLumColor.r <= hueLumColor.b) { \n"
1197 "\t\t\thueLumColor.rbg = %s(hueLumColor.r, hueLum Color.b, hueLumColor.g, sat);\n"
1198 "\t\t} else {\n"
1199 "\t\t\thueLumColor.brg = %s(hueLumColor.b, hueLum Color.r, hueLumColor.g, sat);\n"
1200 "\t\t}\n"
1201 "\t} else if (hueLumColor.r <= hueLumColor.b) {\n "
1202 "\t\thueLumColor.grb = %s(hueLumColor.g, hueLumCo lor.r, hueLumColor.b, sat);\n"
1203 "\t} else if (hueLumColor.g <= hueLumColor.b) {\n "
1204 "\t\thueLumColor.gbr = %s(hueLumColor.g, hueLumCo lor.b, hueLumColor.r, sat);\n"
1205 "\t} else {\n"
1206 "\t\thueLumColor.bgr = %s(hueLumColor.b, hueLumCo lor.g, hueLumColor.r, sat);\n"
1207 "\t}\n"
1208 "\treturn hueLumColor;\n",
1209 getFunction.c_str(), helpFunc, helpFunc, helpFunc , helpFunc,
1210 helpFunc, helpFunc);
1211 fsBuilder->emitFunction(kVec3f_GrSLType,
1212 "set_saturation",
1213 SK_ARRAY_COUNT(setSatArgs), setSatArgs,
1214 setSatBody.c_str(),
1215 setSatFunction);
1216
1217 }
1218
1219 typedef GrGLFragmentProcessor INHERITED;
1220 };
1221
1222 GR_DECLARE_FRAGMENT_PROCESSOR_TEST;
1223
1224 private:
1225 XferEffect(SkXfermode::Mode mode, GrTexture* background)
1226 : fMode(mode) {
1227 this->initClassID<XferEffect>();
1228 if (background) {
1229 fBackgroundTransform.reset(kLocal_GrCoordSet, background,
1230 GrTextureParams::kNone_FilterMode);
1231 this->addCoordTransform(&fBackgroundTransform);
1232 fBackgroundAccess.reset(background);
1233 this->addTextureAccess(&fBackgroundAccess);
1234 } else {
1235 this->setWillReadDstColor();
1236 }
1237 }
1238 bool onIsEqual(const GrFragmentProcessor& other) const SK_OVERRIDE {
1239 const XferEffect& s = other.cast<XferEffect>();
1240 return fMode == s.fMode;
1241 }
1242
1243 void onComputeInvariantOutput(GrInvariantOutput* inout) const SK_OVERRIDE {
1244 inout->setToUnknown(GrInvariantOutput::kWill_ReadInput);
1245 }
1246
1247 SkXfermode::Mode fMode;
1248 GrCoordTransform fBackgroundTransform;
1249 GrTextureAccess fBackgroundAccess;
1250
1251 typedef GrFragmentProcessor INHERITED;
1252 };
1253
1254 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(XferEffect);
1255 GrFragmentProcessor* XferEffect::TestCreate(SkRandom* rand,
1256 GrContext*,
1257 const GrDrawTargetCaps&,
1258 GrTexture*[]) {
1259 int mode = rand->nextRangeU(SkXfermode::kLastCoeffMode + 1, SkXfermode::kLas tSeparableMode);
1260
1261 return SkNEW_ARGS(XferEffect, (static_cast<SkXfermode::Mode>(mode), NULL));
1262 }
1263
1264 #endif
1265
1266 /////////////////////////////////////////////////////////////////////////////// 798 ///////////////////////////////////////////////////////////////////////////////
1267 /////////////////////////////////////////////////////////////////////////////// 799 ///////////////////////////////////////////////////////////////////////////////
1268 800
1269 SkFlattenable* SkProcCoeffXfermode::CreateProc(SkReadBuffer& buffer) { 801 SkFlattenable* SkProcCoeffXfermode::CreateProc(SkReadBuffer& buffer) {
1270 uint32_t mode32 = buffer.read32(); 802 uint32_t mode32 = buffer.read32();
1271 if (!buffer.validate(mode32 < SK_ARRAY_COUNT(gProcCoeffs))) { 803 if (!buffer.validate(mode32 < SK_ARRAY_COUNT(gProcCoeffs))) {
1272 return NULL; 804 return NULL;
1273 } 805 }
1274 return SkXfermode::Create((SkXfermode::Mode)mode32); 806 return SkXfermode::Create((SkXfermode::Mode)mode32);
1275 } 807 }
(...skipping 104 matching lines...) Expand 10 before | Expand all | Expand 10 after
1380 A = SkAlphaBlend(A, dstA, SkAlpha255To256(a)); 912 A = SkAlphaBlend(A, dstA, SkAlpha255To256(a));
1381 } 913 }
1382 dst[i] = SkToU8(A); 914 dst[i] = SkToU8(A);
1383 } 915 }
1384 } 916 }
1385 } 917 }
1386 } 918 }
1387 } 919 }
1388 920
1389 #if SK_SUPPORT_GPU 921 #if SK_SUPPORT_GPU
922 #include "effects/GrCustomXfermode.h"
923
1390 bool SkProcCoeffXfermode::asFragmentProcessor(GrFragmentProcessor** fp, 924 bool SkProcCoeffXfermode::asFragmentProcessor(GrFragmentProcessor** fp,
1391 GrTexture* background) const { 925 GrTexture* background) const {
1392 if (XferEffect::IsSupportedMode(fMode)) { 926 if (GrCustomXfermode::IsSupportedMode(fMode)) {
1393 if (fp) { 927 if (fp) {
1394 *fp = XferEffect::Create(fMode, background); 928 *fp = GrCustomXfermode::CreateFP(fMode, background);
1395 SkASSERT(*fp); 929 SkASSERT(*fp);
1396 } 930 }
1397 return true; 931 return true;
1398 } 932 }
1399 return false; 933 return false;
1400 } 934 }
1401 #endif 935 #endif
1402 936
1403 const char* SkXfermode::ModeName(Mode mode) { 937 const char* SkXfermode::ModeName(Mode mode) {
1404 SkASSERT((unsigned) mode <= (unsigned)kLastMode); 938 SkASSERT((unsigned) mode <= (unsigned)kLastMode);
(...skipping 548 matching lines...) Expand 10 before | Expand all | Expand 10 after
1953 } else { 1487 } else {
1954 proc16 = rec.fProc16_General; 1488 proc16 = rec.fProc16_General;
1955 } 1489 }
1956 } 1490 }
1957 return proc16; 1491 return proc16;
1958 } 1492 }
1959 1493
1960 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode) 1494 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_START(SkXfermode)
1961 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode) 1495 SK_DEFINE_FLATTENABLE_REGISTRAR_ENTRY(SkProcCoeffXfermode)
1962 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END 1496 SK_DEFINE_FLATTENABLE_REGISTRAR_GROUP_END
OLDNEW
« no previous file with comments | « include/gpu/effects/GrCustomXfermode.h ('k') | src/gpu/effects/GrCustomXfermode.cpp » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698