impl SkRuntimeColorFilter::getFlags()

Simply build the skvm program and look to see if in.a.id == out.a.id.

This obviously is conservative, with false negatives possible.  I
haven't done it here, but one possible improvement is to splat uniforms
so constant folding can peer through uniforms too.

Add some basic tests.

Change-Id: I5578ba38ff490b96bf84538025e08d9d352f0320
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/370825
Commit-Queue: Mike Klein <mtklein@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/src/core/SkRuntimeEffect.cpp b/src/core/SkRuntimeEffect.cpp
index ae714ed..46873b9 100644
--- a/src/core/SkRuntimeEffect.cpp
+++ b/src/core/SkRuntimeEffect.cpp
@@ -462,6 +462,21 @@
                                    /*device=*/zeroCoord, /*local=*/zeroCoord, sampleChild);
     }
 
+    uint32_t onGetFlags() const override {
+        skvm::Builder  p;
+        SkColorSpace*  dstCS = sk_srgb_singleton();  // This _shouldn't_ matter for alpha.
+        skvm::Uniforms uniforms{p.uniform(), 0};
+        SkArenaAlloc   alloc{16};
+
+        skvm::Color in = p.load({skvm::PixelFormat::FLOAT, 32,32,32,32, 0,32,64,96}, p.arg(16)),
+                   out = this->onProgram(&p,in,dstCS,&uniforms,&alloc);
+
+        if (out.a.id == in.a.id) {
+            return SkColorFilter::kAlphaUnchanged_Flag;
+        }
+        return 0;
+    }
+
     void flatten(SkWriteBuffer& buffer) const override {
         buffer.writeString(fEffect->source().c_str());
         if (fUniforms) {
diff --git a/tests/SkRuntimeEffectTest.cpp b/tests/SkRuntimeEffectTest.cpp
index 8525e7e..46f4836 100644
--- a/tests/SkRuntimeEffectTest.cpp
+++ b/tests/SkRuntimeEffectTest.cpp
@@ -442,3 +442,23 @@
 DEF_GPUTEST_FOR_RENDERING_CONTEXTS(SkRuntimeStructNameReuse_GPU, r, ctxInfo) {
     test_RuntimeEffectStructNameReuse(r, ctxInfo.directContext());
 }
+
+DEF_TEST(SkRuntimeColorFilterFlags, r) {
+    {   // Here's a non-trivial filter that doesn't change alpha.
+        auto [effect, err] = SkRuntimeEffect::Make(SkString{
+                "uniform shader input; half4 main() { return sample(input) + half4(1,1,1,0); }"});
+        REPORTER_ASSERT(r, effect && err.isEmpty());
+        sk_sp<SkColorFilter> input = nullptr,
+                            filter = effect->makeColorFilter(SkData::MakeEmpty(), &input, 1);
+        REPORTER_ASSERT(r, filter && filter->isAlphaUnchanged());
+    }
+
+    {  // Here's one that definitely changes alpha.
+        auto [effect, err] = SkRuntimeEffect::Make(SkString{
+                "uniform shader input; half4 main() { return sample(input) + half4(0,0,0,4); }"});
+        REPORTER_ASSERT(r, effect && err.isEmpty());
+        sk_sp<SkColorFilter> input = nullptr,
+                            filter = effect->makeColorFilter(SkData::MakeEmpty(), &input, 1);
+        REPORTER_ASSERT(r, filter && !filter->isAlphaUnchanged());
+    }
+}