Skip to content

Commit

Permalink
Add support for WinUI accelerated views
Browse files Browse the repository at this point in the history
Adds the GPU views for WinUI, but there are a few othe things it need
to do:
- Builds ANGLE as this is the primary interop between SkiaSharp and
  DirectX
- Builds an interop library that extends types needed for interacting
  with ANGLE
- Enables AngleSwapChainPanel as this is the WinUI view that sets up
  the GL context
- Enables the SKSwapChainPanel as this is the SkiaSharp accelerated
  view
- Add a new NativeAssets package for WinUI native files
  • Loading branch information
mattleibow committed Feb 2, 2024
1 parent 8c296e5 commit b3762c7
Show file tree
Hide file tree
Showing 37 changed files with 785 additions and 95 deletions.
19 changes: 19 additions & 0 deletions binding/IncludeNativeAssets.SkiaSharp.WinUI.targets
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
<?xml version="1.0" encoding="utf-8"?>
<Project xmlns="http://schemas.microsoft.com/developer/msbuild/2003">

<ItemGroup>
<Content Include="$(MSBuildThisFileDirectory)..\output\native\winui\any\*.dll" Visible="False" />
</ItemGroup>

<ItemGroup Condition="$(TargetFramework.Contains('-windows')) and '$(Platform)' != 'AnyCPU' and '$(Platform)' != 'Any CPU'">
<Content Include="$(MSBuildThisFileDirectory)..\output\native\winui\$(Platform)\*" Visible="False" />
</ItemGroup>

