diff --git a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs index 223c208829..a94fd82e1a 100644 --- a/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs +++ b/src/Windows/Avalonia.Win32/Composition/CompositionHost.cs @@ -2,6 +2,7 @@ using System.Runtime.InteropServices; using Avalonia.OpenGL.Angle; using Windows.UI.Composition; +using Windows.UI.Composition.Interop; using WinRT; namespace Avalonia.Win32 @@ -89,8 +90,24 @@ namespace Avalonia.Win32 var gDevice = interop.CreateGraphicsDevice(display.GetDirect3DDevice()); - gDevice.CreateDrawingSurface(new Windows.Foundation.Size(100,100), Windows.Graphics.DirectX.DirectXPixelFormat.B8G8R8A8UIntNormalized, Windows.Graphics.DirectX.DirectXAlphaMode.Premultiplied); - + var surface = gDevice.CreateDrawingSurface(new Windows.Foundation.Size(100,100), Windows.Graphics.DirectX.DirectXPixelFormat.B8G8R8A8UIntNormalized, Windows.Graphics.DirectX.DirectXAlphaMode.Premultiplied); + + var surfaceInterop = surface.As(); + + surfaceInterop.BeginDraw(new Windows.Foundation.Rect(0, 0, 100, 100), Guid.Parse("6f15aaf2-d208-4e89-9ab4-489535d34f9c"), out var texture, new Windows.Foundation.Point(0, 0)); + surfaceInterop.EndDraw(); + + var brush = _compositor.CreateSurfaceBrush(surface); + + var visual = _compositor.CreateSpriteVisual(); + + visual.RelativeSizeAdjustment = new System.Numerics.Vector2(1.0f, 1.0f); + visual.Brush = brush; + + _target.Root = visual; + + AddElement(100, 200, 200); + } public void CreateBlur() diff --git a/src/Windows/Avalonia.Win32/Composition/ICompositionDrawingSurfaceInterop.cs b/src/Windows/Avalonia.Win32/Composition/ICompositionDrawingSurfaceInterop.cs new file mode 100644 index 0000000000..fd9387b59e --- /dev/null +++ b/src/Windows/Avalonia.Win32/Composition/ICompositionDrawingSurfaceInterop.cs @@ -0,0 +1,135 @@ +using System; +using System.Runtime.InteropServices; +using Windows.Foundation; +using WinRT; + +namespace Windows.UI.Composition.Interop +{ + [WindowsRuntimeType] + [Guid("FD04E6E3-FE0C-4C3C-AB19-A07601A576EE")] + public interface ICompositionDrawingSurfaceInterop + { + void BeginDraw(Rect updateRect, Guid iid, out IntPtr updateObject, Point point); + + void EndDraw(); + + void Resize(Size sizePixels); + + void ResumeDraw(); + + void Scroll(Rect scrollRect, Rect clipRect, int offsetX, int offsetY); + + void SuspendDraw(); + } +} + +namespace ABI.Windows.UI.Composition.Interop +{ + using global::System; + using global::System.Runtime.InteropServices; + using global::Windows.UI.Composition; + + [Guid("FD04E6E3-FE0C-4C3C-AB19-A07601A576EE")] + internal class ICompositionDrawingSurfaceInterop : global::Windows.UI.Composition.Interop.ICompositionDrawingSurfaceInterop + + { + [Guid("FD04E6E3-FE0C-4C3C-AB19-A07601A576EE")] + public struct Vftbl + { + public delegate int _BeginDraw(IntPtr ThisPtr, Guid iid, out IntPtr updateObject, Point updateOffset); + public delegate int _EndDraw(IntPtr ThisPtr); + public delegate int _Resize(IntPtr ThisPtr, Size sizePixels); + public delegate int _ResumeDraw(IntPtr ThisPtr); + public delegate int _Scroll(IntPtr ThisPtr, Rect scrollRect, Rect clipRect, int offsetX, int offsetY); + public delegate int _SuspendDraw(IntPtr ThisPtr); + + internal global::WinRT.Interop.IUnknownVftbl IUnknownVftbl; + public _BeginDraw BeginDraw; + public _EndDraw EndDraw; + public _Resize Resize; + public _ResumeDraw ResumeDraw; + public _Scroll Scroll; + public _SuspendDraw SuspendDraw; + + public static readonly Vftbl AbiToProjectionVftable; + public static readonly IntPtr AbiToProjectionVftablePtr; + + static Vftbl() + { + AbiToProjectionVftable = new Vftbl + { + IUnknownVftbl = global::WinRT.Interop.IUnknownVftbl.AbiToProjectionVftbl, + + BeginDraw = Do_Abi_BeginDraw, + EndDraw = Do_Abi_EndDraw, + Resize = Do_Abi_Resize + + + }; + AbiToProjectionVftablePtr = Marshal.AllocHGlobal(Marshal.SizeOf()); + Marshal.StructureToPtr(AbiToProjectionVftable, AbiToProjectionVftablePtr, false); + } + + private static int Do_Abi_BeginDraw(IntPtr ThisPtr, Guid iid, out IntPtr updateObject, Point updateOffset) + { + updateObject = IntPtr.Zero; + return 0; + } + + private static int Do_Abi_EndDraw(IntPtr ThisPtr) + { + return 0; + } + + private static int Do_Abi_Resize(IntPtr ThisPtr, Size sizePixels) + { + return 0; + } + } + internal static ObjectReference FromAbi(IntPtr thisPtr) => ObjectReference.FromAbi(thisPtr); + + public static implicit operator ICompositionDrawingSurfaceInterop(IObjectReference obj) => (obj != null) ? new ICompositionDrawingSurfaceInterop(obj) : null; + protected readonly ObjectReference _obj; + public IObjectReference ObjRef { get => _obj; } + public IntPtr ThisPtr => _obj.ThisPtr; + public ObjectReference AsInterface() => _obj.As(); + public A As() => _obj.AsType(); + + public ICompositionDrawingSurfaceInterop(IObjectReference obj) : this(obj.As()) { } + internal ICompositionDrawingSurfaceInterop(ObjectReference obj) + { + _obj = obj; + } + + public void BeginDraw(Rect updateRect, Guid iid, out IntPtr updateObject, Point point) + { + Marshal.ThrowExceptionForHR(_obj.Vftbl.BeginDraw(ThisPtr, iid, out updateObject, point)); + } + + public void EndDraw() + { + Marshal.ThrowExceptionForHR(_obj.Vftbl.EndDraw(ThisPtr)); + } + + public void Resize(Size sizePixels) + { + throw new NotImplementedException(); + } + + public void ResumeDraw() + { + throw new NotImplementedException(); + } + + public void Scroll(Rect scrollRect, Rect clipRect, int offsetX, int offsetY) + { + throw new NotImplementedException(); + } + + public void SuspendDraw() + { + throw new NotImplementedException(); + } + } +} + diff --git a/src/Windows/Avalonia.Win32/Composition/IGraphicsEffectD2D1Interop1.cs b/src/Windows/Avalonia.Win32/Composition/IGraphicsEffectD2D1Interop1.cs index 9d053c9e22..8466b05fb5 100644 --- a/src/Windows/Avalonia.Win32/Composition/IGraphicsEffectD2D1Interop1.cs +++ b/src/Windows/Avalonia.Win32/Composition/IGraphicsEffectD2D1Interop1.cs @@ -122,7 +122,7 @@ namespace ABI.Windows.Graphics.Effects.Interop value = default; try - { + { var source = ComWrappersSupport.FindObject(thisPtr).GetSource(index); value = MarshalInterface.FromManaged(source);