Remove template from SkRuntimeEffectBuilder.
fChildren in the Builder is now a vector of ChildPtrs instead of a
vector of one particular type of child. This gives builder.child() the
flexibility to accept a color-filter, shader, or any other type that a
ChildPtr can hold.
Change-Id: I9e1ecf51aab1c74a9a15738bee7900b0c690ce9a
Bug: skia:11813
Reviewed-on: https://skia-review.googlesource.com/c/skia/+/431196
Reviewed-by: Brian Osman <brianosman@google.com>
Commit-Queue: Brian Osman <brianosman@google.com>
Commit-Queue: John Stiles <johnstiles@google.com>
Auto-Submit: John Stiles <johnstiles@google.com>
diff --git a/include/effects/SkRuntimeEffect.h b/include/effects/SkRuntimeEffect.h
index f3eb3f5..cecfedf 100644
--- a/include/effects/SkRuntimeEffect.h
+++ b/include/effects/SkRuntimeEffect.h
@@ -163,6 +163,7 @@
// Object that allows passing either an SkShader or SkColorFilter as a child
struct ChildPtr {
+ ChildPtr() = default;
ChildPtr(sk_sp<SkShader> s) : shader(std::move(s)) {}
ChildPtr(sk_sp<SkColorFilter> cf) : colorFilter(std::move(cf)) {}
sk_sp<SkShader> shader;
@@ -181,8 +182,7 @@
sk_sp<SkImage> makeImage(GrRecordingContext*,
sk_sp<SkData> uniforms,
- sk_sp<SkShader> children[],
- size_t childCount,
+ SkSpan<ChildPtr> children,
const SkMatrix* localMatrix,
SkImageInfo resultInfo,
bool mipmapped) const;
@@ -291,7 +291,7 @@
};
/** Base class for SkRuntimeShaderBuilder, defined below. */
-template <typename Child> class SkRuntimeEffectBuilder {
+class SkRuntimeEffectBuilder {
public:
struct BuilderUniform {
// Copy 'val' to this variable. No type conversion is performed - 'val' must be same
@@ -319,7 +319,8 @@
} else if (fVar->sizeInBytes() != 9 * sizeof(float)) {
SkDEBUGFAIL("Incorrect value size");
} else {
- float* data = SkTAddOffset<float>(fOwner->writableUniformData(), fVar->offset);
+ float* data = SkTAddOffset<float>(fOwner->writableUniformData(),
+ (ptrdiff_t)fVar->offset);
data[0] = val.get(0); data[1] = val.get(3); data[2] = val.get(6);
data[3] = val.get(1); data[4] = val.get(4); data[5] = val.get(7);
data[6] = val.get(2); data[7] = val.get(5); data[8] = val.get(8);
@@ -348,13 +349,20 @@
};
struct BuilderChild {
- template <typename C> BuilderChild& operator=(C&& val) {
- // TODO(skbug:11813): Validate that the type of val lines up with the type of the child
- // (SkShader vs. SkColorFilter).
+ template <typename T> BuilderChild& operator=(sk_sp<T> val) {
if (!fChild) {
SkDEBUGFAIL("Assigning to missing child");
} else {
- fOwner->fChildren[fChild->index] = std::forward<C>(val);
+ fOwner->fChildren[(size_t)fChild->index] = std::move(val);
+ }
+ return *this;
+ }
+
+ BuilderChild& operator=(std::nullptr_t) {
+ if (!fChild) {
+ SkDEBUGFAIL("Assigning to missing child");
+ } else {
+ fOwner->fChildren[(size_t)fChild->index] = SkRuntimeEffect::ChildPtr{};
}
return *this;
}
@@ -388,7 +396,7 @@
SkRuntimeEffectBuilder& operator=(const SkRuntimeEffectBuilder&) = delete;
sk_sp<SkData> uniforms() { return fUniforms; }
- Child* children() { return fChildren.data(); }
+ SkRuntimeEffect::ChildPtr* children() { return fChildren.data(); }
size_t numChildren() { return fChildren.size(); }
private:
@@ -399,9 +407,9 @@
return fUniforms->writable_data();
}
- sk_sp<SkRuntimeEffect> fEffect;
- sk_sp<SkData> fUniforms;
- std::vector<Child> fChildren;
+ sk_sp<SkRuntimeEffect> fEffect;
+ sk_sp<SkData> fUniforms;
+ std::vector<SkRuntimeEffect::ChildPtr> fChildren;
};
/**
@@ -424,7 +432,7 @@
* Note that SkRuntimeShaderBuilder is built entirely on the public API of SkRuntimeEffect,
* so can be used as-is or serve as inspiration for other interfaces or binding techniques.
*/
-class SK_API SkRuntimeShaderBuilder : public SkRuntimeEffectBuilder<sk_sp<SkShader>> {
+class SK_API SkRuntimeShaderBuilder : public SkRuntimeEffectBuilder {
public:
explicit SkRuntimeShaderBuilder(sk_sp<SkRuntimeEffect>);
// This is currently required by Android Framework but may go away if that dependency
@@ -439,13 +447,13 @@
bool mipmapped);
private:
- using INHERITED = SkRuntimeEffectBuilder<sk_sp<SkShader>>;
+ using INHERITED = SkRuntimeEffectBuilder;
};
/**
* SkRuntimeBlendBuilder is a utility to simplify creation and uniform setup of runtime blenders.
*/
-class SK_API SkRuntimeBlendBuilder : public SkRuntimeEffectBuilder<sk_sp<SkBlender>> {
+class SK_API SkRuntimeBlendBuilder : public SkRuntimeEffectBuilder {
public:
explicit SkRuntimeBlendBuilder(sk_sp<SkRuntimeEffect>);
~SkRuntimeBlendBuilder();
@@ -456,7 +464,7 @@
sk_sp<SkBlender> makeBlender();
private:
- using INHERITED = SkRuntimeEffectBuilder<sk_sp<SkBlender>>;
+ using INHERITED = SkRuntimeEffectBuilder;
};
#endif // SK_ENABLE_SKSL
diff --git a/src/core/SkRuntimeEffect.cpp b/src/core/SkRuntimeEffect.cpp
index f62aea8..4420576 100644
--- a/src/core/SkRuntimeEffect.cpp
+++ b/src/core/SkRuntimeEffect.cpp
@@ -1200,8 +1200,7 @@
sk_sp<SkImage> SkRuntimeEffect::makeImage(GrRecordingContext* recordingContext,
sk_sp<SkData> uniforms,
- sk_sp<SkShader> children[],
- size_t childCount,
+ SkSpan<ChildPtr> children,
const SkMatrix* localMatrix,
SkImageInfo resultInfo,
bool mipmapped) const {
@@ -1225,11 +1224,12 @@
GrColorInfo colorInfo(resultInfo.colorInfo());
GrFPArgs args(recordingContext, matrixProvider, &colorInfo);
SkSTArray<8, std::unique_ptr<GrFragmentProcessor>> childFPs;
- for (size_t i = 0; i < childCount; ++i) {
- if (!children[i]) {
+ for (size_t i = 0; i < children.size(); ++i) {
+ // TODO: add support for other types of child effects
+ if (!children[i].shader) {
return nullptr;
}
- childFPs.push_back(as_SB(children[i])->asFragmentProcessor(args));
+ childFPs.push_back(as_SB(children[i].shader)->asFragmentProcessor(args));
}
auto fp = GrSkSLFP::MakeWithData(sk_ref_sp(this),
"runtime_image",
@@ -1268,7 +1268,7 @@
}
SkCanvas* canvas = surf->getCanvas();
SkTLazy<SkCanvas> tempCanvas;
- auto shader = this->makeShader(std::move(uniforms), children, childCount, localMatrix, false);
+ auto shader = this->makeShader(std::move(uniforms), children, localMatrix, false);
if (!shader) {
return nullptr;
}
@@ -1344,8 +1344,7 @@
bool mipmapped) {
return this->effect()->makeImage(recordingContext,
this->uniforms(),
- this->children(),
- this->numChildren(),
+ SkMakeSpan(this->children(), this->numChildren()),
localMatrix,
resultInfo,
mipmapped);
@@ -1353,8 +1352,7 @@
sk_sp<SkShader> SkRuntimeShaderBuilder::makeShader(const SkMatrix* localMatrix, bool isOpaque) {
return this->effect()->makeShader(this->uniforms(),
- this->children(),
- this->numChildren(),
+ SkMakeSpan(this->children(), this->numChildren()),
localMatrix,
isOpaque);
}