Skip to content

Commit

Permalink
Add support for WinUI accelerated views (#2733)
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 authored Feb 3, 2024
1 parent 14b451c commit 79162b3
Show file tree
Hide file tree
Showing 36 changed files with 784 additions and 94 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 79162b3

Please sign in to comment.