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