support skvm fallback for single color filtering
with unit test
Change-Id: I7f0e30435bf4e054fe7436daaadb3512936a58ac
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/367237
Commit-Queue: Mike Klein <mtklein@google.com>
Reviewed-by: Brian Osman <brianosman@google.com>
diff --git a/src/core/SkColorFilter.cpp b/src/core/SkColorFilter.cpp
index d9ad7b5..3d7a22e 100644
--- a/src/core/SkColorFilter.cpp
+++ b/src/core/SkColorFilter.cpp
@@ -102,13 +102,29 @@
SkStageRec rec = {
&pipeline, &alloc, kRGBA_F32_SkColorType, dstCS, dummyPaint, nullptr, matrixProvider
};
- as_CFB(this)->onAppendStages(rec, color.fA == 1);
- SkPMColor4f dst;
- SkRasterPipeline_MemoryCtx dstPtr = { &dst, 0 };
- pipeline.append(SkRasterPipeline::store_f32, &dstPtr);
- pipeline.run(0,0, 1,1);
- return dst.unpremul();
+ if (as_CFB(this)->onAppendStages(rec, color.fA == 1)) {
+ SkPMColor4f dst;
+ SkRasterPipeline_MemoryCtx dstPtr = { &dst, 0 };
+ pipeline.append(SkRasterPipeline::store_f32, &dstPtr);
+ pipeline.run(0,0, 1,1);
+ return dst.unpremul();
+ }
+
+ // This filter doesn't support SkRasterPipeline... try skvm.
+ skvm::Builder b;
+ skvm::Uniforms uni(b.uniform(), 4);
+ if (skvm::Color filtered =
+ as_CFB(this)->program(&b, b.uniformColor(color, &uni), dstCS, &uni, &alloc)) {
+
+ b.store({skvm::PixelFormat::FLOAT, 32,32,32,32, 0,32,64,96},
+ b.varying<SkColor4f>(), unpremul(filtered));
+ b.done().eval(1, uni.buf.data(), &color); // tell SkVM to skip JIT?
+ return color;
+ }
+
+ SkASSERT(false);
+ return SkColor4f{0,0,0,0};
}
///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/tests/SkRuntimeEffectTest.cpp b/tests/SkRuntimeEffectTest.cpp
index 90b45fa..a36f03f 100644
--- a/tests/SkRuntimeEffectTest.cpp
+++ b/tests/SkRuntimeEffectTest.cpp
@@ -382,3 +382,22 @@
thread.join();
}
}
+
+DEF_TEST(SkRuntimeColorFilterSingleColor, r) {
+ // Test runtime colorfilters support filterColor4f().
+ auto [effect, err] = SkRuntimeEffect::Make(SkString{
+ "uniform shader input; half4 main() { half4 c = sample(input); return c*c; }"});
+ REPORTER_ASSERT(r, effect);
+ REPORTER_ASSERT(r, err.isEmpty());
+
+ sk_sp<SkColorFilter> input = nullptr;
+ sk_sp<SkColorFilter> cf = effect->makeColorFilter(SkData::MakeEmpty(), &input, 1);
+ REPORTER_ASSERT(r, cf);
+
+ SkColor4f c = cf->filterColor4f({0.25, 0.5, 0.75, 1.0},
+ sk_srgb_singleton(), sk_srgb_singleton());
+ REPORTER_ASSERT(r, c.fR == 0.0625f);
+ REPORTER_ASSERT(r, c.fG == 0.25f);
+ REPORTER_ASSERT(r, c.fB == 0.5625f);
+ REPORTER_ASSERT(r, c.fA == 1.0f);
+}