avoid redundant clamps

If we clamp the shader color to gamut, we won't need to clamp again when
storing to the destination... blending and coverage will keep the color
in gamut.

Change-Id: I9a4eb609de58fc0cb6295df0ad1c4cef8cd7e307
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/253722
Reviewed-by: Mike Reed <reed@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
diff --git a/src/core/SkVMBlitter.cpp b/src/core/SkVMBlitter.cpp
index 9c2a5702..36f22d6 100644
--- a/src/core/SkVMBlitter.cpp
+++ b/src/core/SkVMBlitter.cpp
@@ -203,6 +203,9 @@
                                                          params.colorSpace.get(),
                                                          uniforms,
                                                          x,y, &src.r, &src.g, &src.b, &src.a));
+            // We don't know if the src color is normalized (logical [0,1], premul [0,a]) or not.
+            bool src_is_normalized = false;
+
             if (params.coverage == Coverage::Mask3D) {
                 skvm::F32 M = unorm(8, load8(varying<uint8_t>())),
                           A = unorm(8, load8(varying<uint8_t>()));
@@ -221,6 +224,11 @@
                 src.r = min(max(splat(0.0f), src.r), src.a);
                 src.g = min(max(splat(0.0f), src.g), src.a);
                 src.b = min(max(splat(0.0f), src.b), src.a);
+
+                // Knowing that we're normalizing here and that blending and coverage
+                // won't affect that when the destination is normalized, we can avoid
+                // avoid a redundant clamp just before storing.
+                src_is_normalized = true;
             }
 
             // There are several orderings here of when we load dst and coverage
@@ -302,7 +310,7 @@
             }
 
             // Clamp to fit destination color format if needed.
-            if (SkColorTypeIsNormalized(params.colorType)) {
+            if (!src_is_normalized && SkColorTypeIsNormalized(params.colorType)) {
                 src.r = min(max(splat(0.0f), src.r), splat(1.0f));
                 src.g = min(max(splat(0.0f), src.g), splat(1.0f));
                 src.b = min(max(splat(0.0f), src.b), splat(1.0f));