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

Update ComputeSharp.D2D1.WinUI to AOT-safe CsWinRT #763

Merged
merged 20 commits into from
Jun 30, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
20 commits
Select commit Hold shift + click to select a range
736610e
Make ICanvasImageInterop bindings AOT safe
Sergio0694 Jan 19, 2024
f1fc6a8
Make ICanvasEffectFactoryNative bindings AOT safe
Sergio0694 Jan 20, 2024
8c53714
Use ActivationFactory.Get() for ICanvasFactoryNative
Sergio0694 Jan 25, 2024
190036d
Remove DynamicallyAccessedMemberTypes.Interfaces
Sergio0694 Jan 25, 2024
0cacfe7
Also use ActivationFactory.Get() in Win2D CLI sample
Sergio0694 Jan 26, 2024
242d90a
Use ActivationFactory.Get() in Win2D unit tests
Sergio0694 Jan 27, 2024
ed088c8
Make ICanvasImageInteropMethods public
Sergio0694 Jan 27, 2024
9e4a416
Make exposed CCW types partial (eg. EffectFactory)
Sergio0694 Jan 29, 2024
da8c14d
Remove unnecessary .rd.xml file for NativeAOT
Sergio0694 Jan 29, 2024
bcee902
Remove unnecessary [DynamicallyAccessedMembers]
Sergio0694 Feb 4, 2024
bac700d
Fix a small typo in a comment
Sergio0694 Feb 4, 2024
b8ef998
Enable CsWinRT AOT generator, fix IIDOptimizer errors
Sergio0694 Feb 5, 2024
5f7f720
Enable enable AOT generator on collection types
Sergio0694 Feb 6, 2024
bf107cb
Add missing accessibility modifier
Sergio0694 Feb 6, 2024
73a49ed
Remove unnecessary trim suppression
Sergio0694 May 11, 2024
d01bcaa
Remove unnecessary 'partial' modifiers
Sergio0694 May 18, 2024
e5f0915
Remove unnecessary [Guid] attributes
Sergio0694 May 19, 2024
9c0fa8d
Update NuGet packages to WinAppSDK 1.6-experimental1
Sergio0694 Jun 14, 2024
8385445
Remove suppressions, enable CsWinRT size saving
Sergio0694 Jun 16, 2024
9024d1f
Update Win2D to 1.2.1-experimental1
Sergio0694 Jun 28, 2024
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
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,6 @@
using System.Runtime.InteropServices;
using TerraFX.Interop.Windows;
using TerraFX.Interop;
using WinRT;
using WinRT.Interop;

#pragma warning disable CS0649, IDE0055, IDE1006

Expand Down Expand Up @@ -79,25 +77,4 @@ public HRESULT GetOrCreate(IUnknown* device, IUnknown* resource, float dpi, void
dpi,
wrapper);
}

