Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add RuntimeShader Support. #3141

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions binding/SkiaSharp.Resources/ResourcesApi.generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
using sk_rrect_t = System.IntPtr;
using sk_rtree_factory_t = System.IntPtr;
using sk_runtimeeffect_t = System.IntPtr;
using sk_runtimeshaderbuilder_t = System.IntPtr;
using sk_shader_t = System.IntPtr;
using sk_stream_asset_t = System.IntPtr;
using sk_stream_filestream_t = System.IntPtr;
Expand Down
1 change: 1 addition & 0 deletions binding/SkiaSharp.SceneGraph/SceneGraphApi.generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
using sk_rrect_t = System.IntPtr;
using sk_rtree_factory_t = System.IntPtr;
using sk_runtimeeffect_t = System.IntPtr;
using sk_runtimeshaderbuilder_t = System.IntPtr;
using sk_shader_t = System.IntPtr;
using sk_stream_asset_t = System.IntPtr;
using sk_stream_filestream_t = System.IntPtr;
Expand Down
1 change: 1 addition & 0 deletions binding/SkiaSharp.Skottie/SkottieApi.generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
using sk_rrect_t = System.IntPtr;
using sk_rtree_factory_t = System.IntPtr;
using sk_runtimeeffect_t = System.IntPtr;
using sk_runtimeshaderbuilder_t = System.IntPtr;
using sk_shader_t = System.IntPtr;
using sk_stream_asset_t = System.IntPtr;
using sk_stream_filestream_t = System.IntPtr;
Expand Down
44 changes: 43 additions & 1 deletion binding/SkiaSharp/SKImageFilter.cs
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
using System;
using System.Runtime.InteropServices;

namespace SkiaSharp
{
Expand Down Expand Up @@ -437,7 +438,48 @@ public static SKImageFilter CreateShader (SKShader? shader, bool dither, SKRect
private static SKImageFilter CreateShader (SKShader? shader, bool dither, SKRect* cropRect) =>
GetObject (SkiaApi.sk_imagefilter_new_shader (shader?.Handle ?? IntPtr.Zero, dither, cropRect));

//
// CreateRuntimeShader
public static SKImageFilter CreateRuntimeShader (SKRuntimeShaderBuilder builder, string childShaderName, SKImageFilter? input) =>
CreateRuntimeShader (builder, 0f, childShaderName, input);

public static SKImageFilter CreateRuntimeShader (SKRuntimeShaderBuilder builder, float maxSampleRadius, string childShaderName, SKImageFilter? input) =>
CreateRuntimeShader (builder, maxSampleRadius, [childShaderName], [input]);

public static SKImageFilter CreateRuntimeShader (SKRuntimeShaderBuilder builder, float maxSampleRadius, string[] childShaderNames, SKImageFilter?[] inputs)
{
SKImageFilter result;
IntPtr runtimeShaderBuilder;

using var childrenHandles = Utils.RentHandlesArray (builder.Children.ToArray (), true);
fixed (IntPtr* childrenHandlesPtr = childrenHandles) {
runtimeShaderBuilder = SkiaApi.sk_runtimeshaderbuilder_new (builder.Effect.Handle, builder.Uniforms.ToData ().Handle, childrenHandlesPtr, (IntPtr)builder.Children.Count);
}

using var inputsHandles = Utils.RentHandlesArray (inputs, true);
using var childShaderNamesHandles = Utils.RentArray<IntPtr> (inputs.Length, true);
var gcHandles = new GCHandle[childShaderNames.Length];

try {
for (int i = 0; i < childShaderNames.Length; i++) {
var handle = GCHandle.Alloc (StringUtilities.GetEncodedText (childShaderNames[i], SKTextEncoding.Utf8), GCHandleType.Pinned);
childShaderNamesHandles[i] = handle.AddrOfPinnedObject ();
}

fixed (IntPtr* inputsHandlesPtr = inputsHandles) {
fixed (IntPtr* childShaderNamesHandlesPtr = childShaderNamesHandles) {
result = GetObject (SkiaApi.sk_imagefilter_new_runtime_shader (runtimeShaderBuilder, maxSampleRadius, (void**)childShaderNamesHandlesPtr, inputsHandlesPtr, childShaderNames.Length));
}
}
} finally {
SkiaApi.sk_runtimeshaderbuilder_destructor (runtimeShaderBuilder);
foreach (var handle in gcHandles) {
if (handle.IsAllocated) {
handle.Free ();
}
}
}
return result;
}

internal static SKImageFilter GetObject (IntPtr handle) =>
GetOrAddObject (handle, (h, o) => new SKImageFilter (h, o));
Expand Down
33 changes: 33 additions & 0 deletions binding/SkiaSharp/SKRuntimeEffect.cs
Original file line number Diff line number Diff line change
Expand Up @@ -263,6 +263,20 @@ public SKRuntimeEffectUniforms (SKRuntimeEffect effect)
}
}

