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

Side by Side Diff: src/gpu/effects/GrCustomXfermode.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 | « src/core/SkXfermode.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
(Empty)
1 /*
2 * Copyright 2015 Google Inc.
3 *
4 * Use of this source code is governed by a BSD-style license that can be
5 * found in the LICENSE file.
6 */
7
8 #include "effects/GrCustomXfermode.h"
9 #include "effects/GrCustomXfermodePriv.h"
10
11 #include "GrCoordTransform.h"
12 #include "GrContext.h"
13 #include "GrFragmentProcessor.h"
14 #include "GrInvariantOutput.h"
15 #include "GrProcessor.h"
16 #include "GrTexture.h"
17 #include "GrTextureAccess.h"
18 #include "SkXfermode.h"
19 #include "gl/GrGLCaps.h"
20 #include "gl/GrGLProcessor.h"
21 #include "gl/GrGLProgramDataManager.h"
22 #include "gl/builders/GrGLProgramBuilder.h"
23
24 bool GrCustomXfermode::IsSupportedMode(SkXfermode::Mode mode) {
25 return mode > SkXfermode::kLastCoeffMode && mode <= SkXfermode::kLastMode;
26 }
27
28 ///////////////////////////////////////////////////////////////////////////////
29 // Static helpers
30 ///////////////////////////////////////////////////////////////////////////////
31
32 static void hard_light(GrGLFPFragmentBuilder* fsBuilder,
33 const char* final,
34 const char* src,
35 const char* dst) {
36 static const char kComponents[] = {'r', 'g', 'b'};
37 for (size_t i = 0; i < SK_ARRAY_COUNT(kComponents); ++i) {
38 char component = kComponents[i];
39 fsBuilder->codeAppendf("if (2.0 * %s.%c <= %s.a) {", src, component, src );
40 fsBuilder->codeAppendf("%s.%c = 2.0 * %s.%c * %s.%c;",
41 final, component, src, component, dst, component) ;
42 fsBuilder->codeAppend("} else {");
43 fsBuilder->codeAppendf("%s.%c = %s.a * %s.a - 2.0 * (%s.a - %s.%c) * (%s .a - %s.%c);",
44 final, component, src, dst, dst, dst, component, src, src,
45 component);
46 fsBuilder->codeAppend("}");
47 }
48 fsBuilder->codeAppendf("%s.rgb += %s.rgb * (1.0 - %s.a) + %s.rgb * (1.0 - %s .a);",
49 final, src, dst, dst, src);
50 }
51
52 // Does one component of color-dodge
53 static void color_dodge_component(GrGLFPFragmentBuilder* fsBuilder,
54 const char* final,
55 const char* src,
56 const char* dst,
57 const char component) {
58 fsBuilder->codeAppendf("if (0.0 == %s.%c) {", dst, component);
59 fsBuilder->codeAppendf("%s.%c = %s.%c * (1.0 - %s.a);",
60 final, component, src, component, dst);
61 fsBuilder->codeAppend("} else {");
62 fsBuilder->codeAppendf("float d = %s.a - %s.%c;", src, src, component);
63 fsBuilder->codeAppend("if (0.0 == d) {");
64 fsBuilder->codeAppendf("%s.%c = %s.a * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);",
65 final, component, src, dst, src, component, dst, dst, component,
66 src);
67 fsBuilder->codeAppend("} else {");
68 fsBuilder->codeAppendf("d = min(%s.a, %s.%c * %s.a / d);",
69 dst, dst, component, src);
70 fsBuilder->codeAppendf("%s.%c = d * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1 .0 - %s.a);",
71 final, component, src, src, component, dst, dst, comp onent, src);
72 fsBuilder->codeAppend("}");
73 fsBuilder->codeAppend("}");
74 }
75
76 // Does one component of color-burn
77 static void color_burn_component(GrGLFPFragmentBuilder* fsBuilder,
78 const char* final,
79 const char* src,
80 const char* dst,
81 const char component) {
82 fsBuilder->codeAppendf("if (%s.a == %s.%c) {", dst, dst, component);
83 fsBuilder->codeAppendf("%s.%c = %s.a * %s.a + %s.%c * (1.0 - %s.a) + %s.%c * (1.0 - %s.a);",
84 final, component, src, dst, src, component, dst, dst, component,
85 src);
86 fsBuilder->codeAppendf("} else if (0.0 == %s.%c) {", src, component);
87 fsBuilder->codeAppendf("%s.%c = %s.%c * (1.0 - %s.a);",
88 final, component, dst, component, src);
89 fsBuilder->codeAppend("} else {");
90 fsBuilder->codeAppendf("float d = max(0.0, %s.a - (%s.a - %s.%c) * %s.a / %s .%c);",
91 dst, dst, dst, component, src, src, component);
92 fsBuilder->codeAppendf("%s.%c = %s.a * d + %s.%c * (1.0 - %s.a) + %s.%c * (1 .0 - %s.a);",
93 final, component, src, src, component, dst, dst, comp onent, src);
94 fsBuilder->codeAppend("}");
95 }
96
97 // Does one component of soft-light. Caller should have already checked that dst alpha > 0.
98 static void soft_light_component_pos_dst_alpha(GrGLFPFragmentBuilder* fsBuilder,
99 const char* final,
100 const char* src,
101 const char* dst,
102 const char component) {
103 // if (2S < Sa)
104 fsBuilder->codeAppendf("if (2.0 * %s.%c <= %s.a) {", src, component, src);
105 // (D^2 (Sa-2 S))/Da+(1-Da) S+D (-Sa+2 S+1)
106 fsBuilder->codeAppendf("%s.%c = (%s.%c*%s.%c*(%s.a - 2.0*%s.%c)) / %s.a +"
107 "(1.0 - %s.a) * %s.%c + %s.%c*(-%s.a + 2.0*%s .%c + 1.0);",
108 final, component, dst, component, dst, component, src , src,
109 component, dst, dst, src, component, dst, component, src, src,
110 component);
111 // else if (4D < Da)
112 fsBuilder->codeAppendf("} else if (4.0 * %s.%c <= %s.a) {",
113 dst, component, dst);
114 fsBuilder->codeAppendf("float DSqd = %s.%c * %s.%c;",
115 dst, component, dst, component);
116 fsBuilder->codeAppendf("float DCub = DSqd * %s.%c;", dst, component);
117 fsBuilder->codeAppendf("float DaSqd = %s.a * %s.a;", dst, dst);
118 fsBuilder->codeAppendf("float DaCub = DaSqd * %s.a;", dst);
119 // (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
120 fsBuilder->codeAppendf("%s.%c ="
121 "(-DaCub*%s.%c + DaSqd*(%s.%c - %s.%c * (3.0*%s.a - 6 .0*%s.%c - 1.0)) +"
122 " 12.0*%s.a*DSqd*(%s.a - 2.0*%s.%c) - 16.0*DCub * (%s .a - 2.0*%s.%c)) /"
123 "DaSqd;",
124 final, component, src, component, src, component, dst , component,
125 src, src, component, dst, src, src, component, src, s rc,
126 component);
127 fsBuilder->codeAppendf("} else {");
128 // -sqrt(Da * D) (Sa-2 S)-Da S+D (Sa-2 S+1)+S
129 fsBuilder->codeAppendf("%s.%c = -sqrt(%s.a*%s.%c)*(%s.a - 2.0*%s.%c) - %s.a* %s.%c +"
130 "%s.%c*(%s.a - 2.0*%s.%c + 1.0) + %s.%c;",
131 final, component, dst, dst, component, src, src, comp onent, dst,
132 src, component, dst, component, src, src, component, src,
133 component);
134 fsBuilder->codeAppendf("}");
135 }
136
137 // Adds a function that takes two colors and an alpha as input. It produces a co lor with the
138 // hue and saturation of the first color, the luminosity of the second color, an d the input
139 // alpha. It has this signature:
140 // vec3 set_luminance(vec3 hueSatColor, float alpha, vec3 lumColor).
141 static void add_lum_function(GrGLFPFragmentBuilder* fsBuilder, SkString* setLumF unction) {
142 // Emit a helper that gets the luminance of a color.
143 SkString getFunction;
144 GrGLShaderVar getLumArgs[] = {
145 GrGLShaderVar("color", kVec3f_GrSLType),
146 };
147 SkString getLumBody("return dot(vec3(0.3, 0.59, 0.11), color);");
148 fsBuilder->emitFunction(kFloat_GrSLType,
149 "luminance",
150 SK_ARRAY_COUNT(getLumArgs), getLumArgs,
151 getLumBody.c_str(),
152 &getFunction);
153
154 // Emit the set luminance function.
155 GrGLShaderVar setLumArgs[] = {
156 GrGLShaderVar("hueSat", kVec3f_GrSLType),
157 GrGLShaderVar("alpha", kFloat_GrSLType),
158 GrGLShaderVar("lumColor", kVec3f_GrSLType),
159 };
160 SkString setLumBody;
161 setLumBody.printf("float diff = %s(lumColor - hueSat);", getFunction.c_str() );
162 setLumBody.append("vec3 outColor = hueSat + diff;");
163 setLumBody.appendf("float outLum = %s(outColor);", getFunction.c_str());
164 setLumBody.append("float minComp = min(min(outColor.r, outColor.g), outColor .b);"
165 "float maxComp = max(max(outColor.r, outColor.g), outColor .b);"
166 "if (minComp < 0.0 && outLum != minComp) {"
167 "outColor = outLum + ((outColor - vec3(outLum, outLum, out Lum)) * outLum) /"
168 "(outLum - minComp);"
169 "}"
170 "if (maxComp > alpha && maxComp != outLum) {"
171 "outColor = outLum +"
172 "((outColor - vec3(outLum, outLum, outLum)) * ( alpha - outLum)) /"
173 "(maxComp - outLum);"
174 "}"
175 "return outColor;");
176 fsBuilder->emitFunction(kVec3f_GrSLType,
177 "set_luminance",
178 SK_ARRAY_COUNT(setLumArgs), setLumArgs,
179 setLumBody.c_str(),
180 setLumFunction);
181 }
182
183 // Adds a function that creates a color with the hue and luminosity of one input color and
184 // the saturation of another color. It will have this signature:
185 // float set_saturation(vec3 hueLumColor, vec3 satColor)
186 static void add_sat_function(GrGLFPFragmentBuilder* fsBuilder, SkString* setSatF unction) {
187 // Emit a helper that gets the saturation of a color
188 SkString getFunction;
189 GrGLShaderVar getSatArgs[] = { GrGLShaderVar("color", kVec3f_GrSLType) };
190 SkString getSatBody;
191 getSatBody.printf("return max(max(color.r, color.g), color.b) - "
192 "min(min(color.r, color.g), color.b);");
193 fsBuilder->emitFunction(kFloat_GrSLType,
194 "saturation",
195 SK_ARRAY_COUNT(getSatArgs), getSatArgs,
196 getSatBody.c_str(),
197 &getFunction);
198
199 // Emit a helper that sets the saturation given sorted input channels. This used
200 // to use inout params for min, mid, and max components but that seems to ca use
201 // problems on PowerVR drivers. So instead it returns a vec3 where r, g ,b a re the
202 // adjusted min, mid, and max inputs, respectively.
203 SkString helperFunction;
204 GrGLShaderVar helperArgs[] = {
205 GrGLShaderVar("minComp", kFloat_GrSLType),
206 GrGLShaderVar("midComp", kFloat_GrSLType),
207 GrGLShaderVar("maxComp", kFloat_GrSLType),
208 GrGLShaderVar("sat", kFloat_GrSLType),
209 };
210 static const char kHelperBody[] = "if (minComp < maxComp) {"
211 "vec3 result;"
212 "result.r = 0.0;"
213 "result.g = sat * (midComp - minComp) / (maxComp - minComp);"
214 "result.b = sat;"
215 "return result;"
216 "} else {"
217 "return vec3(0, 0, 0);"
218 "}";
219 fsBuilder->emitFunction(kVec3f_GrSLType,
220 "set_saturation_helper",
221 SK_ARRAY_COUNT(helperArgs), helperArgs,
222 kHelperBody,
223 &helperFunction);
224
225 GrGLShaderVar setSatArgs[] = {
226 GrGLShaderVar("hueLumColor", kVec3f_GrSLType),
227 GrGLShaderVar("satColor", kVec3f_GrSLType),
228 };
229 const char* helpFunc = helperFunction.c_str();
230 SkString setSatBody;
231 setSatBody.appendf("float sat = %s(satColor);"
232 "if (hueLumColor.r <= hueLumColor.g) {"
233 "if (hueLumColor.g <= hueLumColor.b) {"
234 "hueLumColor.rgb = %s(hueLumColor.r, hueLumColor.g, hueLu mColor.b, sat);"
235 "} else if (hueLumColor.r <= hueLumColor.b) {"
236 "hueLumColor.rbg = %s(hueLumColor.r, hueLumColor.b, hueLu mColor.g, sat);"
237 "} else {"
238 "hueLumColor.brg = %s(hueLumColor.b, hueLumColor.r, hueLu mColor.g, sat);"
239 "}"
240 "} else if (hueLumColor.r <= hueLumColor.b) {"
241 "hueLumColor.grb = %s(hueLumColor.g, hueLumColor.r, hueLu mColor.b, sat);"
242 "} else if (hueLumColor.g <= hueLumColor.b) {"
243 "hueLumColor.gbr = %s(hueLumColor.g, hueLumColor.b, hueLu mColor.r, sat);"
244 "} else {"
245 "hueLumColor.bgr = %s(hueLumColor.b, hueLumColor.g, hueLu mColor.r, sat);"
246 "}"
247 "return hueLumColor;",
248 getFunction.c_str(), helpFunc, helpFunc, helpFunc, helpFu nc,
249 helpFunc, helpFunc);
250 fsBuilder->emitFunction(kVec3f_GrSLType,
251 "set_saturation",
252 SK_ARRAY_COUNT(setSatArgs), setSatArgs,
253 setSatBody.c_str(),
254 setSatFunction);
255
256 }
257
258 static void emit_custom_xfermode_code(SkXfermode::Mode mode,
259 GrGLFPFragmentBuilder* fsBuilder,
260 const char* outputColor,
261 const char* inputColor,
262 const char* dstColor) {
263 // We don't try to optimize for this case at all
264 if (NULL == inputColor) {
265 fsBuilder->codeAppendf("const vec4 ones = vec4(1);");
266 inputColor = "ones";
267 }
268 fsBuilder->codeAppendf("// SkXfermode::Mode: %s\n", SkXfermode::ModeName(mod e));
269
270 // These all perform src-over on the alpha channel.
271 fsBuilder->codeAppendf("%s.a = %s.a + (1.0 - %s.a) * %s.a;",
272 outputColor, inputColor, inputColor, dstColor);
273
274 switch (mode) {
275 case SkXfermode::kOverlay_Mode:
276 // Overlay is Hard-Light with the src and dst reversed
277 hard_light(fsBuilder, outputColor, dstColor, inputColor);
278 break;
279 case SkXfermode::kDarken_Mode:
280 fsBuilder->codeAppendf("%s.rgb = min((1.0 - %s.a) * %s.rgb + %s.rgb, "
281 "(1.0 - %s.a) * %s.rgb + %s.rgb);",
282 outputColor,
283 inputColor, dstColor, inputColor,
284 dstColor, inputColor, dstColor);
285 break;
286 case SkXfermode::kLighten_Mode:
287 fsBuilder->codeAppendf("%s.rgb = max((1.0 - %s.a) * %s.rgb + %s.rgb, "
288 "(1.0 - %s.a) * %s.rgb + %s.rgb);",
289 outputColor,
290 inputColor, dstColor, inputColor,
291 dstColor, inputColor, dstColor);
292 break;
293 case SkXfermode::kColorDodge_Mode:
294 color_dodge_component(fsBuilder, outputColor, inputColor, dstColor, 'r');
295 color_dodge_component(fsBuilder, outputColor, inputColor, dstColor, 'g');
296 color_dodge_component(fsBuilder, outputColor, inputColor, dstColor, 'b');
297 break;
298 case SkXfermode::kColorBurn_Mode:
299 color_burn_component(fsBuilder, outputColor, inputColor, dstColor, ' r');
300 color_burn_component(fsBuilder, outputColor, inputColor, dstColor, ' g');
301 color_burn_component(fsBuilder, outputColor, inputColor, dstColor, ' b');
302 break;
303 case SkXfermode::kHardLight_Mode:
304 hard_light(fsBuilder, outputColor, inputColor, dstColor);
305 break;
306 case SkXfermode::kSoftLight_Mode:
307 fsBuilder->codeAppendf("if (0.0 == %s.a) {", dstColor);
308 fsBuilder->codeAppendf("%s.rgba = %s;", outputColor, inputColor);
309 fsBuilder->codeAppendf("} else {");
310 soft_light_component_pos_dst_alpha(fsBuilder, outputColor, inputColo r, dstColor, 'r');
311 soft_light_component_pos_dst_alpha(fsBuilder, outputColor, inputColo r, dstColor, 'g');
312 soft_light_component_pos_dst_alpha(fsBuilder, outputColor, inputColo r, dstColor, 'b');
313 fsBuilder->codeAppendf("}");
314 break;
315 case SkXfermode::kDifference_Mode:
316 fsBuilder->codeAppendf("%s.rgb = %s.rgb + %s.rgb -"
317 "2.0 * min(%s.rgb * %s.a, %s.rgb * %s.a);",
318 outputColor, inputColor, dstColor, inputColor , dstColor,
319 dstColor, inputColor);
320 break;
321 case SkXfermode::kExclusion_Mode:
322 fsBuilder->codeAppendf("%s.rgb = %s.rgb + %s.rgb - "
323 "2.0 * %s.rgb * %s.rgb;",
324 outputColor, dstColor, inputColor, dstColor, inputColor);
325 break;
326 case SkXfermode::kMultiply_Mode:
327 fsBuilder->codeAppendf("%s.rgb = (1.0 - %s.a) * %s.rgb + "
328 "(1.0 - %s.a) * %s.rgb + "
329 "%s.rgb * %s.rgb;",
330 outputColor, inputColor, dstColor, dstColor, inputColor,
331 inputColor, dstColor);
332 break;
333 case SkXfermode::kHue_Mode: {
334 // SetLum(SetSat(S * Da, Sat(D * Sa)), Sa*Da, D*Sa) + (1 - Sa) * D + (1 - Da) * S
335 SkString setSat, setLum;
336 add_sat_function(fsBuilder, &setSat);
337 add_lum_function(fsBuilder, &setLum);
338 fsBuilder->codeAppendf("vec4 dstSrcAlpha = %s * %s.a;",
339 dstColor, inputColor);
340 fsBuilder->codeAppendf("%s.rgb = %s(%s(%s.rgb * %s.a, dstSrcAlpha.rg b),"
341 "dstSrcAlpha.a, dstSrcAlpha.rgb); ",
342 outputColor, setLum.c_str(), setSat.c_str(), inputColor,
343 dstColor);
344 fsBuilder->codeAppendf("%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s. a) * %s.rgb;",
345 outputColor, inputColor, dstColor, dstColor, inputColor);
346 break;
347 }
348 case SkXfermode::kSaturation_Mode: {
349 // SetLum(SetSat(D * Sa, Sat(S * Da)), Sa*Da, D*Sa)) + (1 - Sa) * D + (1 - Da) * S
350 SkString setSat, setLum;
351 add_sat_function(fsBuilder, &setSat);
352 add_lum_function(fsBuilder, &setLum);
353 fsBuilder->codeAppendf("vec4 dstSrcAlpha = %s * %s.a;",
354 dstColor, inputColor);
355 fsBuilder->codeAppendf("%s.rgb = %s(%s(dstSrcAlpha.rgb, %s.rgb * %s. a),"
356 "dstSrcAlpha.a, dstSrcAlpha.rgb); ",
357 outputColor, setLum.c_str(), setSat.c_str(), inputColor,
358 dstColor);
359 fsBuilder->codeAppendf("%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s. a) * %s.rgb;",
360 outputColor, inputColor, dstColor, dstColor, inputColor);
361 break;
362 }
363 case SkXfermode::kColor_Mode: {
364 // SetLum(S * Da, Sa* Da, D * Sa) + (1 - Sa) * D + (1 - Da) * S
365 SkString setLum;
366 add_lum_function(fsBuilder, &setLum);
367 fsBuilder->codeAppendf("vec4 srcDstAlpha = %s * %s.a;",
368 inputColor, dstColor);
369 fsBuilder->codeAppendf("%s.rgb = %s(srcDstAlpha.rgb, srcDstAlpha.a, %s.rgb * %s.a);",
370 outputColor, setLum.c_str(), dstColor, inputC olor);
371 fsBuilder->codeAppendf("%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s. a) * %s.rgb;",
372 outputColor, inputColor, dstColor, dstColor, inputColor);
373 break;
374 }
375 case SkXfermode::kLuminosity_Mode: {
376 // SetLum(D * Sa, Sa* Da, S * Da) + (1 - Sa) * D + (1 - Da) * S
377 SkString setLum;
378 add_lum_function(fsBuilder, &setLum);
379 fsBuilder->codeAppendf("vec4 srcDstAlpha = %s * %s.a;",
380 inputColor, dstColor);
381 fsBuilder->codeAppendf("%s.rgb = %s(%s.rgb * %s.a, srcDstAlpha.a, sr cDstAlpha.rgb);",
382 outputColor, setLum.c_str(), dstColor, inputC olor);
383 fsBuilder->codeAppendf("%s.rgb += (1.0 - %s.a) * %s.rgb + (1.0 - %s. a) * %s.rgb;",
384 outputColor, inputColor, dstColor, dstColor, inputColor);
385 break;
386 }
387 default:
388 SkFAIL("Unknown Custom Xfer mode.");
389 break;
390 }
391 }
392
393 ///////////////////////////////////////////////////////////////////////////////
394 // Fragment Processor
395 ///////////////////////////////////////////////////////////////////////////////
396
397 GrFragmentProcessor* GrCustomXfermode::CreateFP(SkXfermode::Mode mode, GrTexture * background) {
398 if (!GrCustomXfermode::IsSupportedMode(mode)) {
399 return NULL;
400 } else {
401 return SkNEW_ARGS(GrCustomXferFP, (mode, background));
402 }
403 }
404
405 ///////////////////////////////////////////////////////////////////////////////
406
407 class GLCustomXferFP : public GrGLFragmentProcessor {
408 public:
409 GLCustomXferFP(const GrFragmentProcessor&) {}
410 ~GLCustomXferFP() SK_OVERRIDE {};
411
412 void emitCode(GrGLFPBuilder* builder,
413 const GrFragmentProcessor& fp,
414 const char* outputColor,
415 const char* inputColor,
416 const TransformedCoordsArray& coords,
417 const TextureSamplerArray& samplers) SK_OVERRIDE {
418 SkXfermode::Mode mode = fp.cast<GrCustomXferFP>().mode();
419 const GrTexture* backgroundTex =
420 fp.cast<GrCustomXferFP>().backgroundAccess().getTexture();
421 GrGLFPFragmentBuilder* fsBuilder = builder->getFragmentShaderBuilder();
422 const char* dstColor;
423 if (backgroundTex) {
424 dstColor = "bgColor";
425 fsBuilder->codeAppendf("vec4 %s = ", dstColor);
426 fsBuilder->appendTextureLookup(samplers[0], coords[0].c_str(), coord s[0].getType());
427 fsBuilder->codeAppendf(";");
428 } else {
429 dstColor = fsBuilder->dstColor();
430 }
431 SkASSERT(dstColor);
432
433 emit_custom_xfermode_code(mode, fsBuilder, outputColor, inputColor, dstC olor);
434 }
435
436 void setData(const GrGLProgramDataManager&, const GrProcessor&) SK_OVERRIDE {}
437
438 static void GenKey(const GrFragmentProcessor& proc, const GrGLCaps&, GrProce ssorKeyBuilder* b) {
439 // The background may come from the dst or from a texture.
440 uint32_t key = proc.numTextures();
441 SkASSERT(key <= 1);
442 key |= proc.cast<GrCustomXferFP>().mode() << 1;
443 b->add32(key);
444 }
445
446 private:
447 typedef GrGLFragmentProcessor INHERITED;
448 };
449
450 ///////////////////////////////////////////////////////////////////////////////
451
452 GrCustomXferFP::GrCustomXferFP(SkXfermode::Mode mode, GrTexture* background)
453 : fMode(mode) {
454 this->initClassID<GrCustomXferFP>();
455 if (background) {
456 fBackgroundTransform.reset(kLocal_GrCoordSet, background,
457 GrTextureParams::kNone_FilterMode);
458 this->addCoordTransform(&fBackgroundTransform);
459 fBackgroundAccess.reset(background);
460 this->addTextureAccess(&fBackgroundAccess);
461 } else {
462 this->setWillReadDstColor();
463 }
464 }
465
466 void GrCustomXferFP::getGLProcessorKey(const GrGLCaps& caps, GrProcessorKeyBuild er* b) const {
467 GLCustomXferFP::GenKey(*this, caps, b);
468 }
469
470 GrGLFragmentProcessor* GrCustomXferFP::createGLInstance() const {
471 return SkNEW_ARGS(GLCustomXferFP, (*this));
472 }
473
474 bool GrCustomXferFP::onIsEqual(const GrFragmentProcessor& other) const {
475 const GrCustomXferFP& s = other.cast<GrCustomXferFP>();
476 return fMode == s.fMode;
477 }
478
479 void GrCustomXferFP::onComputeInvariantOutput(GrInvariantOutput* inout) const {
480 inout->setToUnknown(GrInvariantOutput::kWill_ReadInput);
481 }
482
483 GR_DEFINE_FRAGMENT_PROCESSOR_TEST(GrCustomXferFP);
484 GrFragmentProcessor* GrCustomXferFP::TestCreate(SkRandom* rand,
485 GrContext*,
486 const GrDrawTargetCaps&,
487 GrTexture*[]) {
488 int mode = rand->nextRangeU(SkXfermode::kLastCoeffMode + 1, SkXfermode::kLas tSeparableMode);
489
490 return SkNEW_ARGS(GrCustomXferFP, (static_cast<SkXfermode::Mode>(mode), NULL ));
491 }
492
OLDNEW
« no previous file with comments | « src/core/SkXfermode.cpp ('k') | src/gpu/effects/GrCustomXfermodePriv.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698