/// <summary>
/// The managed interface for <see cref="ICanvasFactoryNative"/>.
/// </summary>
[Guid("695C440D-04B3-4EDD-BFD9-63E51E9F7202")]
[WindowsRuntimeType]
[WindowsRuntimeHelperType(typeof(Interface))]
public interface Interface
{
/// <summary>
/// The vtable type for <see cref="Interface"/>.
/// </summary>
[Guid("695C440D-04B3-4EDD-BFD9-63E51E9F7202")]
public readonly struct Vftbl
{
/// <summary>
/// Allows CsWinRT to retrieve a pointer to the projection vtable (the name is hardcoded by convention).
/// </summary>
public static readonly IntPtr AbiToProjectionVftablePtr = IUnknownVftbl.AbiToProjectionVftblPtr;
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ namespace ComputeSharp.SwapChain.D2D1.Backend;
/// <summary>
/// An base effect for an animated pixel shader.
/// </summary>
internal abstract class PixelShaderEffect : CanvasEffect
internal abstract partial class PixelShaderEffect : CanvasEffect
{
/// <summary>
/// The current elapsed time.
Expand Down Expand Up @@ -57,7 +57,7 @@ public int ScreenHeight
/// </summary>
/// <typeparam name="T">The type of pixel shader to render.</typeparam>
/// <param name="factory">The input <typeparamref name="T"/> factory.</param>
public sealed class For<T>(For<T>.Factory factory) : PixelShaderEffect
public sealed partial class For<T>(For<T>.Factory factory) : PixelShaderEffect
where T : unmanaged, ID2D1PixelShader, ID2D1PixelShaderDescriptor<T>
{
/// <summary>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -117,15 +117,11 @@ public unsafe void OnInitialize(HWND hwnd)
using ComPtr<ICanvasFactoryNative> canvasFactoryNative = default;

// Get the activation factory for CanvasDevice
using (ComPtr<IUnknown> canvasFactoryNativeUnknown = default)
using (IObjectReference canvasDeviceActivationFactory = ActivationFactory.Get(
typeName: "Microsoft.Graphics.Canvas.CanvasDevice",
iid: Windows.__uuidof<ICanvasFactoryNative>()))
{
ICanvasFactoryNative.Interface canvasDeviceActivationFactory = CanvasDevice.As<ICanvasFactoryNative.Interface>();

canvasFactoryNativeUnknown.Attach((IUnknown*)MarshalInterface<ICanvasFactoryNative.Interface>.FromManaged(canvasDeviceActivationFactory));

hresult = canvasFactoryNativeUnknown.CopyTo(canvasFactoryNative.GetAddressOf());

ExceptionHelpers.ThrowExceptionForHR(hresult);
canvasFactoryNative.Attach((ICanvasFactoryNative*)canvasDeviceActivationFactory.GetRef());
}

// Create a Win2D wrapper for the swapchain
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<OutputType Condition="'$(CI_RUNNER_SAMPLES_INTEGRATION_TESTS)' == 'true'">Exe</OutputType>
<OutputType Condition="'$(CI_RUNNER_SAMPLES_INTEGRATION_TESTS)' != 'true'">WinExe</OutputType>
<TargetFramework>net8.0-windows10.0.22621</TargetFramework>
<WindowsSdkPackageVersion>10.0.22621.35-preview</WindowsSdkPackageVersion>
<ApplicationManifest>app.manifest</ApplicationManifest>
<Platforms>x64;ARM64</Platforms>
<RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers>
Expand All @@ -12,14 +13,24 @@

<PropertyGroup>

<!--
Generate a .pdb file to avoid IIDOptimizer build errors.
See: https://github.com/microsoft/CsWinRT/issues/1478.
-->
<DebugType>full</DebugType>

<!-- Suppress warnings for using directives inside namespaces (needed to avoid some WinRT conflicts) -->
<NoWarn>$(NoWarn);IDE0065</NoWarn>

<!-- Workaround for WinRT.TypeExtensions.GetAuthoringMetadataType(Type) trim warning (see https://github.com/microsoft/CsWinRT/issues/1319) -->
<NoWarn>$(NoWarn);IL2104;IL2026</NoWarn>

<!-- Workaround for WinRT.Runtime and System.Linq.Expressions producing trim warnings -->
<NoWarn>$(NoWarn);IL3053</NoWarn>
</PropertyGroup>

<!-- CsWinRT size saving options (same as in ComputeSharp.NativeLibrary.WinRT) -->
<PropertyGroup>
<CsWinRTEnableDynamicObjectsSupport>false</CsWinRTEnableDynamicObjectsSupport>
<CsWinRTUseExceptionResourceKeys>true</CsWinRTUseExceptionResourceKeys>
<CsWinRTEnableDefaultCustomTypeMappings>false</CsWinRTEnableDefaultCustomTypeMappings>
<CsWinRTEnableICustomPropertyProviderSupport>false</CsWinRTEnableICustomPropertyProviderSupport>
<CsWinRTEnableIReferenceSupport>false</CsWinRTEnableIReferenceSupport>
<CsWinRTEnableIDynamicInterfaceCastableSupport>false</CsWinRTEnableIDynamicInterfaceCastableSupport>
</PropertyGroup>

<!-- Options for R2R publishing -->
Expand All @@ -42,13 +53,14 @@
<OptimizationPreference>Speed</OptimizationPreference>
</PropertyGroup>

<!-- Also include the .rd.xml file to fix some NativeAOT issues with CsWinRT -->
<ItemGroup Condition="'$(COMPUTESHARP_SWAPCHAIN_D2D1_PUBLISH_AOT)' == 'true'">
<RdXmlFile Include="Properties\Default.rd.xml" />
</ItemGroup>

<ItemGroup>
<PackageReference Include="TerraFX.Interop.Windows" Version="10.0.22621.6" />

<!--
Reference CsWinRT locally for the source generators (see comments in ComputeSharp.D2D1.WinUI).
Note that this is an executable and not a library, so we must drop the 'PrivateAssets' here.
-->
<PackageReference Include="Microsoft.Windows.CsWinRT" Version="2.1.0-prerelease.240602.1" />
</ItemGroup>

<!-- Note: using SetPlatform="Platform=AnyCPU" for the analyzers to avoid issues (see https://github.com/dotnet/roslyn/issues/70148) -->
Expand Down
18 changes: 0 additions & 18 deletions samples/ComputeSharp.SwapChain.D2D1.Cli/Properties/Default.rd.xml

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
<OutputType>WinExe</OutputType>
<TargetFramework>net8.0-windows10.0.22621.0</TargetFramework>
<TargetPlatformMinVersion>10.0.17763.0</TargetPlatformMinVersion>
<WindowsSdkPackageVersion>10.0.22621.35-preview</WindowsSdkPackageVersion>
<ApplicationManifest>app.manifest</ApplicationManifest>
<Platforms>x64;arm64</Platforms>
<RuntimeIdentifiers>win-x64;win-arm64</RuntimeIdentifiers>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,107 +8,124 @@

#pragma warning disable CS0649, IDE0055, IDE1006

namespace ABI.Microsoft.Graphics.Canvas;

/// <summary>
/// The interop Win2D interface for factories of external effects.
/// </summary>
[NativeTypeName("class ICanvasEffectFactoryNative : IUnknown")]
[NativeInheritance("IUnknown")]
internal unsafe struct ICanvasEffectFactoryNative : IComObject
namespace ABI.Microsoft.Graphics.Canvas
{
/// <inheritdoc/>
static Guid* IComObject.IID
/// <summary>
/// The interop Win2D interface for factories of external effects.
/// </summary>
[NativeTypeName("class ICanvasEffectFactoryNative : IUnknown")]
[NativeInheritance("IUnknown")]
internal unsafe struct ICanvasEffectFactoryNative : IComObject
{
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
/// <inheritdoc/>
public static Guid* IID
{
ReadOnlySpan<byte> data =
[
0x1F, 0x1A, 0xBA, 0x29,
0xFE, 0x1C,
0xC3, 0x44,
0x98, 0x4D,
0x42,
0x6D,
0x61,
0xB5,
0x14,
0x27
];

return (Guid*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(data));
[MethodImpl(MethodImplOptions.AggressiveInlining)]
get
{
ReadOnlySpan<byte> data =
[
0x1F, 0x1A, 0xBA, 0x29,
0xFE, 0x1C,
0xC3, 0x44,
0x98, 0x4D,
0x42,
0x6D,
0x61,
0xB5,
0x14,
0x27
];

return (Guid*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(data));
}
}
}

public void** lpVtbl;
public void** lpVtbl;

/// <inheritdoc cref="IUnknown.QueryInterface"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[VtblIndex(0)]
public HRESULT QueryInterface([NativeTypeName("const IID &")] Guid* riid, void** ppvObject)
{
return ((delegate* unmanaged[MemberFunction]<ICanvasEffectFactoryNative*, Guid*, void**, int>)this.lpVtbl[0])((ICanvasEffectFactoryNative*)Unsafe.AsPointer(ref this), riid, ppvObject);
}
/// <inheritdoc cref="IUnknown.QueryInterface"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[VtblIndex(0)]
public HRESULT QueryInterface([NativeTypeName("const IID &")] Guid* riid, void** ppvObject)
{
return ((delegate* unmanaged[MemberFunction]<ICanvasEffectFactoryNative*, Guid*, void**, int>)this.lpVtbl[0])((ICanvasEffectFactoryNative*)Unsafe.AsPointer(ref this), riid, ppvObject);
}

/// <inheritdoc cref="IUnknown.AddRef"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[VtblIndex(1)]
[return: NativeTypeName("ULONG")]
public uint AddRef()
{
return ((delegate* unmanaged[MemberFunction]<ICanvasEffectFactoryNative*, uint>)this.lpVtbl[1])((ICanvasEffectFactoryNative*)Unsafe.AsPointer(ref this));
}
/// <inheritdoc cref="IUnknown.AddRef"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[VtblIndex(1)]
[return: NativeTypeName("ULONG")]
public uint AddRef()
{
return ((delegate* unmanaged[MemberFunction]<ICanvasEffectFactoryNative*, uint>)this.lpVtbl[1])((ICanvasEffectFactoryNative*)Unsafe.AsPointer(ref this));
}

/// <inheritdoc cref="IUnknown.Release"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[VtblIndex(2)]
[return: NativeTypeName("ULONG")]
public uint Release()
{
return ((delegate* unmanaged[MemberFunction]<ICanvasEffectFactoryNative*, uint>)this.lpVtbl[2])((ICanvasEffectFactoryNative*)Unsafe.AsPointer(ref this));
/// <inheritdoc cref="IUnknown.Release"/>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[VtblIndex(2)]
[return: NativeTypeName("ULONG")]
public uint Release()
{
return ((delegate* unmanaged[MemberFunction]<ICanvasEffectFactoryNative*, uint>)this.lpVtbl[2])((ICanvasEffectFactoryNative*)Unsafe.AsPointer(ref this));
}

/// <summary>
/// Creates a new inspectable wrapper for an input D2D effect previosly registered through <see cref="ICanvasFactoryNative.RegisterEffectFactory"/>.
/// </summary>
/// <param name="device">The input canvas device.</param>
/// <param name="resource">The input native effect to create a wrapper for.</param>
/// <param name="dpi">The realization DPIs for <paramref name="resource"/>.</param>
/// <param name="wrapper">The resulting wrapper for <paramref name="resource"/>.</param>
/// <returns>The <see cref="HRESULT"/> for the operation.</returns>
/// <remarks>
/// All parameters are directly forwarded from the ones the caller passed to <see cref="ICanvasFactoryNative.GetOrCreate"/>. The returned
/// wrapper should implement <see cref="global::Microsoft.Graphics.Canvas.ICanvasImage"/> to be returned correctly from Win2D after this call.
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[VtblIndex(3)]
public HRESULT CreateWrapper(ICanvasDevice* device, ID2D1Effect* resource, float dpi, IInspectable** wrapper)
{
return ((delegate* unmanaged[MemberFunction]<ICanvasEffectFactoryNative*, ICanvasDevice*, ID2D1Effect*, float, IInspectable**, int>)this.lpVtbl[3])(
(ICanvasEffectFactoryNative*)Unsafe.AsPointer(ref this),
device,
resource,
dpi,
wrapper);
}
}

/// <summary>
/// Creates a new inspectable wrapper for an input D2D effect previosly registered through <see cref="ICanvasFactoryNative.RegisterEffectFactory"/>.
/// The ABI methods for <see cref="ICanvasEffectFactoryNative"/>.
/// </summary>
/// <param name="device">The input canvas device.</param>
/// <param name="resource">The input native effect to create a wrapper for.</param>
/// <param name="dpi">The realization DPIs for <paramref name="resource"/>.</param>
/// <param name="wrapper">The resulting wrapper for <paramref name="resource"/>.</param>
/// <returns>The <see cref="HRESULT"/> for the operation.</returns>
/// <remarks>
/// All parameters are directly forwarded from the ones the caller passed to <see cref="ICanvasFactoryNative.GetOrCreate"/>. The returned
/// wrapper should implement <see cref="global::Microsoft.Graphics.Canvas.ICanvasImage"/> to be returned correctly from Win2D after this call.
/// </remarks>
[MethodImpl(MethodImplOptions.AggressiveInlining)]
[VtblIndex(3)]
public HRESULT CreateWrapper(ICanvasDevice* device, ID2D1Effect* resource, float dpi, IInspectable** wrapper)
internal static unsafe class ICanvasEffectFactoryNativeMethods
{
return ((delegate* unmanaged[MemberFunction]<ICanvasEffectFactoryNative*, ICanvasDevice*, ID2D1Effect*, float, IInspectable**, int>)this.lpVtbl[3])(
(ICanvasEffectFactoryNative*)Unsafe.AsPointer(ref this),
device,
resource,
dpi,
wrapper);
/// <inheritdoc cref="ICanvasEffectFactoryNative.IID"/>
public static Guid IID => *ICanvasEffectFactoryNative.IID;

/// <inheritdoc cref="global::Microsoft.Graphics.Canvas.ICanvasEffectFactoryNative.Vftbl.AbiToProjectionVftablePtr"/>
public static IntPtr AbiToProjectionVftablePtr => global::Microsoft.Graphics.Canvas.ICanvasEffectFactoryNative.Vftbl.AbiToProjectionVftablePtr;
}
}

namespace Microsoft.Graphics.Canvas
{
using ABI.Microsoft.Graphics.Canvas;

/// <summary>
/// The managed implementation of <see cref="ICanvasEffectFactoryNative"/>.
/// The managed implementation of <see cref="ABI.Microsoft.Graphics.Canvas.ICanvasEffectFactoryNative"/>.
/// </summary>
[Guid("29BA1A1F-1CFE-44C3-984D-426D61B51427")]
[WindowsRuntimeType]
[WindowsRuntimeHelperType(typeof(Interface))]
public interface Interface
[WindowsRuntimeHelperType(typeof(ICanvasEffectFactoryNative))]
internal unsafe interface ICanvasEffectFactoryNative
{
/// <inheritdoc cref="ICanvasEffectFactoryNative.CreateWrapper"/>
/// <inheritdoc cref="ABI.Microsoft.Graphics.Canvas.ICanvasEffectFactoryNative.CreateWrapper"/>
[return: NativeTypeName("HRESULT")]
int CreateWrapper(ICanvasDevice* device, ID2D1Effect* resource, float dpi, IInspectable** wrapper);

/// <summary>
/// The vtable type for <see cref="Interface"/>.
/// The vtable type for <see cref="ICanvasEffectFactoryNative"/>.
/// </summary>
[Guid("29BA1A1F-1CFE-44C3-984D-426D61B51427")]
public struct Vftbl
{
/// <summary>
Expand All @@ -117,9 +134,9 @@ public struct Vftbl
public static readonly IntPtr AbiToProjectionVftablePtr = InitVtbl();

/// <summary>
/// Builds the custom method table pointer for <see cref="Interface"/>.
/// Builds the custom method table pointer for <see cref="ICanvasEffectFactoryNative"/>.
/// </summary>
/// <returns>The method table pointer for <see cref="Interface"/>.</returns>
/// <returns>The method table pointer for <see cref="ICanvasEffectFactoryNative"/>.</returns>
private static IntPtr InitVtbl()
{
Vftbl* lpVtbl = (Vftbl*)ComWrappersSupport.AllocateVtableMemory(typeof(Vftbl), sizeof(Vftbl));
Expand All @@ -140,14 +157,14 @@ private static IntPtr InitVtbl()
/// </summary>
private delegate* unmanaged[MemberFunction]<IntPtr, ICanvasDevice*, ID2D1Effect*, float, IInspectable**, int> CreateWrapper;

/// <inheritdoc cref="Interface.CreateWrapper"/>
/// <inheritdoc cref="ICanvasEffectFactoryNative.CreateWrapper"/>
[UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
[return: NativeTypeName("HRESULT")]
private static int CreateWrapperFromAbi(IntPtr thisPtr, ICanvasDevice* device, ID2D1Effect* resource, float dpi, IInspectable** wrapper)
{
try
{
return ComWrappersSupport.FindObject<Interface>(thisPtr).CreateWrapper(device, resource, dpi, wrapper);
return ComWrappersSupport.FindObject<ICanvasEffectFactoryNative>(thisPtr).CreateWrapper(device, resource, dpi, wrapper);
}
catch (Exception e)
{
Expand Down
Loading