SkRuntimeEffectBuilder API usage

17 views
Skip to first unread message

Clark Kent

unread,
Sep 8, 2022, 11:33:46 PMSep 8
to skia-discuss
for uniform

class SK_API SkRuntimeEffect : public SkRefCnt {
public:
    // Reflected description of a uniform variable in the effect's SkSL
    struct Uniform {
        enum class Type {
            kFloat,
            kFloat2,
            kFloat3,
            kFloat4,
            kFloat2x2,
            kFloat3x3,
            kFloat4x4,
            kInt,
            kInt2,
            kInt3,
            kInt4,
        };

would `sk_runtime_effect_builder.uniform(name)` accept the following C types?
```
float
float[2]
float[3]
float[4]
float[2][2]
float[3][3]
float[4][4]
int
int[2]
int[3]
int[4]
```


and for child

    // Reflected description of a uniform child (shader or colorFilter) in the effect's SkSL
    enum class ChildType {
        kShader,
        kColorFilter,
        kBlender,
    };

would `sk_runtime_effect_builder.child(name)` accept the following C++ types?
```
SkShader
SkColorFilter
SkBlender
```

Brian Osman

unread,
Sep 9, 2022, 8:54:48 AMSep 9
to skia-d...@googlegroups.com

The way that the builder's Uniform type works is that you can assign using ANY type that's the right size. (It just does a memcpy inside). What we typically do is use Skia's vector types (SkPoint, SkV3, SkV4), depending on what size of vector you want to assign. This is true for matrix types as well - if the uniform is kFloat2x2, you can use any type that has 4 floats in it (the values are inserted into the matrix in column-major order).

Note that if you have an actual C++ array, you can't use that directly (it gets passed to the function as a pointer, so we can't verify the size), but you CAN use the C++ wrapper std::array (because it knows it's size). So:

    builder.uniform("someVec4") = std::array<float, 4> { 1, 2, 3, 4 };

Will work. It might be even easier (if you are writing C bindings) to use the .set() function. That just takes a pointer and size, so you CAN use a C++ array:

    builder.uniform("someVec4").set(ptrToFourFloats, 4);

For the Child type, you're right - it takes any of those three (SkShader, SkColorFilter, SkBlender). However, the exact type you assign has to match how the child was declared in the SkSL (shader, colorFilter, or blender).

--
You received this message because you are subscribed to the Google Groups "skia-discuss" group.
To unsubscribe from this group and stop receiving emails from it, send an email to skia-discuss...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/skia-discuss/62a5debc-b36a-4580-b926-becf298b2a67n%40googlegroups.com.
Message has been deleted

Brian Osman

unread,
Sep 9, 2022, 9:59:53 AMSep 9
to skia-d...@googlegroups.com
Yes, that all looks correct.

On Fri, Sep 9, 2022 at 9:45 AM Clark Kent <smallvi...@gmail.com> wrote:
so this?



void sk_runtime_effect_builder_set_uniform_int(sk_runtime_effect_builder_t* builder, const char* name, int value) {
    AsRuntimeEffectBuilder(builder)->uniform(name) = value;
}
void sk_runtime_effect_builder_set_uniform_int2(sk_runtime_effect_builder_t* builder, const char* name, int v1, int v2) {
    AsRuntimeEffectBuilder(builder)->uniform(name) = std::array<int, 2> { v1, v2 };
}
void sk_runtime_effect_builder_set_uniform_int3(sk_runtime_effect_builder_t* builder, const char* name, int v1, int v2, int v3) {
    AsRuntimeEffectBuilder(builder)->uniform(name) = std::array<int, 3> { v1, v2, v3 };
}
void sk_runtime_effect_builder_set_uniform_int4(sk_runtime_effect_builder_t* builder, const char* name, int v1, int v2, int v3, int v4) {
    AsRuntimeEffectBuilder(builder)->uniform(name) = std::array<int, 4> { v1, v2, v3, v4 };
}


void sk_runtime_effect_builder_set_uniform_float(sk_runtime_effect_builder_t* builder, const char* name, float value) {
    AsRuntimeEffectBuilder(builder)->uniform(name) = value;
}
void sk_runtime_effect_builder_set_uniform_float2(sk_runtime_effect_builder_t* builder, const char* name, float v1, float v2) {
    AsRuntimeEffectBuilder(builder)->uniform(name) = std::array<float, 2> { v1, v2 };
}
void sk_runtime_effect_builder_set_uniform_float3(sk_runtime_effect_builder_t* builder, const char* name, float v1, float v2, float v3) {
    AsRuntimeEffectBuilder(builder)->uniform(name) = std::array<float, 3> { v1, v2, v3 };
}
void sk_runtime_effect_builder_set_uniform_float4(sk_runtime_effect_builder_t* builder, const char* name, float v1, float v2, float v3, float v4) {
    AsRuntimeEffectBuilder(builder)->uniform(name) = std::array<float, 4> { v1, v2, v3, v4 };
}


void sk_runtime_effect_builder_set_uniform_float2x2(sk_runtime_effect_builder_t* builder, const char* name, float v1, float v2, float v3, float v4) {
    AsRuntimeEffectBuilder(builder)->uniform(name) = std::array<float, 4> {
        v1, v2,
        v3, v4
    };
}
void sk_runtime_effect_builder_set_uniform_float3x3(sk_runtime_effect_builder_t* builder, const char* name, float v1, float v2, float v3, float v4, float v5, float v6, float v7, float v8, float v9) {
    AsRuntimeEffectBuilder(builder)->uniform(name) = std::array<float, 9> {
        v1, v2, v3,
        v4, v5, v6,
        v7, v8, v9
    };
}
void sk_runtime_effect_builder_set_uniform_float4x4(sk_runtime_effect_builder_t* builder, const char* name, float v1, float v2, float v3, float v4, float v5, float v6, float v7, float v8, float v9, float v10, float v11, float v12, float v13, float v14, float v15, float v16) {
    AsRuntimeEffectBuilder(builder)->uniform(name) = std::array<float, 16> {
        v1,  v2,  v3,  v4,
        v5,  v6,  v7,  v8,
        v9,  v10, v11, v12,
        v13, v14, v15, v16
    };
}


void sk_runtime_effect_builder_set_uniform_matrix(sk_runtime_effect_builder_t* builder, const char* name, const sk_matrix_t value) {
    AsRuntimeEffectBuilder(builder)->uniform(name) = value;
}


void sk_runtime_effect_builder_set_child_shader(sk_runtime_effect_builder_t* builder, const char* name, const sk_shader_t* value) {
    AsRuntimeEffectBuilder(builder)->child(name) = value;
}
void sk_runtime_effect_builder_set_child_color_filter(sk_runtime_effect_builder_t* builder, const char* name, const sk_colorfilter_t* value) {
    AsRuntimeEffectBuilder(builder)->child(name) = value;
}
void sk_runtime_effect_builder_set_child_blender(sk_runtime_effect_builder_t* builder, const char* name, const sk_blender_t* value) {
    AsRuntimeEffectBuilder(builder)->child(name) = value;
}

Clark Kent

unread,
Sep 9, 2022, 10:00:38 AMSep 9
to skia-discuss
so this?



sk_runtime_effect_builder_t* sk_runtime_effect_builder_new() {
    return ToRuntimeEffectBuilder(new SkRuntimeEffectBuilder());
}

void sk_runtime_effect_builder_delete(sk_runtime_effect_builder_t* builder) {
    delete AsRuntimeEffectBuilder(builder);
    // SkMatrix AsMatrix(const sk_matrix_t* matrix)

    AsRuntimeEffectBuilder(builder)->uniform(name) = AsMatrix(value);
}


// should we use
//   sk_sp<T>(const T*)
// or
//   sk_ref_sp<T>(const T*)
// ?

void sk_runtime_effect_builder_set_child_nullptr(sk_runtime_effect_builder_t* builder, const char* name) {
    AsRuntimeEffectBuilder(builder)->child(name) = nullptr;

}
void sk_runtime_effect_builder_set_child_shader(sk_runtime_effect_builder_t* builder, const char* name, const sk_shader_t* value) {
    AsRuntimeEffectBuilder(builder)->child(name) = sk_ref_sp<SkShader>(AsShader(value));

}
void sk_runtime_effect_builder_set_child_color_filter(sk_runtime_effect_builder_t* builder, const char* name, const sk_colorfilter_t* value) {
    AsRuntimeEffectBuilder(builder)->child(name) = sk_ref_sp<SkColorFilter>(AsColorFilter(value));

}
void sk_runtime_effect_builder_set_child_blender(sk_runtime_effect_builder_t* builder, const char* name, const sk_blender_t* value) {
    AsRuntimeEffectBuilder(builder)->child(name) = sk_ref_sp<SkBlender>(AsBlender(value));
}


On Friday, 9 September 2022 at 22:54:48 UTC+10 brian...@google.com wrote:

Clark Kent

unread,
Sep 9, 2022, 10:02:01 AMSep 9
to skia-discuss
also is it possible to pass in an SkM44 ?

Clark Kent

unread,
Sep 9, 2022, 10:24:45 AMSep 9
to skia-discuss
also do we work with SkRuntimeEffectBuilder directly or do we use SkRuntimeShaderBuilder ?

as `SkRuntimeEffectBuilder() = delete;`

and `SkRuntimeEffectBuilder(sk_sp<SkRuntimeEffect> effect)` is protected

Clark Kent

unread,
Sep 9, 2022, 10:52:07 AMSep 9
to skia-discuss
also is it safe to reinterpret_cast<SkRuntimeEffectBuilder*>(SkRuntimeShaderBuilder_ptr); ?

eg,

SkRuntimeShaderBuilder * shader_builder = new SkRuntimeShaderBuilder(effect);
SkRuntimeEffectBuilder * effect_builder = reinterpret_cast<SkRuntimeEffectBuilder*>(shader_builder);

// access SkRuntimeEffectBuilder API via effect_builder
// access SkRuntimeShaderBuilder API via shader_builder

delete shader_builder; // CANNOT delete effect_builder cus incorrect type
Reply all
Reply to author
Forward
0 new messages