[graphite] Fix SkEmpty (take 2)

Bug: chromium:1517553
Change-Id: I19b94f52b2f2d32163b531628463a6a358d46ed7
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/808218
Reviewed-by: Michael Ludwig <michaelludwig@google.com>
Commit-Queue: Robert Phillips <robertphillips@google.com>
diff --git a/gm/emptyshader.cpp b/gm/emptyshader.cpp
new file mode 100644
index 0000000..aca59d4
--- /dev/null
+++ b/gm/emptyshader.cpp
@@ -0,0 +1,118 @@
+/*
+ * Copyright 2024 Google LLC
+ *
+ * Use of this source code is governed by a BSD-style license that can be
+ * found in the LICENSE file.
+ */
+
+#include "gm/gm.h"
+
+#include "include/core/SkCanvas.h"
+#include "include/core/SkPaint.h"
+#include "include/effects/SkGradientShader.h"
+#include "src/shaders/SkEmptyShader.h"
+
+namespace skiagm {
+
+namespace {
+
+sk_sp<SkShader> empty(SkRect r) { return sk_make_sp<SkEmptyShader>(); }
+
+sk_sp<SkShader> degen_sweep(SkRect r) {
+    // A too small angle between start and end falls back to an empty shader
+    const float startAngle = 0.0f;
+    const float endAngle = nextafter(startAngle, 360.0f);
+    const SkColor colors[2] = { SK_ColorRED, SK_ColorGREEN };
+
+    return SkGradientShader::MakeSweep(r.centerX(), r.centerY(),
+                                       colors,
+                                       /* pos= */ nullptr,
+                                       std::size(colors),
+                                       SkTileMode::kDecal,
+                                       startAngle, endAngle,
+                                       /* flags= */ 0,
+                                       /* localMatrix= */ nullptr);
+}
+
+sk_sp<SkShader> degen_linear(SkRect r) {
+    // Having the two positions be the same causes a fallback to an empty shader
+    const SkPoint pts[2] = { r.center(), r.center() };
+    const SkColor colors[2] = { SK_ColorRED, SK_ColorGREEN };
+
+    return SkGradientShader::MakeLinear(pts,
+                                        colors,
+                                        /* pos= */ nullptr,
+                                        std::size(colors),
+                                        SkTileMode::kDecal);
+}
+
+sk_sp<SkShader> degen_radial(SkRect r) {
+    const SkColor colors[2] = { SK_ColorRED, SK_ColorGREEN };
+
+    // Having a radius of 0.0 causes a fallback to an empty shader
+    return SkGradientShader::MakeRadial(r.center(),
+                                        /* radius= */ 0.0f,
+                                        colors,
+                                        /* pos= */ nullptr,
+                                        std::size(colors),
+                                        SkTileMode::kDecal);
+}
+
+sk_sp<SkShader> degen_conical(SkRect r) {
+    const SkColor colors[2] = {SK_ColorRED, SK_ColorGREEN};
+
+    // Having the start and end radii be the same causes a fallback to an empty shader
+    return SkGradientShader::MakeTwoPointConical(r.center(), /* startRadius= */ 0.0f,
+                                                 r.center(), /* endRadius= */ 0.0f,
+                                                 colors,
+                                                 /* pos= */ nullptr,
+                                                 std::size(colors),
+                                                 SkTileMode::kDecal);
+}
+
+} // anonymous namespace
+
+class EmptyShaderGM : public GM {
+public:
+    EmptyShaderGM() {
+        this->setBGColor(0xFFCCCCCC);
+    }
+
+protected:
+    SkString getName() const override { return SkString("emptyshader"); }
+
+    SkISize getISize() override { return SkISize::Make(128, 88); }
+
+    void onDraw(SkCanvas* canvas) override {
+        SkPaint stroke;
+        stroke.setStyle(SkPaint::kStroke_Style);
+
+        int left = kPad, top = kPad;
+        for (auto f : { empty, degen_sweep, degen_linear, degen_radial, degen_conical }) {
+            SkRect r = SkRect::MakeXYWH(left, top, kSize, kSize);
+
+            SkPaint p;
+            p.setColor(SK_ColorBLUE);
+            p.setShader(f(r));
+
+            canvas->drawRect(r, p);
+            canvas->drawRect(r, stroke);
+
+            left += kSize + kPad;
+            if (left >= this->getISize().width()) {
+                left = kPad;
+                top += kSize + kPad;
+            }
+        }
+    }
+
+private:
+    static constexpr int kPad = 8;
+    static constexpr int kSize = 32;
+};
+
+//////////////////////////////////////////////////////////////////////////////
+
+DEF_GM(return new EmptyShaderGM;)
+
+}  // namespace skiagm
diff --git a/gn/gm.gni b/gn/gm.gni
index b8b3eed..a779d59 100644
--- a/gn/gm.gni
+++ b/gn/gm.gni
@@ -166,6 +166,7 @@
   "$_gm/ducky_yuv_blend.cpp",
   "$_gm/emboss.cpp",
   "$_gm/emptypath.cpp",
+  "$_gm/emptyshader.cpp",
   "$_gm/encode.cpp",
   "$_gm/encode_alpha_jpeg.cpp",
   "$_gm/encode_color_types.cpp",
diff --git a/src/gpu/graphite/KeyHelpers.cpp b/src/gpu/graphite/KeyHelpers.cpp
index 499b094..db38991 100644
--- a/src/gpu/graphite/KeyHelpers.cpp
+++ b/src/gpu/graphite/KeyHelpers.cpp
@@ -1350,7 +1350,7 @@
                        PaintParamsKeyBuilder* builder,
                        PipelineDataGatherer* gatherer,
                        const SkEmptyShader*) {
-    // The empty shader acts as a no-op
+    builder->addBlock(BuiltInCodeSnippetID::kPriorOutput);
 }
 
 static void add_yuv_image_to_key(const KeyContext& keyContext,