Support children in SkRuntimeEffect::makeColorFilter
Change-Id: Icf8c69464a44341a08df16dce53aebedc2826bfd
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/270064
Reviewed-by: Brian Salomon <bsalomon@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
diff --git a/include/effects/SkRuntimeEffect.h b/include/effects/SkRuntimeEffect.h
index 71d93a6..921b42e 100644
--- a/include/effects/SkRuntimeEffect.h
+++ b/include/effects/SkRuntimeEffect.h
@@ -82,6 +82,8 @@
sk_sp<SkShader> makeShader(sk_sp<SkData> inputs, sk_sp<SkShader> children[], size_t childCount,
const SkMatrix* localMatrix, bool isOpaque);
+ sk_sp<SkColorFilter> makeColorFilter(sk_sp<SkData> inputs, sk_sp<SkColorFilter> children[],
+ size_t childCount);
sk_sp<SkColorFilter> makeColorFilter(sk_sp<SkData> inputs);
const SkString& source() const { return fSkSL; }
diff --git a/src/core/SkColorFilter.cpp b/src/core/SkColorFilter.cpp
index efa9d61..468ff5c 100644
--- a/src/core/SkColorFilter.cpp
+++ b/src/core/SkColorFilter.cpp
@@ -401,14 +401,25 @@
class SkRuntimeColorFilter : public SkColorFilter {
public:
- SkRuntimeColorFilter(sk_sp<SkRuntimeEffect> effect, sk_sp<SkData> inputs)
- : fEffect(std::move(effect))
- , fInputs(std::move(inputs)) {}
+ SkRuntimeColorFilter(sk_sp<SkRuntimeEffect> effect, sk_sp<SkData> inputs,
+ sk_sp<SkColorFilter> children[], size_t childCount)
+ : fEffect(std::move(effect))
+ , fInputs(std::move(inputs))
+ , fChildren(children, children + childCount) {}
#if SK_SUPPORT_GPU
- std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(GrRecordingContext* context,
- const GrColorInfo&) const override {
- return GrSkSLFP::Make(context, fEffect, "Runtime Color Filter", fInputs);
+ std::unique_ptr<GrFragmentProcessor> asFragmentProcessor(
+ GrRecordingContext* context, const GrColorInfo& colorInfo) const override {
+ auto fp = GrSkSLFP::Make(context, fEffect, "Runtime Color Filter", fInputs);
+ for (const auto& child : fChildren) {
+ auto childFP = child ? child->asFragmentProcessor(context, colorInfo) : nullptr;
+ if (!childFP) {
+ // TODO: This is the case that should eventually mean "the original input color"
+ return nullptr;
+ }
+ fp->addChild(std::move(childFP));
+ }
+ return fp;
}
#endif
@@ -445,6 +456,10 @@
} else {
buffer.writeByteArray(nullptr, 0);
}
+ buffer.write32(fChildren.size());
+ for (const auto& child : fChildren) {
+ buffer.writeFlattenable(child.get());
+ }
}
private:
@@ -452,6 +467,7 @@
sk_sp<SkRuntimeEffect> fEffect;
sk_sp<SkData> fInputs;
+ std::vector<sk_sp<SkColorFilter>> fChildren;
mutable SkMutex fInterpreterMutex;
mutable std::unique_ptr<SkSL::Interpreter<SkRasterPipeline_InterpreterCtx::VECTOR_WIDTH>>
@@ -468,13 +484,21 @@
buffer.readString(&sksl);
sk_sp<SkData> inputs = buffer.readByteArrayAsData();
+ std::vector<sk_sp<SkColorFilter>> children;
+ children.resize(buffer.read32());
+ for (size_t i = 0; i < children.size(); ++i) {
+ children[i] = buffer.readColorFilter();
+ }
+
auto effect = std::get<0>(SkRuntimeEffect::Make(std::move(sksl)));
- return effect->makeColorFilter(std::move(inputs));
+ return effect->makeColorFilter(std::move(inputs), children.data(), children.size());
}
// Private helper method so SkRuntimeEffect can access SkRuntimeColorFilter
-sk_sp<SkColorFilter> SkMakeRuntimeColorFilter(sk_sp<SkRuntimeEffect> effect, sk_sp<SkData> inputs) {
- return sk_sp<SkColorFilter>(new SkRuntimeColorFilter(std::move(effect), std::move(inputs)));
+sk_sp<SkColorFilter> SkMakeRuntimeColorFilter(sk_sp<SkRuntimeEffect> effect, sk_sp<SkData> inputs,
+ sk_sp<SkColorFilter> children[], size_t childCount) {
+ return sk_sp<SkColorFilter>(
+ new SkRuntimeColorFilter(std::move(effect), std::move(inputs), children, childCount));
}
///////////////////////////////////////////////////////////////////////////////////////////////////
diff --git a/src/core/SkRuntimeEffect.cpp b/src/core/SkRuntimeEffect.cpp
index efdb658..926b1f4 100644
--- a/src/core/SkRuntimeEffect.cpp
+++ b/src/core/SkRuntimeEffect.cpp
@@ -296,16 +296,23 @@
sk_sp<SkShader> SkRuntimeEffect::makeShader(sk_sp<SkData> inputs,
sk_sp<SkShader> children[], size_t childCount,
const SkMatrix* localMatrix, bool isOpaque) {
- return inputs && inputs->size() == this->inputSize() && childCount >= fChildren.size()
+ return inputs && inputs->size() == this->inputSize() && childCount == fChildren.size()
? sk_sp<SkShader>(new SkRTShader(sk_ref_sp(this), std::move(inputs), localMatrix,
children, childCount, isOpaque))
: nullptr;
}
-sk_sp<SkColorFilter> SkRuntimeEffect::makeColorFilter(sk_sp<SkData> inputs) {
- extern sk_sp<SkColorFilter> SkMakeRuntimeColorFilter(sk_sp<SkRuntimeEffect>, sk_sp<SkData>);
+sk_sp<SkColorFilter> SkRuntimeEffect::makeColorFilter(sk_sp<SkData> inputs,
+ sk_sp<SkColorFilter> children[],
+ size_t childCount) {
+ extern sk_sp<SkColorFilter> SkMakeRuntimeColorFilter(sk_sp<SkRuntimeEffect>, sk_sp<SkData>,
+ sk_sp<SkColorFilter>[], size_t);
- return inputs && inputs->size() == this->inputSize()
- ? SkMakeRuntimeColorFilter(sk_ref_sp(this), std::move(inputs))
+ return inputs && inputs->size() == this->inputSize() && childCount == fChildren.size()
+ ? SkMakeRuntimeColorFilter(sk_ref_sp(this), std::move(inputs), children, childCount)
: nullptr;
}
+
+sk_sp<SkColorFilter> SkRuntimeEffect::makeColorFilter(sk_sp<SkData> inputs) {
+ return this->makeColorFilter(std::move(inputs), nullptr, 0);
+}