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>
This commit is contained in:
parent
7a0d3c3f12
commit
4d5708c464
@ -163,6 +163,7 @@ public:
|
||||
|
||||
// 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 @@ public:
|
||||
|
||||
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 @@ private:
|
||||
};
|
||||
|
||||
/** 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 @@ public:
|
||||
} 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 @@ public:
|
||||
};
|
||||
|
||||
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 @@ protected:
|
||||
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 @@ private:
|
||||
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 @@ private:
|
||||
* 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 @@ public:
|
||||
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 @@ public:
|
||||
sk_sp<SkBlender> makeBlender();
|
||||
|
||||
private:
|
||||
using INHERITED = SkRuntimeEffectBuilder<sk_sp<SkBlender>>;
|
||||
using INHERITED = SkRuntimeEffectBuilder;
|
||||
};
|
||||
|
||||
#endif // SK_ENABLE_SKSL
|
||||
|
@ -1200,8 +1200,7 @@ sk_sp<SkShader> SkRuntimeEffect::makeShader(sk_sp<SkData> uniforms,
|
||||
|
||||
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 @@ sk_sp<SkImage> SkRuntimeEffect::makeImage(GrRecordingContext* recordingContext,
|
||||
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 @@ sk_sp<SkImage> SkRuntimeEffect::makeImage(GrRecordingContext* recordingContext,
|
||||
}
|
||||
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 @@ sk_sp<SkImage> SkRuntimeShaderBuilder::makeImage(GrRecordingContext* recordingCo
|
||||
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<SkImage> SkRuntimeShaderBuilder::makeImage(GrRecordingContext* recordingCo
|
||||
|
||||
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);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user