<ItemGroup Condition="$(TargetFramework.Contains('-windows')) and ('$(Platform)' == 'AnyCPU' or '$(Platform)' == 'Any CPU')">
<Content Include="$(MSBuildThisFileDirectory)..\output\native\winui\x64\*" Condition="'$(RuntimeIdentifier)' == 'win10-x64'" Visible="False" />
<Content Include="$(MSBuildThisFileDirectory)..\output\native\winui\x86\*" Condition="'$(RuntimeIdentifier)' == 'win10-x86'" Visible="False" />
<Content Include="$(MSBuildThisFileDirectory)..\output\native\winui\arm64\*" Condition="'$(RuntimeIdentifier)' == 'win10-arm64'" Visible="False" />
<Content Include="$(MSBuildThisFileDirectory)..\output\native\winui\x64\*" Condition="'$(RuntimeIdentifier)' == ''" Visible="False" CopyToOutputDirectory="PreserveNewest" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,16 @@
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<TargetFrameworks>$(WindowsTargetFrameworks)</TargetFrameworks>
<PackagingGroup>SkiaSharp</PackagingGroup>
<Title>$(PackagingGroup) - Native Assets for Windows UI (WinUI 3)</Title>
<IsWindowsNativeAssets>true</IsWindowsNativeAssets>
</PropertyGroup>
<ItemGroup>
<NativeWindowsPackageFile Include="..\..\output\native\winui\any\*" RuntimeIdentifier="win-x64" />
<NativeWindowsPackageFile Include="..\..\output\native\winui\x64\*" RuntimeIdentifier="win-x64" />
<NativeWindowsPackageFile Include="..\..\output\native\winui\any\*" RuntimeIdentifier="win-x86" />
<NativeWindowsPackageFile Include="..\..\output\native\winui\x86\*" RuntimeIdentifier="win-x86" />
<NativeWindowsPackageFile Include="..\..\output\native\winui\any\*" RuntimeIdentifier="win-arm64" />
<NativeWindowsPackageFile Include="..\..\output\native\winui\arm64\*" RuntimeIdentifier="win-arm64" />
</ItemGroup>
</Project>
1 change: 1 addition & 0 deletions build.cake
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,7 @@ var TRACKED_NUGETS = new Dictionary<string, Version> {
{ "SkiaSharp.NativeAssets.Tizen", new Version (1, 60, 0) },
{ "SkiaSharp.NativeAssets.tvOS", new Version (1, 60, 0) },
{ "SkiaSharp.NativeAssets.Win32", new Version (1, 60, 0) },
{ "SkiaSharp.NativeAssets.WinUI", new Version (1, 60, 0) },
{ "SkiaSharp.Views", new Version (1, 60, 0) },
{ "SkiaSharp.Views.Desktop.Common", new Version (1, 60, 0) },
{ "SkiaSharp.Views.Gtk3", new Version (1, 60, 0) },
Expand Down
1 change: 1 addition & 0 deletions externals/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
angle/
package_cache/
vcpkg/
winappsdk/
1 change: 1 addition & 0 deletions native/.gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
xcuserdata/
project.xcworkspace/
uwp/ANGLE/triplets
Generated Files/
75 changes: 75 additions & 0 deletions native/winui/ANGLE.cake
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
void InitializeAngle(string branch, DirectoryPath ANGLE_PATH, DirectoryPath WINAPPSDK_PATH)
{
if (!DirectoryExists(ANGLE_PATH)) {
RunProcess("git", $"clone https://github.com/google/angle.git --branch {branch} --depth 1 --single-branch --shallow-submodules {ANGLE_PATH}");
}

var submodules = new[] {
"build",
"testing",
"third_party/zlib",
"third_party/jsoncpp",
"third_party/vulkan-deps",
"third_party/astc-encoder/src",
"tools/clang",
};
foreach (var submodule in submodules) {
var sub = ANGLE_PATH.Combine(submodule);
if (FileExists(sub.CombineWithFilePath("BUILD.gn")) || FileExists(sub.CombineWithFilePath(".gitignore")))
continue;

RunProcess("git", new ProcessSettings {
Arguments = $"submodule update --init --recursive {submodule}",
WorkingDirectory = ANGLE_PATH.FullPath,
});
}

{
var toolchain = ANGLE_PATH.CombineWithFilePath("build/toolchain/win/toolchain.gni");
var contents = System.IO.File.ReadAllText(toolchain.FullPath);
var newContents = contents
.Replace("\"${dllname}.lib\"", "\"{{output_dir}}/{{target_output_name}}.lib\"")
.Replace("\"${dllname}.pdb\"", "\"{{output_dir}}/{{target_output_name}}.pdb\"");
if (contents != newContents)
System.IO.File.WriteAllText(toolchain.FullPath, newContents);
}

if (!FileExists(ANGLE_PATH.CombineWithFilePath("build/config/gclient_args.gni"))) {
var lines = new[] {
"checkout_angle_internal = false",
"checkout_angle_mesa = false",
"checkout_angle_restricted_traces = false",
"generate_location_tags = false"
};
System.IO.File.WriteAllLines(ANGLE_PATH.CombineWithFilePath("build/config/gclient_args.gni").FullPath, lines);
}

if (!FileExists(ANGLE_PATH.CombineWithFilePath("build/util/LASTCHANGE"))) {
var lastchange = ANGLE_PATH.CombineWithFilePath("build/util/LASTCHANGE");
RunPython(ANGLE_PATH, ANGLE_PATH.CombineWithFilePath("build/util/lastchange.py"), $"-o {lastchange}");
}

if (!FileExists(ANGLE_PATH.CombineWithFilePath("build/toolchain/win/rc/win/rc.exe"))) {
var oldPath = EnvironmentVariable("PATH");
try {
System.Environment.SetEnvironmentVariable("PATH", DEPOT_PATH.FullPath + System.IO.Path.PathSeparator + oldPath);

RunPython(ANGLE_PATH,
DEPOT_PATH.CombineWithFilePath("download_from_google_storage.py"),
$"--no_resume --no_auth --bucket chromium-browser-clang/rc -s build/toolchain/win/rc/win/rc.exe.sha1");
} finally {
System.Environment.SetEnvironmentVariable("PATH", oldPath);
}
}

if (!FileExists(ANGLE_PATH.CombineWithFilePath("third_party/llvm-build/Release+Asserts/cr_build_revision"))) {
RunPython(ANGLE_PATH, ANGLE_PATH.CombineWithFilePath("tools/clang/scripts/update.py"));
}

if (!FileExists(WINAPPSDK_PATH.CombineWithFilePath("Microsoft.WindowsAppSDK.nuspec"))) {
var setup = ANGLE_PATH.CombineWithFilePath("scripts/winappsdk_setup.py");
RunProcess(
ROOT_PATH.CombineWithFilePath("scripts/vcvarsall.bat"),
$"\"{VS_INSTALL}\" \"x64\" \"{PYTHON_EXE}\" \"{setup}\" --output \"{WINAPPSDK_PATH}\"");
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<Project>

<Import Project="$(MSBuildThisFileDirectory)..\..\..\..\source\SkiaSharp.Build.props" />

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
<Project>

<Import Project="$(MSBuildThisFileDirectory)..\..\..\..\source\SkiaSharp.Build.targets" />

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFramework>net7.0-windows10.0.19041.0</TargetFramework>
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
<PackageId>SkiaSharp.Views.WinUI</PackageId>
<PackagingGroup>SkiaSharp.Views.WinUI</PackagingGroup>
<IsPackable>false</IsPackable>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
</PropertyGroup>

<PropertyGroup>
<ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>None</ResolveAssemblyWarnOrErrorOnTargetArchitectureMismatch>
<CsWinRTIncludes>SkiaSharp.Views.WinUI.Native</CsWinRTIncludes>
</PropertyGroup>

<ItemGroup>
<PackageReference Include="Microsoft.Windows.CsWinRT" Version="2.0.4" />
</ItemGroup>

<ItemGroup>
<ProjectReference Include="..\SkiaSharp.Views.WinUI.Native\SkiaSharp.Views.WinUI.Native.vcxproj" />
</ItemGroup>

</Project>
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio Version 17
VisualStudioVersion = 17.9.34310.174
MinimumVisualStudioVersion = 10.0.40219.1
Project("{8BC9CEB8-8B4A-11D0-8D11-00A0C91BC942}") = "SkiaSharp.Views.WinUI.Native", "SkiaSharp.Views.WinUI.Native\SkiaSharp.Views.WinUI.Native.vcxproj", "{730AF4C9-82D2-4FA7-AA32-154F3524EBD2}"
EndProject
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "SkiaSharp.Views.WinUI.Native.Projection", "SkiaSharp.Views.WinUI.Native.Projection\SkiaSharp.Views.WinUI.Native.Projection.csproj", "{95E9FEB4-DCD3-4514-8208-A87688788BB2}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Debug|ARM64 = Debug|ARM64
Debug|x64 = Debug|x64
Debug|x86 = Debug|x86
Release|Any CPU = Release|Any CPU
Release|ARM64 = Release|ARM64
Release|x64 = Release|x64
Release|x86 = Release|x86
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Debug|Any CPU.ActiveCfg = Debug|x64
{730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Debug|Any CPU.Build.0 = Debug|x64
{730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Debug|ARM64.ActiveCfg = Debug|ARM64
{730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Debug|ARM64.Build.0 = Debug|ARM64
{730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Debug|x64.ActiveCfg = Debug|x64
{730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Debug|x64.Build.0 = Debug|x64
{730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Debug|x86.ActiveCfg = Debug|Win32
{730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Debug|x86.Build.0 = Debug|Win32
{730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Release|Any CPU.ActiveCfg = Release|x64
{730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Release|Any CPU.Build.0 = Release|x64
{730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Release|ARM64.ActiveCfg = Release|ARM64
{730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Release|ARM64.Build.0 = Release|ARM64
{730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Release|x64.ActiveCfg = Release|x64
{730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Release|x64.Build.0 = Release|x64
{730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Release|x86.ActiveCfg = Release|Win32
{730AF4C9-82D2-4FA7-AA32-154F3524EBD2}.Release|x86.Build.0 = Release|Win32
{95E9FEB4-DCD3-4514-8208-A87688788BB2}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{95E9FEB4-DCD3-4514-8208-A87688788BB2}.Debug|Any CPU.Build.0 = Debug|Any CPU
{95E9FEB4-DCD3-4514-8208-A87688788BB2}.Debug|ARM64.ActiveCfg = Debug|Any CPU
{95E9FEB4-DCD3-4514-8208-A87688788BB2}.Debug|ARM64.Build.0 = Debug|Any CPU
{95E9FEB4-DCD3-4514-8208-A87688788BB2}.Debug|x64.ActiveCfg = Debug|Any CPU
{95E9FEB4-DCD3-4514-8208-A87688788BB2}.Debug|x64.Build.0 = Debug|Any CPU
{95E9FEB4-DCD3-4514-8208-A87688788BB2}.Debug|x86.ActiveCfg = Debug|Any CPU
{95E9FEB4-DCD3-4514-8208-A87688788BB2}.Debug|x86.Build.0 = Debug|Any CPU
{95E9FEB4-DCD3-4514-8208-A87688788BB2}.Release|Any CPU.ActiveCfg = Release|Any CPU
{95E9FEB4-DCD3-4514-8208-A87688788BB2}.Release|Any CPU.Build.0 = Release|Any CPU
{95E9FEB4-DCD3-4514-8208-A87688788BB2}.Release|ARM64.ActiveCfg = Release|Any CPU
{95E9FEB4-DCD3-4514-8208-A87688788BB2}.Release|ARM64.Build.0 = Release|Any CPU
{95E9FEB4-DCD3-4514-8208-A87688788BB2}.Release|x64.ActiveCfg = Release|Any CPU
{95E9FEB4-DCD3-4514-8208-A87688788BB2}.Release|x64.Build.0 = Release|Any CPU
{95E9FEB4-DCD3-4514-8208-A87688788BB2}.Release|x86.ActiveCfg = Release|Any CPU
{95E9FEB4-DCD3-4514-8208-A87688788BB2}.Release|x86.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(ExtensibilityGlobals) = postSolution
SolutionGuid = {FB8DA12F-84B5-4D7F-A6E1-7F0A53AA4535}
EndGlobalSection
EndGlobal
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
#include "pch.h"
#include "PropertySetExtensions.h"
#include "PropertySetExtensions.g.cpp"

using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Foundation::Collections;

namespace winrt::SkiaSharp::Views::WinUI::Native::implementation
{
void PropertySetExtensions::AddSingle(PropertySet const& propertySet, hstring const& key, float value)
{
propertySet.Insert(key, PropertyValue::CreateSingle(value));
}

void PropertySetExtensions::AddSize(PropertySet const& propertySet, hstring const& key, Size const& height)
{
propertySet.Insert(key, PropertyValue::CreateSize(height));
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#pragma once

#include "PropertySetExtensions.g.h"

using namespace winrt::Windows::Foundation;
using namespace winrt::Windows::Foundation::Collections;

namespace winrt::SkiaSharp::Views::WinUI::Native::implementation
{
struct PropertySetExtensions
{
PropertySetExtensions() = default;

static void AddSingle(PropertySet const& propertySet, hstring const& key, float value);
static void AddSize(PropertySet const& propertySet, hstring const& key, Size const& value);
};
}

namespace winrt::SkiaSharp::Views::WinUI::Native::factory_implementation
{
struct PropertySetExtensions : PropertySetExtensionsT<PropertySetExtensions, implementation::PropertySetExtensions>
{
};
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,8 @@
namespace SkiaSharp.Views.WinUI.Native
{
static runtimeclass PropertySetExtensions
{
static void AddSingle(Windows.Foundation.Collections.PropertySet propertySet, String key, Single value);
static void AddSize(Windows.Foundation.Collections.PropertySet propertySet, String key, Windows.Foundation.Size value);
}
}
Loading

0 comments on commit b3762c7

Please sign in to comment.