Index: src/core/SkXfermode.cpp |
diff --git a/src/core/SkXfermode.cpp b/src/core/SkXfermode.cpp |
index 993c754711ac472fd3bc49b6fd01ae578d520fd8..45e83c80a2981a0573d23a756236325af1d1661f 100644 |
--- a/src/core/SkXfermode.cpp |
+++ b/src/core/SkXfermode.cpp |
@@ -885,6 +885,9 @@ void SkProcXfermode::toString(SkString* str) const { |
#include "GrTBackendEffectFactory.h" |
#include "gl/GrGLEffect.h" |
+template GrGLSLExpr3 GrGLSL::min<GrGLSLExpr3>(const GrGLSLExpr3&, const GrGLSLExpr3&); |
+template GrGLSLExpr3 GrGLSL::max<GrGLSLExpr3>(const GrGLSLExpr3&, const GrGLSLExpr3&); |
+ |
/** |
* GrEffect that implements the all the separable xfer modes that cannot be expressed as Coeffs. |
*/ |
@@ -926,7 +929,7 @@ public: |
const GrDrawEffect& drawEffect, |
EffectKey key, |
const char* outputColor, |
- const char* inputColor, |
+ const GrGLSLExpr4& inputColorExpr, |
const TransformedCoordsArray& coords, |
const TextureSamplerArray& samplers) SK_OVERRIDE { |
SkXfermode::Mode mode = drawEffect.castEffect<XferEffect>().mode(); |
@@ -942,16 +945,16 @@ public: |
} |
SkASSERT(NULL != dstColor); |
- // We don't try to optimize for this case at all |
- if (NULL == inputColor) { |
- builder->fsCodeAppendf("\t\tconst vec4 ones = vec4(1);\n"); |
- inputColor = "ones"; |
- } |
builder->fsCodeAppendf("\t\t// SkXfermode::Mode: %s\n", SkXfermode::ModeName(mode)); |
+ GrGLSLExpr1 one(1); |
+ GrGLSLExpr4 dstColorExpr(dstColor); |
// These all perform src-over on the alpha channel. |
- builder->fsCodeAppendf("\t\t%s.a = %s.a + (1.0 - %s.a) * %s.a;\n", |
- outputColor, inputColor, inputColor, dstColor); |
+ builder->fsCodeAppendf("\t\t%s.a = %s;\n", |
+ outputColor, |
+ (inputColorExpr.a() + (one - inputColorExpr.a()) * dstColorExpr.a()).c_str()); |
+ |
+ const char* inputColor = inputColorExpr.c_str(); // Shorthand for below. |
switch (mode) { |
case SkXfermode::kOverlay_Mode: |
@@ -959,19 +962,15 @@ public: |
HardLight(builder, outputColor, dstColor, inputColor); |
break; |
case SkXfermode::kDarken_Mode: |
- builder->fsCodeAppendf("\t\t%s.rgb = min((1.0 - %s.a) * %s.rgb + %s.rgb, " |
- "(1.0 - %s.a) * %s.rgb + %s.rgb);\n", |
- outputColor, |
- inputColor, dstColor, inputColor, |
- dstColor, inputColor, dstColor); |
- break; |
- case SkXfermode::kLighten_Mode: |
- builder->fsCodeAppendf("\t\t%s.rgb = max((1.0 - %s.a) * %s.rgb + %s.rgb, " |
- "(1.0 - %s.a) * %s.rgb + %s.rgb);\n", |
- outputColor, |
- inputColor, dstColor, inputColor, |
- dstColor, inputColor, dstColor); |
+ case SkXfermode::kLighten_Mode: { |
+ GrGLSLExpr3 (*minOrMax)(const GrGLSLExpr3&, const GrGLSLExpr3&); |
+ minOrMax = mode == SkXfermode::kDarken_Mode ? &GrGLSL::min<GrGLSLExpr3> : &GrGLSL::max<GrGLSLExpr3>; |
+ |
+ builder->fsCodeAppendf("\t\t%s.rgb = %s;\n", outputColor, |
+ minOrMax((one - inputColorExpr.a()) * dstColorExpr.rgb() + inputColorExpr.rgb(), |
+ (one - dstColorExpr.a()) * inputColorExpr.rgb() + dstColorExpr.rgb()).c_str()); |
break; |
+ } |
case SkXfermode::kColorDodge_Mode: |
ColorDodgeComponent(builder, outputColor, inputColor, dstColor, 'r'); |
ColorDodgeComponent(builder, outputColor, inputColor, dstColor, 'g'); |