add clamp_gamut

This should be cheaper in both float and lowp modes.

Change-Id: If6bba3abd31990b622f010c8fcdebff3288c9d70
Reviewed-on: https://skia-review.googlesource.com/152581
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Mike Klein <mtklein@google.com>
diff --git a/src/core/SkRasterPipeline.h b/src/core/SkRasterPipeline.h
index be197e4..d637240 100644
--- a/src/core/SkRasterPipeline.h
+++ b/src/core/SkRasterPipeline.h
@@ -37,7 +37,7 @@
 #define SK_RASTER_PIPELINE_STAGES(M)                               \
     M(callback)                                                    \
     M(move_src_dst) M(move_dst_src)                                \
-    M(clamp_0) M(clamp_1) M(clamp_a) M(clamp_a_dst)                \
+    M(clamp_0) M(clamp_1) M(clamp_a) M(clamp_a_dst) M(clamp_gamut) \
     M(unpremul) M(premul) M(premul_dst)                            \
     M(force_opaque) M(force_opaque_dst)                            \
     M(set_rgb) M(swap_rb)                                          \
diff --git a/src/core/SkRasterPipelineBlitter.cpp b/src/core/SkRasterPipelineBlitter.cpp
index 0ae6df3..5e4ec64 100644
--- a/src/core/SkRasterPipelineBlitter.cpp
+++ b/src/core/SkRasterPipelineBlitter.cpp
@@ -97,9 +97,7 @@
         dstInfo.colorType() != kRGBA_F32_SkColorType &&
         dstInfo.alphaType() == kPremul_SkAlphaType)
     {
-        // TODO: this will be common enough that we may want to fuse into ::clamp_premul.
-        p->append(SkRasterPipeline::clamp_0);
-        p->append(SkRasterPipeline::clamp_a);
+        p->append(SkRasterPipeline::clamp_gamut);
     }
 }
 
diff --git a/src/opts/SkRasterPipeline_opts.h b/src/opts/SkRasterPipeline_opts.h
index 0144bec..fb1f6a0 100644
--- a/src/opts/SkRasterPipeline_opts.h
+++ b/src/opts/SkRasterPipeline_opts.h
@@ -1276,6 +1276,13 @@
     db = min(db, da);
 }
 
+STAGE(clamp_gamut, Ctx::None) {
+    // If you're using this stage, a should already be in [0,1].
+    r = min(max(r, 0), a);
+    g = min(max(g, 0), a);
+    b = min(max(b, 0), a);
+}
+
 STAGE(set_rgb, const float* rgb) {
     r = rgb[0];
     g = rgb[1];
@@ -2573,6 +2580,11 @@
     db = min(db, da);
 }
 
+STAGE_PP(clamp_gamut, Ctx::None) {
+    // It shouldn't be possible to get out-of-gamut
+    // colors when working in lowp.
+}
+
 STAGE_PP(premul, Ctx::None) {
     r = div255(r * a);
     g = div255(g * a);