diff --git a/include/c/sk_runtimeeffect.h b/include/c/sk_runtimeeffect.h index fe56b447f403..ed7091fb0f2a 100644 --- a/include/c/sk_runtimeeffect.h +++ b/include/c/sk_runtimeeffect.h @@ -19,6 +19,8 @@ SK_C_API void sk_runtimeeffect_unref(sk_runtimeeffect_t* effect); SK_C_API sk_shader_t* sk_runtimeeffect_make_shader(sk_runtimeeffect_t* effect, sk_data_t* uniforms, sk_flattenable_t** children, size_t childCount, const sk_matrix_t* localMatrix); SK_C_API sk_colorfilter_t* sk_runtimeeffect_make_color_filter(sk_runtimeeffect_t* effect, sk_data_t* uniforms, sk_flattenable_t** children, size_t childCount); SK_C_API sk_blender_t* sk_runtimeeffect_make_blender(sk_runtimeeffect_t* effect, sk_data_t* uniforms, sk_flattenable_t** children, size_t childCount); +SK_C_API sk_imagefilter_t* sk_runtimeeffect_make_image_filter(sk_runtimeeffect_t* effect, sk_data_t* uniforms, sk_flattenable_t** children, size_t childCount, float maxSampleRadius, const char* childShaderName, const sk_imagefilter_t* input); +SK_C_API sk_imagefilter_t* sk_runtimeeffect_make_image_filter_with_children(sk_runtimeeffect_t* effect, sk_data_t* uniforms, sk_flattenable_t** children, size_t childCount, float maxSampleRadius, const char** childShaderNames, const sk_imagefilter_t** inputs, int inputCount); SK_C_API size_t sk_runtimeeffect_get_uniform_byte_size(const sk_runtimeeffect_t* effect); SK_C_API size_t sk_runtimeeffect_get_uniforms_size(const sk_runtimeeffect_t* effect); diff --git a/src/c/sk_imagefilter.cpp b/src/c/sk_imagefilter.cpp index fe98b1c79e02..b39c1f5d9b52 100644 --- a/src/c/sk_imagefilter.cpp +++ b/src/c/sk_imagefilter.cpp @@ -12,6 +12,7 @@ #include "include/core/SkPicture.h" #include "include/core/SkRegion.h" #include "include/effects/SkImageFilters.h" +#include "include/effects/SkRuntimeEffect.h" #include "include/c/sk_imagefilter.h" diff --git a/src/c/sk_runtimeeffect.cpp b/src/c/sk_runtimeeffect.cpp index a700576d6903..695ded746639 100644 --- a/src/c/sk_runtimeeffect.cpp +++ b/src/c/sk_runtimeeffect.cpp @@ -7,8 +7,11 @@ #include "include/core/SkTypes.h" #include "include/core/SkColorFilter.h" +#include "include/core/SkImageFilter.h" #include "include/core/SkShader.h" +#include "include/effects/SkImageFilters.h" #include "include/effects/SkRuntimeEffect.h" +#include "include/private/base/SkTArray.h" #include "include/c/sk_types.h" #include "include/c/sk_runtimeeffect.h" @@ -129,3 +132,33 @@ void sk_runtimeeffect_get_child_from_index(const sk_runtimeeffect_t* effect, int void sk_runtimeeffect_get_child_from_name(const sk_runtimeeffect_t* effect, const char* name, size_t len, sk_runtimeeffect_child_t* cchild) { *cchild = *ToRuntimeEffectChild(AsRuntimeEffect(effect)->findChild(std::string_view(name, len))); } + +sk_imagefilter_t* sk_runtimeeffect_make_image_filter(sk_runtimeeffect_t* effect, sk_data_t* uniforms, sk_flattenable_t** children, size_t childCount, float maxSampleRadius, const char* childShaderName, const sk_imagefilter_t* input) { + SkRuntimeShaderBuilder builder(sk_ref_sp(AsRuntimeEffect(effect)), sk_ref_sp(AsData(uniforms))); + + auto effectChildren = AsRuntimeEffect(effect)->children(); + for (size_t i = 0; i < childCount && i < effectChildren.size(); i++) { + builder.child(effectChildren[i].name) = sk_ref_sp(AsFlattenable(children[i])); + } + + std::string_view name = childShaderName ? std::string_view(childShaderName) : std::string_view(); + return ToImageFilter(SkImageFilters::RuntimeShader(builder, maxSampleRadius, name, sk_ref_sp(AsImageFilter(input))).release()); +} + +sk_imagefilter_t* sk_runtimeeffect_make_image_filter_with_children(sk_runtimeeffect_t* effect, sk_data_t* uniforms, sk_flattenable_t** children, size_t childCount, float maxSampleRadius, const char** childShaderNames, const sk_imagefilter_t** inputs, int inputCount) { + SkRuntimeShaderBuilder builder(sk_ref_sp(AsRuntimeEffect(effect)), sk_ref_sp(AsData(uniforms))); + + auto effectChildren = AsRuntimeEffect(effect)->children(); + for (size_t i = 0; i < childCount && i < effectChildren.size(); i++) { + builder.child(effectChildren[i].name) = sk_ref_sp(AsFlattenable(children[i])); + } + + skia_private::STArray<4, std::string_view> names(inputCount); + skia_private::STArray<4, sk_sp> skInputs(inputCount); + for (int i = 0; i < inputCount; i++) { + names.push_back(std::string_view(childShaderNames[i])); + skInputs.push_back(sk_ref_sp(AsImageFilter(inputs[i]))); + } + + return ToImageFilter(SkImageFilters::RuntimeShader(builder, maxSampleRadius, names.data(), skInputs.data(), inputCount).release()); +}