public SKRuntimeEffectUniforms (SKRuntimeEffectUniforms effectUniforms)
{
names = effectUniforms.names.ToArray ();
uniforms = effectUniforms.uniforms.ToDictionary (e => e.Key, e => e.Value);

var dataSize = effectUniforms.data.Size;
if (dataSize > 0) {
data = SKData.CreateCopy (effectUniforms.data.Data, effectUniforms.data.Size);
} else {
data = SKData.Empty;
}

}

public IReadOnlyList<string> Names =>
names;

Expand Down Expand Up @@ -375,6 +389,12 @@ public SKRuntimeEffectChildren (SKRuntimeEffect effect)
children = new SKObject[names.Length];
}

public SKRuntimeEffectChildren (SKRuntimeEffectChildren effectChildren)
{
names = effectChildren.names.ToArray ();
children = effectChildren.children.ToArray ();
}

public IReadOnlyList<string> Names =>
names;

Expand Down Expand Up @@ -640,6 +660,14 @@ public SKRuntimeEffectBuilder (SKRuntimeEffect effect)
Children = new SKRuntimeEffectChildren (effect);
}

public SKRuntimeEffectBuilder (SKRuntimeEffectBuilder builder)
{
Effect = builder.Effect;

Uniforms = new SKRuntimeEffectUniforms (builder.Uniforms);
Children = new SKRuntimeEffectChildren (builder.Children);
}

public SKRuntimeEffect Effect { get; }

public SKRuntimeEffectUniforms Uniforms { get; }
Expand All @@ -661,6 +689,11 @@ public SKRuntimeShaderBuilder (SKRuntimeEffect effect)
{
}

public SKRuntimeShaderBuilder (SKRuntimeShaderBuilder builder)
: base (builder)
{
}

public SKShader Build () =>
Effect.ToShader (Uniforms, Children);

