diff --git a/binding/HarfBuzzSharp.NativeAssets.WebAssembly/buildTransitive/HarfBuzzSharp.targets b/binding/HarfBuzzSharp.NativeAssets.WebAssembly/buildTransitive/HarfBuzzSharp.targets
index e55580187e..7198786ae6 100644
--- a/binding/HarfBuzzSharp.NativeAssets.WebAssembly/buildTransitive/HarfBuzzSharp.targets
+++ b/binding/HarfBuzzSharp.NativeAssets.WebAssembly/buildTransitive/HarfBuzzSharp.targets
@@ -1,19 +1,34 @@
+
+
+ True
+
+
-
+
-
-
+
+
true
+
+ <_HarfBuzzSharpNativeBinaryType Condition="'$(WasmEnableThreads)' == 'True'">mt
+ <_HarfBuzzSharpNativeBinaryType Condition="'$(WasmEnableThreads)' != 'True'">st
+
+ <_HarfBuzzSharpNativeBinaryType Condition="'$(WasmEnableSIMD)' == 'True'">$(_HarfBuzzSharpNativeBinaryType),simd
+ <_HarfBuzzSharpNativeBinaryType Condition="'$(WasmEnableSIMD)' != 'True'">$(_HarfBuzzSharpNativeBinaryType)
-
+
+
-
-
-
+
+
+
+
+
+
\ No newline at end of file
diff --git a/binding/IncludeNativeAssets.HarfBuzzSharp.targets b/binding/IncludeNativeAssets.HarfBuzzSharp.targets
index 97bb5c7fd1..075c0b61a1 100644
--- a/binding/IncludeNativeAssets.HarfBuzzSharp.targets
+++ b/binding/IncludeNativeAssets.HarfBuzzSharp.targets
@@ -62,14 +62,18 @@
-
+
true
+ <_HarfBuzzSharpNativeBinaryType Condition="'$(WasmEnableThreads)' == 'True'">mt
+ <_HarfBuzzSharpNativeBinaryType Condition="'$(WasmEnableThreads)' != 'True'">st
+ <_HarfBuzzSharpNativeBinaryType Condition="'$(WasmEnableSIMD)' == 'True'">$(_HarfBuzzSharpNativeBinaryType),simd
+ <_HarfBuzzSharpNativeBinaryType Condition="'$(WasmEnableSIMD)' != 'True'">$(_HarfBuzzSharpNativeBinaryType)
-
+
-
-
-
+
+
+
\ No newline at end of file
diff --git a/binding/IncludeNativeAssets.SkiaSharp.targets b/binding/IncludeNativeAssets.SkiaSharp.targets
index 4e5706fdcf..4596f8942d 100644
--- a/binding/IncludeNativeAssets.SkiaSharp.targets
+++ b/binding/IncludeNativeAssets.SkiaSharp.targets
@@ -66,15 +66,20 @@
-
+
true
$(EmccExtraLDFlags) -s USE_WEBGL2=1
+ <_SkiaSharpNativeBinaryType Condition="'$(WasmEnableThreads)' == 'True'">mt
+ <_SkiaSharpNativeBinaryType Condition="'$(WasmEnableThreads)' != 'True'">st
+ <_SkiaSharpNativeBinaryType Condition="'$(WasmEnableSIMD)' == 'True'">$(_SkiaSharpNativeBinaryType),simd
+ <_SkiaSharpNativeBinaryType Condition="'$(WasmEnableSIMD)' != 'True'">$(_SkiaSharpNativeBinaryType)
-
+
-
-
-
+
+
+
+
\ No newline at end of file
diff --git a/binding/SkiaSharp.NativeAssets.WebAssembly/buildTransitive/SkiaSharp.targets b/binding/SkiaSharp.NativeAssets.WebAssembly/buildTransitive/SkiaSharp.targets
index ed08c6b349..62e8baacb5 100644
--- a/binding/SkiaSharp.NativeAssets.WebAssembly/buildTransitive/SkiaSharp.targets
+++ b/binding/SkiaSharp.NativeAssets.WebAssembly/buildTransitive/SkiaSharp.targets
@@ -1,10 +1,15 @@
+
+
+ True
+
+
-
+
-
+
@@ -13,16 +18,26 @@
-
-
+
+
true
$(EmccExtraLDFlags) -s USE_WEBGL2=1
+
+ <_SkiaSharpNativeBinaryType Condition="'$(WasmEnableThreads)' == 'True'">mt
+ <_SkiaSharpNativeBinaryType Condition="'$(WasmEnableThreads)' != 'True'">st
+
+ <_SkiaSharpNativeBinaryType Condition="'$(WasmEnableSIMD)' == 'True'">$(_SkiaSharpNativeBinaryType),simd
+ <_SkiaSharpNativeBinaryType Condition="'$(WasmEnableSIMD)' != 'True'">$(_SkiaSharpNativeBinaryType)
-
+
+
-
-
-
+
+
+
+
+
+
\ No newline at end of file
diff --git a/samples/Basic/BrowserWebAssembly/SkiaSharpSample.sln b/samples/Basic/BrowserWebAssembly/SkiaSharpSample.sln
new file mode 100644
index 0000000000..a96eff0ec0
--- /dev/null
+++ b/samples/Basic/BrowserWebAssembly/SkiaSharpSample.sln
@@ -0,0 +1,31 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 17
+VisualStudioVersion = 17.0.31717.149
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharpSample", "SkiaSharpSample\SkiaSharpSample.csproj", "{DB5BC6AE-C110-4CA0-9E1E-0328E29989EB}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp", "..\..\..\binding\SkiaSharp\SkiaSharp.csproj", "{8073311E-E158-4608-8479-512B711C0812}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {DB5BC6AE-C110-4CA0-9E1E-0328E29989EB}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {DB5BC6AE-C110-4CA0-9E1E-0328E29989EB}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {DB5BC6AE-C110-4CA0-9E1E-0328E29989EB}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {DB5BC6AE-C110-4CA0-9E1E-0328E29989EB}.Release|Any CPU.Build.0 = Release|Any CPU
+ {8073311E-E158-4608-8479-512B711C0812}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {8073311E-E158-4608-8479-512B711C0812}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {8073311E-E158-4608-8479-512B711C0812}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {8073311E-E158-4608-8479-512B711C0812}.Release|Any CPU.Build.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {66F81B5B-452E-48B0-A360-017D6840BBD2}
+ EndGlobalSection
+EndGlobal
diff --git a/samples/Basic/BrowserWebAssembly/SkiaSharpSample/Program.cs b/samples/Basic/BrowserWebAssembly/SkiaSharpSample/Program.cs
new file mode 100644
index 0000000000..101c717dda
--- /dev/null
+++ b/samples/Basic/BrowserWebAssembly/SkiaSharpSample/Program.cs
@@ -0,0 +1,38 @@
+using System.Runtime.InteropServices.JavaScript;
+using SkiaSharp;
+
+Console.WriteLine("Hello, Browser!");
+Console.WriteLine("Your platform color type is " + SKImageInfo.PlatformColorType);
+
+// crate a surface
+var info = new SKImageInfo(256, 256);
+using var bitmap = new SKBitmap(info);
+
+// the the canvas and properties
+using var canvas = new SKCanvas(bitmap);
+
+// make sure the canvas is blank
+canvas.Clear(SKColors.White);
+
+// draw some text
+using var paint = new SKPaint
+{
+ Color = SKColors.Black,
+ IsAntialias = true,
+ Style = SKPaintStyle.Fill
+};
+using var font = new SKFont
+{
+ Size = 24
+};
+var coord = new SKPoint(info.Width / 2, (info.Height + font.Size) / 2);
+canvas.DrawText("SkiaSharp", coord, SKTextAlign.Center, font, paint);
+
+// render the image
+Renderer.Render(info.Width, info.Height, bitmap.GetPixelSpan());
+
+partial class Renderer
+{
+ [JSImport("renderer.render", "main.js")]
+ internal static partial void Render(int width, int height, [JSMarshalAs] Span buffer);
+}
diff --git a/samples/Basic/BrowserWebAssembly/SkiaSharpSample/Properties/AssemblyInfo.cs b/samples/Basic/BrowserWebAssembly/SkiaSharpSample/Properties/AssemblyInfo.cs
new file mode 100644
index 0000000000..9ad9b578f2
--- /dev/null
+++ b/samples/Basic/BrowserWebAssembly/SkiaSharpSample/Properties/AssemblyInfo.cs
@@ -0,0 +1,4 @@
+// Licensed to the .NET Foundation under one or more agreements.
+// The .NET Foundation licenses this file to you under the MIT license.
+
+[assembly:System.Runtime.Versioning.SupportedOSPlatform("browser")]
diff --git a/samples/Basic/BrowserWebAssembly/SkiaSharpSample/Properties/launchSettings.json b/samples/Basic/BrowserWebAssembly/SkiaSharpSample/Properties/launchSettings.json
new file mode 100644
index 0000000000..558768dae5
--- /dev/null
+++ b/samples/Basic/BrowserWebAssembly/SkiaSharpSample/Properties/launchSettings.json
@@ -0,0 +1,13 @@
+{
+ "profiles": {
+ "SkiaSharpSample": {
+ "commandName": "Project",
+ "launchBrowser": true,
+ "environmentVariables": {
+ "ASPNETCORE_ENVIRONMENT": "Development"
+ },
+ "applicationUrl": "https://localhost:7184;http://localhost:5264",
+ "inspectUri": "{wsProtocol}://{url.hostname}:{url.port}/_framework/debug/ws-proxy?browser={browserInspectUri}",
+ }
+ }
+}
diff --git a/samples/Basic/BrowserWebAssembly/SkiaSharpSample/SkiaSharpSample.csproj b/samples/Basic/BrowserWebAssembly/SkiaSharpSample/SkiaSharpSample.csproj
new file mode 100644
index 0000000000..5a385b99e4
--- /dev/null
+++ b/samples/Basic/BrowserWebAssembly/SkiaSharpSample/SkiaSharpSample.csproj
@@ -0,0 +1,15 @@
+
+
+
+ net8.0
+ true
+ enable
+
+
+
+
+
+
+
+
+
diff --git a/samples/Basic/BrowserWebAssembly/SkiaSharpSample/runtimeconfig.template.json b/samples/Basic/BrowserWebAssembly/SkiaSharpSample/runtimeconfig.template.json
new file mode 100644
index 0000000000..b96a94320b
--- /dev/null
+++ b/samples/Basic/BrowserWebAssembly/SkiaSharpSample/runtimeconfig.template.json
@@ -0,0 +1,10 @@
+{
+ "wasmHostProperties": {
+ "perHostConfig": [
+ {
+ "name": "browser",
+ "host": "browser"
+ }
+ ]
+ }
+}
\ No newline at end of file
diff --git a/samples/Basic/BrowserWebAssembly/SkiaSharpSample/wwwroot/index.html b/samples/Basic/BrowserWebAssembly/SkiaSharpSample/wwwroot/index.html
new file mode 100644
index 0000000000..5028f8faea
--- /dev/null
+++ b/samples/Basic/BrowserWebAssembly/SkiaSharpSample/wwwroot/index.html
@@ -0,0 +1,16 @@
+
+
+
+
+ SkiaSharpSample
+
+
+
+
+
+
+ SkiaSharpSample
+
+
+
+
diff --git a/samples/Basic/BrowserWebAssembly/SkiaSharpSample/wwwroot/main.js b/samples/Basic/BrowserWebAssembly/SkiaSharpSample/wwwroot/main.js
new file mode 100644
index 0000000000..7133e5df6b
--- /dev/null
+++ b/samples/Basic/BrowserWebAssembly/SkiaSharpSample/wwwroot/main.js
@@ -0,0 +1,22 @@
+import { dotnet } from './_framework/dotnet.js'
+
+const { setModuleImports, getAssemblyExports, getConfig } = await dotnet
+ .create();
+
+setModuleImports('main.js', {
+ renderer: {
+ render: (width, height, buffer) => {
+ const surface = document.getElementById("surface");
+ const ctx = surface.getContext('2d');
+ const clamped = new Uint8ClampedArray(buffer.slice());
+ const image = new ImageData(clamped, width, height);
+ ctx.putImageData(image, 0, 0);
+ surface.style = "";
+ }
+ }
+});
+
+const config = getConfig();
+const exports = await getAssemblyExports(config.mainAssemblyName);
+
+await dotnet.run();
diff --git a/scripts/azure-templates-stages.yml b/scripts/azure-templates-stages.yml
index abb0d2e692..97ef62373b 100644
--- a/scripts/azure-templates-stages.yml
+++ b/scripts/azure-templates-stages.yml
@@ -418,7 +418,7 @@ stages:
- 3.1.12:
displayName: '3.1.12_SIMD'
version: 3.1.12
- features: simd
+ features: st,simd
- 3.1.12:
displayName: '3.1.12_Threading'
version: 3.1.12
@@ -440,12 +440,12 @@ stages:
- 3.1.34:
displayName: '3.1.34_SIMD'
version: 3.1.34
- features: _wasmeh,simd,st
+ features: _wasmeh,st,simd
- 3.1.34:
displayName: '3.1.34_SIMD_Threading'
version: 3.1.34
- features: _wasmeh,simd,mt
-
+ features: _wasmeh,mt,simd
+
# .NET 9
- 3.1.56:
displayName: 3.1.56