remove plus clamp

Clamping for plus mode should happen only as the destination format
requires it, or as a consequence of the limited range we're holding
colors in the pipeline, or because non-normalized alpha is nuts.

So I've taken away the clamp on float rgb, keeping it on lowp to stay
in its legal range, and on float alpha because it's crazy not to.

Open questions:
  - also clamp alpha to zero?
  - what do we do with alpha <0 or >1 in general, beyond plus?

Cq-Include-Trybots: luci.chromium.try:linux-blink-rel
Change-Id: I15660ce55cc393e312f18ffdc13bbfdef08ac6e0
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/201040
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
diff --git a/src/opts/SkRasterPipeline_opts.h b/src/opts/SkRasterPipeline_opts.h
index 0bc7e0e..c40db06 100644
--- a/src/opts/SkRasterPipeline_opts.h
+++ b/src/opts/SkRasterPipeline_opts.h
@@ -1124,7 +1124,6 @@
 
 BLEND_MODE(modulate) { return s*d; }
 BLEND_MODE(multiply) { return s*inv(da) + d*inv(sa) + s*d; }
-BLEND_MODE(plus_)    { return min(s + d, 1.0f); }  // We can clamp to either 1 or sa.
 BLEND_MODE(screen)   { return s + d - s*d; }
 BLEND_MODE(xor_)     { return s*inv(da) + d*inv(sa); }
 #undef BLEND_MODE
@@ -1181,6 +1180,17 @@
 }
 #undef BLEND_MODE
 
+STAGE(plus_, Ctx::None) {
+    // We don't clamp here in case the destination supports non-normalized colors.
+    r += dr;
+    g += dg;
+    b += db;
+    a += da;
+
+    // We do clamp alpha, because alpha > 1 is not something we're prepared to admit makes sense.
+    a = min(a, 1);
+}
+
 // We're basing our implemenation of non-separable blend modes on
 //   https://www.w3.org/TR/compositing-1/#blendingnonseparable.
 // and
@@ -2696,7 +2706,11 @@
     BLEND_MODE(dstover)  { return d + div255( s*inv(da) ); }
     BLEND_MODE(modulate) { return div255( s*d ); }
     BLEND_MODE(multiply) { return div255( s*inv(da) + d*inv(sa) + s*d ); }
-    BLEND_MODE(plus_)    { return min(s+d, 255); }
+    BLEND_MODE(plus_)    {
+        // N.B. we're clamping all channels to 255 (1.0) here due to format limitations.
+        // In the float code we only clamp alpha.
+        return min(s+d, 255);
+    }
     BLEND_MODE(screen)   { return s + d - div255( s*d ); }
     BLEND_MODE(xor_)     { return div255( s*inv(da) + d*inv(sa) ); }
 #undef BLEND_MODE