Report optimizations in master gradient effects

All of the FPs for the gradient components have had to be updated to
include the @optimizationFlags section. Layout FPs now can use the
opacity preserving optimization to report whether or not they might
reject a fragment (e.g. 2 point conical gradients).

The previous composition logic that handled ensuring the gradient shader
output a premul color was removing optimizations that should have been
valid for gradients, so the make premul logic has been inlined into
the top-level effect FPs.

Bug: skia:
Change-Id: I73e4224d8dc0e3420a215b0aa805d829b08f6c76
Reviewed-on: https://skia-review.googlesource.com/151547
Commit-Queue: Michael Ludwig <michaelludwig@google.com>
Reviewed-by: Brian Salomon <bsalomon@google.com>
diff --git a/src/gpu/gradients/GrClampedGradientEffect.cpp b/src/gpu/gradients/GrClampedGradientEffect.cpp
index d3b1d28..409549c 100644
--- a/src/gpu/gradients/GrClampedGradientEffect.cpp
+++ b/src/gpu/gradients/GrClampedGradientEffect.cpp
@@ -26,6 +26,10 @@
         (void)leftBorderColor;
         auto rightBorderColor = _outer.rightBorderColor();
         (void)rightBorderColor;
+        auto makePremul = _outer.makePremul();
+        (void)makePremul;
+        auto colorsAreOpaque = _outer.colorsAreOpaque();
+        (void)colorsAreOpaque;
         fLeftBorderColorVar = args.fUniformHandler->addUniform(
                 kFragment_GrShaderFlag, kHalf4_GrSLType, kDefault_GrSLPrecision, "leftBorderColor");
         fRightBorderColorVar =
@@ -34,15 +38,20 @@
         SkString _child1("_child1");
         this->emitChild(1, &_child1, args);
         fragBuilder->codeAppendf(
-                "half4 t = %s;\nif (t.y < 0.0) {\n    %s = half4(0.0);\n} else if (t.x < 0.0) {\n  "
-                "  %s = %s;\n} else if (float(t.x) > 1.0) {\n    %s = %s;\n} else {",
-                _child1.c_str(), args.fOutputColor, args.fOutputColor,
+                "half4 t = %s;\nif (!%s && t.y < 0.0) {\n    %s = half4(0.0);\n} else if (t.x < "
+                "0.0) {\n    %s = %s;\n} else if (float(t.x) > 1.0) {\n    %s = %s;\n} else {",
+                _child1.c_str(),
+                (_outer.childProcessor(1).preservesOpaqueInput() ? "true" : "false"),
+                args.fOutputColor, args.fOutputColor,
                 args.fUniformHandler->getUniformCStr(fLeftBorderColorVar), args.fOutputColor,
                 args.fUniformHandler->getUniformCStr(fRightBorderColorVar));
         SkString _input0("t");
         SkString _child0("_child0");
         this->emitChild(0, _input0.c_str(), &_child0, args);
-        fragBuilder->codeAppendf("\n    %s = %s;\n}\n", args.fOutputColor, _child0.c_str());
+        fragBuilder->codeAppendf("\n    %s = %s;\n}\n@if (%s) {\n    %s.xyz *= %s.w;\n}\n",
+                                 args.fOutputColor, _child0.c_str(),
+                                 (_outer.makePremul() ? "true" : "false"), args.fOutputColor,
+                                 args.fOutputColor);
     }
 
 private:
@@ -71,18 +80,24 @@
     return new GrGLSLClampedGradientEffect();
 }
 void GrClampedGradientEffect::onGetGLSLProcessorKey(const GrShaderCaps& caps,
-                                                    GrProcessorKeyBuilder* b) const {}
+                                                    GrProcessorKeyBuilder* b) const {
+    b->add32((int32_t)fMakePremul);
+}
 bool GrClampedGradientEffect::onIsEqual(const GrFragmentProcessor& other) const {
     const GrClampedGradientEffect& that = other.cast<GrClampedGradientEffect>();
     (void)that;
     if (fLeftBorderColor != that.fLeftBorderColor) return false;
     if (fRightBorderColor != that.fRightBorderColor) return false;
+    if (fMakePremul != that.fMakePremul) return false;
+    if (fColorsAreOpaque != that.fColorsAreOpaque) return false;
     return true;
 }
 GrClampedGradientEffect::GrClampedGradientEffect(const GrClampedGradientEffect& src)
         : INHERITED(kGrClampedGradientEffect_ClassID, src.optimizationFlags())
         , fLeftBorderColor(src.fLeftBorderColor)
-        , fRightBorderColor(src.fRightBorderColor) {
+        , fRightBorderColor(src.fRightBorderColor)
+        , fMakePremul(src.fMakePremul)
+        , fColorsAreOpaque(src.fColorsAreOpaque) {
     this->registerChildProcessor(src.childProcessor(0).clone());
     this->registerChildProcessor(src.childProcessor(1).clone());
 }