Expand Down
58 changes: 58 additions & 0 deletions binding/SkiaSharp/SkiaApi.generated.cs
Original file line number Diff line number Diff line change
Expand Up @@ -62,6 +62,7 @@
using sk_rrect_t = System.IntPtr;
using sk_rtree_factory_t = System.IntPtr;
using sk_runtimeeffect_t = System.IntPtr;
using sk_runtimeshaderbuilder_t = System.IntPtr;
using sk_shader_t = System.IntPtr;
using sk_stream_asset_t = System.IntPtr;
using sk_stream_filestream_t = System.IntPtr;
Expand Down Expand Up @@ -7785,6 +7786,25 @@ internal static sk_imagefilter_t sk_imagefilter_new_point_lit_specular (SKPoint3
(sk_imagefilter_new_point_lit_specular_delegate ??= GetSymbol<Delegates.sk_imagefilter_new_point_lit_specular> ("sk_imagefilter_new_point_lit_specular")).Invoke (location, lightColor, surfaceScale, ks, shininess, input, cropRect);
#endif

// sk_imagefilter_t* sk_imagefilter_new_runtime_shader(const sk_runtimeshaderbuilder_t* builder, float maxSampleRadius, const char*[-1] childShaderNames, const sk_imagefilter_t*[-1] inputs, int inputCount)
#if !USE_DELEGATES
#if USE_LIBRARY_IMPORT
[LibraryImport (SKIA)]
internal static partial sk_imagefilter_t sk_imagefilter_new_runtime_shader (sk_runtimeshaderbuilder_t builder, Single maxSampleRadius, /* char */ void** childShaderNames, sk_imagefilter_t* inputs, Int32 inputCount);
#else // !USE_LIBRARY_IMPORT
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern sk_imagefilter_t sk_imagefilter_new_runtime_shader (sk_runtimeshaderbuilder_t builder, Single maxSampleRadius, /* char */ void** childShaderNames, sk_imagefilter_t* inputs, Int32 inputCount);
#endif
#else
private partial class Delegates {
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
internal delegate sk_imagefilter_t sk_imagefilter_new_runtime_shader (sk_runtimeshaderbuilder_t builder, Single maxSampleRadius, /* char */ void** childShaderNames, sk_imagefilter_t* inputs, Int32 inputCount);
}
private static Delegates.sk_imagefilter_new_runtime_shader sk_imagefilter_new_runtime_shader_delegate;
internal static sk_imagefilter_t sk_imagefilter_new_runtime_shader (sk_runtimeshaderbuilder_t builder, Single maxSampleRadius, /* char */ void** childShaderNames, sk_imagefilter_t* inputs, Int32 inputCount) =>
(sk_imagefilter_new_runtime_shader_delegate ??= GetSymbol<Delegates.sk_imagefilter_new_runtime_shader> ("sk_imagefilter_new_runtime_shader")).Invoke (builder, maxSampleRadius, childShaderNames, inputs, inputCount);
#endif

// sk_imagefilter_t* sk_imagefilter_new_shader(const sk_shader_t* shader, bool dither, const sk_rect_t* cropRect)
#if !USE_DELEGATES
#if USE_LIBRARY_IMPORT
Expand Down Expand Up @@ -13282,6 +13302,44 @@ internal static void sk_runtimeeffect_unref (sk_runtimeeffect_t effect) =>
(sk_runtimeeffect_unref_delegate ??= GetSymbol<Delegates.sk_runtimeeffect_unref> ("sk_runtimeeffect_unref")).Invoke (effect);
#endif

// void sk_runtimeshaderbuilder_destructor(sk_runtimeshaderbuilder_t* builder)
#if !USE_DELEGATES
#if USE_LIBRARY_IMPORT
[LibraryImport (SKIA)]
internal static partial void sk_runtimeshaderbuilder_destructor (sk_runtimeshaderbuilder_t builder);
#else // !USE_LIBRARY_IMPORT
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern void sk_runtimeshaderbuilder_destructor (sk_runtimeshaderbuilder_t builder);
#endif
#else
private partial class Delegates {
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
internal delegate void sk_runtimeshaderbuilder_destructor (sk_runtimeshaderbuilder_t builder);
}
private static Delegates.sk_runtimeshaderbuilder_destructor sk_runtimeshaderbuilder_destructor_delegate;
internal static void sk_runtimeshaderbuilder_destructor (sk_runtimeshaderbuilder_t builder) =>
(sk_runtimeshaderbuilder_destructor_delegate ??= GetSymbol<Delegates.sk_runtimeshaderbuilder_destructor> ("sk_runtimeshaderbuilder_destructor")).Invoke (builder);
#endif

// sk_runtimeshaderbuilder_t* sk_runtimeshaderbuilder_new(const sk_runtimeeffect_t* effect, sk_data_t* uniforms, sk_flattenable_t** children, size_t childCount)
#if !USE_DELEGATES
#if USE_LIBRARY_IMPORT
[LibraryImport (SKIA)]
internal static partial sk_runtimeshaderbuilder_t sk_runtimeshaderbuilder_new (sk_runtimeeffect_t effect, sk_data_t uniforms, sk_flattenable_t* children, /* size_t */ IntPtr childCount);
#else // !USE_LIBRARY_IMPORT
[DllImport (SKIA, CallingConvention = CallingConvention.Cdecl)]
internal static extern sk_runtimeshaderbuilder_t sk_runtimeshaderbuilder_new (sk_runtimeeffect_t effect, sk_data_t uniforms, sk_flattenable_t* children, /* size_t */ IntPtr childCount);
#endif
#else
private partial class Delegates {
[UnmanagedFunctionPointer (CallingConvention.Cdecl)]
internal delegate sk_runtimeshaderbuilder_t sk_runtimeshaderbuilder_new (sk_runtimeeffect_t effect, sk_data_t uniforms, sk_flattenable_t* children, /* size_t */ IntPtr childCount);
}
private static Delegates.sk_runtimeshaderbuilder_new sk_runtimeshaderbuilder_new_delegate;
internal static sk_runtimeshaderbuilder_t sk_runtimeshaderbuilder_new (sk_runtimeeffect_t effect, sk_data_t uniforms, sk_flattenable_t* children, /* size_t */ IntPtr childCount) =>
(sk_runtimeshaderbuilder_new_delegate ??= GetSymbol<Delegates.sk_runtimeshaderbuilder_new> ("sk_runtimeshaderbuilder_new")).Invoke (effect, uniforms, children, childCount);
#endif

#endregion

#region sk_shader.h
Expand Down