diff --git a/samples/ComputeSharp.SwapChain.D2D1.Cli/Backend/ABI.Microsoft.Graphics.Canvas/ICanvasFactoryNative.cs b/samples/ComputeSharp.SwapChain.D2D1.Cli/Backend/ABI.Microsoft.Graphics.Canvas/ICanvasFactoryNative.cs
index a137a4386..49bfa2839 100644
--- a/samples/ComputeSharp.SwapChain.D2D1.Cli/Backend/ABI.Microsoft.Graphics.Canvas/ICanvasFactoryNative.cs
+++ b/samples/ComputeSharp.SwapChain.D2D1.Cli/Backend/ABI.Microsoft.Graphics.Canvas/ICanvasFactoryNative.cs
@@ -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
@@ -79,25 +77,4 @@ public HRESULT GetOrCreate(IUnknown* device, IUnknown* resource, float dpi, void
dpi,
wrapper);
}
-
- ///
- /// The managed interface for .
- ///
- [Guid("695C440D-04B3-4EDD-BFD9-63E51E9F7202")]
- [WindowsRuntimeType]
- [WindowsRuntimeHelperType(typeof(Interface))]
- public interface Interface
- {
- ///
- /// The vtable type for .
- ///
- [Guid("695C440D-04B3-4EDD-BFD9-63E51E9F7202")]
- public readonly struct Vftbl
- {
- ///
- /// Allows CsWinRT to retrieve a pointer to the projection vtable (the name is hardcoded by convention).
- ///
- public static readonly IntPtr AbiToProjectionVftablePtr = IUnknownVftbl.AbiToProjectionVftblPtr;
- }
- }
}
\ No newline at end of file
diff --git a/samples/ComputeSharp.SwapChain.D2D1.Cli/Backend/PixelShaderEffect.cs b/samples/ComputeSharp.SwapChain.D2D1.Cli/Backend/PixelShaderEffect.cs
index 614804c2d..349880ff6 100644
--- a/samples/ComputeSharp.SwapChain.D2D1.Cli/Backend/PixelShaderEffect.cs
+++ b/samples/ComputeSharp.SwapChain.D2D1.Cli/Backend/PixelShaderEffect.cs
@@ -8,7 +8,7 @@ namespace ComputeSharp.SwapChain.D2D1.Backend;
///
/// An base effect for an animated pixel shader.
///
-internal abstract class PixelShaderEffect : CanvasEffect
+internal abstract partial class PixelShaderEffect : CanvasEffect
{
///
/// The current elapsed time.
@@ -57,7 +57,7 @@ public int ScreenHeight
///
/// The type of pixel shader to render.
/// The input factory.
- public sealed class For(For.Factory factory) : PixelShaderEffect
+ public sealed partial class For(For.Factory factory) : PixelShaderEffect
where T : unmanaged, ID2D1PixelShader, ID2D1PixelShaderDescriptor
{
///
diff --git a/samples/ComputeSharp.SwapChain.D2D1.Cli/Backend/Win32Application.cs b/samples/ComputeSharp.SwapChain.D2D1.Cli/Backend/Win32Application.cs
index 3f3d5a793..4eef52a2f 100644
--- a/samples/ComputeSharp.SwapChain.D2D1.Cli/Backend/Win32Application.cs
+++ b/samples/ComputeSharp.SwapChain.D2D1.Cli/Backend/Win32Application.cs
@@ -117,15 +117,11 @@ public unsafe void OnInitialize(HWND hwnd)
using ComPtr canvasFactoryNative = default;
// Get the activation factory for CanvasDevice
- using (ComPtr canvasFactoryNativeUnknown = default)
+ using (IObjectReference canvasDeviceActivationFactory = ActivationFactory.Get(
+ typeName: "Microsoft.Graphics.Canvas.CanvasDevice",
+ iid: Windows.__uuidof()))
{
- ICanvasFactoryNative.Interface canvasDeviceActivationFactory = CanvasDevice.As();
-
- canvasFactoryNativeUnknown.Attach((IUnknown*)MarshalInterface.FromManaged(canvasDeviceActivationFactory));
-
- hresult = canvasFactoryNativeUnknown.CopyTo(canvasFactoryNative.GetAddressOf());
-
- ExceptionHelpers.ThrowExceptionForHR(hresult);
+ canvasFactoryNative.Attach((ICanvasFactoryNative*)canvasDeviceActivationFactory.GetRef());
}
// Create a Win2D wrapper for the swapchain
diff --git a/samples/ComputeSharp.SwapChain.D2D1.Cli/ComputeSharp.SwapChain.D2D1.Cli.csproj b/samples/ComputeSharp.SwapChain.D2D1.Cli/ComputeSharp.SwapChain.D2D1.Cli.csproj
index 03cfe048c..5b0fcd279 100644
--- a/samples/ComputeSharp.SwapChain.D2D1.Cli/ComputeSharp.SwapChain.D2D1.Cli.csproj
+++ b/samples/ComputeSharp.SwapChain.D2D1.Cli/ComputeSharp.SwapChain.D2D1.Cli.csproj
@@ -3,6 +3,7 @@
Exe
WinExe
net8.0-windows10.0.22621
+ 10.0.22621.35-preview
app.manifest
x64;ARM64
win-x64;win-arm64
@@ -12,14 +13,24 @@
+
+ full
+
$(NoWarn);IDE0065
-
-
- $(NoWarn);IL2104;IL2026
-
-
- $(NoWarn);IL3053
+
+
+
+
+ false
+ true
+ false
+ false
+ false
+ false
@@ -42,13 +53,14 @@
Speed
-
-
-
-
-
+
+
+
diff --git a/samples/ComputeSharp.SwapChain.D2D1.Cli/Properties/Default.rd.xml b/samples/ComputeSharp.SwapChain.D2D1.Cli/Properties/Default.rd.xml
deleted file mode 100644
index 4b8aa35b6..000000000
--- a/samples/ComputeSharp.SwapChain.D2D1.Cli/Properties/Default.rd.xml
+++ /dev/null
@@ -1,18 +0,0 @@
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/samples/ComputeSharp.SwapChain.WinUI/ComputeSharp.SwapChain.WinUI.csproj b/samples/ComputeSharp.SwapChain.WinUI/ComputeSharp.SwapChain.WinUI.csproj
index 2183b3541..f95ae902d 100644
--- a/samples/ComputeSharp.SwapChain.WinUI/ComputeSharp.SwapChain.WinUI.csproj
+++ b/samples/ComputeSharp.SwapChain.WinUI/ComputeSharp.SwapChain.WinUI.csproj
@@ -3,6 +3,7 @@
WinExe
net8.0-windows10.0.22621.0
10.0.17763.0
+ 10.0.22621.35-preview
app.manifest
x64;arm64
win-x64;win-arm64
diff --git a/src/ComputeSharp.D2D1.WinUI/ABI.Microsoft.Graphics.Canvas/ICanvasEffectFactoryNative.cs b/src/ComputeSharp.D2D1.WinUI/ABI.Microsoft.Graphics.Canvas/ICanvasEffectFactoryNative.cs
index 8f28b281f..82fd8f569 100644
--- a/src/ComputeSharp.D2D1.WinUI/ABI.Microsoft.Graphics.Canvas/ICanvasEffectFactoryNative.cs
+++ b/src/ComputeSharp.D2D1.WinUI/ABI.Microsoft.Graphics.Canvas/ICanvasEffectFactoryNative.cs
@@ -8,107 +8,124 @@
#pragma warning disable CS0649, IDE0055, IDE1006
-namespace ABI.Microsoft.Graphics.Canvas;
-
-///
-/// The interop Win2D interface for factories of external effects.
-///
-[NativeTypeName("class ICanvasEffectFactoryNative : IUnknown")]
-[NativeInheritance("IUnknown")]
-internal unsafe struct ICanvasEffectFactoryNative : IComObject
+namespace ABI.Microsoft.Graphics.Canvas
{
- ///
- static Guid* IComObject.IID
+ ///
+ /// The interop Win2D interface for factories of external effects.
+ ///
+ [NativeTypeName("class ICanvasEffectFactoryNative : IUnknown")]
+ [NativeInheritance("IUnknown")]
+ internal unsafe struct ICanvasEffectFactoryNative : IComObject
{
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get
+ ///
+ public static Guid* IID
{
- ReadOnlySpan 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 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;
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- [VtblIndex(0)]
- public HRESULT QueryInterface([NativeTypeName("const IID &")] Guid* riid, void** ppvObject)
- {
- return ((delegate* unmanaged[MemberFunction])this.lpVtbl[0])((ICanvasEffectFactoryNative*)Unsafe.AsPointer(ref this), riid, ppvObject);
- }
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [VtblIndex(0)]
+ public HRESULT QueryInterface([NativeTypeName("const IID &")] Guid* riid, void** ppvObject)
+ {
+ return ((delegate* unmanaged[MemberFunction])this.lpVtbl[0])((ICanvasEffectFactoryNative*)Unsafe.AsPointer(ref this), riid, ppvObject);
+ }
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- [VtblIndex(1)]
- [return: NativeTypeName("ULONG")]
- public uint AddRef()
- {
- return ((delegate* unmanaged[MemberFunction])this.lpVtbl[1])((ICanvasEffectFactoryNative*)Unsafe.AsPointer(ref this));
- }
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [VtblIndex(1)]
+ [return: NativeTypeName("ULONG")]
+ public uint AddRef()
+ {
+ return ((delegate* unmanaged[MemberFunction])this.lpVtbl[1])((ICanvasEffectFactoryNative*)Unsafe.AsPointer(ref this));
+ }
- ///
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- [VtblIndex(2)]
- [return: NativeTypeName("ULONG")]
- public uint Release()
- {
- return ((delegate* unmanaged[MemberFunction])this.lpVtbl[2])((ICanvasEffectFactoryNative*)Unsafe.AsPointer(ref this));
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [VtblIndex(2)]
+ [return: NativeTypeName("ULONG")]
+ public uint Release()
+ {
+ return ((delegate* unmanaged[MemberFunction])this.lpVtbl[2])((ICanvasEffectFactoryNative*)Unsafe.AsPointer(ref this));
+ }
+
+ ///
+ /// Creates a new inspectable wrapper for an input D2D effect previosly registered through .
+ ///
+ /// The input canvas device.
+ /// The input native effect to create a wrapper for.
+ /// The realization DPIs for .
+ /// The resulting wrapper for .
+ /// The for the operation.
+ ///
+ /// All parameters are directly forwarded from the ones the caller passed to . The returned
+ /// wrapper should implement to be returned correctly from Win2D after this call.
+ ///
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [VtblIndex(3)]
+ public HRESULT CreateWrapper(ICanvasDevice* device, ID2D1Effect* resource, float dpi, IInspectable** wrapper)
+ {
+ return ((delegate* unmanaged[MemberFunction])this.lpVtbl[3])(
+ (ICanvasEffectFactoryNative*)Unsafe.AsPointer(ref this),
+ device,
+ resource,
+ dpi,
+ wrapper);
+ }
}
///
- /// Creates a new inspectable wrapper for an input D2D effect previosly registered through .
+ /// The ABI methods for .
///
- /// The input canvas device.
- /// The input native effect to create a wrapper for.
- /// The realization DPIs for .
- /// The resulting wrapper for .
- /// The for the operation.
- ///
- /// All parameters are directly forwarded from the ones the caller passed to . The returned
- /// wrapper should implement to be returned correctly from Win2D after this call.
- ///
- [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])this.lpVtbl[3])(
- (ICanvasEffectFactoryNative*)Unsafe.AsPointer(ref this),
- device,
- resource,
- dpi,
- wrapper);
+ ///
+ public static Guid IID => *ICanvasEffectFactoryNative.IID;
+
+ ///
+ public static IntPtr AbiToProjectionVftablePtr => global::Microsoft.Graphics.Canvas.ICanvasEffectFactoryNative.Vftbl.AbiToProjectionVftablePtr;
}
+}
+
+namespace Microsoft.Graphics.Canvas
+{
+ using ABI.Microsoft.Graphics.Canvas;
///
- /// The managed implementation of .
+ /// The managed implementation of .
///
[Guid("29BA1A1F-1CFE-44C3-984D-426D61B51427")]
[WindowsRuntimeType]
- [WindowsRuntimeHelperType(typeof(Interface))]
- public interface Interface
+ [WindowsRuntimeHelperType(typeof(ICanvasEffectFactoryNative))]
+ internal unsafe interface ICanvasEffectFactoryNative
{
- ///
+ ///
[return: NativeTypeName("HRESULT")]
int CreateWrapper(ICanvasDevice* device, ID2D1Effect* resource, float dpi, IInspectable** wrapper);
///
- /// The vtable type for .
+ /// The vtable type for .
///
- [Guid("29BA1A1F-1CFE-44C3-984D-426D61B51427")]
public struct Vftbl
{
///
@@ -117,9 +134,9 @@ public struct Vftbl
public static readonly IntPtr AbiToProjectionVftablePtr = InitVtbl();
///
- /// Builds the custom method table pointer for .
+ /// Builds the custom method table pointer for .
///
- /// The method table pointer for .
+ /// The method table pointer for .
private static IntPtr InitVtbl()
{
Vftbl* lpVtbl = (Vftbl*)ComWrappersSupport.AllocateVtableMemory(typeof(Vftbl), sizeof(Vftbl));
@@ -140,14 +157,14 @@ private static IntPtr InitVtbl()
///
private delegate* unmanaged[MemberFunction] 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(thisPtr).CreateWrapper(device, resource, dpi, wrapper);
+ return ComWrappersSupport.FindObject(thisPtr).CreateWrapper(device, resource, dpi, wrapper);
}
catch (Exception e)
{
diff --git a/src/ComputeSharp.D2D1.WinUI/ABI.Microsoft.Graphics.Canvas/ICanvasFactoryNative.cs b/src/ComputeSharp.D2D1.WinUI/ABI.Microsoft.Graphics.Canvas/ICanvasFactoryNative.cs
index 1f60788ab..853052f24 100644
--- a/src/ComputeSharp.D2D1.WinUI/ABI.Microsoft.Graphics.Canvas/ICanvasFactoryNative.cs
+++ b/src/ComputeSharp.D2D1.WinUI/ABI.Microsoft.Graphics.Canvas/ICanvasFactoryNative.cs
@@ -2,11 +2,8 @@
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using ComputeSharp.Win32;
-using WinRT;
-using WinRT.Interop;
-using IInspectable = ComputeSharp.Win32.IInspectable;
-#pragma warning disable CS0649, IDE1006
+#pragma warning disable CS0649, IDE0055, IDE1006
namespace ABI.Microsoft.Graphics.Canvas;
@@ -15,8 +12,32 @@ namespace ABI.Microsoft.Graphics.Canvas;
///
[NativeTypeName("class ICanvasFactoryNative : public IInspectable")]
[NativeInheritance("IInspectable")]
-internal unsafe struct ICanvasFactoryNative
+internal unsafe struct ICanvasFactoryNative : IComObject
{
+ ///
+ public static Guid* IID
+ {
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get
+ {
+ ReadOnlySpan data =
+ [
+ 0x0D, 0x44, 0x5C, 0x69,
+ 0xB3, 0x04,
+ 0xDD, 0x4E,
+ 0xBF, 0xD9,
+ 0x63,
+ 0xE5,
+ 0x1E,
+ 0x9F,
+ 0x72,
+ 0x02
+ ];
+
+ return (Guid*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(data));
+ }
+ }
+
public void** lpVtbl;
///
@@ -144,25 +165,4 @@ public HRESULT UnregisterEffectFactory([NativeTypeName("const IID &")] Guid* eff
(ICanvasFactoryNative*)Unsafe.AsPointer(ref this),
effectId);
}
-
- ///
- /// The managed interface for .
- ///
- [Guid("695C440D-04B3-4EDD-BFD9-63E51E9F7202")]
- [WindowsRuntimeType]
- [WindowsRuntimeHelperType(typeof(Interface))]
- public interface Interface
- {
- ///
- /// The vtable type for .
- ///
- [Guid("695C440D-04B3-4EDD-BFD9-63E51E9F7202")]
- public readonly struct Vftbl
- {
- ///
- /// Allows CsWinRT to retrieve a pointer to the projection vtable (the name is hardcoded by convention).
- ///
- public static readonly IntPtr AbiToProjectionVftablePtr = IUnknownVftbl.AbiToProjectionVftblPtr;
- }
- }
}
\ No newline at end of file
diff --git a/src/ComputeSharp.D2D1.WinUI/ABI.Microsoft.Graphics.Canvas/ICanvasImageInterop.cs b/src/ComputeSharp.D2D1.WinUI/ABI.Microsoft.Graphics.Canvas/ICanvasImageInterop.cs
index 8cefb7c3d..a1a68d35a 100644
--- a/src/ComputeSharp.D2D1.WinUI/ABI.Microsoft.Graphics.Canvas/ICanvasImageInterop.cs
+++ b/src/ComputeSharp.D2D1.WinUI/ABI.Microsoft.Graphics.Canvas/ICanvasImageInterop.cs
@@ -1,4 +1,5 @@
using System;
+using System.ComponentModel;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
using ComputeSharp.Win32;
@@ -7,113 +8,137 @@
#pragma warning disable CS0649, IDE0055, IDE1006
-namespace ABI.Microsoft.Graphics.Canvas;
-
-///
-/// An interop Win2D interface for all images and effects that can be drawn.
-///
-[NativeTypeName("class ICanvasImageInterop : IUnknown")]
-[NativeInheritance("IUnknown")]
-internal unsafe struct ICanvasImageInterop : IComObject
+namespace ABI.Microsoft.Graphics.Canvas
{
- ///
- static Guid* IComObject.IID
+ ///
+ /// An interop Win2D interface for all images and effects that can be drawn.
+ ///
+ [NativeTypeName("class ICanvasImageInterop : IUnknown")]
+ [NativeInheritance("IUnknown")]
+ internal unsafe struct ICanvasImageInterop : IComObject
{
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- get
+ ///
+ public static Guid* IID
{
- ReadOnlySpan data =
- [
- 0xF7, 0xD1, 0x42, 0xE0,
- 0xAD, 0xF9,
- 0x79, 0x44,
- 0xA7, 0x13,
- 0x67,
- 0x62,
- 0x7E,
- 0xA3,
- 0x18,
- 0x63
- ];
-
- return (Guid*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(data));
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ get
+ {
+ ReadOnlySpan data =
+ [
+ 0xF7, 0xD1, 0x42, 0xE0,
+ 0xAD, 0xF9,
+ 0x79, 0x44,
+ 0xA7, 0x13,
+ 0x67,
+ 0x62,
+ 0x7E,
+ 0xA3,
+ 0x18,
+ 0x63
+ ];
+
+ return (Guid*)Unsafe.AsPointer(ref MemoryMarshal.GetReference(data));
+ }
}
- }
- public void** lpVtbl;
+ public void** lpVtbl;
- ///
- /// Gets the device that the effect is currently realized on, if any.
- ///
- /// The resulting device, if available (as a marshalled ).
- /// The value describing the returned instance.
- /// The for the operation.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- [VtblIndex(3)]
- public HRESULT GetDevice(ICanvasDevice** device, WIN2D_GET_DEVICE_ASSOCIATION_TYPE* type)
- {
- return ((delegate* unmanaged[MemberFunction])this.lpVtbl[3])((ICanvasImageInterop*)Unsafe.AsPointer(ref this), device, type);
+ ///
+ /// Gets the device that the effect is currently realized on, if any.
+ ///
+ /// The resulting device, if available (as a marshalled ).
+ /// The value describing the returned instance.
+ /// The for the operation.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [VtblIndex(3)]
+ public HRESULT GetDevice(ICanvasDevice** device, WIN2D_GET_DEVICE_ASSOCIATION_TYPE* type)
+ {
+ return ((delegate* unmanaged[MemberFunction])this.lpVtbl[3])((ICanvasImageInterop*)Unsafe.AsPointer(ref this), device, type);
+ }
+
+ ///
+ /// Gets an from an instance.
+ ///
+ /// The input canvas device (as a marshalled ).
+ ///
+ /// The device context in use. This value is is optional (but recommended), except when the
+ /// flag is specified. This is because
+ /// not all callers of have easy access to a context. It is always
+ /// possible to get a resource creation context from the device, but the context is only
+ /// actually necessary if a new effect realization needs to be created, so it is more efficient
+ /// to have the implementation do this lookup only if/when it turns out to be needed.
+ ///
+ /// The flags to use to get the image.
+ ///
+ /// The DPI of the target device context. This is used to determine when a D2D1DpiCompensation
+ /// effect needs to be inserted. Behavior of this parameter can be overridden by the flag values
+ /// ,
+ ///
+ /// or
+ ///
+ ///
+ /// The DPI of a source bitmap, or zero if the image does not have a fixed DPI. A D2D1DpiCompensation effect
+ /// will be inserted if and are different (flags permitting).
+ ///
+ /// The resulting for the effect.
+ /// The for the operation.
+ [MethodImpl(MethodImplOptions.AggressiveInlining)]
+ [VtblIndex(4)]
+ public HRESULT GetD2DImage(
+ ICanvasDevice* device,
+ ID2D1DeviceContext* deviceContext,
+ WIN2D_GET_D2D_IMAGE_FLAGS flags,
+ float targetDpi,
+ float* realizeDpi,
+ ID2D1Image** ppImage)
+ {
+ return ((delegate* unmanaged[MemberFunction])this.lpVtbl[4])(
+ (ICanvasImageInterop*)Unsafe.AsPointer(ref this),
+ device,
+ deviceContext,
+ flags,
+ targetDpi,
+ realizeDpi,
+ ppImage);
+ }
}
///
- /// Gets an from an instance.
+ /// The ABI methods for .
///
- /// The input canvas device (as a marshalled ).
- ///
- /// The device context in use. This value is is optional (but recommended), except when the
- /// flag is specified. This is because
- /// not all callers of have easy access to a context. It is always
- /// possible to get a resource creation context from the device, but the context is only
- /// actually necessary if a new effect realization needs to be created, so it is more efficient
- /// to have the implementation do this lookup only if/when it turns out to be needed.
- ///
- /// The flags to use to get the image.
- ///
- /// The DPI of the target device context. This is used to determine when a D2D1DpiCompensation
- /// effect needs to be inserted. Behavior of this parameter can be overridden by the flag values
- /// ,
- ///
- /// or
- ///
- ///
- /// The DPI of a source bitmap, or zero if the image does not have a fixed DPI. A D2D1DpiCompensation effect
- /// will be inserted if and are different (flags permitting).
- ///
- /// The resulting for the effect.
- /// The for the operation.
- [MethodImpl(MethodImplOptions.AggressiveInlining)]
- [VtblIndex(4)]
- public HRESULT GetD2DImage(
- ICanvasDevice* device,
- ID2D1DeviceContext* deviceContext,
- WIN2D_GET_D2D_IMAGE_FLAGS flags,
- float targetDpi,
- float* realizeDpi,
- ID2D1Image** ppImage)
+ ///
+ /// This type has public accessibility to allow the AOT generator in CsWinRT to reference
+ /// the and properties to make
+ /// marshalling of CCW types AOT-safe. It is not meant to be used directly by developers.
+ ///
+ [EditorBrowsable(EditorBrowsableState.Never)]
+ public static unsafe class ICanvasImageInteropMethods
{
- return ((delegate* unmanaged[MemberFunction])this.lpVtbl[4])(
- (ICanvasImageInterop*)Unsafe.AsPointer(ref this),
- device,
- deviceContext,
- flags,
- targetDpi,
- realizeDpi,
- ppImage);
+ ///
+ public static Guid IID => *ICanvasImageInterop.IID;
+
+ ///
+ public static IntPtr AbiToProjectionVftablePtr => global::Microsoft.Graphics.Canvas.ICanvasImageInterop.Vftbl.AbiToProjectionVftablePtr;
}
+}
+
+namespace Microsoft.Graphics.Canvas
+{
+ using ABI.Microsoft.Graphics.Canvas;
///
- /// The managed implementation of .
+ /// The managed implementation of .
///
[Guid("E042D1F7-F9AD-4479-A713-67627EA31863")]
[WindowsRuntimeType]
- [WindowsRuntimeHelperType(typeof(Interface))]
- public interface Interface
+ [WindowsRuntimeHelperType(typeof(ICanvasImageInterop))]
+ internal unsafe interface ICanvasImageInterop
{
- ///
+ ///
[return: NativeTypeName("HRESULT")]
int GetDevice(ICanvasDevice** device, WIN2D_GET_DEVICE_ASSOCIATION_TYPE* type);
- ///
+ ///
[return: NativeTypeName("HRESULT")]
int GetD2DImage(
ICanvasDevice* device,
@@ -124,9 +149,8 @@ int GetD2DImage(
ID2D1Image** ppImage);
///
- /// The vtable type for .
+ /// The vtable type for .
///
- [Guid("E042D1F7-F9AD-4479-A713-67627EA31863")]
public struct Vftbl
{
///
@@ -135,9 +159,9 @@ public struct Vftbl
public static readonly IntPtr AbiToProjectionVftablePtr = InitVtbl();
///
- /// Builds the custom method table pointer for .
+ /// Builds the custom method table pointer for .
///
- /// The method table pointer for .
+ /// The method table pointer for .
private static IntPtr InitVtbl()
{
Vftbl* lpVtbl = (Vftbl*)ComWrappersSupport.AllocateVtableMemory(typeof(Vftbl), sizeof(Vftbl));
@@ -164,14 +188,14 @@ private static IntPtr InitVtbl()
///
private delegate* unmanaged[MemberFunction] GetD2DImage;
- ///
+ ///
[UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
[return: NativeTypeName("HRESULT")]
private static int GetDeviceFromAbi(IntPtr thisPtr, ICanvasDevice** device, WIN2D_GET_DEVICE_ASSOCIATION_TYPE* type)
{
try
{
- return ComWrappersSupport.FindObject(thisPtr).GetDevice(device, type);
+ return ComWrappersSupport.FindObject(thisPtr).GetDevice(device, type);
}
catch (Exception e)
{
@@ -181,7 +205,7 @@ private static int GetDeviceFromAbi(IntPtr thisPtr, ICanvasDevice** device, WIN2
}
}
- ///
+ ///
[UnmanagedCallersOnly(CallConvs = [typeof(CallConvMemberFunction)])]
[return: NativeTypeName("HRESULT")]
private static int GetD2DImageFromAbi(
@@ -195,7 +219,7 @@ private static int GetD2DImageFromAbi(
{
try
{
- return ComWrappersSupport.FindObject(thisPtr).GetD2DImage(device, deviceContext, flags, targetDpi, realizeDpi, ppImage);
+ return ComWrappersSupport.FindObject(thisPtr).GetD2DImage(device, deviceContext, flags, targetDpi, realizeDpi, ppImage);
}
catch (Exception e)
{
diff --git a/src/ComputeSharp.D2D1.WinUI/ABI.Microsoft.Graphics.Canvas/WIN2D_GET_D2D_IMAGE_FLAGS.cs b/src/ComputeSharp.D2D1.WinUI/ABI.Microsoft.Graphics.Canvas/WIN2D_GET_D2D_IMAGE_FLAGS.cs
index 063bd8a64..0180f17b5 100644
--- a/src/ComputeSharp.D2D1.WinUI/ABI.Microsoft.Graphics.Canvas/WIN2D_GET_D2D_IMAGE_FLAGS.cs
+++ b/src/ComputeSharp.D2D1.WinUI/ABI.Microsoft.Graphics.Canvas/WIN2D_GET_D2D_IMAGE_FLAGS.cs
@@ -3,7 +3,7 @@
namespace ABI.Microsoft.Graphics.Canvas;
///
-/// Options for fine-tuning the behavior of .
+/// Options for fine-tuning the behavior of .
///
[Flags]
internal enum WIN2D_GET_D2D_IMAGE_FLAGS : uint
diff --git a/src/ComputeSharp.D2D1.WinUI/ABI.Microsoft.Graphics.Canvas/WIN2D_GET_DEVICE_ASSOCIATION_TYPE.cs b/src/ComputeSharp.D2D1.WinUI/ABI.Microsoft.Graphics.Canvas/WIN2D_GET_DEVICE_ASSOCIATION_TYPE.cs
index 9ce3c2e4b..32452df22 100644
--- a/src/ComputeSharp.D2D1.WinUI/ABI.Microsoft.Graphics.Canvas/WIN2D_GET_DEVICE_ASSOCIATION_TYPE.cs
+++ b/src/ComputeSharp.D2D1.WinUI/ABI.Microsoft.Graphics.Canvas/WIN2D_GET_DEVICE_ASSOCIATION_TYPE.cs
@@ -3,7 +3,7 @@
namespace ABI.Microsoft.Graphics.Canvas;
///
-/// Options for fine-tuning the behavior of .
+/// Options for fine-tuning the behavior of .
///
[Flags]
internal enum WIN2D_GET_DEVICE_ASSOCIATION_TYPE : uint
diff --git a/src/ComputeSharp.D2D1.WinUI/Buffers/SourceReference.cs b/src/ComputeSharp.D2D1.WinUI/Buffers/SourceReference.cs
index 286424050..a20583ca9 100644
--- a/src/ComputeSharp.D2D1.WinUI/Buffers/SourceReference.cs
+++ b/src/ComputeSharp.D2D1.WinUI/Buffers/SourceReference.cs
@@ -41,7 +41,7 @@ namespace ComputeSharp.D2D1.WinUI.Buffers;
internal unsafe struct SourceReference : IDisposable
{
///
- /// The produced by calling
+ /// The produced by calling
/// on the input managed wrapper used as source for the effect (ie. ).
///
private ComPtr d2D1ImageSource;
diff --git a/src/ComputeSharp.D2D1.WinUI/CanvasEffect.Interop.cs b/src/ComputeSharp.D2D1.WinUI/CanvasEffect.Interop.cs
index 5f4d8b0d4..a539d1601 100644
--- a/src/ComputeSharp.D2D1.WinUI/CanvasEffect.Interop.cs
+++ b/src/ComputeSharp.D2D1.WinUI/CanvasEffect.Interop.cs
@@ -7,6 +7,7 @@
using ComputeSharp.Win32;
using Microsoft.Graphics.Canvas;
using Windows.Foundation;
+using ICanvasImageInterop = Microsoft.Graphics.Canvas.ICanvasImageInterop;
using ICanvasResourceCreator = Microsoft.Graphics.Canvas.ICanvasResourceCreator;
namespace ComputeSharp.D2D1.WinUI;
@@ -27,9 +28,9 @@ public Rect GetBounds(ICanvasResourceCreator resourceCreator, Matrix3x2 transfor
}
///
- unsafe int ICanvasImageInterop.Interface.GetDevice(ICanvasDevice** device, WIN2D_GET_DEVICE_ASSOCIATION_TYPE* type)
+ unsafe int ICanvasImageInterop.GetDevice(ICanvasDevice** device, WIN2D_GET_DEVICE_ASSOCIATION_TYPE* type)
{
- using ComPtr canvasImageInterop = default;
+ using ComPtr canvasImageInterop = default;
RcwMarshaller.GetNativeInterface(GetCanvasImage(), canvasImageInterop.GetAddressOf()).Assert();
@@ -37,7 +38,7 @@ unsafe int ICanvasImageInterop.Interface.GetDevice(ICanvasDevice** device, WIN2D
}
///
- unsafe int ICanvasImageInterop.Interface.GetD2DImage(
+ unsafe int ICanvasImageInterop.GetD2DImage(
ICanvasDevice* device,
ID2D1DeviceContext* deviceContext,
WIN2D_GET_D2D_IMAGE_FLAGS flags,
@@ -45,7 +46,7 @@ unsafe int ICanvasImageInterop.Interface.GetD2DImage(
float* realizeDpi,
ID2D1Image** ppImage)
{
- using ComPtr canvasImageInterop = default;
+ using ComPtr canvasImageInterop = default;
RcwMarshaller.GetNativeInterface(GetCanvasImage(), canvasImageInterop.GetAddressOf()).Assert();
diff --git a/src/ComputeSharp.D2D1.WinUI/CanvasEffect.cs b/src/ComputeSharp.D2D1.WinUI/CanvasEffect.cs
index 4247f5d2b..f9bd17c49 100644
--- a/src/ComputeSharp.D2D1.WinUI/CanvasEffect.cs
+++ b/src/ComputeSharp.D2D1.WinUI/CanvasEffect.cs
@@ -1,7 +1,6 @@
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
-using ABI.Microsoft.Graphics.Canvas;
using Microsoft.Graphics.Canvas;
namespace ComputeSharp.D2D1.WinUI;
@@ -9,7 +8,7 @@ namespace ComputeSharp.D2D1.WinUI;
///
/// A base type to implement packaged and easy to use -based effects that can be used with Win2D.
///
-public abstract partial class CanvasEffect : ICanvasImage, ICanvasImageInterop.Interface
+public abstract partial class CanvasEffect : ICanvasImage, ICanvasImageInterop
{
///
/// The mapping of registered transform nodes for the current effect graph.
diff --git a/src/ComputeSharp.D2D1.WinUI/Collections/IFixedCountList{T}.cs b/src/ComputeSharp.D2D1.WinUI/Collections/IFixedCountList{T}.cs
index 6dcd595c5..78290d630 100644
--- a/src/ComputeSharp.D2D1.WinUI/Collections/IFixedCountList{T}.cs
+++ b/src/ComputeSharp.D2D1.WinUI/Collections/IFixedCountList{T}.cs
@@ -7,7 +7,7 @@ namespace ComputeSharp.D2D1.WinUI.Collections;
/// An interface for a list with a fixed collection.
///
/// The type of elements in the list.
-interface IFixedCountList
+internal interface IFixedCountList
{
///
/// Gets the collection of valid indices for the current effect.
diff --git a/src/ComputeSharp.D2D1.WinUI/ComputeSharp.D2D1.WinUI.csproj b/src/ComputeSharp.D2D1.WinUI/ComputeSharp.D2D1.WinUI.csproj
index 2c20eeaa6..53d69e5f1 100644
--- a/src/ComputeSharp.D2D1.WinUI/ComputeSharp.D2D1.WinUI.csproj
+++ b/src/ComputeSharp.D2D1.WinUI/ComputeSharp.D2D1.WinUI.csproj
@@ -2,12 +2,20 @@
net8.0-windows10.0.22621.0
10.0.17763.0
+ 10.0.22621.35-preview
x64;ARM64
win-x64;win-arm64
+
+ true
+
+
diff --git a/src/ComputeSharp.D2D1.WinUI/Helpers/RcwMarshaller.cs b/src/ComputeSharp.D2D1.WinUI/Helpers/RcwMarshaller.cs
index 83588f37b..9253efbd3 100644
--- a/src/ComputeSharp.D2D1.WinUI/Helpers/RcwMarshaller.cs
+++ b/src/ComputeSharp.D2D1.WinUI/Helpers/RcwMarshaller.cs
@@ -1,5 +1,4 @@
using System;
-using System.Diagnostics.CodeAnalysis;
using ComputeSharp.Win32;
using WinRT;
using IInspectable = ComputeSharp.Win32.IInspectable;
@@ -31,7 +30,7 @@ public static T GetOrCreateManagedInterface(IUnknown* nativeObject)
/// The input RCW instance to unwrap.
/// A pointer to the resulting native object to retrieve.
/// This method should only be called with being a concrete projected type.
- public static void GetNativeObject<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.Interfaces)] T>(T managedObject, IInspectable** nativeObject)
+ public static void GetNativeObject(T managedObject, IInspectable** nativeObject)
where T : class
{
*nativeObject = (IInspectable*)MarshalInspectable.FromManaged(managedObject);
diff --git a/src/ComputeSharp.D2D1.WinUI/Helpers/ResourceManager.cs b/src/ComputeSharp.D2D1.WinUI/Helpers/ResourceManager.cs
index 6a81f4480..8535324b3 100644
--- a/src/ComputeSharp.D2D1.WinUI/Helpers/ResourceManager.cs
+++ b/src/ComputeSharp.D2D1.WinUI/Helpers/ResourceManager.cs
@@ -1,5 +1,4 @@
using System;
-using System.Diagnostics.CodeAnalysis;
using ABI.Microsoft.Graphics.Canvas;
using ComputeSharp.D2D1.Extensions;
using ComputeSharp.Win32;
@@ -9,6 +8,7 @@
namespace ComputeSharp.D2D1.WinUI.Helpers;
using CanvasDevice = Microsoft.Graphics.Canvas.CanvasDevice;
+using ICanvasEffectFactoryNative = Microsoft.Graphics.Canvas.ICanvasEffectFactoryNative;
using IInspectable = Win32.IInspectable;
///
@@ -51,7 +51,7 @@ public static IGraphicsEffectSource GetOrCreate(ICanvasDevice* device, IUnknown*
///
/// The input native resource to register a wrapper for.
/// The wrapper to register for .
- public static void RegisterWrapper<[DynamicallyAccessedMembers(DynamicallyAccessedMemberTypes.NonPublicConstructors | DynamicallyAccessedMemberTypes.Interfaces)] T>(IUnknown* resource, T wrapper)
+ public static void RegisterWrapper(IUnknown* resource, T wrapper)
where T : class
{
using ComPtr canvasFactoryNative = default;
@@ -86,13 +86,13 @@ public static void UnregisterWrapper(IUnknown* resource)
///
/// The id of the effects to register a factory for.
/// The input factory to create wrappers of native effects.
- public static void RegisterEffectFactory(Guid effectId, ICanvasEffectFactoryNative.Interface factory)
+ public static void RegisterEffectFactory(Guid effectId, ICanvasEffectFactoryNative factory)
{
using ComPtr canvasFactoryNative = default;
GetActivationFactory(canvasFactoryNative.GetAddressOf());
- using ComPtr canvasEffectFactoryNative = default;
+ using ComPtr canvasEffectFactoryNative = default;
RcwMarshaller.GetNativeInterface(factory, canvasEffectFactoryNative.GetAddressOf()).Assert();
@@ -106,12 +106,14 @@ public static void RegisterEffectFactory(Guid effectId, ICanvasEffectFactoryNati
/// A pointer to the resulting activation factory.
private static void GetActivationFactory(ICanvasFactoryNative** factoryNative)
{
- // On WinUI 3, the types are not guaranteed to be registered for activation. Additionally,
- // for concistency with other types, we just use the built-in T.As() method, which will
+ const string ActivatableClassId = "Microsoft.Graphics.Canvas.CanvasDevice";
+
+ // On WinUI 3, the types are not guaranteed to be registered for activation. Additionally, for
+ // concistency with other types, we just use the built-in ActivationFactory type, which will
// automatically handle fallback logic to resolve types to activate if they're not registered.
// For instance, this will ensure the following call will work fine in unpackaged apps.
- ICanvasFactoryNative.Interface canvasDeviceActivationFactory = CanvasDevice.As();
+ using IObjectReference canvasDeviceActivationFactory = ActivationFactory.Get(ActivatableClassId, *ICanvasFactoryNative.IID);
- *factoryNative = (ICanvasFactoryNative*)MarshalInterface.FromManaged(canvasDeviceActivationFactory);
+ *factoryNative = (ICanvasFactoryNative*)canvasDeviceActivationFactory.GetRef();
}
}
\ No newline at end of file
diff --git a/src/ComputeSharp.D2D1.WinUI/PixelShaderEffect{T}.ICanvasEffectFactoryNative.cs b/src/ComputeSharp.D2D1.WinUI/PixelShaderEffect{T}.ICanvasEffectFactoryNative.cs
index d1b23d9ae..9fa2d101f 100644
--- a/src/ComputeSharp.D2D1.WinUI/PixelShaderEffect{T}.ICanvasEffectFactoryNative.cs
+++ b/src/ComputeSharp.D2D1.WinUI/PixelShaderEffect{T}.ICanvasEffectFactoryNative.cs
@@ -5,11 +5,12 @@
using ComputeSharp.D2D1.WinUI.Extensions;
using ComputeSharp.D2D1.WinUI.Helpers;
using ComputeSharp.Win32;
+using ICanvasEffectFactoryNative = Microsoft.Graphics.Canvas.ICanvasEffectFactoryNative;
namespace ComputeSharp.D2D1.WinUI;
///
-unsafe partial class PixelShaderEffect
+partial class PixelShaderEffect
{
///
/// A manager type to handle the effect factory registration logic for .
@@ -74,10 +75,14 @@ private void EnsureEffectFactoryIsRegisteredWithLock()
///
/// A managed implementation of for .
///
- private sealed class EffectFactory : ICanvasEffectFactoryNative.Interface
+ ///
+ /// This type is partial even though there are no other explicit partial type declarations in the project, so the CsWinRT
+ /// generator can generate one using and the precomputed vtable entries.
+ ///
+ internal sealed unsafe partial class EffectFactory : ICanvasEffectFactoryNative
{
///
- int ICanvasEffectFactoryNative.Interface.CreateWrapper(ICanvasDevice* device, ID2D1Effect* resource, float dpi, IInspectable** wrapper)
+ int ICanvasEffectFactoryNative.CreateWrapper(ICanvasDevice* device, ID2D1Effect* resource, float dpi, IInspectable** wrapper)
{
PixelShaderEffect @this;
diff --git a/src/ComputeSharp.D2D1.WinUI/PixelShaderEffect{T}.ICanvasImageInterop.cs b/src/ComputeSharp.D2D1.WinUI/PixelShaderEffect{T}.ICanvasImageInterop.cs
index 0d729c984..0ac9a12c9 100644
--- a/src/ComputeSharp.D2D1.WinUI/PixelShaderEffect{T}.ICanvasImageInterop.cs
+++ b/src/ComputeSharp.D2D1.WinUI/PixelShaderEffect{T}.ICanvasImageInterop.cs
@@ -11,6 +11,7 @@
using Windows.Graphics.Effects;
using static ABI.Microsoft.Graphics.Canvas.WIN2D_GET_D2D_IMAGE_FLAGS;
using static ABI.Microsoft.Graphics.Canvas.WIN2D_GET_DEVICE_ASSOCIATION_TYPE;
+using ICanvasImageInterop = Microsoft.Graphics.Canvas.ICanvasImageInterop;
namespace ComputeSharp.D2D1.WinUI;
@@ -18,7 +19,7 @@ namespace ComputeSharp.D2D1.WinUI;
unsafe partial class PixelShaderEffect
{
///
- int ICanvasImageInterop.Interface.GetDevice(ICanvasDevice** device, WIN2D_GET_DEVICE_ASSOCIATION_TYPE* type)
+ int ICanvasImageInterop.GetDevice(ICanvasDevice** device, WIN2D_GET_DEVICE_ASSOCIATION_TYPE* type)
{
// Validate all input parameters
if (device is null || type is null)
@@ -71,7 +72,7 @@ int ICanvasImageInterop.Interface.GetDevice(ICanvasDevice** device, WIN2D_GET_DE
}
///
- int ICanvasImageInterop.Interface.GetD2DImage(
+ int ICanvasImageInterop.GetD2DImage(
ICanvasDevice* device,
ID2D1DeviceContext* deviceContext,
WIN2D_GET_D2D_IMAGE_FLAGS flags,
@@ -361,7 +362,7 @@ private void RefreshInputs(WIN2D_GET_D2D_IMAGE_FLAGS flags, float targetDpi, ID2
}
else
{
- using ComPtr canvasImageInterop = default;
+ using ComPtr canvasImageInterop = default;
// Convert to ICanvasImageInterop (this must always succeed, and throws if it doesn't)
RcwMarshaller.GetNativeInterface(source, canvasImageInterop.GetAddressOf()).Assert();
diff --git a/src/ComputeSharp.D2D1.WinUI/PixelShaderEffect{T}.Properties.ResourceTextureManagerCollection.cs b/src/ComputeSharp.D2D1.WinUI/PixelShaderEffect{T}.Properties.ResourceTextureManagerCollection.cs
index d5355762a..bb5322c87 100644
--- a/src/ComputeSharp.D2D1.WinUI/PixelShaderEffect{T}.Properties.ResourceTextureManagerCollection.cs
+++ b/src/ComputeSharp.D2D1.WinUI/PixelShaderEffect{T}.Properties.ResourceTextureManagerCollection.cs
@@ -18,6 +18,7 @@ partial class PixelShaderEffect
///
/// Represents the collection of objects in a instance.
///
+ ///
public sealed class ResourceTextureManagerCollection : IList, IReadOnlyList, IList, IFixedCountList
{
///
diff --git a/src/ComputeSharp.D2D1.WinUI/PixelShaderEffect{T}.Properties.SourceCollection.cs b/src/ComputeSharp.D2D1.WinUI/PixelShaderEffect{T}.Properties.SourceCollection.cs
index f071c37ea..80d2bdf87 100644
--- a/src/ComputeSharp.D2D1.WinUI/PixelShaderEffect{T}.Properties.SourceCollection.cs
+++ b/src/ComputeSharp.D2D1.WinUI/PixelShaderEffect{T}.Properties.SourceCollection.cs
@@ -16,6 +16,7 @@ partial class PixelShaderEffect
///
/// Represents the collection of sources in a instance.
///
+ ///
public sealed class SourceCollection : IList, IReadOnlyList, IList, IFixedCountList
{
///
diff --git a/src/ComputeSharp.D2D1.WinUI/PixelShaderEffect{T}.ReferenceTracking.cs b/src/ComputeSharp.D2D1.WinUI/PixelShaderEffect{T}.ReferenceTracking.cs
index 0429e3d74..d709e19a8 100644
--- a/src/ComputeSharp.D2D1.WinUI/PixelShaderEffect{T}.ReferenceTracking.cs
+++ b/src/ComputeSharp.D2D1.WinUI/PixelShaderEffect{T}.ReferenceTracking.cs
@@ -43,7 +43,7 @@ unsafe void IReferenceTrackedObject.DangerousOnDispose()
{
// When the effect is disposed, we also unregister it from the resource manager cache. This
// is analogous to what is done when manually unrealizing the effect (eg. when using a new
- // device. Without this call, the resource manager would keep registered effects alive for
+ // device). Without this call, the resource manager would keep registered effects alive for
// the entire process duration, even if their original wrappers are gone (ie. collected).
if (this.d2D1Effect.Get() is not null)
{
diff --git a/src/ComputeSharp.D2D1.WinUI/PixelShaderEffect{T}.cs b/src/ComputeSharp.D2D1.WinUI/PixelShaderEffect{T}.cs
index 65e2ddc59..cae06b138 100644
--- a/src/ComputeSharp.D2D1.WinUI/PixelShaderEffect{T}.cs
+++ b/src/ComputeSharp.D2D1.WinUI/PixelShaderEffect{T}.cs
@@ -1,4 +1,3 @@
-using System.Diagnostics.CodeAnalysis;
using ABI.Microsoft.Graphics.Canvas;
using ComputeSharp.D2D1.Descriptors;
using ComputeSharp.D2D1.Interop;
@@ -6,6 +5,7 @@
using ComputeSharp.Win32;
using Microsoft.Graphics.Canvas;
using Microsoft.Graphics.Canvas.Effects;
+using ICanvasImageInterop = Microsoft.Graphics.Canvas.ICanvasImageInterop;
namespace ComputeSharp.D2D1.WinUI;
@@ -13,7 +13,7 @@ namespace ComputeSharp.D2D1.WinUI;
/// A custom implementation powered by a supplied shader type.
///
/// The type of shader to use to render frames.
-public sealed partial class PixelShaderEffect : IReferenceTrackedObject, ICanvasEffect, ICanvasImageInterop.Interface
+public sealed partial class PixelShaderEffect : IReferenceTrackedObject, ICanvasEffect, ICanvasImageInterop
where T : unmanaged, ID2D1PixelShader, ID2D1PixelShaderDescriptor
{
///
@@ -27,7 +27,7 @@ public sealed partial class PixelShaderEffect : IReferenceTrackedObject, ICan
private readonly object lockObject = new();
///
- /// Flag to track whether a given call is recursively invoked by , to avoid graph cycles.
+ /// Flag to track whether a given call is recursively invoked by , to avoid graph cycles.
///
private volatile int isInsideGetD2DImage;
@@ -69,14 +69,6 @@ public sealed partial class PixelShaderEffect : IReferenceTrackedObject, ICan
///
/// Creates a new instance.
///
- // Workaround for trimming bug in custom COM/WinRT components with CsWinRT. Without manually preserving metadata for
- // these types, using them will throw an InvalidCastException (see https://github.com/microsoft/CsWinRT/issues/1319).
- [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ICanvasImageInterop.Interface))]
- [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ICanvasImageInterop.Interface.Vftbl))]
- [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ICanvasFactoryNative.Interface))]
- [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ICanvasFactoryNative.Interface.Vftbl))]
- [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ICanvasEffectFactoryNative.Interface))]
- [DynamicDependency(DynamicallyAccessedMemberTypes.All, typeof(ICanvasEffectFactoryNative.Interface.Vftbl))]
public PixelShaderEffect()
{
using ReferenceTracker.Lease _0 = ReferenceTracker.Create(this, out this.referenceTracker);
diff --git a/src/ComputeSharp.WinUI/ComputeSharp.WinUI.csproj b/src/ComputeSharp.WinUI/ComputeSharp.WinUI.csproj
index 4ebf5d635..5a49a7d61 100644
--- a/src/ComputeSharp.WinUI/ComputeSharp.WinUI.csproj
+++ b/src/ComputeSharp.WinUI/ComputeSharp.WinUI.csproj
@@ -2,12 +2,22 @@
net8.0-windows10.0.22621.0
10.0.17763.0
+ 10.0.22621.35-preview
x64;ARM64
win-x64;win-arm64
+
+
+
+ true
+
+
-
+
+
+
+
diff --git a/tests/ComputeSharp.D2D1.WinUI.Tests/ComputeSharp.D2D1.WinUI.Tests.csproj b/tests/ComputeSharp.D2D1.WinUI.Tests/ComputeSharp.D2D1.WinUI.Tests.csproj
index 133ab3107..31119f1e9 100644
--- a/tests/ComputeSharp.D2D1.WinUI.Tests/ComputeSharp.D2D1.WinUI.Tests.csproj
+++ b/tests/ComputeSharp.D2D1.WinUI.Tests/ComputeSharp.D2D1.WinUI.Tests.csproj
@@ -3,6 +3,7 @@
WinExe
net8.0-windows10.0.22621.0
10.0.17763.0
+ 10.0.22621.35-preview
app.manifest
x64;ARM64
win-x64;win-arm64
diff --git a/tests/ComputeSharp.D2D1.WinUI.Tests/Helpers/Win2DHelper.cs b/tests/ComputeSharp.D2D1.WinUI.Tests/Helpers/Win2DHelper.cs
index 98f093889..e1900cbfe 100644
--- a/tests/ComputeSharp.D2D1.WinUI.Tests/Helpers/Win2DHelper.cs
+++ b/tests/ComputeSharp.D2D1.WinUI.Tests/Helpers/Win2DHelper.cs
@@ -4,7 +4,6 @@
using TerraFX.Interop.DirectX;
using TerraFX.Interop.Windows;
using WinRT;
-using WinRT.Interop;
namespace ComputeSharp.D2D1.WinUI.Tests.Helpers;
@@ -21,20 +20,15 @@ internal static class Win2DHelper
/// The resulting managed wrapper for .
public static unsafe object GetOrCreate(ID2D1Image* d2D1Image, CanvasDevice? canvasDevice = null)
{
- using ComPtr activationFactoryUnknown = default;
-
- ICanvasFactoryNative activationFactory = CanvasDevice.As();
-
- activationFactoryUnknown.Attach((IUnknown*)MarshalInterface.FromManaged(activationFactory));
-
using ComPtr canvasFactoryNativeUnknown = default;
- Guid uuidOfCanvasFactoryNativeUnknown = new("695C440D-04B3-4EDD-BFD9-63E51E9F7202");
-
- //Get the ICanvasFactoryNative object
- int hresult = activationFactoryUnknown.CopyTo(&uuidOfCanvasFactoryNativeUnknown, (void**)canvasFactoryNativeUnknown.GetAddressOf());
-
- Marshal.ThrowExceptionForHR(hresult);
+ // Get the ICanvasFactoryNative object
+ using (IObjectReference canvasDeviceActivationFactory = ActivationFactory.Get(
+ typeName: "Microsoft.Graphics.Canvas.CanvasDevice",
+ iid: new Guid("695C440D-04B3-4EDD-BFD9-63E51E9F7202")))
+ {
+ canvasFactoryNativeUnknown.Attach((IUnknown*)canvasDeviceActivationFactory.GetRef());
+ }
using ComPtr canvasDeviceUnknown = default;
@@ -43,6 +37,8 @@ public static unsafe object GetOrCreate(ID2D1Image* d2D1Image, CanvasDevice? can
canvasDeviceUnknown.Attach((IUnknown*)MarshalInspectable.FromManaged(canvasDevice));
}
+ int hresult;
+
using ComPtr canvasDeviceInterfaceUnknown = default;
if (canvasDevice is not null)
@@ -51,6 +47,8 @@ public static unsafe object GetOrCreate(ID2D1Image* d2D1Image, CanvasDevice? can
// Get the ICanvasDevice object (as an IUnknown* as well)
hresult = canvasDeviceUnknown.CopyTo(&uuidOfCanvasDeviceInterface, (void**)canvasDeviceInterfaceUnknown.GetAddressOf());
+
+ Marshal.ThrowExceptionForHR(hresult);
}
using ComPtr wrapperUnknown = default;
@@ -115,25 +113,4 @@ public static unsafe void GetD2DImage(ICanvasImage canvasImage, CanvasDevice can
Marshal.ThrowExceptionForHR(hresult);
}
-
- ///
- /// The managed interface for .
- ///
- [Guid("695C440D-04B3-4EDD-BFD9-63E51E9F7202")]
- [WindowsRuntimeType]
- [WindowsRuntimeHelperType(typeof(ICanvasFactoryNative))]
- public interface ICanvasFactoryNative
- {
- ///
- /// The vtable type for .
- ///
- [Guid("695C440D-04B3-4EDD-BFD9-63E51E9F7202")]
- public readonly struct Vftbl
- {
- ///
- /// Allows CsWinRT to retrieve a pointer to the projection vtable (the name is hardcoded by convention).
- ///
- public static readonly IntPtr AbiToProjectionVftablePtr = IUnknownVftbl.AbiToProjectionVftblPtr;
- }
- }
}
\ No newline at end of file