| 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');
|
|
|