Disable the unpremultiply/remultiply in SkArithmeticMode, both raster and GPU, since the SVG spec actually defines arithmetic compositing to operate on premul colours directly.

The unpremul/remul code has been placed behind a gUseUnpremul global, which is default false. The non-unpremul path uses a min() to keep the colours to valid premult values.

Note:  This change will require new baselines for the arithmode and xfermodeimagefilter GMs.

R=reed@google.com

Review URL: https://codereview.chromium.org/16034013

git-svn-id: http://skia.googlecode.com/svn/trunk@9555 2bbb7eff-a529-9590-31e7-b0007b416f81
diff --git a/src/effects/SkArithmeticMode.cpp b/src/effects/SkArithmeticMode.cpp
index e9dc782..43c62ec 100644
--- a/src/effects/SkArithmeticMode.cpp
+++ b/src/effects/SkArithmeticMode.cpp
@@ -18,6 +18,8 @@
 #include "SkImageFilterUtils.h"
 #endif
 
+static const bool gUseUnpremul = false;
+
 class SkArithmeticMode_scalar : public SkXfermode {
 public:
     SkArithmeticMode_scalar(SkScalar k1, SkScalar k2, SkScalar k3, SkScalar k4) {
@@ -95,44 +97,55 @@
         if ((NULL == aaCoverage) || aaCoverage[i]) {
             SkPMColor sc = src[i];
             SkPMColor dc = dst[i];
-            int sa = SkGetPackedA32(sc);
-            int da = SkGetPackedA32(dc);
-
-            int srcNeedsUnpremul = needsUnpremul(sa);
-            int dstNeedsUnpremul = needsUnpremul(da);
 
             int a, r, g, b;
 
-            if (!srcNeedsUnpremul && !dstNeedsUnpremul) {
-                a = arith(k1, k2, k3, k4, sa, da);
-                r = arith(k1, k2, k3, k4, SkGetPackedR32(sc), SkGetPackedR32(dc));
-                g = arith(k1, k2, k3, k4, SkGetPackedG32(sc), SkGetPackedG32(dc));
-                b = arith(k1, k2, k3, k4, SkGetPackedB32(sc), SkGetPackedB32(dc));
+            if (gUseUnpremul) {
+                int sa = SkGetPackedA32(sc);
+                int da = SkGetPackedA32(dc);
+
+                int srcNeedsUnpremul = needsUnpremul(sa);
+                int dstNeedsUnpremul = needsUnpremul(da);
+
+                if (!srcNeedsUnpremul && !dstNeedsUnpremul) {
+                    a = arith(k1, k2, k3, k4, sa, da);
+                    r = arith(k1, k2, k3, k4, SkGetPackedR32(sc), SkGetPackedR32(dc));
+                    g = arith(k1, k2, k3, k4, SkGetPackedG32(sc), SkGetPackedG32(dc));
+                    b = arith(k1, k2, k3, k4, SkGetPackedB32(sc), SkGetPackedB32(dc));
+                } else {
+                    int sr = SkGetPackedR32(sc);
+                    int sg = SkGetPackedG32(sc);
+                    int sb = SkGetPackedB32(sc);
+                    if (srcNeedsUnpremul) {
+                        SkUnPreMultiply::Scale scale = SkUnPreMultiply::GetScale(sa);
+                        sr = SkUnPreMultiply::ApplyScale(scale, sr);
+                        sg = SkUnPreMultiply::ApplyScale(scale, sg);
+                        sb = SkUnPreMultiply::ApplyScale(scale, sb);
+                    }
+
+                    int dr = SkGetPackedR32(dc);
+                    int dg = SkGetPackedG32(dc);
+                    int db = SkGetPackedB32(dc);
+                    if (dstNeedsUnpremul) {
+                        SkUnPreMultiply::Scale scale = SkUnPreMultiply::GetScale(da);
+                        dr = SkUnPreMultiply::ApplyScale(scale, dr);
+                        dg = SkUnPreMultiply::ApplyScale(scale, dg);
+                        db = SkUnPreMultiply::ApplyScale(scale, db);
+                    }
+
+                    a = arith(k1, k2, k3, k4, sa, da);
+                    r = arith(k1, k2, k3, k4, sr, dr);
+                    g = arith(k1, k2, k3, k4, sg, dg);
+                    b = arith(k1, k2, k3, k4, sb, db);
+                }
             } else {
-                int sr = SkGetPackedR32(sc);
-                int sg = SkGetPackedG32(sc);
-                int sb = SkGetPackedB32(sc);
-                if (srcNeedsUnpremul) {
-                    SkUnPreMultiply::Scale scale = SkUnPreMultiply::GetScale(sa);
-                    sr = SkUnPreMultiply::ApplyScale(scale, sr);
-                    sg = SkUnPreMultiply::ApplyScale(scale, sg);
-                    sb = SkUnPreMultiply::ApplyScale(scale, sb);
-                }
-
-                int dr = SkGetPackedR32(dc);
-                int dg = SkGetPackedG32(dc);
-                int db = SkGetPackedB32(dc);
-                if (dstNeedsUnpremul) {
-                    SkUnPreMultiply::Scale scale = SkUnPreMultiply::GetScale(da);
-                    dr = SkUnPreMultiply::ApplyScale(scale, dr);
-                    dg = SkUnPreMultiply::ApplyScale(scale, dg);
-                    db = SkUnPreMultiply::ApplyScale(scale, db);
-                }
-
-                a = arith(k1, k2, k3, k4, sa, da);
-                r = arith(k1, k2, k3, k4, sr, dr);
-                g = arith(k1, k2, k3, k4, sg, dg);
-                b = arith(k1, k2, k3, k4, sb, db);
+                a = arith(k1, k2, k3, k4, SkGetPackedA32(sc), SkGetPackedA32(dc));
+                r = arith(k1, k2, k3, k4, SkGetPackedR32(sc), SkGetPackedR32(dc));
+                r = SkMin32(r, a);
+                g = arith(k1, k2, k3, k4, SkGetPackedG32(sc), SkGetPackedG32(dc));
+                g = SkMin32(g, a);
+                b = arith(k1, k2, k3, k4, SkGetPackedB32(sc), SkGetPackedB32(dc));
+                b = SkMin32(b, a);
             }
 
             // apply antialias coverage if necessary
@@ -145,7 +158,7 @@
             }
 
             // turn the result back into premul
-            if (0xFF != a) {
+            if (gUseUnpremul && (0xFF != a)) {
                 int scale = a + (a >> 7);
                 r = SkAlphaMul(r, scale);
                 g = SkAlphaMul(g, scale);
@@ -361,15 +374,23 @@
         builder->fsCodeAppendf("\t\tconst vec4 src = %s;\n", GrGLSLOnesVecf(4));
     } else {
         builder->fsCodeAppendf("\t\tvec4 src = %s;\n", inputColor);
-        builder->fsCodeAppendf("\t\tsrc.rgb = clamp(src.rgb / src.a, 0.0, 1.0);\n");
+        if (gUseUnpremul) {
+            builder->fsCodeAppendf("\t\tsrc.rgb = clamp(src.rgb / src.a, 0.0, 1.0);\n");
+        }
     }
 
     builder->fsCodeAppendf("\t\tvec4 dst = %s;\n", dstColor);
-    builder->fsCodeAppendf("\t\tdst.rgb = clamp(dst.rgb / dst.a, 0.0, 1.0);\n");
+    if (gUseUnpremul) {
+        builder->fsCodeAppendf("\t\tdst.rgb = clamp(dst.rgb / dst.a, 0.0, 1.0);\n");
+    }
 
     builder->fsCodeAppendf("\t\t%s = %s.x * src * dst + %s.y * src + %s.z * dst + %s.w;\n", outputColor, kUni, kUni, kUni, kUni);
     builder->fsCodeAppendf("\t\t%s = clamp(%s, 0.0, 1.0);\n", outputColor, outputColor);
-    builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
+    if (gUseUnpremul) {
+        builder->fsCodeAppendf("\t\t%s.rgb *= %s.a;\n", outputColor, outputColor);
+    } else {
+        builder->fsCodeAppendf("\t\t%s.rgb = min(%s.rgb, %s.a);\n", outputColor, outputColor, outputColor);
+    }
 }
 
 void GrGLArithmeticEffect::setData(const GrGLUniformManager& uman, const GrDrawEffect& drawEffect) {