diff --git a/api/Avalonia.LinuxFramebuffer.nupkg.xml b/api/Avalonia.LinuxFramebuffer.nupkg.xml new file mode 100644 index 0000000000..10c927a203 --- /dev/null +++ b/api/Avalonia.LinuxFramebuffer.nupkg.xml @@ -0,0 +1,40 @@ + + + + + CP0002 + M:Avalonia.LinuxFramebuffer.FbdevOutput.CreateFramebufferRenderTarget + baseline/Avalonia.LinuxFramebuffer/lib/net10.0/Avalonia.LinuxFramebuffer.dll + current/Avalonia.LinuxFramebuffer/lib/net10.0/Avalonia.LinuxFramebuffer.dll + + + CP0002 + M:Avalonia.LinuxFramebuffer.FbdevOutput.Lock + baseline/Avalonia.LinuxFramebuffer/lib/net10.0/Avalonia.LinuxFramebuffer.dll + current/Avalonia.LinuxFramebuffer/lib/net10.0/Avalonia.LinuxFramebuffer.dll + + + CP0002 + M:Avalonia.LinuxFramebuffer.FbdevOutput.CreateFramebufferRenderTarget + baseline/Avalonia.LinuxFramebuffer/lib/net8.0/Avalonia.LinuxFramebuffer.dll + current/Avalonia.LinuxFramebuffer/lib/net8.0/Avalonia.LinuxFramebuffer.dll + + + CP0002 + M:Avalonia.LinuxFramebuffer.FbdevOutput.Lock + baseline/Avalonia.LinuxFramebuffer/lib/net8.0/Avalonia.LinuxFramebuffer.dll + current/Avalonia.LinuxFramebuffer/lib/net8.0/Avalonia.LinuxFramebuffer.dll + + + CP0008 + T:Avalonia.LinuxFramebuffer.FbdevOutput + baseline/Avalonia.LinuxFramebuffer/lib/net10.0/Avalonia.LinuxFramebuffer.dll + current/Avalonia.LinuxFramebuffer/lib/net10.0/Avalonia.LinuxFramebuffer.dll + + + CP0008 + T:Avalonia.LinuxFramebuffer.FbdevOutput + baseline/Avalonia.LinuxFramebuffer/lib/net8.0/Avalonia.LinuxFramebuffer.dll + current/Avalonia.LinuxFramebuffer/lib/net8.0/Avalonia.LinuxFramebuffer.dll + + \ No newline at end of file diff --git a/api/Avalonia.Skia.nupkg.xml b/api/Avalonia.Skia.nupkg.xml index cd9dedbd0f..c1afe2f966 100644 --- a/api/Avalonia.Skia.nupkg.xml +++ b/api/Avalonia.Skia.nupkg.xml @@ -1,6 +1,12 @@ - + + + CP0001 + T:Avalonia.Skia.ISkiaGpu + baseline/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll + current/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll + CP0001 T:Avalonia.Skia.ISkiaGpuRenderTarget2 @@ -13,6 +19,12 @@ baseline/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll current/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll + + CP0001 + T:Avalonia.Skia.ISkiaGpu + baseline/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll + current/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll + CP0001 T:Avalonia.Skia.ISkiaGpuRenderTarget2 @@ -31,30 +43,66 @@ baseline/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll current/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll + + CP0002 + M:Avalonia.Skia.ISkiaGpu.TryCreateRenderTarget(System.Collections.Generic.IEnumerable{System.Object}) + baseline/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll + current/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll + CP0002 M:Avalonia.Skia.ISkiaGpuRenderTarget.BeginRenderingSession baseline/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll current/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll + + CP0002 + M:Avalonia.Skia.ISkiaGpuRenderTarget.BeginRenderingSession(System.Nullable{Avalonia.PixelSize}) + baseline/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll + current/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll + CP0002 M:Avalonia.Skia.Helpers.DrawingContextHelper.WrapSkiaCanvas(SkiaSharp.SKCanvas,Avalonia.Vector) baseline/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll current/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll + + CP0002 + M:Avalonia.Skia.ISkiaGpu.TryCreateRenderTarget(System.Collections.Generic.IEnumerable{System.Object}) + baseline/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll + current/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll + CP0002 M:Avalonia.Skia.ISkiaGpuRenderTarget.BeginRenderingSession baseline/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll current/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll + + CP0002 + M:Avalonia.Skia.ISkiaGpuRenderTarget.BeginRenderingSession(System.Nullable{Avalonia.PixelSize}) + baseline/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll + current/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll + + + CP0006 + M:Avalonia.Skia.ISkiaGpu.TryCreateRenderTarget(System.Collections.Generic.IEnumerable{Avalonia.Platform.Surfaces.IPlatformRenderSurface}) + baseline/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll + current/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll + CP0006 M:Avalonia.Skia.ISkiaGpu.TryGetGrContext baseline/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll current/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll + + CP0006 + M:Avalonia.Skia.ISkiaGpuRenderTarget.BeginRenderingSession(Avalonia.Platform.IRenderTarget.RenderTargetSceneInfo) + baseline/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll + current/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll + CP0006 M:Avalonia.Skia.ISkiaGpuRenderTarget.BeginRenderingSession(System.Nullable{Avalonia.PixelSize}) @@ -67,12 +115,24 @@ baseline/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll current/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll + + CP0006 + M:Avalonia.Skia.ISkiaGpu.TryCreateRenderTarget(System.Collections.Generic.IEnumerable{Avalonia.Platform.Surfaces.IPlatformRenderSurface}) + baseline/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll + current/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll + CP0006 M:Avalonia.Skia.ISkiaGpu.TryGetGrContext baseline/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll current/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll + + CP0006 + M:Avalonia.Skia.ISkiaGpuRenderTarget.BeginRenderingSession(Avalonia.Platform.IRenderTarget.RenderTargetSceneInfo) + baseline/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll + current/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll + CP0006 M:Avalonia.Skia.ISkiaGpuRenderTarget.BeginRenderingSession(System.Nullable{Avalonia.PixelSize}) @@ -109,4 +169,4 @@ baseline/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll current/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll - + \ No newline at end of file diff --git a/api/Avalonia.nupkg.xml b/api/Avalonia.nupkg.xml index e0f0fa2956..92f41c6606 100644 --- a/api/Avalonia.nupkg.xml +++ b/api/Avalonia.nupkg.xml @@ -1,4 +1,4 @@ - + @@ -337,6 +337,36 @@ baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll current/Avalonia/lib/net10.0/Avalonia.Controls.dll + + CP0001 + T:Avalonia.Controls.Platform.Surfaces.FramebufferLockProperties + baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll + current/Avalonia/lib/net10.0/Avalonia.Controls.dll + + + CP0001 + T:Avalonia.Controls.Platform.Surfaces.FuncFramebufferRenderTarget + baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll + current/Avalonia/lib/net10.0/Avalonia.Controls.dll + + + CP0001 + T:Avalonia.Controls.Platform.Surfaces.IFramebufferPlatformSurface + baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll + current/Avalonia/lib/net10.0/Avalonia.Controls.dll + + + CP0001 + T:Avalonia.Controls.Platform.Surfaces.IFramebufferRenderTarget + baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll + current/Avalonia/lib/net10.0/Avalonia.Controls.dll + + + CP0001 + T:Avalonia.Controls.Platform.Surfaces.IFramebufferRenderTargetWithProperties + baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll + current/Avalonia/lib/net10.0/Avalonia.Controls.dll + CP0001 T:Avalonia.Controls.Primitives.ChromeOverlayLayer @@ -769,6 +799,36 @@ baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll current/Avalonia/lib/net8.0/Avalonia.Controls.dll + + CP0001 + T:Avalonia.Controls.Platform.Surfaces.FramebufferLockProperties + baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll + current/Avalonia/lib/net8.0/Avalonia.Controls.dll + + + CP0001 + T:Avalonia.Controls.Platform.Surfaces.FuncFramebufferRenderTarget + baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll + current/Avalonia/lib/net8.0/Avalonia.Controls.dll + + + CP0001 + T:Avalonia.Controls.Platform.Surfaces.IFramebufferPlatformSurface + baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll + current/Avalonia/lib/net8.0/Avalonia.Controls.dll + + + CP0001 + T:Avalonia.Controls.Platform.Surfaces.IFramebufferRenderTarget + baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll + current/Avalonia/lib/net8.0/Avalonia.Controls.dll + + + CP0001 + T:Avalonia.Controls.Platform.Surfaces.IFramebufferRenderTargetWithProperties + baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll + current/Avalonia/lib/net8.0/Avalonia.Controls.dll + CP0001 T:Avalonia.Controls.Primitives.ChromeOverlayLayer @@ -1417,6 +1477,12 @@ baseline/Avalonia/lib/net10.0/Avalonia.Base.dll current/Avalonia/lib/net10.0/Avalonia.Base.dll + + CP0002 + M:Avalonia.Platform.ICursorFactory.CreateCursor(Avalonia.Platform.IBitmapImpl,Avalonia.PixelPoint) + baseline/Avalonia/lib/net10.0/Avalonia.Base.dll + current/Avalonia/lib/net10.0/Avalonia.Base.dll + CP0002 M:Avalonia.Platform.IDrawingContextImplWithEffects.PushEffect(Avalonia.Media.IEffect) @@ -1459,6 +1525,24 @@ baseline/Avalonia/lib/net10.0/Avalonia.Base.dll current/Avalonia/lib/net10.0/Avalonia.Base.dll + + CP0002 + M:Avalonia.Platform.IPlatformRenderInterfaceContext.CreateRenderTarget(System.Collections.Generic.IEnumerable{System.Object}) + baseline/Avalonia/lib/net10.0/Avalonia.Base.dll + current/Avalonia/lib/net10.0/Avalonia.Base.dll + + + CP0002 + M:Avalonia.Platform.IRenderTarget.CreateDrawingContext(Avalonia.PixelSize,Avalonia.Platform.RenderTargetDrawingContextProperties@) + baseline/Avalonia/lib/net10.0/Avalonia.Base.dll + current/Avalonia/lib/net10.0/Avalonia.Base.dll + + + CP0002 + M:Avalonia.Platform.IRenderTarget.CreateDrawingContext(System.Boolean) + baseline/Avalonia/lib/net10.0/Avalonia.Base.dll + current/Avalonia/lib/net10.0/Avalonia.Base.dll + CP0002 M:Avalonia.Platform.LockedFramebuffer.#ctor(System.IntPtr,Avalonia.PixelSize,System.Int32,Avalonia.Vector,Avalonia.Platform.PixelFormat,System.Action) @@ -1735,6 +1819,12 @@ baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll current/Avalonia/lib/net10.0/Avalonia.Controls.dll + + CP0002 + M:Avalonia.Controls.Embedding.Offscreen.OffscreenTopLevelImplBase.get_Surfaces + baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll + current/Avalonia/lib/net10.0/Avalonia.Controls.dll + CP0002 M:Avalonia.Controls.Generators.ItemContainerGenerator.ContainerFromIndex(System.Int32) @@ -2029,6 +2119,12 @@ baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll current/Avalonia/lib/net10.0/Avalonia.Controls.dll + + CP0002 + M:Avalonia.Platform.ITopLevelImpl.get_Surfaces + baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll + current/Avalonia/lib/net10.0/Avalonia.Controls.dll + CP0002 M:Avalonia.Platform.IWindowImpl.GetWindowsZOrder(System.Span{Avalonia.Controls.Window},System.Span{System.Int64}) @@ -2137,18 +2233,66 @@ baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll + + CP0002 + M:Avalonia.OpenGL.Egl.EglPlatformSurfaceRenderTargetBase.BeginDraw(System.Nullable{Avalonia.PixelSize}) + baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll + current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll + CP0002 M:Avalonia.OpenGL.Egl.EglPlatformSurfaceRenderTargetBase.BeginDrawCore baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll + + CP0002 + M:Avalonia.OpenGL.Egl.EglPlatformSurfaceRenderTargetBase.BeginDrawCore(System.Nullable{Avalonia.PixelSize}) + baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll + current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll + + + CP0002 + M:Avalonia.OpenGL.IGlPlatformSurfaceRenderTargetFactory.CanRenderToSurface(Avalonia.OpenGL.IGlContext,System.Object) + baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll + current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll + + + CP0002 + M:Avalonia.OpenGL.IGlPlatformSurfaceRenderTargetFactory.CreateRenderTarget(Avalonia.OpenGL.IGlContext,System.Object) + baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll + current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll + CP0002 M:Avalonia.OpenGL.Surfaces.IGlPlatformSurfaceRenderTarget.BeginDraw baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll + + CP0002 + M:Avalonia.OpenGL.Surfaces.IGlPlatformSurfaceRenderTarget.BeginDraw(System.Nullable{Avalonia.PixelSize}) + baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll + current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll + + + CP0002 + M:Avalonia.Vulkan.IVulkanKhrSurfacePlatformSurfaceFactory.CanRenderToSurface(Avalonia.Vulkan.IVulkanPlatformGraphicsContext,System.Object) + baseline/Avalonia/lib/net10.0/Avalonia.Vulkan.dll + current/Avalonia/lib/net10.0/Avalonia.Vulkan.dll + + + CP0002 + M:Avalonia.Vulkan.IVulkanKhrSurfacePlatformSurfaceFactory.CreateSurface(Avalonia.Vulkan.IVulkanPlatformGraphicsContext,System.Object) + baseline/Avalonia/lib/net10.0/Avalonia.Vulkan.dll + current/Avalonia/lib/net10.0/Avalonia.Vulkan.dll + + + CP0002 + M:Avalonia.Vulkan.IVulkanPlatformGraphicsContext.CreateRenderTarget(System.Collections.Generic.IEnumerable{System.Object}) + baseline/Avalonia/lib/net10.0/Avalonia.Vulkan.dll + current/Avalonia/lib/net10.0/Avalonia.Vulkan.dll + CP0002 F:Avalonia.Media.Fonts.FontCollectionBase._glyphTypefaceCache @@ -2731,6 +2875,12 @@ baseline/Avalonia/lib/net8.0/Avalonia.Base.dll current/Avalonia/lib/net8.0/Avalonia.Base.dll + + CP0002 + M:Avalonia.Platform.ICursorFactory.CreateCursor(Avalonia.Platform.IBitmapImpl,Avalonia.PixelPoint) + baseline/Avalonia/lib/net8.0/Avalonia.Base.dll + current/Avalonia/lib/net8.0/Avalonia.Base.dll + CP0002 M:Avalonia.Platform.IDrawingContextImplWithEffects.PushEffect(Avalonia.Media.IEffect) @@ -2773,6 +2923,24 @@ baseline/Avalonia/lib/net8.0/Avalonia.Base.dll current/Avalonia/lib/net8.0/Avalonia.Base.dll + + CP0002 + M:Avalonia.Platform.IPlatformRenderInterfaceContext.CreateRenderTarget(System.Collections.Generic.IEnumerable{System.Object}) + baseline/Avalonia/lib/net8.0/Avalonia.Base.dll + current/Avalonia/lib/net8.0/Avalonia.Base.dll + + + CP0002 + M:Avalonia.Platform.IRenderTarget.CreateDrawingContext(Avalonia.PixelSize,Avalonia.Platform.RenderTargetDrawingContextProperties@) + baseline/Avalonia/lib/net8.0/Avalonia.Base.dll + current/Avalonia/lib/net8.0/Avalonia.Base.dll + + + CP0002 + M:Avalonia.Platform.IRenderTarget.CreateDrawingContext(System.Boolean) + baseline/Avalonia/lib/net8.0/Avalonia.Base.dll + current/Avalonia/lib/net8.0/Avalonia.Base.dll + CP0002 M:Avalonia.Platform.LockedFramebuffer.#ctor(System.IntPtr,Avalonia.PixelSize,System.Int32,Avalonia.Vector,Avalonia.Platform.PixelFormat,System.Action) @@ -3049,6 +3217,12 @@ baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll current/Avalonia/lib/net8.0/Avalonia.Controls.dll + + CP0002 + M:Avalonia.Controls.Embedding.Offscreen.OffscreenTopLevelImplBase.get_Surfaces + baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll + current/Avalonia/lib/net8.0/Avalonia.Controls.dll + CP0002 M:Avalonia.Controls.Generators.ItemContainerGenerator.ContainerFromIndex(System.Int32) @@ -3343,6 +3517,12 @@ baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll current/Avalonia/lib/net8.0/Avalonia.Controls.dll + + CP0002 + M:Avalonia.Platform.ITopLevelImpl.get_Surfaces + baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll + current/Avalonia/lib/net8.0/Avalonia.Controls.dll + CP0002 M:Avalonia.Platform.IWindowImpl.GetWindowsZOrder(System.Span{Avalonia.Controls.Window},System.Span{System.Int64}) @@ -3457,18 +3637,66 @@ baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll + + CP0002 + M:Avalonia.OpenGL.Egl.EglPlatformSurfaceRenderTargetBase.BeginDraw(System.Nullable{Avalonia.PixelSize}) + baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll + current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll + CP0002 M:Avalonia.OpenGL.Egl.EglPlatformSurfaceRenderTargetBase.BeginDrawCore baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll + + CP0002 + M:Avalonia.OpenGL.Egl.EglPlatformSurfaceRenderTargetBase.BeginDrawCore(System.Nullable{Avalonia.PixelSize}) + baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll + current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll + + + CP0002 + M:Avalonia.OpenGL.IGlPlatformSurfaceRenderTargetFactory.CanRenderToSurface(Avalonia.OpenGL.IGlContext,System.Object) + baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll + current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll + + + CP0002 + M:Avalonia.OpenGL.IGlPlatformSurfaceRenderTargetFactory.CreateRenderTarget(Avalonia.OpenGL.IGlContext,System.Object) + baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll + current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll + CP0002 M:Avalonia.OpenGL.Surfaces.IGlPlatformSurfaceRenderTarget.BeginDraw baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll + + CP0002 + M:Avalonia.OpenGL.Surfaces.IGlPlatformSurfaceRenderTarget.BeginDraw(System.Nullable{Avalonia.PixelSize}) + baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll + current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll + + + CP0002 + M:Avalonia.Vulkan.IVulkanKhrSurfacePlatformSurfaceFactory.CanRenderToSurface(Avalonia.Vulkan.IVulkanPlatformGraphicsContext,System.Object) + baseline/Avalonia/lib/net8.0/Avalonia.Vulkan.dll + current/Avalonia/lib/net8.0/Avalonia.Vulkan.dll + + + CP0002 + M:Avalonia.Vulkan.IVulkanKhrSurfacePlatformSurfaceFactory.CreateSurface(Avalonia.Vulkan.IVulkanPlatformGraphicsContext,System.Object) + baseline/Avalonia/lib/net8.0/Avalonia.Vulkan.dll + current/Avalonia/lib/net8.0/Avalonia.Vulkan.dll + + + CP0002 + M:Avalonia.Vulkan.IVulkanPlatformGraphicsContext.CreateRenderTarget(System.Collections.Generic.IEnumerable{System.Object}) + baseline/Avalonia/lib/net8.0/Avalonia.Vulkan.dll + current/Avalonia/lib/net8.0/Avalonia.Vulkan.dll + CP0002 F:Avalonia.Media.Fonts.FontCollectionBase._glyphTypefaceCache @@ -3511,12 +3739,48 @@ baseline/netstandard2.0/Avalonia.Base.dll target/netstandard2.0/Avalonia.Base.dll + + CP0005 + M:Avalonia.Controls.Embedding.Offscreen.OffscreenTopLevelImplBase.get_Surfaces + baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll + current/Avalonia/lib/net10.0/Avalonia.Controls.dll + + + CP0005 + P:Avalonia.Controls.Embedding.Offscreen.OffscreenTopLevelImplBase.Surfaces + baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll + current/Avalonia/lib/net10.0/Avalonia.Controls.dll + + + CP0005 + M:Avalonia.OpenGL.Egl.EglPlatformSurfaceRenderTargetBase.BeginDrawCore(Avalonia.Platform.IRenderTarget.RenderTargetSceneInfo) + baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll + current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll + CP0005 M:Avalonia.OpenGL.Egl.EglPlatformSurfaceRenderTargetBase.BeginDrawCore(System.Nullable{Avalonia.PixelSize}) baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll + + CP0005 + M:Avalonia.Controls.Embedding.Offscreen.OffscreenTopLevelImplBase.get_Surfaces + baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll + current/Avalonia/lib/net8.0/Avalonia.Controls.dll + + + CP0005 + P:Avalonia.Controls.Embedding.Offscreen.OffscreenTopLevelImplBase.Surfaces + baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll + current/Avalonia/lib/net8.0/Avalonia.Controls.dll + + + CP0005 + M:Avalonia.OpenGL.Egl.EglPlatformSurfaceRenderTargetBase.BeginDrawCore(Avalonia.Platform.IRenderTarget.RenderTargetSceneInfo) + baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll + current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll + CP0005 M:Avalonia.OpenGL.Egl.EglPlatformSurfaceRenderTargetBase.BeginDrawCore(System.Nullable{Avalonia.PixelSize}) @@ -3529,6 +3793,12 @@ baseline/Avalonia/lib/net10.0/Avalonia.Base.dll current/Avalonia/lib/net10.0/Avalonia.Base.dll + + CP0006 + M:Avalonia.Platform.ICursorFactory.CreateCursor(Avalonia.Media.Imaging.Bitmap,Avalonia.PixelPoint) + baseline/Avalonia/lib/net10.0/Avalonia.Base.dll + current/Avalonia/lib/net10.0/Avalonia.Base.dll + CP0006 M:Avalonia.Platform.IDrawingContextImpl.PopTextOptions @@ -3547,6 +3817,12 @@ baseline/Avalonia/lib/net10.0/Avalonia.Base.dll current/Avalonia/lib/net10.0/Avalonia.Base.dll + + CP0006 + M:Avalonia.Platform.IDrawingContextLayerImpl.CreateDrawingContext + baseline/Avalonia/lib/net10.0/Avalonia.Base.dll + current/Avalonia/lib/net10.0/Avalonia.Base.dll + CP0006 M:Avalonia.Platform.IFontManagerImpl.TryMatchCharacter(System.Int32,Avalonia.Media.FontStyle,Avalonia.Media.FontWeight,Avalonia.Media.FontStretch,System.String,System.Globalization.CultureInfo,Avalonia.Media.Typeface@) @@ -3583,18 +3859,42 @@ baseline/Avalonia/lib/net10.0/Avalonia.Base.dll current/Avalonia/lib/net10.0/Avalonia.Base.dll + + CP0006 + M:Avalonia.Platform.IPlatformRenderInterfaceContext.CreateRenderTarget(System.Collections.Generic.IEnumerable{Avalonia.Platform.Surfaces.IPlatformRenderSurface}) + baseline/Avalonia/lib/net10.0/Avalonia.Base.dll + current/Avalonia/lib/net10.0/Avalonia.Base.dll + CP0006 M:Avalonia.Platform.IRenderTarget.CreateDrawingContext(Avalonia.PixelSize,Avalonia.Platform.RenderTargetDrawingContextProperties@) baseline/Avalonia/lib/net10.0/Avalonia.Base.dll current/Avalonia/lib/net10.0/Avalonia.Base.dll + + CP0006 + M:Avalonia.Platform.IRenderTarget.CreateDrawingContext(Avalonia.Platform.IRenderTarget.RenderTargetSceneInfo,Avalonia.Platform.RenderTargetDrawingContextProperties@) + baseline/Avalonia/lib/net10.0/Avalonia.Base.dll + current/Avalonia/lib/net10.0/Avalonia.Base.dll + + + CP0006 + M:Avalonia.Platform.IRenderTargetBitmapImpl.CreateDrawingContext + baseline/Avalonia/lib/net10.0/Avalonia.Base.dll + current/Avalonia/lib/net10.0/Avalonia.Base.dll + CP0006 P:Avalonia.Input.IInputRoot.FocusRoot baseline/Avalonia/lib/net10.0/Avalonia.Base.dll current/Avalonia/lib/net10.0/Avalonia.Base.dll + + CP0006 + P:Avalonia.Platform.IDrawingContextLayerImpl.IsCorrupted + baseline/Avalonia/lib/net10.0/Avalonia.Base.dll + current/Avalonia/lib/net10.0/Avalonia.Base.dll + CP0006 P:Avalonia.Platform.ILockedFramebuffer.AlphaFormat @@ -3631,12 +3931,36 @@ baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll current/Avalonia/lib/net10.0/Avalonia.Controls.dll + + CP0006 + P:Avalonia.Platform.ITopLevelImpl.Surfaces + baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll + current/Avalonia/lib/net10.0/Avalonia.Controls.dll + CP0006 P:Avalonia.Platform.IWindowImpl.RequestedDrawnDecorations baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll current/Avalonia/lib/net10.0/Avalonia.Controls.dll + + CP0006 + M:Avalonia.OpenGL.IGlPlatformSurfaceRenderTargetFactory.CanRenderToSurface(Avalonia.OpenGL.IGlContext,Avalonia.Platform.Surfaces.IPlatformRenderSurface) + baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll + current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll + + + CP0006 + M:Avalonia.OpenGL.IGlPlatformSurfaceRenderTargetFactory.CreateRenderTarget(Avalonia.OpenGL.IGlContext,Avalonia.Platform.Surfaces.IPlatformRenderSurface) + baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll + current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll + + + CP0006 + M:Avalonia.OpenGL.Surfaces.IGlPlatformSurfaceRenderTarget.BeginDraw(Avalonia.Platform.IRenderTarget.RenderTargetSceneInfo) + baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll + current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll + CP0006 M:Avalonia.OpenGL.Surfaces.IGlPlatformSurfaceRenderTarget.BeginDraw(System.Nullable{Avalonia.PixelSize}) @@ -3649,6 +3973,24 @@ baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll + + CP0006 + M:Avalonia.Vulkan.IVulkanKhrSurfacePlatformSurfaceFactory.CanRenderToSurface(Avalonia.Vulkan.IVulkanPlatformGraphicsContext,Avalonia.Platform.Surfaces.IPlatformRenderSurface) + baseline/Avalonia/lib/net10.0/Avalonia.Vulkan.dll + current/Avalonia/lib/net10.0/Avalonia.Vulkan.dll + + + CP0006 + M:Avalonia.Vulkan.IVulkanKhrSurfacePlatformSurfaceFactory.CreateSurface(Avalonia.Vulkan.IVulkanPlatformGraphicsContext,Avalonia.Platform.Surfaces.IPlatformRenderSurface) + baseline/Avalonia/lib/net10.0/Avalonia.Vulkan.dll + current/Avalonia/lib/net10.0/Avalonia.Vulkan.dll + + + CP0006 + M:Avalonia.Vulkan.IVulkanPlatformGraphicsContext.CreateRenderTarget(System.Collections.Generic.IEnumerable{Avalonia.Platform.Surfaces.IPlatformRenderSurface}) + baseline/Avalonia/lib/net10.0/Avalonia.Vulkan.dll + current/Avalonia/lib/net10.0/Avalonia.Vulkan.dll + CP0006 M:Avalonia.Input.Platform.IClipboard.SetDataAsync(Avalonia.Input.IAsyncDataTransfer) @@ -3739,6 +4081,12 @@ baseline/Avalonia/lib/net8.0/Avalonia.Base.dll current/Avalonia/lib/net8.0/Avalonia.Base.dll + + CP0006 + M:Avalonia.Platform.ICursorFactory.CreateCursor(Avalonia.Media.Imaging.Bitmap,Avalonia.PixelPoint) + baseline/Avalonia/lib/net8.0/Avalonia.Base.dll + current/Avalonia/lib/net8.0/Avalonia.Base.dll + CP0006 M:Avalonia.Platform.IDrawingContextImpl.PopTextOptions @@ -3757,6 +4105,12 @@ baseline/Avalonia/lib/net8.0/Avalonia.Base.dll current/Avalonia/lib/net8.0/Avalonia.Base.dll + + CP0006 + M:Avalonia.Platform.IDrawingContextLayerImpl.CreateDrawingContext + baseline/Avalonia/lib/net8.0/Avalonia.Base.dll + current/Avalonia/lib/net8.0/Avalonia.Base.dll + CP0006 M:Avalonia.Platform.IFontManagerImpl.TryMatchCharacter(System.Int32,Avalonia.Media.FontStyle,Avalonia.Media.FontWeight,Avalonia.Media.FontStretch,System.String,System.Globalization.CultureInfo,Avalonia.Media.Typeface@) @@ -3793,6 +4147,12 @@ baseline/Avalonia/lib/net8.0/Avalonia.Base.dll current/Avalonia/lib/net8.0/Avalonia.Base.dll + + CP0006 + M:Avalonia.Platform.IPlatformRenderInterfaceContext.CreateRenderTarget(System.Collections.Generic.IEnumerable{Avalonia.Platform.Surfaces.IPlatformRenderSurface}) + baseline/Avalonia/lib/net8.0/Avalonia.Base.dll + current/Avalonia/lib/net8.0/Avalonia.Base.dll + CP0006 M:Avalonia.Platform.IPlatformRenderInterfaceImportedImage.SnapshotWithTimelineSemaphores(Avalonia.Platform.IPlatformRenderInterfaceImportedSemaphore,System.UInt64,Avalonia.Platform.IPlatformRenderInterfaceImportedSemaphore,System.UInt64) @@ -3805,6 +4165,18 @@ baseline/Avalonia/lib/net8.0/Avalonia.Base.dll current/Avalonia/lib/net8.0/Avalonia.Base.dll + + CP0006 + M:Avalonia.Platform.IRenderTarget.CreateDrawingContext(Avalonia.Platform.IRenderTarget.RenderTargetSceneInfo,Avalonia.Platform.RenderTargetDrawingContextProperties@) + baseline/Avalonia/lib/net8.0/Avalonia.Base.dll + current/Avalonia/lib/net8.0/Avalonia.Base.dll + + + CP0006 + M:Avalonia.Platform.IRenderTargetBitmapImpl.CreateDrawingContext + baseline/Avalonia/lib/net8.0/Avalonia.Base.dll + current/Avalonia/lib/net8.0/Avalonia.Base.dll + CP0006 M:Avalonia.Platform.Storage.IStorageProvider.SaveFilePickerWithResultAsync(Avalonia.Platform.Storage.FilePickerSaveOptions) @@ -3817,6 +4189,12 @@ baseline/Avalonia/lib/net8.0/Avalonia.Base.dll current/Avalonia/lib/net8.0/Avalonia.Base.dll + + CP0006 + P:Avalonia.Platform.IDrawingContextLayerImpl.IsCorrupted + baseline/Avalonia/lib/net8.0/Avalonia.Base.dll + current/Avalonia/lib/net8.0/Avalonia.Base.dll + CP0006 P:Avalonia.Platform.ILockedFramebuffer.AlphaFormat @@ -3853,6 +4231,12 @@ baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll current/Avalonia/lib/net8.0/Avalonia.Controls.dll + + CP0006 + P:Avalonia.Platform.ITopLevelImpl.Surfaces + baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll + current/Avalonia/lib/net8.0/Avalonia.Controls.dll + CP0006 P:Avalonia.Platform.IWindowImpl.RequestedDrawnDecorations @@ -3871,6 +4255,24 @@ baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll + + CP0006 + M:Avalonia.OpenGL.IGlPlatformSurfaceRenderTargetFactory.CanRenderToSurface(Avalonia.OpenGL.IGlContext,Avalonia.Platform.Surfaces.IPlatformRenderSurface) + baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll + current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll + + + CP0006 + M:Avalonia.OpenGL.IGlPlatformSurfaceRenderTargetFactory.CreateRenderTarget(Avalonia.OpenGL.IGlContext,Avalonia.Platform.Surfaces.IPlatformRenderSurface) + baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll + current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll + + + CP0006 + M:Avalonia.OpenGL.Surfaces.IGlPlatformSurfaceRenderTarget.BeginDraw(Avalonia.Platform.IRenderTarget.RenderTargetSceneInfo) + baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll + current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll + CP0006 M:Avalonia.OpenGL.Surfaces.IGlPlatformSurfaceRenderTarget.BeginDraw(System.Nullable{Avalonia.PixelSize}) @@ -3889,6 +4291,24 @@ baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll + + CP0006 + M:Avalonia.Vulkan.IVulkanKhrSurfacePlatformSurfaceFactory.CanRenderToSurface(Avalonia.Vulkan.IVulkanPlatformGraphicsContext,Avalonia.Platform.Surfaces.IPlatformRenderSurface) + baseline/Avalonia/lib/net8.0/Avalonia.Vulkan.dll + current/Avalonia/lib/net8.0/Avalonia.Vulkan.dll + + + CP0006 + M:Avalonia.Vulkan.IVulkanKhrSurfacePlatformSurfaceFactory.CreateSurface(Avalonia.Vulkan.IVulkanPlatformGraphicsContext,Avalonia.Platform.Surfaces.IPlatformRenderSurface) + baseline/Avalonia/lib/net8.0/Avalonia.Vulkan.dll + current/Avalonia/lib/net8.0/Avalonia.Vulkan.dll + + + CP0006 + M:Avalonia.Vulkan.IVulkanPlatformGraphicsContext.CreateRenderTarget(System.Collections.Generic.IEnumerable{Avalonia.Platform.Surfaces.IPlatformRenderSurface}) + baseline/Avalonia/lib/net8.0/Avalonia.Vulkan.dll + current/Avalonia/lib/net8.0/Avalonia.Vulkan.dll + CP0006 M:Avalonia.Input.Platform.IClipboard.SetDataAsync(Avalonia.Input.IAsyncDataTransfer) @@ -3985,6 +4405,18 @@ baseline/Avalonia/lib/net10.0/Avalonia.Base.dll current/Avalonia/lib/net10.0/Avalonia.Base.dll + + CP0008 + T:Avalonia.Platform.IDrawingContextLayerImpl + baseline/Avalonia/lib/net10.0/Avalonia.Base.dll + current/Avalonia/lib/net10.0/Avalonia.Base.dll + + + CP0008 + T:Avalonia.Platform.IDrawingContextLayerWithRenderContextAffinityImpl + baseline/Avalonia/lib/net10.0/Avalonia.Base.dll + current/Avalonia/lib/net10.0/Avalonia.Base.dll + CP0008 T:Avalonia.Platform.IPlatformGraphicsContext @@ -4003,6 +4435,12 @@ baseline/Avalonia/lib/net10.0/Avalonia.Base.dll current/Avalonia/lib/net10.0/Avalonia.Base.dll + + CP0008 + T:Avalonia.Platform.IRenderTargetBitmapImpl + baseline/Avalonia/lib/net10.0/Avalonia.Base.dll + current/Avalonia/lib/net10.0/Avalonia.Base.dll + CP0008 T:Avalonia.Platform.IWriteableBitmapImpl @@ -4153,6 +4591,18 @@ baseline/Avalonia/lib/net8.0/Avalonia.Base.dll current/Avalonia/lib/net8.0/Avalonia.Base.dll + + CP0008 + T:Avalonia.Platform.IDrawingContextLayerImpl + baseline/Avalonia/lib/net8.0/Avalonia.Base.dll + current/Avalonia/lib/net8.0/Avalonia.Base.dll + + + CP0008 + T:Avalonia.Platform.IDrawingContextLayerWithRenderContextAffinityImpl + baseline/Avalonia/lib/net8.0/Avalonia.Base.dll + current/Avalonia/lib/net8.0/Avalonia.Base.dll + CP0008 T:Avalonia.Platform.IPlatformGraphicsContext @@ -4171,6 +4621,12 @@ baseline/Avalonia/lib/net8.0/Avalonia.Base.dll current/Avalonia/lib/net8.0/Avalonia.Base.dll + + CP0008 + T:Avalonia.Platform.IRenderTargetBitmapImpl + baseline/Avalonia/lib/net8.0/Avalonia.Base.dll + current/Avalonia/lib/net8.0/Avalonia.Base.dll + CP0008 T:Avalonia.Platform.IWriteableBitmapImpl @@ -4513,4 +4969,4 @@ baseline/Avalonia/lib/netstandard2.0/Avalonia.Base.dll current/Avalonia/lib/netstandard2.0/Avalonia.Base.dll - + \ No newline at end of file diff --git a/src/Android/Avalonia.Android/CursorFactory.cs b/src/Android/Avalonia.Android/CursorFactory.cs index 6293637d4e..e60524c2b7 100644 --- a/src/Android/Avalonia.Android/CursorFactory.cs +++ b/src/Android/Avalonia.Android/CursorFactory.cs @@ -5,7 +5,7 @@ namespace Avalonia.Android { internal class CursorFactory : ICursorFactory { - public ICursorImpl CreateCursor(IBitmapImpl cursor, PixelPoint hotSpot) => CursorImpl.ZeroCursor; + public ICursorImpl CreateCursor(Avalonia.Media.Imaging.Bitmap cursor, PixelPoint hotSpot) => CursorImpl.ZeroCursor; public ICursorImpl GetCursor(StandardCursorType cursorType) => CursorImpl.ZeroCursor; diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/FramebufferManager.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/FramebufferManager.cs index e096d32f48..596f09fda3 100644 --- a/src/Android/Avalonia.Android/Platform/SkiaPlatform/FramebufferManager.cs +++ b/src/Android/Avalonia.Android/Platform/SkiaPlatform/FramebufferManager.cs @@ -1,5 +1,5 @@ using System; -using Avalonia.Controls.Platform.Surfaces; +using Avalonia.Platform.Surfaces; using Avalonia.Platform; namespace Avalonia.Android.Platform.SkiaPlatform diff --git a/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs b/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs index b11d35d1ef..20284906be 100644 --- a/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs +++ b/src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs @@ -18,6 +18,7 @@ using Avalonia.Input.Raw; using Avalonia.Input.TextInput; using Avalonia.OpenGL.Egl; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using Avalonia.Platform.Storage; using Avalonia.Rendering.Composition; using Java.Lang; @@ -96,7 +97,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform public double DesktopScaling => RenderScaling; public IPlatformHandle Handle { get; } - public IEnumerable Surfaces { get; } + public IPlatformRenderSurface[] Surfaces { get; } public Compositor Compositor => AndroidPlatform.Compositor ?? throw new InvalidOperationException("Android backend wasn't initialized. Make sure .UseAndroid() was executed."); diff --git a/src/Android/Avalonia.Android/Platform/Vulkan/VulkanSupport.cs b/src/Android/Avalonia.Android/Platform/Vulkan/VulkanSupport.cs index c1abaa05a5..d8e17e4330 100644 --- a/src/Android/Avalonia.Android/Platform/Vulkan/VulkanSupport.cs +++ b/src/Android/Avalonia.Android/Platform/Vulkan/VulkanSupport.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Runtime.InteropServices; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using Avalonia.Vulkan; namespace Avalonia.Android.Platform.Vulkan @@ -24,10 +25,10 @@ namespace Avalonia.Android.Platform.Vulkan internal class VulkanSurfaceFactory : IVulkanKhrSurfacePlatformSurfaceFactory { - public bool CanRenderToSurface(IVulkanPlatformGraphicsContext context, object surface) => + public bool CanRenderToSurface(IVulkanPlatformGraphicsContext context, IPlatformRenderSurface surface) => surface is INativePlatformHandleSurface handle; - public IVulkanKhrSurfacePlatformSurface CreateSurface(IVulkanPlatformGraphicsContext context, object handle) => + public IVulkanKhrSurfacePlatformSurface CreateSurface(IVulkanPlatformGraphicsContext context, IPlatformRenderSurface handle) => new AndroidVulkanSurface((INativePlatformHandleSurface)handle); } diff --git a/src/Avalonia.Base/Input/Cursor.cs b/src/Avalonia.Base/Input/Cursor.cs index 2de2f12aff..21726898b5 100644 --- a/src/Avalonia.Base/Input/Cursor.cs +++ b/src/Avalonia.Base/Input/Cursor.cs @@ -56,7 +56,7 @@ namespace Avalonia.Input } public Cursor(Bitmap cursor, PixelPoint hotSpot) - : this(GetCursorFactory().CreateCursor(cursor.PlatformImpl.Item, hotSpot), "BitmapCursor") + : this(GetCursorFactory().CreateCursor(cursor, hotSpot), "BitmapCursor") { } diff --git a/src/Avalonia.Base/Media/Imaging/Bitmap.cs b/src/Avalonia.Base/Media/Imaging/Bitmap.cs index 63ec02737f..dc1541414b 100644 --- a/src/Avalonia.Base/Media/Imaging/Bitmap.cs +++ b/src/Avalonia.Base/Media/Imaging/Bitmap.cs @@ -178,12 +178,8 @@ namespace Avalonia.Media.Imaging public virtual AlphaFormat? AlphaFormat => (PlatformImpl.Item as IReadableBitmapImpl)?.AlphaFormat; - private protected unsafe void CopyPixelsCore(PixelRect sourceRect, IntPtr buffer, int bufferSize, int stride, - ILockedFramebuffer fb) + private PixelRect ValidateSourceRect(PixelRect sourceRect) { - if (Format == null) - throw new NotSupportedException("CopyPixels is not supported for this bitmap type"); - if ((sourceRect.Width <= 0 || sourceRect.Height <= 0) && (sourceRect.X != 0 || sourceRect.Y != 0)) throw new ArgumentOutOfRangeException(nameof(sourceRect)); @@ -197,6 +193,16 @@ namespace Avalonia.Media.Imaging if (sourceRect.Right > PixelSize.Width || sourceRect.Bottom > PixelSize.Height) throw new ArgumentOutOfRangeException(nameof(sourceRect)); + return sourceRect; + } + + private protected unsafe void CopyPixelsCore(PixelRect sourceRect, IntPtr buffer, int bufferSize, int stride, + ILockedFramebuffer fb) + { + if (Format == null) + throw new NotSupportedException("CopyPixels is not supported for this bitmap type"); + + sourceRect = ValidateSourceRect(sourceRect); int minStride = checked(((sourceRect.Width * fb.Format.BitsPerPixel) + 7) / 8); if (stride < minStride) @@ -223,8 +229,10 @@ namespace Avalonia.Media.Imaging || PlatformImpl.Item is not IReadableBitmapImpl readable || Format != readable.Format ) + { throw new NotSupportedException("CopyPixels is not supported for this bitmap type"); - + } + if (_isTranscoded) throw new NotSupportedException("CopyPixels is not supported for transcoded bitmaps"); @@ -241,7 +249,13 @@ namespace Avalonia.Media.Imaging { if (PlatformImpl.Item is not IReadableBitmapImpl readable || readable.Format == null || readable.AlphaFormat == null) { - throw new NotSupportedException("CopyPixels is not supported for this bitmap type"); + // Since we can't read pixels from the bitmap, we need to render it to a compatible bitmap and read pixels from it. + using var rtb = new RenderTargetBitmap(PixelSize); + using (var ctx = rtb.CreateDrawingContext()) + ctx.DrawImage(this, new Rect(rtb.Size)); + rtb.CopyPixels(buffer); + + return; } if (buffer.Format != readable.Format || buffer.AlphaFormat != readable.AlphaFormat) diff --git a/src/Avalonia.Base/Media/Imaging/RenderTargetBitmap.cs b/src/Avalonia.Base/Media/Imaging/RenderTargetBitmap.cs index 26229b5ecb..98f90c7768 100644 --- a/src/Avalonia.Base/Media/Imaging/RenderTargetBitmap.cs +++ b/src/Avalonia.Base/Media/Imaging/RenderTargetBitmap.cs @@ -77,7 +77,7 @@ namespace Avalonia.Media.Imaging /// The drawing context. public DrawingContext CreateDrawingContext(bool clear) { - var platform = PlatformImpl.Item.CreateDrawingContext(true); + var platform = PlatformImpl.Item.CreateDrawingContext(); if(clear) platform.Clear(Colors.Transparent); return new PlatformDrawingContext(platform); diff --git a/src/Avalonia.Base/Platform/ICursorFactory.cs b/src/Avalonia.Base/Platform/ICursorFactory.cs index 99a9a9d7fa..82f54a7b71 100644 --- a/src/Avalonia.Base/Platform/ICursorFactory.cs +++ b/src/Avalonia.Base/Platform/ICursorFactory.cs @@ -1,4 +1,5 @@ using Avalonia.Input; +using Avalonia.Media.Imaging; using Avalonia.Metadata; #nullable enable @@ -9,6 +10,6 @@ namespace Avalonia.Platform public interface ICursorFactory { ICursorImpl GetCursor(StandardCursorType cursorType); - ICursorImpl CreateCursor(IBitmapImpl cursor, PixelPoint hotSpot); + ICursorImpl CreateCursor(Bitmap cursor, PixelPoint hotSpot); } } diff --git a/src/Avalonia.Base/Platform/IDrawingContextImpl.cs b/src/Avalonia.Base/Platform/IDrawingContextImpl.cs index 848620dae2..54310eefa6 100644 --- a/src/Avalonia.Base/Platform/IDrawingContextImpl.cs +++ b/src/Avalonia.Base/Platform/IDrawingContextImpl.cs @@ -228,7 +228,7 @@ namespace Avalonia.Platform (T?)context.GetFeature(typeof(T)); } - public interface IDrawingContextLayerImpl : IRenderTargetBitmapImpl + public interface IDrawingContextLayerImpl : IBitmapImpl { /// /// Does optimized blit with Src blend mode. @@ -240,6 +240,16 @@ namespace Avalonia.Platform /// Returns true if layer supports optimized blit. /// bool CanBlit { get; } + + /// + /// Indicates if the render target is no longer usable and needs to be recreated + /// + bool IsCorrupted { get; } + + /// + /// Creates drawing context. It matches the properties of the original drawing context this layer was created from. + /// + IDrawingContextImpl CreateDrawingContext(); } public interface IDrawingContextLayerWithRenderContextAffinityImpl : IDrawingContextLayerImpl diff --git a/src/Avalonia.Base/Platform/IPlatformRenderInterface.cs b/src/Avalonia.Base/Platform/IPlatformRenderInterface.cs index 3a42a88aed..bffc00235b 100644 --- a/src/Avalonia.Base/Platform/IPlatformRenderInterface.cs +++ b/src/Avalonia.Base/Platform/IPlatformRenderInterface.cs @@ -5,6 +5,7 @@ using Avalonia.Media; using Avalonia.Media.Imaging; using Avalonia.Media.TextFormatting; using Avalonia.Metadata; +using Avalonia.Platform.Surfaces; namespace Avalonia.Platform { @@ -214,7 +215,7 @@ namespace Avalonia.Platform /// The list of native platform surfaces that can be used for output. /// /// An . - IRenderTarget CreateRenderTarget(IEnumerable surfaces); + IRenderTarget CreateRenderTarget(IEnumerable surfaces); /// /// Creates an offscreen render target @@ -239,5 +240,10 @@ namespace Avalonia.Platform /// Maximum supported offscreen render target pixel size, or null if no limit /// public PixelSize? MaxOffscreenRenderTargetPixelSize { get; } + + /// + /// Checks if a render target can be created for the given surfaces and the preferred surface is ready + /// + bool IsReadyToCreateRenderTarget(IEnumerable surfaces) => true; } } diff --git a/src/Avalonia.Base/Platform/IRenderTarget.cs b/src/Avalonia.Base/Platform/IRenderTarget.cs index a31e7e550a..e66d14995e 100644 --- a/src/Avalonia.Base/Platform/IRenderTarget.cs +++ b/src/Avalonia.Base/Platform/IRenderTarget.cs @@ -25,16 +25,18 @@ namespace Avalonia.Platform /// /// Creates an for a rendering session. /// - /// Apply DPI reported by the render target as a hidden transform matrix - IDrawingContextImpl CreateDrawingContext(bool useScaledDrawing); + /// Information about the scene that's about to be rendered into this render target. + /// This is expected to be reported to the underlying platform and affect the framebuffer size, however + /// the implementation may choose to ignore that information. + /// + /// Returns various properties about the returned drawing context + IDrawingContextImpl CreateDrawingContext(RenderTargetSceneInfo sceneInfo, out RenderTargetDrawingContextProperties properties); /// - /// Creates an for a rendering session. + /// Indicates if the render target is currently ready to be rendered to /// - /// The pixel size of the surface - /// Returns various properties about the returned drawing context - IDrawingContextImpl CreateDrawingContext( - PixelSize expectedPixelSize, - out RenderTargetDrawingContextProperties properties); + bool IsReady => true; + + public record struct RenderTargetSceneInfo(PixelSize Size, double Scaling); } } diff --git a/src/Avalonia.Base/Platform/IRenderTargetBitmapImpl.cs b/src/Avalonia.Base/Platform/IRenderTargetBitmapImpl.cs index d33c503650..aab734c7c9 100644 --- a/src/Avalonia.Base/Platform/IRenderTargetBitmapImpl.cs +++ b/src/Avalonia.Base/Platform/IRenderTargetBitmapImpl.cs @@ -7,7 +7,8 @@ namespace Avalonia.Platform /// . /// [Unstable] - public interface IRenderTargetBitmapImpl : IBitmapImpl, IRenderTarget + public interface IRenderTargetBitmapImpl : IReadableBitmapImpl { + IDrawingContextImpl CreateDrawingContext(); } } diff --git a/src/Avalonia.Base/Platform/Surfaces/IFramebufferPlatformSurface.cs b/src/Avalonia.Base/Platform/Surfaces/IFramebufferPlatformSurface.cs new file mode 100644 index 0000000000..794e2cc229 --- /dev/null +++ b/src/Avalonia.Base/Platform/Surfaces/IFramebufferPlatformSurface.cs @@ -0,0 +1,66 @@ +using System; +using Avalonia.Metadata; + +namespace Avalonia.Platform.Surfaces +{ + [Unstable] + public interface IFramebufferPlatformSurface : IPlatformRenderSurface + { + IFramebufferRenderTarget CreateFramebufferRenderTarget(); + } + + + [PrivateApi] + public interface IFramebufferRenderTarget : IDisposable, IPlatformRenderSurfaceRenderTarget + { + /// + /// Provides a framebuffer descriptor for drawing. + /// + /// + /// Contents should be drawn on actual window after disposing + /// + ILockedFramebuffer Lock(IRenderTarget.RenderTargetSceneInfo sceneInfo, out FramebufferLockProperties properties); + + bool RetainsFrameContents => false; + } + + [PrivateApi] + public record struct FramebufferLockProperties(bool PreviousFrameIsRetained); + + /// + /// For simple cases when framebuffer is always available + /// + public class FuncFramebufferRenderTarget : IFramebufferRenderTarget + { + public delegate ILockedFramebuffer LockFramebufferDelegate(IRenderTarget.RenderTargetSceneInfo sceneInfo, out FramebufferLockProperties properties); + private readonly LockFramebufferDelegate _lockFramebuffer; + + public FuncFramebufferRenderTarget(Func lockFramebuffer) : + this((_, out properties) => + { + properties = default; + return lockFramebuffer(); + }) + { + + } + + + public FuncFramebufferRenderTarget(LockFramebufferDelegate lockFramebuffer, bool retainsFrameContents = false) + { + _lockFramebuffer = lockFramebuffer; + RetainsFrameContents = retainsFrameContents; + } + + public void Dispose() + { + // No-op + } + + public ILockedFramebuffer Lock(IRenderTarget.RenderTargetSceneInfo sceneInfo, + out FramebufferLockProperties properties) => _lockFramebuffer(sceneInfo, out properties); + + public bool RetainsFrameContents { get; } + } + +} diff --git a/src/Avalonia.Base/Platform/Surfaces/IPlatformRenderSurface.cs b/src/Avalonia.Base/Platform/Surfaces/IPlatformRenderSurface.cs new file mode 100644 index 0000000000..ff71a700c4 --- /dev/null +++ b/src/Avalonia.Base/Platform/Surfaces/IPlatformRenderSurface.cs @@ -0,0 +1,15 @@ +using Avalonia.Metadata; + +namespace Avalonia.Platform.Surfaces; + +[PrivateApi] +public interface IPlatformRenderSurface +{ + bool IsReady => true; +} + +[PrivateApi] +public interface IPlatformRenderSurfaceRenderTarget +{ + bool IsReady => true; +} diff --git a/src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs b/src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs index 66ee5579c8..1bff835f17 100644 --- a/src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs +++ b/src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs @@ -8,6 +8,8 @@ using System.Threading.Tasks; using Avalonia.Collections; using Avalonia.Collections.Pooled; using Avalonia.Diagnostics; +using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using Avalonia.Media; using Avalonia.Rendering.Composition.Drawing; using Avalonia.Threading; @@ -48,7 +50,7 @@ internal class CompositingRenderer : IRendererWithCompositor, IHitTester /// /// A function returning the list of native platform's surfaces that can be consumed by rendering subsystems. /// - public CompositingRenderer(IPresentationSource root, Compositor compositor, Func> surfaces) + public CompositingRenderer(IPresentationSource root, Compositor compositor, Func> surfaces) { _root = root; _compositor = compositor; diff --git a/src/Avalonia.Base/Rendering/Composition/Compositor.Factories.cs b/src/Avalonia.Base/Rendering/Composition/Compositor.Factories.cs index 52c34cbc41..b1ff53e5c8 100644 --- a/src/Avalonia.Base/Rendering/Composition/Compositor.Factories.cs +++ b/src/Avalonia.Base/Rendering/Composition/Compositor.Factories.cs @@ -1,5 +1,7 @@ using System; using System.Collections.Generic; +using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using Avalonia.Rendering.Composition.Animations; using Avalonia.Rendering.Composition.Server; @@ -12,7 +14,7 @@ public partial class Compositor /// /// A factory method to create IRenderTarget to be called from the render thread /// - internal CompositionTarget CreateCompositionTarget(Func> surfaces) + internal CompositionTarget CreateCompositionTarget(Func> surfaces) { return new CompositionTarget(this, new ServerCompositionTarget(_server, surfaces)); } diff --git a/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionTarget.cs b/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionTarget.cs index 0c8656604a..f8382547b9 100644 --- a/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionTarget.cs +++ b/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionTarget.cs @@ -8,6 +8,7 @@ using Avalonia.Media; using Avalonia.Media.Imaging; using Avalonia.Media.Immutable; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using Avalonia.Rendering.Composition.Transport; using Avalonia.Utilities; @@ -20,7 +21,7 @@ namespace Avalonia.Rendering.Composition.Server internal partial class ServerCompositionTarget : IDisposable { private readonly ServerCompositor _compositor; - private readonly Func> _surfaces; + private readonly Func> _surfaces; private CompositionTargetOverlays _overlays; private static long s_nextId = 1; private IRenderTarget? _renderTarget; @@ -39,7 +40,7 @@ namespace Avalonia.Rendering.Composition.Server public int RenderedVisuals { get; set; } public int VisitedVisuals { get; set; } - public ServerCompositionTarget(ServerCompositor compositor, Func> surfaces) + public ServerCompositionTarget(ServerCompositor compositor, Func> surfaces) : base(compositor) { _compositor = compositor; @@ -141,6 +142,8 @@ namespace Avalonia.Rendering.Composition.Server try { + if (_renderTarget == null && !_compositor.IsReadyToCreateRenderTarget(_surfaces())) + return; _renderTarget ??= _compositor.CreateRenderTarget(_surfaces()); } catch (RenderTargetNotReadyException) @@ -160,13 +163,15 @@ namespace Avalonia.Rendering.Composition.Server if (!_redrawRequested) return; + if (!_renderTarget.IsReady) + return; + var needLayer = _overlays.RequireLayer // Check if we don't need overlays // Check if render target can be rendered to directly and preserves the previous frame || !(_renderTarget.Properties.RetainsPreviousFrameContents && _renderTarget.Properties.IsSuitableForDirectRendering); - using (var renderTargetContext = _renderTarget.CreateDrawingContext( - this.PixelSize, out var properties)) + using (var renderTargetContext = _renderTarget.CreateDrawingContext(new(PixelSize, Scaling), out var properties)) using (var renderTiming = Diagnostic.BeginCompositorRenderPass()) { var fullRedraw = false; @@ -203,7 +208,7 @@ namespace Avalonia.Rendering.Composition.Server DirtyRects.FinalizeFrame(renderBounds); if (_layer != null) { - using (var context = _layer.CreateDrawingContext(false)) + using (var context = _layer.CreateDrawingContext()) RenderRootToContextWithClip(context, Root); renderTargetContext.Clear(Colors.Transparent); diff --git a/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual/ServerCompositionVisualCache.cs b/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual/ServerCompositionVisualCache.cs index a9a481b5e3..973ac8a834 100644 --- a/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual/ServerCompositionVisualCache.cs +++ b/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual/ServerCompositionVisualCache.cs @@ -193,7 +193,7 @@ internal class ServerCompositionVisualCache // Render to layer if needed if (!_dirtyRectTracker.IsEmpty) { - using var ctx = _layer.CreateDrawingContext(false); + using var ctx = _layer.CreateDrawingContext(); using (_needsFullReRender ? null : _dirtyRectTracker.BeginDraw(ctx)) { ctx.Clear(Colors.Transparent); diff --git a/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositor.UserApis.cs b/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositor.UserApis.cs index d299bed384..e440ffab26 100644 --- a/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositor.UserApis.cs +++ b/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositor.UserApis.cs @@ -62,7 +62,7 @@ internal partial class ServerCompositor try { target = RenderInterface.Value.CreateOffscreenRenderTarget(pixelSize, new(scaling, scaling), true); - using (var canvas = target.CreateDrawingContext(false)) + using (var canvas = target.CreateDrawingContext()) { canvas.Transform = scaleTransform; visual.Render(canvas, LtrbRect.Infinite, null, renderChildren); diff --git a/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositor.cs b/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositor.cs index e23197ff13..76e649407f 100644 --- a/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositor.cs +++ b/src/Avalonia.Base/Rendering/Composition/Server/ServerCompositor.cs @@ -4,6 +4,7 @@ using System.Diagnostics; using System.Threading; using Avalonia.Logging; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using Avalonia.Rendering.Composition.Animations; using Avalonia.Rendering.Composition.Expressions; using Avalonia.Rendering.Composition.Transport; @@ -274,12 +275,17 @@ namespace Avalonia.Rendering.Composition.Server _activeTargets.Remove(target); } - public IRenderTarget CreateRenderTarget(IEnumerable surfaces) + public IRenderTarget CreateRenderTarget(IEnumerable surfaces) { using (RenderInterface.EnsureCurrent()) return RenderInterface.CreateRenderTarget(surfaces); } + public bool IsReadyToCreateRenderTarget(IEnumerable surfaces) + { + return RenderInterface.IsReadyToCreateRenderTarget(surfaces); + } + public bool CheckAccess() => _safeThread == Thread.CurrentThread; public void VerifyAccess() { diff --git a/src/Avalonia.Base/Rendering/PlatformRenderInterfaceContextManager.cs b/src/Avalonia.Base/Rendering/PlatformRenderInterfaceContextManager.cs index db61ad84f1..980c7818c7 100644 --- a/src/Avalonia.Base/Rendering/PlatformRenderInterfaceContextManager.cs +++ b/src/Avalonia.Base/Rendering/PlatformRenderInterfaceContextManager.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using Avalonia.Metadata; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using Avalonia.Reactive; namespace Avalonia.Rendering; @@ -77,9 +78,16 @@ internal class PlatformRenderInterfaceContextManager return Disposable.Empty; } - public IRenderTarget CreateRenderTarget(IEnumerable surfaces) + public IRenderTarget CreateRenderTarget(IEnumerable surfaces) { EnsureValidBackendContext(); return _backend!.CreateRenderTarget(surfaces); } + + public bool IsReadyToCreateRenderTarget(IEnumerable surfaces) + { + if (_backend == null) + return IsReady; + return _backend.IsReadyToCreateRenderTarget(surfaces); + } } diff --git a/src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevelImpl.cs b/src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevelImpl.cs index bdc7c8894b..27f927a3c4 100644 --- a/src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevelImpl.cs +++ b/src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevelImpl.cs @@ -4,6 +4,7 @@ using Avalonia.Input; using Avalonia.Input.Raw; using Avalonia.Metadata; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using Avalonia.Rendering.Composition; namespace Avalonia.Controls.Embedding.Offscreen @@ -27,7 +28,7 @@ namespace Avalonia.Controls.Embedding.Offscreen public OffscreenTopLevelImplBase() => Compositor = new Compositor(null); - public abstract IEnumerable Surfaces { get; } + public abstract IPlatformRenderSurface[] Surfaces { get; } public virtual double DesktopScaling => _scaling; diff --git a/src/Avalonia.Controls/Platform/IPlatformNativeSurfaceHandle.cs b/src/Avalonia.Controls/Platform/IPlatformNativeSurfaceHandle.cs index 068ee39e84..aaa534138c 100644 --- a/src/Avalonia.Controls/Platform/IPlatformNativeSurfaceHandle.cs +++ b/src/Avalonia.Controls/Platform/IPlatformNativeSurfaceHandle.cs @@ -1,10 +1,11 @@ using System; +using Avalonia.Platform.Surfaces; using Avalonia.Metadata; namespace Avalonia.Platform { [Unstable] - public interface INativePlatformHandleSurface : IPlatformHandle + public interface INativePlatformHandleSurface : IPlatformHandle, IPlatformRenderSurface { PixelSize Size { get; } double Scaling { get; } diff --git a/src/Avalonia.Controls/Platform/ITopLevelImpl.cs b/src/Avalonia.Controls/Platform/ITopLevelImpl.cs index 9b847d71d3..bab5e4ffe9 100644 --- a/src/Avalonia.Controls/Platform/ITopLevelImpl.cs +++ b/src/Avalonia.Controls/Platform/ITopLevelImpl.cs @@ -4,6 +4,7 @@ using Avalonia.Controls; using Avalonia.Input; using Avalonia.Input.Raw; using Avalonia.Metadata; +using Avalonia.Platform.Surfaces; using Avalonia.Rendering.Composition; namespace Avalonia.Platform @@ -48,7 +49,7 @@ namespace Avalonia.Platform /// If you have some rendering platform that's tied to your particular windowing platform, /// just expose some toolkit-specific object (e. g. Func<Gdk.Drawable> in case of GTK#+Cairo) /// - IEnumerable Surfaces { get; } + IPlatformRenderSurface[] Surfaces { get; } /// /// Gets or sets a method called when the toplevel receives input. diff --git a/src/Avalonia.Controls/Platform/Surfaces/IFramebufferPlatformSurface.cs b/src/Avalonia.Controls/Platform/Surfaces/IFramebufferPlatformSurface.cs deleted file mode 100644 index a717bfcd22..0000000000 --- a/src/Avalonia.Controls/Platform/Surfaces/IFramebufferPlatformSurface.cs +++ /dev/null @@ -1,86 +0,0 @@ -using System; -using Avalonia.Metadata; -using Avalonia.Platform; - -namespace Avalonia.Controls.Platform.Surfaces -{ - [Unstable] - public interface IFramebufferPlatformSurface - { - IFramebufferRenderTarget CreateFramebufferRenderTarget(); - } - - [Unstable] - public interface IFramebufferRenderTarget : IDisposable - { - /// - /// Provides a framebuffer descriptor for drawing. - /// - /// - /// Contents should be drawn on actual window after disposing - /// - ILockedFramebuffer Lock(); - } - - [PrivateApi] - public interface IFramebufferRenderTargetWithProperties : IFramebufferRenderTarget - { - /// - /// Provides a framebuffer descriptor for drawing. - /// - /// - /// Contents should be drawn on actual window after disposing - /// - ILockedFramebuffer Lock(out FramebufferLockProperties properties); - - bool RetainsFrameContents { get; } - } - - [PrivateApi] - public record struct FramebufferLockProperties(bool PreviousFrameIsRetained); - - /// - /// For simple cases when framebuffer is always available - /// - public class FuncFramebufferRenderTarget : IFramebufferRenderTarget - { - private readonly Func _lockFramebuffer; - - public FuncFramebufferRenderTarget(Func lockFramebuffer) - { - _lockFramebuffer = lockFramebuffer; - } - - public void Dispose() - { - // No-op - } - - public ILockedFramebuffer Lock() => _lockFramebuffer(); - } - - internal class FuncRetainedFramebufferRenderTarget : IFramebufferRenderTargetWithProperties - { - public delegate ILockedFramebuffer LockDelegate(out FramebufferLockProperties properties); - private readonly LockDelegate _lockFramebuffer; - - public FuncRetainedFramebufferRenderTarget(LockDelegate lockFramebuffer) - { - _lockFramebuffer = lockFramebuffer; - } - - public void Dispose() - { - // No-op - } - - public ILockedFramebuffer Lock() => _lockFramebuffer(out _); - - public ILockedFramebuffer Lock(out FramebufferLockProperties properties) - { - return _lockFramebuffer(out properties); - } - - public bool RetainsFrameContents => true; - } -} diff --git a/src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.cs b/src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.cs index 5712ad5564..486d401c80 100644 --- a/src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.cs +++ b/src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.cs @@ -1,12 +1,12 @@ using System; using System.Collections.Generic; using Avalonia.Controls.Embedding.Offscreen; -using Avalonia.Controls.Platform.Surfaces; using Avalonia.Input; using Avalonia.Input.Raw; using Avalonia.Layout; using Avalonia.Metadata; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using Avalonia.Remote.Protocol; using Avalonia.Remote.Protocol.Input; using Avalonia.Remote.Protocol.Viewport; @@ -270,7 +270,7 @@ namespace Avalonia.Controls.Remote.Server return l.DesiredSize; } - public override IEnumerable Surfaces => new[] { this }; + public override IPlatformRenderSurface[] Surfaces => [this]; private Framebuffer GetOrCreateFramebuffer() { diff --git a/src/Avalonia.DesignerSupport/Remote/Stubs.cs b/src/Avalonia.DesignerSupport/Remote/Stubs.cs index 706cd7de75..d13d442e09 100644 --- a/src/Avalonia.DesignerSupport/Remote/Stubs.cs +++ b/src/Avalonia.DesignerSupport/Remote/Stubs.cs @@ -10,7 +10,9 @@ using Avalonia.Controls.Primitives.PopupPositioning; using Avalonia.Input; using Avalonia.Input.Platform; using Avalonia.Input.Raw; +using Avalonia.Media.Imaging; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using Avalonia.Platform.Storage; using Avalonia.Platform.Storage.FileIO; using Avalonia.Rendering; @@ -28,7 +30,7 @@ namespace Avalonia.DesignerSupport.Remote public Size? FrameSize => null; public double RenderScaling { get; } = 1.0; public double DesktopScaling => 1.0; - public IEnumerable Surfaces => []; + public IPlatformRenderSurface[] Surfaces => []; public Action? Input { get; set; } public Action? Paint { get; set; } public Action? Resized { get; set; } @@ -235,7 +237,7 @@ namespace Avalonia.DesignerSupport.Remote class CursorFactoryStub : ICursorFactory { public ICursorImpl GetCursor(StandardCursorType cursorType) => new CursorStub(); - public ICursorImpl CreateCursor(IBitmapImpl cursor, PixelPoint hotSpot) => new CursorStub(); + public ICursorImpl CreateCursor(Bitmap cursor, PixelPoint hotSpot) => new CursorStub(); private class CursorStub : ICursorImpl { diff --git a/src/Avalonia.Metal/IMetalDevice.cs b/src/Avalonia.Metal/IMetalDevice.cs index 0910e6aa17..aebfca4a58 100644 --- a/src/Avalonia.Metal/IMetalDevice.cs +++ b/src/Avalonia.Metal/IMetalDevice.cs @@ -1,6 +1,7 @@ using System; using Avalonia.Metadata; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; namespace Avalonia.Metal; @@ -13,13 +14,13 @@ public interface IMetalDevice : IPlatformGraphicsContext } [PrivateApi] -public interface IMetalPlatformSurface +public interface IMetalPlatformSurface : IPlatformRenderSurface { IMetalPlatformSurfaceRenderTarget CreateMetalRenderTarget(IMetalDevice device); } [PrivateApi] -public interface IMetalPlatformSurfaceRenderTarget : IDisposable +public interface IMetalPlatformSurfaceRenderTarget : IDisposable, IPlatformRenderSurfaceRenderTarget { IMetalPlatformSurfaceRenderingSession BeginRendering(); } diff --git a/src/Avalonia.Native/AvaloniaNativeGlPlatformGraphics.cs b/src/Avalonia.Native/AvaloniaNativeGlPlatformGraphics.cs index fdf80bdc18..91e4dd2680 100644 --- a/src/Avalonia.Native/AvaloniaNativeGlPlatformGraphics.cs +++ b/src/Avalonia.Native/AvaloniaNativeGlPlatformGraphics.cs @@ -175,7 +175,7 @@ namespace Avalonia.Native public bool IsCorrupted => false; - public IGlPlatformSurfaceRenderingSession BeginDraw(PixelSize? expectedPixelSize) + public IGlPlatformSurfaceRenderingSession BeginDraw(IRenderTarget.RenderTargetSceneInfo sceneInfo) { // TODO: use expectedPixelSize ObjectDisposedException.ThrowIf(_target is null, this); diff --git a/src/Avalonia.Native/Cursor.cs b/src/Avalonia.Native/Cursor.cs index 4ffd6a108d..58306b5698 100644 --- a/src/Avalonia.Native/Cursor.cs +++ b/src/Avalonia.Native/Cursor.cs @@ -1,6 +1,7 @@ using System; using System.IO; using Avalonia.Input; +using Avalonia.Media.Imaging; using Avalonia.Platform; using Avalonia.Native.Interop; @@ -40,7 +41,7 @@ namespace Avalonia.Native return new AvaloniaNativeCursor( cursor ); } - public unsafe ICursorImpl CreateCursor(IBitmapImpl cursor, PixelPoint hotSpot) + public unsafe ICursorImpl CreateCursor(Bitmap cursor, PixelPoint hotSpot) { using(var ms = new MemoryStream()) { diff --git a/src/Avalonia.Native/DeferredFramebuffer.cs b/src/Avalonia.Native/DeferredFramebuffer.cs index a352fc2e8b..18376dfe60 100644 --- a/src/Avalonia.Native/DeferredFramebuffer.cs +++ b/src/Avalonia.Native/DeferredFramebuffer.cs @@ -1,6 +1,5 @@ using System; using System.Runtime.InteropServices; -using Avalonia.Controls.Platform.Surfaces; using Avalonia.Native.Interop; using Avalonia.Platform; diff --git a/src/Avalonia.Native/TopLevelImpl.cs b/src/Avalonia.Native/TopLevelImpl.cs index 925c00c3dd..04e1318da8 100644 --- a/src/Avalonia.Native/TopLevelImpl.cs +++ b/src/Avalonia.Native/TopLevelImpl.cs @@ -4,13 +4,13 @@ using System.Runtime.InteropServices; using Avalonia.Automation.Peers; using Avalonia.Controls; using Avalonia.Controls.Platform; -using Avalonia.Controls.Platform.Surfaces; using Avalonia.Input; using Avalonia.Input.Platform; using Avalonia.Input.Raw; using Avalonia.Input.TextInput; using Avalonia.Native.Interop; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using Avalonia.Platform.Storage; using Avalonia.Platform.Storage.FileIO; using Avalonia.Rendering.Composition; @@ -80,7 +80,7 @@ internal class TopLevelImpl : ITopLevelImpl, IFramebufferPlatformSurface protected MacOSTopLevelHandle? _handle; private object _syncRoot = new object(); - private IEnumerable? _surfaces; + private IPlatformRenderSurface[]? _surfaces; public TopLevelImpl(IAvaloniaNativeFactory factory) { @@ -99,7 +99,7 @@ internal class TopLevelImpl : ITopLevelImpl, IFramebufferPlatformSurface _savedScaling = Native?.Scaling ?? 1; _nativeControlHost = new NativeControlHostImpl(Native!.CreateNativeControlHost()); _platformBehaviorInhibition = new PlatformBehaviorInhibition(Factory.CreatePlatformBehaviorInhibition()); - _surfaces = new object[] { new GlPlatformSurface(Native), new MetalPlatformSurface(Native), this }; + _surfaces = [new GlPlatformSurface(Native), new MetalPlatformSurface(Native), this]; InputMethod = new AvaloniaNativeTextInputMethod(Native); } @@ -134,7 +134,7 @@ internal class TopLevelImpl : ITopLevelImpl, IFramebufferPlatformSurface } public double RenderScaling => _savedScaling; - public IEnumerable Surfaces => _surfaces ?? Array.Empty(); + public IPlatformRenderSurface[] Surfaces => _surfaces ?? []; public Action? Input { get; set; } public Action? Paint { get; set; } public Action? Resized { get; set; } @@ -562,10 +562,11 @@ internal class TopLevelImpl : ITopLevelImpl, IFramebufferPlatformSurface } } - public ILockedFramebuffer Lock() + + public ILockedFramebuffer Lock(IRenderTarget.RenderTargetSceneInfo sceneInfo, out FramebufferLockProperties properties) { ObjectDisposedException.ThrowIf(_target is null, this); - + properties = default; var w = Math.Max(_parent._savedLogicalSize.Width * _parent._savedScaling, 1); var h = Math.Max(_parent._savedLogicalSize.Height * _parent._savedScaling, 1); var dpi = _parent._savedScaling * 96; @@ -580,5 +581,7 @@ internal class TopLevelImpl : ITopLevelImpl, IFramebufferPlatformSurface } }, (int)w, (int)h, new Vector(dpi, dpi)); } + + public bool RetainsFrameContents => false; } } diff --git a/src/Avalonia.OpenGL/Egl/EglGlPlatformSurface.cs b/src/Avalonia.OpenGL/Egl/EglGlPlatformSurface.cs index 0565dfee88..10d1746086 100644 --- a/src/Avalonia.OpenGL/Egl/EglGlPlatformSurface.cs +++ b/src/Avalonia.OpenGL/Egl/EglGlPlatformSurface.cs @@ -1,6 +1,7 @@ using System; using Avalonia.Metadata; using Avalonia.OpenGL.Surfaces; +using Avalonia.Platform; namespace Avalonia.OpenGL.Egl { @@ -54,7 +55,7 @@ namespace Avalonia.OpenGL.Egl public override void Dispose() => _glSurface?.Dispose(); - public override IGlPlatformSurfaceRenderingSession BeginDrawCore(PixelSize? expectedPixelSize) + public override IGlPlatformSurfaceRenderingSession BeginDrawCore(IRenderTarget.RenderTargetSceneInfo sceneInfo) { // TODO: use expectedPixelSize if (_info.Size != _currentSize diff --git a/src/Avalonia.OpenGL/Egl/EglGlPlatformSurfaceBase.cs b/src/Avalonia.OpenGL/Egl/EglGlPlatformSurfaceBase.cs index f7cfeecdc2..ef4ae257bd 100644 --- a/src/Avalonia.OpenGL/Egl/EglGlPlatformSurfaceBase.cs +++ b/src/Avalonia.OpenGL/Egl/EglGlPlatformSurfaceBase.cs @@ -1,5 +1,6 @@ using System; using Avalonia.OpenGL.Surfaces; +using Avalonia.Platform; namespace Avalonia.OpenGL.Egl { @@ -22,17 +23,17 @@ namespace Avalonia.OpenGL.Egl } - public IGlPlatformSurfaceRenderingSession BeginDraw(PixelSize? expectedPixelSize) + public IGlPlatformSurfaceRenderingSession BeginDraw(IRenderTarget.RenderTargetSceneInfo sceneInfo) { if (Context.IsLost) throw new RenderTargetCorruptedException(); - return BeginDrawCore(expectedPixelSize); + return BeginDrawCore(sceneInfo); } private protected virtual bool SkipWaits => false; - public abstract IGlPlatformSurfaceRenderingSession BeginDrawCore(PixelSize? expectedPixelSize); + public abstract IGlPlatformSurfaceRenderingSession BeginDrawCore(IRenderTarget.RenderTargetSceneInfo sceneInfo); protected IGlPlatformSurfaceRenderingSession BeginDraw(EglSurface surface, PixelSize size, double scaling, Action? onFinish = null, bool isYFlipped = false) diff --git a/src/Avalonia.OpenGL/IGlContext.cs b/src/Avalonia.OpenGL/IGlContext.cs index 63e766f448..b8869ca97e 100644 --- a/src/Avalonia.OpenGL/IGlContext.cs +++ b/src/Avalonia.OpenGL/IGlContext.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using Avalonia.OpenGL.Surfaces; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; namespace Avalonia.OpenGL { @@ -19,7 +20,7 @@ namespace Avalonia.OpenGL public interface IGlPlatformSurfaceRenderTargetFactory { - bool CanRenderToSurface(IGlContext context, object surface); - IGlPlatformSurfaceRenderTarget CreateRenderTarget(IGlContext context, object surface); + bool CanRenderToSurface(IGlContext context, IPlatformRenderSurface surface); + IGlPlatformSurfaceRenderTarget CreateRenderTarget(IGlContext context, IPlatformRenderSurface surface); } } diff --git a/src/Avalonia.OpenGL/IGlContextExternalObjectsFeature.cs b/src/Avalonia.OpenGL/IGlContextExternalObjectsFeature.cs index 3cf26cf9a3..ab781b6f84 100644 --- a/src/Avalonia.OpenGL/IGlContextExternalObjectsFeature.cs +++ b/src/Avalonia.OpenGL/IGlContextExternalObjectsFeature.cs @@ -6,8 +6,7 @@ using Avalonia.Rendering.Composition; namespace Avalonia.OpenGL; -//TODO12: Make private and expose IBitmapImpl-based import API for composition visuals -[NotClientImplementable] +[PrivateApi] public interface IGlContextExternalObjectsFeature { IReadOnlyList SupportedImportableExternalImageTypes { get; } @@ -26,8 +25,7 @@ public interface IGlContextExternalObjectsFeature public byte[]? DeviceUuid { get; } } -//TODO12: Make private and expose IBitmapImpl-based import API for composition visuals -[NotClientImplementable] +[PrivateApi] public interface IGlExternalSemaphore : IDisposable { void WaitSemaphore(IGlExternalImageTexture texture); @@ -36,12 +34,13 @@ public interface IGlExternalSemaphore : IDisposable void SignalTimelineSemaphore(IGlExternalImageTexture texture, ulong value); } +[PrivateApi] public interface IGlExportableExternalSemaphore : IGlExternalSemaphore { IPlatformHandle GetHandle(); } -[NotClientImplementable] +[PrivateApi] public interface IGlExternalImageTexture : IDisposable { void AcquireKeyedMutex(uint key); @@ -56,6 +55,7 @@ public interface IGlExternalImageTexture : IDisposable PlatformGraphicsExternalImageProperties Properties { get; } } +[PrivateApi] public interface IGlExportableExternalImageTexture : IGlExternalImageTexture { IPlatformHandle GetHandle(); diff --git a/src/Avalonia.OpenGL/Surfaces/IGlPlatformSurface.cs b/src/Avalonia.OpenGL/Surfaces/IGlPlatformSurface.cs index d80e72e4e7..b0a3479c8e 100644 --- a/src/Avalonia.OpenGL/Surfaces/IGlPlatformSurface.cs +++ b/src/Avalonia.OpenGL/Surfaces/IGlPlatformSurface.cs @@ -1,6 +1,8 @@ +using Avalonia.Platform.Surfaces; + namespace Avalonia.OpenGL.Surfaces { - public interface IGlPlatformSurface + public interface IGlPlatformSurface : IPlatformRenderSurface { IGlPlatformSurfaceRenderTarget CreateGlRenderTarget(IGlContext context); } diff --git a/src/Avalonia.OpenGL/Surfaces/IGlPlatformSurfaceRenderTarget.cs b/src/Avalonia.OpenGL/Surfaces/IGlPlatformSurfaceRenderTarget.cs index 436cb4ce03..da35de6649 100644 --- a/src/Avalonia.OpenGL/Surfaces/IGlPlatformSurfaceRenderTarget.cs +++ b/src/Avalonia.OpenGL/Surfaces/IGlPlatformSurfaceRenderTarget.cs @@ -1,11 +1,14 @@ using System; +using Avalonia.Metadata; +using Avalonia.Platform; +using Avalonia.Platform.Surfaces; namespace Avalonia.OpenGL.Surfaces { - public interface IGlPlatformSurfaceRenderTarget : IDisposable + [PrivateApi] + public interface IGlPlatformSurfaceRenderTarget : IDisposable, IPlatformRenderSurfaceRenderTarget { bool IsCorrupted { get; } - - IGlPlatformSurfaceRenderingSession BeginDraw(PixelSize? expectedPixelSize); + IGlPlatformSurfaceRenderingSession BeginDraw(IRenderTarget.RenderTargetSceneInfo sceneInfo); } } diff --git a/src/Avalonia.Vulkan/IVulkanDevice.cs b/src/Avalonia.Vulkan/IVulkanDevice.cs index 66dafac990..846097c39f 100644 --- a/src/Avalonia.Vulkan/IVulkanDevice.cs +++ b/src/Avalonia.Vulkan/IVulkanDevice.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using Avalonia.Metadata; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using Avalonia.Vulkan.UnmanagedInterop; namespace Avalonia.Vulkan; @@ -37,5 +38,5 @@ public interface IVulkanPlatformGraphicsContext : IPlatformGraphicsContext internal VkInstance InstanceHandle { get; } internal VkQueue MainQueueHandle { get; } internal uint GraphicsQueueFamilyIndex { get; } - IVulkanRenderTarget CreateRenderTarget(IEnumerable surfaces); + IVulkanRenderTarget CreateRenderTarget(IEnumerable surfaces); } \ No newline at end of file diff --git a/src/Avalonia.Vulkan/IVulkanPlatformSurface.cs b/src/Avalonia.Vulkan/IVulkanPlatformSurface.cs index 9d34a4da8e..3c281c0bc9 100644 --- a/src/Avalonia.Vulkan/IVulkanPlatformSurface.cs +++ b/src/Avalonia.Vulkan/IVulkanPlatformSurface.cs @@ -1,7 +1,8 @@ using System; +using Avalonia.Platform.Surfaces; namespace Avalonia.Vulkan; -public interface IVulkanKhrSurfacePlatformSurface : IDisposable +public interface IVulkanKhrSurfacePlatformSurface : IDisposable, IPlatformRenderSurface { double Scaling { get; } PixelSize Size { get; } @@ -10,6 +11,6 @@ public interface IVulkanKhrSurfacePlatformSurface : IDisposable public interface IVulkanKhrSurfacePlatformSurfaceFactory { - bool CanRenderToSurface(IVulkanPlatformGraphicsContext context, object surface); - IVulkanKhrSurfacePlatformSurface CreateSurface(IVulkanPlatformGraphicsContext context, object surface); + bool CanRenderToSurface(IVulkanPlatformGraphicsContext context, IPlatformRenderSurface surface); + IVulkanKhrSurfacePlatformSurface CreateSurface(IVulkanPlatformGraphicsContext context, IPlatformRenderSurface surface); } \ No newline at end of file diff --git a/src/Avalonia.Vulkan/IVulkanRenderTarget.cs b/src/Avalonia.Vulkan/IVulkanRenderTarget.cs index 0088ec8867..a63762f4f2 100644 --- a/src/Avalonia.Vulkan/IVulkanRenderTarget.cs +++ b/src/Avalonia.Vulkan/IVulkanRenderTarget.cs @@ -1,10 +1,11 @@ using System; +using Avalonia.Platform.Surfaces; using Avalonia.Metadata; namespace Avalonia.Vulkan; [NotClientImplementable] -public interface IVulkanRenderTarget : IDisposable +public interface IVulkanRenderTarget : IDisposable, IPlatformRenderSurfaceRenderTarget { IVulkanRenderSession BeginDraw(); } diff --git a/src/Avalonia.Vulkan/VulkanContext.cs b/src/Avalonia.Vulkan/VulkanContext.cs index dab8ec5230..6667055e8c 100644 --- a/src/Avalonia.Vulkan/VulkanContext.cs +++ b/src/Avalonia.Vulkan/VulkanContext.cs @@ -1,6 +1,7 @@ using System; using System.Collections.Generic; using System.Linq; +using Avalonia.Platform.Surfaces; using Avalonia.Vulkan.UnmanagedInterop; namespace Avalonia.Vulkan; @@ -54,7 +55,7 @@ internal class VulkanContext : IVulkanPlatformGraphicsContext public VulkanInstanceApi InstanceApi { get; } public VulkanDeviceApi DeviceApi { get; } - public IVulkanRenderTarget CreateRenderTarget(IEnumerable surfaces) + public IVulkanRenderTarget CreateRenderTarget(IEnumerable surfaces) { foreach (var surf in surfaces) { diff --git a/src/Avalonia.X11/Glx/GlxGlPlatformSurface.cs b/src/Avalonia.X11/Glx/GlxGlPlatformSurface.cs index e1cd12bece..81d7a4e9bc 100644 --- a/src/Avalonia.X11/Glx/GlxGlPlatformSurface.cs +++ b/src/Avalonia.X11/Glx/GlxGlPlatformSurface.cs @@ -2,6 +2,7 @@ using System; using Avalonia.OpenGL; using Avalonia.OpenGL.Egl; using Avalonia.OpenGL.Surfaces; +using Avalonia.Platform; using static Avalonia.OpenGL.GlConsts; namespace Avalonia.X11.Glx @@ -39,11 +40,10 @@ namespace Avalonia.X11.Glx } public bool IsCorrupted => false; - - public IGlPlatformSurfaceRenderingSession BeginDraw(PixelSize? expectedSize) + public IGlPlatformSurfaceRenderingSession BeginDraw(IRenderTarget.RenderTargetSceneInfo sceneInfo) { - var size = expectedSize ?? _info.Size; - if (expectedSize.HasValue) + var size = sceneInfo.Size; + //if (expectedSize.HasValue) { XLib.XConfigureResizeWindow(_context.Display.X11Info.DeferredDisplay, _info.Handle, size.Width, size.Height); diff --git a/src/Avalonia.X11/Vulkan/VulkanSupport.cs b/src/Avalonia.X11/Vulkan/VulkanSupport.cs index 5f9dcf7953..8dc2acbbc2 100644 --- a/src/Avalonia.X11/Vulkan/VulkanSupport.cs +++ b/src/Avalonia.X11/Vulkan/VulkanSupport.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Runtime.InteropServices; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using Avalonia.Vulkan; namespace Avalonia.X11.Vulkan; @@ -41,10 +42,10 @@ internal class VulkanSupport _display = display; } - public bool CanRenderToSurface(IVulkanPlatformGraphicsContext context, object surface) => + public bool CanRenderToSurface(IVulkanPlatformGraphicsContext context, IPlatformRenderSurface surface) => surface is INativePlatformHandleSurface handle && handle.HandleDescriptor == "XID"; - public IVulkanKhrSurfacePlatformSurface CreateSurface(IVulkanPlatformGraphicsContext context, object handle) => + public IVulkanKhrSurfacePlatformSurface CreateSurface(IVulkanPlatformGraphicsContext context, IPlatformRenderSurface handle) => new XidSurface(_display, (INativePlatformHandleSurface)handle); } diff --git a/src/Avalonia.X11/X11CursorFactory.cs b/src/Avalonia.X11/X11CursorFactory.cs index c6be968bfd..1ac4c1fe8d 100644 --- a/src/Avalonia.X11/X11CursorFactory.cs +++ b/src/Avalonia.X11/X11CursorFactory.cs @@ -1,8 +1,8 @@ using System; using System.Collections.Generic; using System.Runtime.InteropServices; -using Avalonia.Controls.Platform.Surfaces; using Avalonia.Input; +using Avalonia.Media.Imaging; using Avalonia.Platform; using Avalonia.Platform.Internal; @@ -71,7 +71,7 @@ namespace Avalonia.X11 return new CursorImpl(handle); } - public unsafe ICursorImpl CreateCursor(IBitmapImpl cursor, PixelPoint hotSpot) + public unsafe ICursorImpl CreateCursor(Bitmap cursor, PixelPoint hotSpot) { return new XImageCursor(_display, cursor, hotSpot); } @@ -84,13 +84,13 @@ namespace Avalonia.X11 return XLib.XCreatePixmapCursor(display, pixmap, pixmap, ref color, ref color, 0, 0); } - private unsafe class XImageCursor : CursorImpl, IFramebufferPlatformSurface, IPlatformHandle + private unsafe class XImageCursor : CursorImpl, IPlatformHandle { private readonly IntPtr _display; private readonly PixelSize _pixelSize; private readonly UnmanagedBlob _blob; - public XImageCursor(IntPtr display, IBitmapImpl bitmap, PixelPoint hotSpot) + public XImageCursor(IntPtr display, Bitmap bitmap, PixelPoint hotSpot) { var size = Marshal.SizeOf() + (bitmap.PixelSize.Width * bitmap.PixelSize.Height * 4); @@ -108,15 +108,12 @@ namespace Avalonia.X11 image->xhot = hotSpot.X; image->yhot = hotSpot.Y; image->pixels = (IntPtr)(image + 1); - - using (var cpuContext = platformRenderInterface.CreateBackendContext(null)) - using (var renderTarget = cpuContext.CreateRenderTarget(new[] { this })) - using (var ctx = renderTarget.CreateDrawingContext(true)) - { - var r = new Rect(_pixelSize.ToSize(1)); - ctx.DrawBitmap(bitmap, 1, r, r); - } + bitmap.CopyPixels(new LockedFramebuffer( + _blob.Address + Marshal.SizeOf(), + _pixelSize, _pixelSize.Width * 4, + new Vector(96, 96), PixelFormat.Bgra8888, AlphaFormat.Premul, null)); + Handle = XLib.XcursorImageLoadCursor(display, _blob.Address); } @@ -127,16 +124,6 @@ namespace Avalonia.X11 XLib.XFreeCursor(_display, Handle); _blob.Dispose(); } - - public ILockedFramebuffer Lock() - { - return new LockedFramebuffer( - _blob.Address + Marshal.SizeOf(), - _pixelSize, _pixelSize.Width * 4, - new Vector(96, 96), PixelFormat.Bgra8888, AlphaFormat.Premul, null); - } - - public IFramebufferRenderTarget CreateFramebufferRenderTarget() => new FuncFramebufferRenderTarget(Lock); } private nint GetCursorHandleCached(StandardCursorType type) diff --git a/src/Avalonia.X11/X11FramebufferSurface.cs b/src/Avalonia.X11/X11FramebufferSurface.cs index 4efd7f072d..10fd885b93 100644 --- a/src/Avalonia.X11/X11FramebufferSurface.cs +++ b/src/Avalonia.X11/X11FramebufferSurface.cs @@ -1,5 +1,5 @@ using System; -using Avalonia.Controls.Platform.Surfaces; +using Avalonia.Platform.Surfaces; using Avalonia.Platform; using static Avalonia.X11.XLib; namespace Avalonia.X11 @@ -49,7 +49,7 @@ namespace Avalonia.X11 } } - public ILockedFramebuffer Lock(out FramebufferLockProperties properties) + public ILockedFramebuffer Lock(IRenderTarget.RenderTargetSceneInfo _, out FramebufferLockProperties properties) { XLockDisplay(_display); XGetGeometry(_display, _xid, out var root, out var x, out var y, out var width, out var height, @@ -68,11 +68,6 @@ namespace Avalonia.X11 return _fb!.Lock(new Vector(96, 96), Blit); } - public IFramebufferRenderTarget CreateFramebufferRenderTarget() - { - return _retain - ? new FuncRetainedFramebufferRenderTarget(Lock) - : new FuncFramebufferRenderTarget(() => Lock(out _)); - } + public IFramebufferRenderTarget CreateFramebufferRenderTarget() => new FuncFramebufferRenderTarget(Lock, _retain); } } diff --git a/src/Avalonia.X11/X11IconLoader.cs b/src/Avalonia.X11/X11IconLoader.cs index 1cfe009062..a45c77e7c0 100644 --- a/src/Avalonia.X11/X11IconLoader.cs +++ b/src/Avalonia.X11/X11IconLoader.cs @@ -1,7 +1,6 @@ using System; using System.IO; using System.Runtime.InteropServices; -using Avalonia.Controls.Platform.Surfaces; using Avalonia.Media.Imaging; using Avalonia.Platform; @@ -29,23 +28,23 @@ namespace Avalonia.X11 } } - internal unsafe class X11IconData : IWindowIconImpl, IFramebufferPlatformSurface + internal unsafe class X11IconData : IWindowIconImpl { private int _width; private int _height; - private uint[]? _bdata; + public UIntPtr[] Data { get; } public X11IconData(Bitmap bitmap) { _width = Math.Min(bitmap.PixelSize.Width, 128); _height = Math.Min(bitmap.PixelSize.Height, 128); - _bdata = new uint[_width * _height]; - using(var cpuContext = AvaloniaLocator.Current.GetRequiredService().CreateBackendContext(null)) - using(var rt = cpuContext.CreateRenderTarget(new[]{this})) - using (var ctx = rt.CreateDrawingContext(true)) - ctx.DrawBitmap(bitmap.PlatformImpl.Item, 1, new Rect(bitmap.Size), - new Rect(0, 0, _width, _height)); + var pixels = new uint[_width * _height]; + + fixed (void* pPixels = pixels) + bitmap.CopyPixels(new LockedFramebuffer((IntPtr)pPixels, new PixelSize(_width, _height), _width * 4, + new Vector(96, 96), PixelFormat.Bgra8888, AlphaFormat.Premul, null)); + Data = new UIntPtr[_width * _height + 2]; Data[0] = new UIntPtr((uint)_width); Data[1] = new UIntPtr((uint)_height); @@ -53,10 +52,10 @@ namespace Avalonia.X11 { var r = y * _width; for (var x = 0; x < _width; x++) - Data[r + x + 2] = new UIntPtr(_bdata[r + x]); + Data[r + x + 2] = new UIntPtr(pixels[r + x]); } - _bdata = null; + pixels = null; } public void Save(Stream outputStream) @@ -78,15 +77,5 @@ namespace Avalonia.X11 wr.Save(outputStream); } } - - public ILockedFramebuffer Lock() - { - var h = GCHandle.Alloc(_bdata, GCHandleType.Pinned); - return new LockedFramebuffer(h.AddrOfPinnedObject(), new PixelSize(_width, _height), _width * 4, - new Vector(96, 96), PixelFormat.Bgra8888, AlphaFormat.Premul, - () => h.Free()); - } - - public IFramebufferRenderTarget CreateFramebufferRenderTarget() => new FuncFramebufferRenderTarget(Lock); } } diff --git a/src/Avalonia.X11/X11Window.cs b/src/Avalonia.X11/X11Window.cs index 014dd014a5..52456ca1b6 100644 --- a/src/Avalonia.X11/X11Window.cs +++ b/src/Avalonia.X11/X11Window.cs @@ -16,6 +16,7 @@ using Avalonia.Input.TextInput; using Avalonia.OpenGL; using Avalonia.OpenGL.Egl; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using Avalonia.Platform.Storage; using Avalonia.Rendering.Composition; using Avalonia.Threading; @@ -211,7 +212,7 @@ namespace Avalonia.X11 SetWmClass(_handle, _platform.Options.WmClass); } - var surfaces = new List + var surfaces = new List { new X11FramebufferSurface(_x11.DeferredDisplay, _renderHandle, depth, _platform.Options.UseRetainedFramebuffer ?? false) @@ -481,7 +482,7 @@ namespace Avalonia.X11 public double DesktopScaling => RenderScaling; - public IEnumerable Surfaces { get; } + public IPlatformRenderSurface[] Surfaces { get; } public Action? Input { get; set; } public Action? Paint { get; set; } public Action? Resized { get; set; } diff --git a/src/Browser/Avalonia.Browser/BrowserTopLevelImpl.cs b/src/Browser/Avalonia.Browser/BrowserTopLevelImpl.cs index bca4aa807a..6b712391e4 100644 --- a/src/Browser/Avalonia.Browser/BrowserTopLevelImpl.cs +++ b/src/Browser/Avalonia.Browser/BrowserTopLevelImpl.cs @@ -14,6 +14,7 @@ using Avalonia.Input.Platform; using Avalonia.Input.Raw; using Avalonia.Input.TextInput; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using Avalonia.Platform.Storage; using Avalonia.Rendering.Composition; @@ -132,7 +133,7 @@ namespace Avalonia.Browser public Size? FrameSize => null; public double RenderScaling => _surface?.Scaling ?? 1; - public IEnumerable Surfaces => _surface?.GetRenderSurfaces() ?? []; + public IPlatformRenderSurface[] Surfaces => _surface?.GetRenderSurfaces() ?? []; public Action? Input { get; set; } public Action? Paint { get; set; } diff --git a/src/Browser/Avalonia.Browser/Cursor.cs b/src/Browser/Avalonia.Browser/Cursor.cs index 7d77f6e0d2..bf782f2126 100644 --- a/src/Browser/Avalonia.Browser/Cursor.cs +++ b/src/Browser/Avalonia.Browser/Cursor.cs @@ -76,7 +76,7 @@ namespace Avalonia.Browser internal class CssCursorFactory : ICursorFactory { - public ICursorImpl CreateCursor(IBitmapImpl cursor, PixelPoint hotSpot) + public ICursorImpl CreateCursor(Avalonia.Media.Imaging.Bitmap cursor, PixelPoint hotSpot) { using var imageStream = new MemoryStream(); cursor.Save(imageStream); diff --git a/src/Browser/Avalonia.Browser/Rendering/BrowserSoftwareRenderTarget.cs b/src/Browser/Avalonia.Browser/Rendering/BrowserSoftwareRenderTarget.cs index 6a0fb61f70..da10c10dc1 100644 --- a/src/Browser/Avalonia.Browser/Rendering/BrowserSoftwareRenderTarget.cs +++ b/src/Browser/Avalonia.Browser/Rendering/BrowserSoftwareRenderTarget.cs @@ -1,7 +1,7 @@ using System; using System.Runtime.InteropServices.JavaScript; using Avalonia.Browser.Interop; -using Avalonia.Controls.Platform.Surfaces; +using Avalonia.Platform.Surfaces; using Avalonia.Platform; using Avalonia.Reactive; #pragma warning disable CS0169 @@ -38,8 +38,9 @@ partial class BrowserSoftwareRenderTarget : BrowserRenderTarget, IFramebufferPla _fb = null; } - public ILockedFramebuffer Lock() + public ILockedFramebuffer Lock(IRenderTarget.RenderTargetSceneInfo sceneInfo, out FramebufferLockProperties properties) { + properties = default; var (size, scaling) = _parent._sizeGetter(); _parent.UpdateSize(size); diff --git a/src/Browser/Avalonia.Browser/Rendering/BrowserSurface.cs b/src/Browser/Avalonia.Browser/Rendering/BrowserSurface.cs index e93cdee703..a7b27f120e 100644 --- a/src/Browser/Avalonia.Browser/Rendering/BrowserSurface.cs +++ b/src/Browser/Avalonia.Browser/Rendering/BrowserSurface.cs @@ -8,13 +8,14 @@ using Avalonia.Browser.Interop; using Avalonia.Browser.Rendering; using Avalonia.Logging; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using Avalonia.Rendering; using Avalonia.Rendering.Composition; using Avalonia.Threading; namespace Avalonia.Browser.Skia; -internal abstract class BrowserSurface : IDisposable +internal abstract class BrowserSurface : IDisposable, IPlatformRenderSurface { protected BrowserSurface(JSObject jsSurface, Compositor compositor) { @@ -68,5 +69,5 @@ internal abstract class BrowserSurface : IDisposable ScalingChanged?.Invoke(); } - public virtual object[] GetRenderSurfaces() => [this]; + public virtual IPlatformRenderSurface[] GetRenderSurfaces() => [this]; } diff --git a/src/Browser/Avalonia.Browser/Rendering/BrowserWebGlRenderTarget.cs b/src/Browser/Avalonia.Browser/Rendering/BrowserWebGlRenderTarget.cs index 4417dd2301..4489460104 100644 --- a/src/Browser/Avalonia.Browser/Rendering/BrowserWebGlRenderTarget.cs +++ b/src/Browser/Avalonia.Browser/Rendering/BrowserWebGlRenderTarget.cs @@ -73,9 +73,8 @@ partial class BrowserWebGlRenderTarget : BrowserRenderTarget, IGlPlatformSurface // No-op } - public IGlPlatformSurfaceRenderingSession BeginDraw(PixelSize? expectedPixelSize) + public IGlPlatformSurfaceRenderingSession BeginDraw(IRenderTarget.RenderTargetSceneInfo sceneInfo) { - // TODO: use expectedPixelSize var s = _target._sizeGetter(); _target.UpdateSize(s.Size); var restoreContext = _target.GlContext.EnsureCurrent(); diff --git a/src/Browser/Avalonia.Browser/Rendering/RenderTargetBrowserSurface.cs b/src/Browser/Avalonia.Browser/Rendering/RenderTargetBrowserSurface.cs index f97b329734..bc94e1e131 100644 --- a/src/Browser/Avalonia.Browser/Rendering/RenderTargetBrowserSurface.cs +++ b/src/Browser/Avalonia.Browser/Rendering/RenderTargetBrowserSurface.cs @@ -5,6 +5,7 @@ using System.Runtime.InteropServices.JavaScript; using Avalonia.Browser.Interop; using Avalonia.Browser.Skia; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using Avalonia.Rendering.Composition; namespace Avalonia.Browser.Rendering; @@ -29,11 +30,11 @@ internal class RenderTargetBrowserSurface : BrowserSurface } - public override object[] GetRenderSurfaces() + public override IPlatformRenderSurface[] GetRenderSurfaces() { - if (_graphics.Target == null) + if (_graphics.Target is not IPlatformRenderSurface target) return []; - return [_graphics.Target]; + return [target]; } public override void OnSizeChanged(double pixelWidth, double pixelHeight, double dpr) diff --git a/src/Headless/Avalonia.Headless/HeadlessPlatformRenderInterface.cs b/src/Headless/Avalonia.Headless/HeadlessPlatformRenderInterface.cs index c2f024cf37..b83cf8b526 100644 --- a/src/Headless/Avalonia.Headless/HeadlessPlatformRenderInterface.cs +++ b/src/Headless/Avalonia.Headless/HeadlessPlatformRenderInterface.cs @@ -8,6 +8,7 @@ using Avalonia.Media; using Avalonia.Media.Imaging; using Avalonia.Media.TextFormatting; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; namespace Avalonia.Headless { @@ -55,7 +56,7 @@ namespace Avalonia.Headless public IGeometryImpl CreateCombinedGeometry(GeometryCombineMode combineMode, IGeometryImpl g1, IGeometryImpl g2) => new HeadlessGeometryStub(g1.Bounds.Union(g2.Bounds)); - public IRenderTarget CreateRenderTarget(IEnumerable surfaces) => new HeadlessRenderTarget(); + public IRenderTarget CreateRenderTarget(IEnumerable surfaces) => new HeadlessRenderTarget(); public IDrawingContextLayerImpl CreateOffscreenRenderTarget(PixelSize pixelSize, Vector scaling, bool enableTextAntialiasing) => new HeadlessBitmapStub(pixelSize, scaling * 96); @@ -376,7 +377,7 @@ namespace Avalonia.Headless } } - private class HeadlessBitmapStub : IBitmapImpl, IDrawingContextLayerImpl, IWriteableBitmapImpl + private class HeadlessBitmapStub : IBitmapImpl, IDrawingContextLayerImpl, IWriteableBitmapImpl, IRenderTargetBitmapImpl { public Size Size { get; } @@ -405,10 +406,8 @@ namespace Avalonia.Headless return new HeadlessDrawingContextStub(); } - public IDrawingContextImpl CreateDrawingContext(PixelSize expectedPixelSize, - out RenderTargetDrawingContextProperties properties) + public IDrawingContextImpl CreateDrawingContext() { - properties = default; return new HeadlessDrawingContextStub(); } @@ -603,7 +602,7 @@ namespace Avalonia.Headless return new HeadlessDrawingContextStub(); } - public IDrawingContextImpl CreateDrawingContext(PixelSize expectedPixelSize, + public IDrawingContextImpl CreateDrawingContext(IRenderTarget.RenderTargetSceneInfo sceneInfo, out RenderTargetDrawingContextProperties properties) { properties = default; diff --git a/src/Headless/Avalonia.Headless/HeadlessPlatformStubs.cs b/src/Headless/Avalonia.Headless/HeadlessPlatformStubs.cs index dedaa2ff58..1b4cb05fa8 100644 --- a/src/Headless/Avalonia.Headless/HeadlessPlatformStubs.cs +++ b/src/Headless/Avalonia.Headless/HeadlessPlatformStubs.cs @@ -13,6 +13,7 @@ using Avalonia.Input; using Avalonia.Input.Platform; using Avalonia.Media; using Avalonia.Media.Fonts; +using Avalonia.Media.Imaging; using Avalonia.Platform; namespace Avalonia.Headless @@ -60,7 +61,7 @@ namespace Avalonia.Headless internal class HeadlessCursorFactoryStub : ICursorFactory { public ICursorImpl GetCursor(StandardCursorType cursorType) => new CursorStub(); - public ICursorImpl CreateCursor(IBitmapImpl cursor, PixelPoint hotSpot) => new CursorStub(); + public ICursorImpl CreateCursor(Bitmap cursor, PixelPoint hotSpot) => new CursorStub(); private class CursorStub : ICursorImpl { diff --git a/src/Headless/Avalonia.Headless/HeadlessWindowImpl.cs b/src/Headless/Avalonia.Headless/HeadlessWindowImpl.cs index c755caf4eb..275dc7f48a 100644 --- a/src/Headless/Avalonia.Headless/HeadlessWindowImpl.cs +++ b/src/Headless/Avalonia.Headless/HeadlessWindowImpl.cs @@ -3,13 +3,13 @@ using System.Collections.Generic; using System.Diagnostics; using Avalonia.Controls; using Avalonia.Controls.Platform; -using Avalonia.Controls.Platform.Surfaces; using Avalonia.Controls.Primitives.PopupPositioning; using Avalonia.Input; using Avalonia.Input.Platform; using Avalonia.Input.Raw; using Avalonia.Media.Imaging; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using Avalonia.Rendering.Composition; using Avalonia.Threading; @@ -31,7 +31,7 @@ namespace Avalonia.Headless public HeadlessWindowImpl(bool isPopup, PixelFormat frameBufferFormat) { IsPopup = isPopup; - Surfaces = new object[] { this }; + Surfaces = [this]; _keyboard = AvaloniaLocator.Current.GetRequiredService(); _screen = new HeadlessScreensStub(); _mousePointer = new Pointer(Pointer.GetNextFreeId(), PointerType.Mouse, true); @@ -51,7 +51,7 @@ namespace Avalonia.Headless public Size? FrameSize => null; public double RenderScaling { get; } = 1; public double DesktopScaling => RenderScaling; - public IEnumerable Surfaces { get; } + public IPlatformRenderSurface[] Surfaces { get; } public Action? Input { get; set; } public Action? Paint { get; set; } public Action? Resized { get; set; } diff --git a/src/Linux/Avalonia.LinuxFramebuffer/FramebufferToplevelImpl.cs b/src/Linux/Avalonia.LinuxFramebuffer/FramebufferToplevelImpl.cs index edd0b1ef72..22965c05fe 100644 --- a/src/Linux/Avalonia.LinuxFramebuffer/FramebufferToplevelImpl.cs +++ b/src/Linux/Avalonia.LinuxFramebuffer/FramebufferToplevelImpl.cs @@ -6,6 +6,7 @@ using Avalonia.Input.Raw; using Avalonia.LinuxFramebuffer.Input; using Avalonia.LinuxFramebuffer.Output; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using Avalonia.Rendering.Composition; using Avalonia.Threading; @@ -26,7 +27,7 @@ using Avalonia.Rendering.Composition; _inputQueue = new RawEventGrouper(groupedInput => Input?.Invoke(groupedInput), LinuxFramebufferPlatform.EventGrouperDispatchQueue); - Surfaces = new object[] { _outputBackend }; + Surfaces = [_outputBackend]; _inputBackend.Initialize(this, e => Dispatcher.UIThread.Post(() => _inputQueue.HandleEvent(e), DispatcherPriority.Send )); } @@ -60,7 +61,7 @@ using Avalonia.Rendering.Composition; public IPopupImpl? CreatePopup() => null; public double RenderScaling => _outputBackend.Scaling; - public IEnumerable Surfaces { get; } + public IPlatformRenderSurface[] Surfaces { get; } public Action? Input { get; set; } public Action? Paint { get; set; } public Action? Resized { get; set; } diff --git a/src/Linux/Avalonia.LinuxFramebuffer/Output/DrmOutput.cs b/src/Linux/Avalonia.LinuxFramebuffer/Output/DrmOutput.cs index 59de00f4b3..cf0bf1e49a 100644 --- a/src/Linux/Avalonia.LinuxFramebuffer/Output/DrmOutput.cs +++ b/src/Linux/Avalonia.LinuxFramebuffer/Output/DrmOutput.cs @@ -377,7 +377,7 @@ namespace Avalonia.LinuxFramebuffer.Output { //Go through two cycles of buffer swapping (there are render artifacts otherwise) for (var c = 0; c < 2; c++) - using (CreateGlRenderTarget().BeginDraw(PixelSize)) + using (CreateGlRenderTarget().BeginDraw(new IRenderTarget.RenderTargetSceneInfo(PixelSize, 1))) { _deferredContext.GlInterface.ClearColor(initialBufferSwappingColorR, initialBufferSwappingColorG, initialBufferSwappingColorB, initialBufferSwappingColorA); @@ -511,7 +511,7 @@ namespace Avalonia.LinuxFramebuffer.Output public bool IsYFlipped => false; } - public IGlPlatformSurfaceRenderingSession BeginDraw(PixelSize? expectedPixelSize) + public IGlPlatformSurfaceRenderingSession BeginDraw(IRenderTarget.RenderTargetSceneInfo sceneInfo) { var clearContext = _parent._deferredContext.MakeCurrent(_parent._eglSurface); var gl = _parent._deferredContext.GlInterface; diff --git a/src/Linux/Avalonia.LinuxFramebuffer/Output/FbdevOutput.cs b/src/Linux/Avalonia.LinuxFramebuffer/Output/FbdevOutput.cs index 08a99d7c07..b3527e77ef 100644 --- a/src/Linux/Avalonia.LinuxFramebuffer/Output/FbdevOutput.cs +++ b/src/Linux/Avalonia.LinuxFramebuffer/Output/FbdevOutput.cs @@ -2,7 +2,7 @@ using System.Diagnostics.CodeAnalysis; using System.Runtime.InteropServices; using System.Text; -using Avalonia.Controls.Platform.Surfaces; +using Avalonia.Platform.Surfaces; using Avalonia.LinuxFramebuffer.Output; using Avalonia.Platform; @@ -162,9 +162,7 @@ namespace Avalonia.LinuxFramebuffer } } - public ILockedFramebuffer Lock() => Lock(out _); - - private ILockedFramebuffer Lock(out FramebufferLockProperties properties) + public ILockedFramebuffer Lock(IRenderTarget.RenderTargetSceneInfo _, out FramebufferLockProperties properties) { if (_fd <= 0) throw new ObjectDisposedException("LinuxFramebuffer"); @@ -187,7 +185,7 @@ namespace Avalonia.LinuxFramebuffer .Lock(new Vector(96, 96) * Scaling); } - public IFramebufferRenderTarget CreateFramebufferRenderTarget() => new FuncRetainedFramebufferRenderTarget(Lock); + public IFramebufferRenderTarget CreateFramebufferRenderTarget() => new FuncFramebufferRenderTarget(Lock, true); private void ReleaseUnmanagedResources() diff --git a/src/Linux/Avalonia.LinuxFramebuffer/Output/IOutputBackend.cs b/src/Linux/Avalonia.LinuxFramebuffer/Output/IOutputBackend.cs index 17a39b0219..f61ecb4038 100644 --- a/src/Linux/Avalonia.LinuxFramebuffer/Output/IOutputBackend.cs +++ b/src/Linux/Avalonia.LinuxFramebuffer/Output/IOutputBackend.cs @@ -1,6 +1,8 @@ +using Avalonia.Platform.Surfaces; + namespace Avalonia.LinuxFramebuffer.Output { - public interface IOutputBackend + public interface IOutputBackend : IPlatformRenderSurface { PixelSize PixelSize { get; } double Scaling { get; set; } diff --git a/src/Linux/Avalonia.LinuxFramebuffer/Stubs.cs b/src/Linux/Avalonia.LinuxFramebuffer/Stubs.cs index c5c7c13c67..3ef0783d04 100644 --- a/src/Linux/Avalonia.LinuxFramebuffer/Stubs.cs +++ b/src/Linux/Avalonia.LinuxFramebuffer/Stubs.cs @@ -1,5 +1,6 @@ using System; using Avalonia.Input; +using Avalonia.Media.Imaging; using Avalonia.Platform; namespace Avalonia.LinuxFramebuffer @@ -7,7 +8,7 @@ namespace Avalonia.LinuxFramebuffer internal class CursorFactoryStub : ICursorFactory { public ICursorImpl GetCursor(StandardCursorType cursorType) => new CursorStub(); - public ICursorImpl CreateCursor(IBitmapImpl cursor, PixelPoint hotSpot) => new CursorStub(); + public ICursorImpl CreateCursor(Bitmap cursor, PixelPoint hotSpot) => new CursorStub(); private class CursorStub : ICursorImpl { diff --git a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs index 8051dd7993..8fd2454f33 100644 --- a/src/Skia/Avalonia.Skia/DrawingContextImpl.cs +++ b/src/Skia/Avalonia.Skia/DrawingContextImpl.cs @@ -641,7 +641,7 @@ namespace Avalonia.Skia public IDrawingContextLayerImpl CreateLayer(PixelSize size) { CheckLease(); - return CreateRenderTarget(size, true); + return CreateRenderTarget(size, true, false); } /// @@ -1092,11 +1092,11 @@ namespace Avalonia.Skia { var calc = new TileBrushCalculator(tileBrush, tileBrushImage.PixelSize.ToSizeWithDpi(_intermediateSurfaceDpi), targetBox.Size); var intermediate = CreateRenderTarget( - PixelSize.FromSizeWithDpi(calc.IntermediateSize, _intermediateSurfaceDpi), false); + PixelSize.FromSizeWithDpi(calc.IntermediateSize, _intermediateSurfaceDpi), false, true); paintWrapper.AddDisposable(intermediate); - using (var context = intermediate.CreateDrawingContext(true)) + using (var context = intermediate.CreateDrawingContext()) { var sourceRect = new Rect(tileBrushImage.PixelSize.ToSizeWithDpi(96)); var targetRect = new Rect(tileBrushImage.PixelSize.ToSizeWithDpi(_intermediateSurfaceDpi)); @@ -1184,9 +1184,9 @@ namespace Avalonia.Skia if (intermediateSize.Width >= 1 && intermediateSize.Height >= 1) { using var intermediate = CreateRenderTarget( - PixelSize.FromSizeWithDpi(intermediateSize, _intermediateSurfaceDpi), false); + PixelSize.FromSizeWithDpi(intermediateSize, _intermediateSurfaceDpi), false, true); - using (var ctx = intermediate.CreateDrawingContext(true)) + using (var ctx = intermediate.CreateDrawingContext()) { ctx.PushRenderOptions(RenderOptions); ctx.Clear(Colors.Transparent); @@ -1487,9 +1487,10 @@ namespace Avalonia.Skia /// /// The size of the render target. /// Whether the render target is being created for a layer. + /// Auto-scales to DPI /// Pixel format. /// - private SurfaceRenderTarget CreateRenderTarget(PixelSize pixelSize, bool isLayer, PixelFormat? format = null) + private SurfaceRenderTarget CreateRenderTarget(PixelSize pixelSize, bool isLayer, bool useScaledDrawing, PixelFormat? format = null) { var createInfo = new SurfaceRenderTarget.CreateInfo { @@ -1502,6 +1503,7 @@ namespace Avalonia.Skia Gpu = _gpu, Session = _session, DisableManualFbo = !isLayer, + UseScaledDrawing = useScaledDrawing }; return new SurfaceRenderTarget(createInfo); diff --git a/src/Skia/Avalonia.Skia/FramebufferRenderTarget.cs b/src/Skia/Avalonia.Skia/FramebufferRenderTarget.cs index 0eb11ff404..5491df93b8 100644 --- a/src/Skia/Avalonia.Skia/FramebufferRenderTarget.cs +++ b/src/Skia/Avalonia.Skia/FramebufferRenderTarget.cs @@ -1,8 +1,8 @@ using System; using System.Diagnostics.CodeAnalysis; using Avalonia.Reactive; -using Avalonia.Controls.Platform.Surfaces; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using SkiaSharp; namespace Avalonia.Skia @@ -12,23 +12,24 @@ namespace Avalonia.Skia /// internal class FramebufferRenderTarget : IRenderTarget { + private readonly bool _useScaledDrawing; private SKImageInfo _currentImageInfo; private IntPtr _currentFramebufferAddress; private SKSurface? _framebufferSurface; private PixelFormatConversionShim? _conversionShim; private IDisposable? _preFramebufferCopyHandler; private IFramebufferRenderTarget? _renderTarget; - private IFramebufferRenderTargetWithProperties? _renderTargetWithProperties; private bool _hadConversionShim; /// /// Create new framebuffer render target using a target surface. /// /// Target surface. - public FramebufferRenderTarget(IFramebufferPlatformSurface platformSurface) + /// Tells the render target to scale to framebuffer dpi + public FramebufferRenderTarget(IFramebufferPlatformSurface platformSurface, bool useScaledDrawing = false) { + _useScaledDrawing = useScaledDrawing; _renderTarget = platformSurface.CreateFramebufferRenderTarget(); - _renderTargetWithProperties = _renderTarget as IFramebufferRenderTargetWithProperties; } /// @@ -36,35 +37,28 @@ namespace Avalonia.Skia { _renderTarget?.Dispose(); _renderTarget = null; - _renderTargetWithProperties = null; FreeSurface(); } public RenderTargetProperties Properties => new() { RetainsPreviousFrameContents = !_hadConversionShim - && _renderTargetWithProperties?.RetainsFrameContents == true, + && _renderTarget?.RetainsFrameContents == true, IsSuitableForDirectRendering = true }; - /// - public IDrawingContextImpl CreateDrawingContext(bool scaleDrawingToDpi) => - CreateDrawingContextCore(scaleDrawingToDpi, out _); + /// - public IDrawingContextImpl CreateDrawingContext(PixelSize expectedPixelSize, - out RenderTargetDrawingContextProperties properties) - => CreateDrawingContextCore(false, out properties); - - IDrawingContextImpl CreateDrawingContextCore(bool scaleDrawingToDpi, + public IDrawingContextImpl CreateDrawingContext(IRenderTarget.RenderTargetSceneInfo sceneInfo, out RenderTargetDrawingContextProperties properties) { if (_renderTarget == null) throw new ObjectDisposedException(nameof(FramebufferRenderTarget)); - - FramebufferLockProperties lockProperties = default; - var framebuffer = _renderTargetWithProperties?.Lock(out lockProperties) ?? _renderTarget.Lock(); + + var framebuffer = _renderTarget.Lock(sceneInfo, out var lockProperties); + var framebufferImageInfo = new SKImageInfo(framebuffer.Size.Width, framebuffer.Size.Height, framebuffer.Format.ToSkColorType(), framebuffer.AlphaFormat.ToSkAlphaType()); @@ -82,7 +76,7 @@ namespace Avalonia.Skia { Surface = _framebufferSurface, Dpi = framebuffer.Dpi, - ScaleDrawingToDpi = scaleDrawingToDpi + ScaleDrawingToDpi = _useScaledDrawing }; properties = new() @@ -95,6 +89,8 @@ namespace Avalonia.Skia public bool IsCorrupted => false; + public bool IsReady => _renderTarget is not IPlatformRenderSurfaceRenderTarget prs || prs.IsReady; + /// /// Check if two images info are compatible. /// diff --git a/src/Skia/Avalonia.Skia/Gpu/ISkiaGpu.cs b/src/Skia/Avalonia.Skia/Gpu/ISkiaGpu.cs index 93edea7169..511a3c2627 100644 --- a/src/Skia/Avalonia.Skia/Gpu/ISkiaGpu.cs +++ b/src/Skia/Avalonia.Skia/Gpu/ISkiaGpu.cs @@ -1,16 +1,15 @@ using System; using System.Collections.Generic; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using SkiaSharp; namespace Avalonia.Skia { - //TODO12: Make it private - /// /// Custom Skia gpu instance. /// - public interface ISkiaGpu : IPlatformGraphicsContext + internal interface ISkiaGpu : IPlatformGraphicsContext { /// /// Gets the platform graphics context. @@ -22,7 +21,12 @@ namespace Avalonia.Skia /// /// Surfaces. /// Created render target or if it fails. - ISkiaGpuRenderTarget? TryCreateRenderTarget(IEnumerable surfaces); + ISkiaGpuRenderTarget? TryCreateRenderTarget(IEnumerable surfaces); + + /// + /// Checks if a render target can be created for the given surfaces and the preferred surface is ready. + /// + bool IsReadyToCreateRenderTarget(IEnumerable surfaces); /// /// Creates an offscreen render target surface diff --git a/src/Skia/Avalonia.Skia/Gpu/ISkiaGpuRenderTarget.cs b/src/Skia/Avalonia.Skia/Gpu/ISkiaGpuRenderTarget.cs index eb7399f6a6..65b6b5a8df 100644 --- a/src/Skia/Avalonia.Skia/Gpu/ISkiaGpuRenderTarget.cs +++ b/src/Skia/Avalonia.Skia/Gpu/ISkiaGpuRenderTarget.cs @@ -1,4 +1,5 @@ using System; +using Avalonia.Platform; namespace Avalonia.Skia { @@ -10,10 +11,12 @@ namespace Avalonia.Skia /// /// Start rendering to this render target. /// - /// The expected size. + /// Information about the scene that will be rendered. /// A render session instance. - ISkiaGpuRenderSession BeginRenderingSession(PixelSize? expectedPixelSize); + ISkiaGpuRenderSession BeginRenderingSession(IRenderTarget.RenderTargetSceneInfo sceneInfo); bool IsCorrupted { get; } + + bool IsReady => true; } } diff --git a/src/Skia/Avalonia.Skia/Gpu/Metal/SkiaMetalGpu.cs b/src/Skia/Avalonia.Skia/Gpu/Metal/SkiaMetalGpu.cs index 460a994839..ef3c191904 100644 --- a/src/Skia/Avalonia.Skia/Gpu/Metal/SkiaMetalGpu.cs +++ b/src/Skia/Avalonia.Skia/Gpu/Metal/SkiaMetalGpu.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using Avalonia.Metal; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using SkiaSharp; namespace Avalonia.Skia.Metal; @@ -49,7 +50,7 @@ internal class SkiaMetalGpu : ISkiaGpu public IScopedResource TryGetGrContext() => ScopedResource.Create(GrContext, EnsureCurrent().Dispose); - public ISkiaGpuRenderTarget? TryCreateRenderTarget(IEnumerable surfaces) + public ISkiaGpuRenderTarget? TryCreateRenderTarget(IEnumerable surfaces) { foreach (var surface in surfaces) { @@ -63,6 +64,19 @@ internal class SkiaMetalGpu : ISkiaGpu return null; } + public bool IsReadyToCreateRenderTarget(IEnumerable surfaces) + { + foreach (var surface in surfaces) + { + if (surface is IMetalPlatformSurface) + { + return surface.IsReady; + } + } + + return false; + } + public class SkiaMetalRenderTarget : ISkiaGpuRenderTarget { private readonly SkiaMetalGpu _gpu; @@ -80,7 +94,7 @@ internal class SkiaMetalGpu : ISkiaGpu _target = null; } - public ISkiaGpuRenderSession BeginRenderingSession(PixelSize? expectedPixelSize) + public ISkiaGpuRenderSession BeginRenderingSession(IRenderTarget.RenderTargetSceneInfo sceneInfo) { // TODO: use expectedPixelSize var session = (_target ?? throw new ObjectDisposedException(nameof(SkiaMetalRenderTarget))).BeginRendering(); @@ -95,6 +109,8 @@ internal class SkiaMetalGpu : ISkiaGpu } public bool IsCorrupted => false; + + public bool IsReady => _target?.IsReady ?? false; } internal class SkiaMetalRenderSession : ISkiaGpuRenderSession diff --git a/src/Skia/Avalonia.Skia/Gpu/OpenGl/GlRenderTarget.cs b/src/Skia/Avalonia.Skia/Gpu/OpenGl/GlRenderTarget.cs index bb43e13b55..f5c164be45 100644 --- a/src/Skia/Avalonia.Skia/Gpu/OpenGl/GlRenderTarget.cs +++ b/src/Skia/Avalonia.Skia/Gpu/OpenGl/GlRenderTarget.cs @@ -1,6 +1,7 @@ using System; using Avalonia.OpenGL; using Avalonia.OpenGL.Surfaces; +using Avalonia.Platform; using SkiaSharp; using static Avalonia.OpenGL.GlConsts; @@ -22,6 +23,8 @@ namespace Avalonia.Skia public bool IsCorrupted => _surface.IsCorrupted; + public bool IsReady => _surface.IsReady; + class GlGpuSession : ISkiaGpuRenderSession { private readonly GRBackendRenderTarget _backendRenderTarget; @@ -56,9 +59,9 @@ namespace Avalonia.Skia public double ScaleFactor => _glSession.Scaling; } - public ISkiaGpuRenderSession BeginRenderingSession(PixelSize? expectedPixelSize) + public ISkiaGpuRenderSession BeginRenderingSession(IRenderTarget.RenderTargetSceneInfo sceneInfo) { - var glSession = _surface.BeginDraw(expectedPixelSize); + var glSession = _surface.BeginDraw(sceneInfo); bool success = false; try diff --git a/src/Skia/Avalonia.Skia/Gpu/OpenGl/GlSkiaGpu.cs b/src/Skia/Avalonia.Skia/Gpu/OpenGl/GlSkiaGpu.cs index a20ceb0fd0..ed29231adf 100644 --- a/src/Skia/Avalonia.Skia/Gpu/OpenGl/GlSkiaGpu.cs +++ b/src/Skia/Avalonia.Skia/Gpu/OpenGl/GlSkiaGpu.cs @@ -5,6 +5,7 @@ using Avalonia.Logging; using Avalonia.OpenGL; using Avalonia.OpenGL.Surfaces; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using SkiaSharp; using static Avalonia.OpenGL.GlConsts; @@ -53,13 +54,15 @@ namespace Avalonia.Skia private class SurfaceWrapper : IGlPlatformSurface { - private readonly object _surface; + private readonly IPlatformRenderSurface _surface; - public SurfaceWrapper( object surface) + public SurfaceWrapper(IPlatformRenderSurface surface) { _surface = surface; } + public bool IsReady => _surface.IsReady; + public IGlPlatformSurfaceRenderTarget CreateGlRenderTarget(IGlContext context) { var feature = context.TryGetFeature()!; @@ -67,7 +70,7 @@ namespace Avalonia.Skia } } - public ISkiaGpuRenderTarget? TryCreateRenderTarget(IEnumerable surfaces) + public ISkiaGpuRenderTarget? TryCreateRenderTarget(IEnumerable surfaces) { var customRenderTargetFactory = _glContext.TryGetFeature(); foreach (var surface in surfaces) @@ -85,6 +88,21 @@ namespace Avalonia.Skia return null; } + public bool IsReadyToCreateRenderTarget(IEnumerable surfaces) + { + var customRenderTargetFactory = _glContext.TryGetFeature(); + foreach (var surface in surfaces) + { + if (customRenderTargetFactory?.CanRenderToSurface(_glContext, surface) == true + || surface is IGlPlatformSurface) + { + return surface.IsReady; + } + } + + return false; + } + public ISkiaSurface? TryCreateSurface(PixelSize size, ISkiaGpuRenderSession? session) { // Only windows platform needs our FBO trickery diff --git a/src/Skia/Avalonia.Skia/Gpu/SkiaGpuRenderTarget.cs b/src/Skia/Avalonia.Skia/Gpu/SkiaGpuRenderTarget.cs index 488888f50a..13bd946b74 100644 --- a/src/Skia/Avalonia.Skia/Gpu/SkiaGpuRenderTarget.cs +++ b/src/Skia/Avalonia.Skia/Gpu/SkiaGpuRenderTarget.cs @@ -1,3 +1,4 @@ +using System; using Avalonia.Platform; namespace Avalonia.Skia @@ -21,27 +22,21 @@ namespace Avalonia.Skia _renderTarget.Dispose(); } - public IDrawingContextImpl CreateDrawingContext(PixelSize expectedPixelSize, - out RenderTargetDrawingContextProperties properties) => - CreateDrawingContextCore(expectedPixelSize, false, out properties); + public IDrawingContextImpl CreateDrawingContext(bool useScaledDrawing) => throw new InvalidOperationException( + "This legacy API is only supported by framebuffer render targets and should be removed from there as well, don't use"); - public IDrawingContextImpl CreateDrawingContext(bool useScaledDrawing) - => CreateDrawingContextCore(null, useScaledDrawing, out _); - - - IDrawingContextImpl CreateDrawingContextCore(PixelSize? expectedPixelSize, - bool useScaledDrawing, + public IDrawingContextImpl CreateDrawingContext(IRenderTarget.RenderTargetSceneInfo sceneInfo, out RenderTargetDrawingContextProperties properties) { properties = default; - var session = _renderTarget.BeginRenderingSession(expectedPixelSize); + var session = _renderTarget.BeginRenderingSession(sceneInfo); var nfo = new DrawingContextImpl.CreateInfo { GrContext = session.GrContext, Surface = session.SkSurface, Dpi = SkiaPlatform.DefaultDpi * session.ScaleFactor, - ScaleDrawingToDpi = useScaledDrawing, + ScaleDrawingToDpi = false, Gpu = _skiaGpu, CurrentSession = session }; @@ -50,6 +45,7 @@ namespace Avalonia.Skia } public bool IsCorrupted => _renderTarget.IsCorrupted; + public bool IsReady => _renderTarget.IsReady; public RenderTargetProperties Properties { get; } diff --git a/src/Skia/Avalonia.Skia/Gpu/Vulkan/VulkanSkiaGpu.cs b/src/Skia/Avalonia.Skia/Gpu/Vulkan/VulkanSkiaGpu.cs index 9d3ca6789b..476cb31d95 100644 --- a/src/Skia/Avalonia.Skia/Gpu/Vulkan/VulkanSkiaGpu.cs +++ b/src/Skia/Avalonia.Skia/Gpu/Vulkan/VulkanSkiaGpu.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using Avalonia.Vulkan; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using SkiaSharp; namespace Avalonia.Skia.Vulkan; @@ -77,12 +78,27 @@ internal class VulkanSkiaGpu : ISkiaGpu public IDisposable EnsureCurrent() => Vulkan.EnsureCurrent(); - public ISkiaGpuRenderTarget TryCreateRenderTarget(IEnumerable surfaces) + public ISkiaGpuRenderTarget TryCreateRenderTarget(IEnumerable surfaces) { var target = Vulkan.CreateRenderTarget(surfaces); return new VulkanSkiaRenderTarget(this, target); } + public bool IsReadyToCreateRenderTarget(IEnumerable surfaces) + { + var factory = Vulkan.TryGetFeature(); + foreach (var surface in surfaces) + { + if (surface is IVulkanKhrSurfacePlatformSurface + || (factory?.CanRenderToSurface(Vulkan, surface) == true)) + { + return surface.IsReady; + } + } + + return false; + } + public ISkiaSurface? TryCreateSurface(PixelSize size, ISkiaGpuRenderSession? session) => null; diff --git a/src/Skia/Avalonia.Skia/Gpu/Vulkan/VulkanSkiaRenderTarget.cs b/src/Skia/Avalonia.Skia/Gpu/Vulkan/VulkanSkiaRenderTarget.cs index 3ab1714f6c..6b04fcd8c0 100644 --- a/src/Skia/Avalonia.Skia/Gpu/Vulkan/VulkanSkiaRenderTarget.cs +++ b/src/Skia/Avalonia.Skia/Gpu/Vulkan/VulkanSkiaRenderTarget.cs @@ -1,4 +1,5 @@ using System; +using Avalonia.Platform; using Avalonia.Skia.Helpers; using Avalonia.Vulkan; using SkiaSharp; @@ -21,7 +22,7 @@ class VulkanSkiaRenderTarget : ISkiaGpuRenderTarget _target.Dispose(); } - public ISkiaGpuRenderSession BeginRenderingSession(PixelSize? expectedPixelSize) + public ISkiaGpuRenderSession BeginRenderingSession(IRenderTarget.RenderTargetSceneInfo sceneInfo) { // TODO: use expectedPixelSize var session = _target.BeginDraw(); @@ -75,6 +76,8 @@ class VulkanSkiaRenderTarget : ISkiaGpuRenderTarget public bool IsCorrupted => false; + public bool IsReady => _target.IsReady; + internal class VulkanSkiaRenderSession : ISkiaGpuRenderSession { diff --git a/src/Skia/Avalonia.Skia/RenderTargetBitmapImpl.cs b/src/Skia/Avalonia.Skia/RenderTargetBitmapImpl.cs index 2e63f8bfd3..c5002510f9 100644 --- a/src/Skia/Avalonia.Skia/RenderTargetBitmapImpl.cs +++ b/src/Skia/Avalonia.Skia/RenderTargetBitmapImpl.cs @@ -1,4 +1,4 @@ -using Avalonia.Controls.Platform.Surfaces; +using Avalonia.Platform.Surfaces; using Avalonia.Platform; using SkiaSharp; @@ -14,21 +14,16 @@ internal class RenderTargetBitmapImpl : WriteableBitmapImpl, SKImageInfo.PlatformColorType == SKColorType.Rgba8888 ? PixelFormats.Rgba8888 : PixelFormat.Bgra8888, Platform.AlphaFormat.Premul) { - _renderTarget = new FramebufferRenderTarget(this); + _renderTarget = new FramebufferRenderTarget(this, true); } - - public RenderTargetProperties Properties => default; - - IDrawingContextImpl IRenderTarget.CreateDrawingContext(bool useScaledDrawing) => - _renderTarget.CreateDrawingContext(useScaledDrawing); - - IDrawingContextImpl IRenderTarget.CreateDrawingContext(PixelSize expectedPixelSize, - out RenderTargetDrawingContextProperties properties) + + public IDrawingContextImpl CreateDrawingContext() { - properties = default; - return _renderTarget.CreateDrawingContext(false); + return _renderTarget.CreateDrawingContext(new IRenderTarget.RenderTargetSceneInfo( + PixelSize, Dpi.X / 96.0), out _); } + public bool IsCorrupted => false; public override void Dispose() @@ -36,6 +31,6 @@ internal class RenderTargetBitmapImpl : WriteableBitmapImpl, _renderTarget.Dispose(); base.Dispose(); } - + public IFramebufferRenderTarget CreateFramebufferRenderTarget() => new FuncFramebufferRenderTarget(Lock); } diff --git a/src/Skia/Avalonia.Skia/SkiaBackendContext.cs b/src/Skia/Avalonia.Skia/SkiaBackendContext.cs index dcaf6b542e..c52fe33bc4 100644 --- a/src/Skia/Avalonia.Skia/SkiaBackendContext.cs +++ b/src/Skia/Avalonia.Skia/SkiaBackendContext.cs @@ -2,9 +2,9 @@ using System; using System.Collections; using System.Collections.Generic; using System.Linq; -using Avalonia.Controls.Platform.Surfaces; using Avalonia.OpenGL; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; namespace Avalonia.Skia; @@ -47,7 +47,7 @@ internal class SkiaContext : IPlatformRenderInterfaceContext } /// - public IRenderTarget CreateRenderTarget(IEnumerable surfaces) + public IRenderTarget CreateRenderTarget(IEnumerable surfaces) { if (surfaces is not IList) surfaces = surfaces.ToList(); @@ -67,6 +67,27 @@ internal class SkiaContext : IPlatformRenderInterfaceContext "Don't know how to create a Skia render target from any of provided surfaces"); } + public bool IsReadyToCreateRenderTarget(IEnumerable surfaces) + { + if (surfaces is not IList) + surfaces = surfaces.ToList(); + + if (_gpu != null) + { + return _gpu.IsReadyToCreateRenderTarget(surfaces); + } + + foreach (var surface in surfaces) + { + if (surface is IFramebufferPlatformSurface) + { + return surface.IsReady; + } + } + + return false; + } + public PixelSize? MaxOffscreenRenderTargetPixelSize { get; } diff --git a/src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs b/src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs index 82d0760207..3e54394541 100644 --- a/src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs +++ b/src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs @@ -10,8 +10,9 @@ namespace Avalonia.Skia /// /// Skia render target that writes to a surface. /// - internal class SurfaceRenderTarget : IDrawingContextLayerImpl, IDrawableBitmapImpl, IDrawingContextLayerWithRenderContextAffinityImpl + internal class SurfaceRenderTarget : IDrawableBitmapImpl, IDrawingContextLayerWithRenderContextAffinityImpl { + private readonly bool _useScaledDrawing; private readonly ISkiaSurface _surface; private readonly SKCanvas _canvas; private readonly bool _disableLcdRendering; @@ -44,6 +45,7 @@ namespace Avalonia.Skia /// Create info. public SurfaceRenderTarget(CreateInfo createInfo) { + _useScaledDrawing = createInfo.UseScaledDrawing; PixelSize = new PixelSize(createInfo.Width, createInfo.Height); Dpi = createInfo.Dpi; @@ -98,7 +100,7 @@ namespace Avalonia.Skia } /// - public IDrawingContextImpl CreateDrawingContext(bool useScaledDrawing) + public IDrawingContextImpl CreateDrawingContext() { _canvas.RestoreToCount(-1); _canvas.ResetMatrix(); @@ -107,7 +109,7 @@ namespace Avalonia.Skia { Surface = _surface.Surface, Dpi = Dpi, - ScaleDrawingToDpi = useScaledDrawing, + ScaleDrawingToDpi = _useScaledDrawing, DisableSubpixelTextRendering = _disableLcdRendering, GrContext = _grContext, Gpu = _gpu, @@ -116,15 +118,7 @@ namespace Avalonia.Skia return new DrawingContextImpl(createInfo, Disposable.Create(() => Version++)); } - public IDrawingContextImpl CreateDrawingContext(PixelSize expectedPixelSize, - out RenderTargetDrawingContextProperties properties) - { - properties = default; - return CreateDrawingContext(false); - } - public bool IsCorrupted => _gpu?.IsLost == true; - /// public Vector Dpi { get; } @@ -241,6 +235,7 @@ namespace Avalonia.Skia public ISkiaGpuRenderSession? Session; public bool DisableManualFbo; + public bool UseScaledDrawing; } public bool HasRenderContextAffinity => _grContext != null; diff --git a/src/Windows/Avalonia.Win32/CursorFactory.cs b/src/Windows/Avalonia.Win32/CursorFactory.cs index f6b756b607..975e5da91a 100644 --- a/src/Windows/Avalonia.Win32/CursorFactory.cs +++ b/src/Windows/Avalonia.Win32/CursorFactory.cs @@ -90,7 +90,7 @@ namespace Avalonia.Win32 return rv; } - public ICursorImpl CreateCursor(IBitmapImpl cursor, PixelPoint hotSpot) + public ICursorImpl CreateCursor(Bitmap cursor, PixelPoint hotSpot) { return new CursorImpl(new Win32Icon(cursor, hotSpot)); } diff --git a/src/Windows/Avalonia.Win32/DComposition/DirectCompositionConnection.cs b/src/Windows/Avalonia.Win32/DComposition/DirectCompositionConnection.cs index df940a8035..6c73fbeb9e 100644 --- a/src/Windows/Avalonia.Win32/DComposition/DirectCompositionConnection.cs +++ b/src/Windows/Avalonia.Win32/DComposition/DirectCompositionConnection.cs @@ -4,6 +4,8 @@ using System.Diagnostics; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; +using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using Avalonia.Logging; using Avalonia.MicroCom; using Avalonia.OpenGL.Egl; @@ -125,5 +127,5 @@ internal class DirectCompositionConnection : IRenderTimer, IWindowsSurfaceFactor } public bool RequiresNoRedirectionBitmap => true; - public object CreateSurface(EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo info) => new DirectCompositedWindowSurface(_shared, info); + public IPlatformRenderSurface CreateSurface(EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo info) => new DirectCompositedWindowSurface(_shared, info); } diff --git a/src/Windows/Avalonia.Win32/DirectX/DxgiConnection.cs b/src/Windows/Avalonia.Win32/DirectX/DxgiConnection.cs index c1e77aab76..678b15e0d7 100644 --- a/src/Windows/Avalonia.Win32/DirectX/DxgiConnection.cs +++ b/src/Windows/Avalonia.Win32/DirectX/DxgiConnection.cs @@ -3,6 +3,8 @@ using System.Collections.Generic; using System.Diagnostics; using System.Runtime.InteropServices; using System.Threading.Tasks; +using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using Avalonia.Logging; using Avalonia.OpenGL.Egl; using Avalonia.Rendering; @@ -215,6 +217,6 @@ namespace Avalonia.Win32.DirectX } public bool RequiresNoRedirectionBitmap => false; - public object CreateSurface(EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo info) => new DxgiSwapchainWindow(this, info); + public IPlatformRenderSurface CreateSurface(EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo info) => new DxgiSwapchainWindow(this, info); } } diff --git a/src/Windows/Avalonia.Win32/DirectX/DxgiRenderTarget.cs b/src/Windows/Avalonia.Win32/DirectX/DxgiRenderTarget.cs index 698e47d27e..4ff5596269 100644 --- a/src/Windows/Avalonia.Win32/DirectX/DxgiRenderTarget.cs +++ b/src/Windows/Avalonia.Win32/DirectX/DxgiRenderTarget.cs @@ -1,6 +1,7 @@ using System; using Avalonia.OpenGL.Egl; using Avalonia.OpenGL.Surfaces; +using Avalonia.Platform; using Avalonia.Win32.OpenGl.Angle; using MicroCom.Runtime; using static Avalonia.Win32.Interop.UnmanagedMethods; @@ -76,7 +77,7 @@ namespace Avalonia.Win32.DirectX } /// - public override IGlPlatformSurfaceRenderingSession BeginDrawCore(PixelSize? expectedPixelSize) + public override IGlPlatformSurfaceRenderingSession BeginDrawCore(IRenderTarget.RenderTargetSceneInfo sceneInfo) { // TODO: use expectedPixelSize if (_swapChain is null) diff --git a/src/Windows/Avalonia.Win32/DirectX/IDirect3D11TexturePlatformSurface.cs b/src/Windows/Avalonia.Win32/DirectX/IDirect3D11TexturePlatformSurface.cs index d2a2b2f513..fb1a6a27e7 100644 --- a/src/Windows/Avalonia.Win32/DirectX/IDirect3D11TexturePlatformSurface.cs +++ b/src/Windows/Avalonia.Win32/DirectX/IDirect3D11TexturePlatformSurface.cs @@ -1,10 +1,11 @@ using System; using Avalonia.OpenGL; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; namespace Avalonia.Win32.DirectX; -public interface IDirect3D11TexturePlatformSurface +public interface IDirect3D11TexturePlatformSurface : IPlatformRenderSurface { public IDirect3D11TextureRenderTarget CreateRenderTarget(IPlatformGraphicsContext graphicsContext, IntPtr d3dDevice); } diff --git a/src/Windows/Avalonia.Win32/FramebufferManager.cs b/src/Windows/Avalonia.Win32/FramebufferManager.cs index 7c11277c57..695e16b8f7 100644 --- a/src/Windows/Avalonia.Win32/FramebufferManager.cs +++ b/src/Windows/Avalonia.Win32/FramebufferManager.cs @@ -1,6 +1,6 @@ using System; using System.Threading; -using Avalonia.Controls.Platform.Surfaces; +using Avalonia.Platform.Surfaces; using Avalonia.Platform; using Avalonia.Platform.Internal; using Avalonia.Win32.Interop; diff --git a/src/Windows/Avalonia.Win32/IWindowsSurfaceFactory.cs b/src/Windows/Avalonia.Win32/IWindowsSurfaceFactory.cs index e46c155b1d..97d53c58c2 100644 --- a/src/Windows/Avalonia.Win32/IWindowsSurfaceFactory.cs +++ b/src/Windows/Avalonia.Win32/IWindowsSurfaceFactory.cs @@ -1,4 +1,6 @@ using Avalonia.Controls; +using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using Avalonia.OpenGL.Egl; namespace Avalonia.Win32; @@ -7,5 +9,5 @@ internal interface IWindowsSurfaceFactory { bool RequiresNoRedirectionBitmap { get; } - object CreateSurface(EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo info); + IPlatformRenderSurface CreateSurface(EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo info); } diff --git a/src/Windows/Avalonia.Win32/Interop/Win32Icon.cs b/src/Windows/Avalonia.Win32/Interop/Win32Icon.cs index 1fe301526b..502bdf9915 100644 --- a/src/Windows/Avalonia.Win32/Interop/Win32Icon.cs +++ b/src/Windows/Avalonia.Win32/Interop/Win32Icon.cs @@ -16,15 +16,6 @@ internal class Win32Icon : IDisposable Handle = CreateIcon(bitmap, hotSpot); } - public Win32Icon(IBitmapImpl bitmap, PixelPoint hotSpot = default) - { - using var memoryStream = new MemoryStream(); - bitmap.Save(memoryStream); - memoryStream.Position = 0; - using var bmp = new Bitmap(memoryStream); - Handle = CreateIcon(bmp, hotSpot); - } - public Win32Icon(byte[] iconData, PixelSize size = default) { _bytes = iconData; diff --git a/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleD3DTextureFeature.cs b/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleD3DTextureFeature.cs index e4c63bbeba..0dc8ec453e 100644 --- a/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleD3DTextureFeature.cs +++ b/src/Windows/Avalonia.Win32/OpenGl/Angle/AngleD3DTextureFeature.cs @@ -2,13 +2,15 @@ using System.Runtime.InteropServices; using Avalonia.OpenGL; using Avalonia.OpenGL.Egl; using Avalonia.OpenGL.Surfaces; +using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using Avalonia.Win32.DirectX; namespace Avalonia.Win32.OpenGl.Angle; internal class AngleD3DTextureFeature : IGlPlatformSurfaceRenderTargetFactory { - public bool CanRenderToSurface(IGlContext context, object surface) => + public bool CanRenderToSurface(IGlContext context, IPlatformRenderSurface surface) => context is EglContext { Display: AngleWin32EglDisplay { PlatformApi: AngleOptions.PlatformApi.DirectX11 } @@ -27,7 +29,7 @@ internal class AngleD3DTextureFeature : IGlPlatformSurfaceRenderTargetFactory _target = target; } - public override IGlPlatformSurfaceRenderingSession BeginDrawCore(PixelSize? expectedPixelSize) + public override IGlPlatformSurfaceRenderingSession BeginDrawCore(IRenderTarget.RenderTargetSceneInfo sceneInfo) { // TODO: use expectedPixelSize var success = false; @@ -84,7 +86,7 @@ internal class AngleD3DTextureFeature : IGlPlatformSurfaceRenderTargetFactory public override bool IsCorrupted => _target.IsCorrupted || base.IsCorrupted; } - public IGlPlatformSurfaceRenderTarget CreateRenderTarget(IGlContext context, object surface) + public IGlPlatformSurfaceRenderTarget CreateRenderTarget(IGlContext context, IPlatformRenderSurface surface) { var ctx = (EglContext)context; var angle = (AngleWin32EglDisplay)ctx.Display; diff --git a/src/Windows/Avalonia.Win32/OpenGl/WglGlPlatformSurface.cs b/src/Windows/Avalonia.Win32/OpenGl/WglGlPlatformSurface.cs index 40619660eb..f54ca9b62c 100644 --- a/src/Windows/Avalonia.Win32/OpenGl/WglGlPlatformSurface.cs +++ b/src/Windows/Avalonia.Win32/OpenGl/WglGlPlatformSurface.cs @@ -3,6 +3,7 @@ using System.Diagnostics; using Avalonia.OpenGL; using Avalonia.OpenGL.Egl; using Avalonia.OpenGL.Surfaces; +using Avalonia.Platform; using Avalonia.Win32.Interop; using static Avalonia.OpenGL.GlConsts; using static Avalonia.Win32.Interop.UnmanagedMethods; @@ -43,7 +44,7 @@ namespace Avalonia.Win32.OpenGl WglGdiResourceManager.ReleaseDC(_info.Handle, _hdc); } - public IGlPlatformSurfaceRenderingSession BeginDraw(PixelSize? expectedPixelSize) + public IGlPlatformSurfaceRenderingSession BeginDraw(IRenderTarget.RenderTargetSceneInfo sceneInfo) { // TODO: use expectedPixelSize var oldContext = _context.MakeCurrent(_hdc); diff --git a/src/Windows/Avalonia.Win32/Vulkan/VulkanSupport.cs b/src/Windows/Avalonia.Win32/Vulkan/VulkanSupport.cs index ab72fd5898..145a0b3745 100644 --- a/src/Windows/Avalonia.Win32/Vulkan/VulkanSupport.cs +++ b/src/Windows/Avalonia.Win32/Vulkan/VulkanSupport.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using System.Runtime.InteropServices; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using Avalonia.Vulkan; using Avalonia.Win32.Interop; @@ -26,10 +27,10 @@ internal class VulkanSupport internal class VulkanSurfaceFactory : IVulkanKhrSurfacePlatformSurfaceFactory { - public bool CanRenderToSurface(IVulkanPlatformGraphicsContext context, object surface) => + public bool CanRenderToSurface(IVulkanPlatformGraphicsContext context, IPlatformRenderSurface surface) => surface is INativePlatformHandleSurface handle && handle.HandleDescriptor == "HWND"; - public IVulkanKhrSurfacePlatformSurface CreateSurface(IVulkanPlatformGraphicsContext context, object handle) => + public IVulkanKhrSurfacePlatformSurface CreateSurface(IVulkanPlatformGraphicsContext context, IPlatformRenderSurface handle) => new HwndVulkanSurface((INativePlatformHandleSurface)handle); } diff --git a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositorConnection.cs b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositorConnection.cs index 11721cd47e..fa7ff2e7a3 100644 --- a/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositorConnection.cs +++ b/src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositorConnection.cs @@ -3,6 +3,8 @@ using System.Diagnostics; using System.Runtime.InteropServices; using System.Threading; using System.Threading.Tasks; +using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using Avalonia.Logging; using Avalonia.MicroCom; using Avalonia.OpenGL.Egl; @@ -210,5 +212,5 @@ internal class WinUiCompositorConnection : IRenderTimer, Win32.IWindowsSurfaceFa } public bool RequiresNoRedirectionBitmap => true; - public object CreateSurface(EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo info) => new WinUiCompositedWindowSurface(_shared, info); + public IPlatformRenderSurface CreateSurface(EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo info) => new WinUiCompositedWindowSurface(_shared, info); } diff --git a/src/Windows/Avalonia.Win32/WindowImpl.cs b/src/Windows/Avalonia.Win32/WindowImpl.cs index cda1d91194..cc2e7211f1 100644 --- a/src/Windows/Avalonia.Win32/WindowImpl.cs +++ b/src/Windows/Avalonia.Win32/WindowImpl.cs @@ -14,6 +14,7 @@ using Avalonia.Input.Raw; using Avalonia.Input.TextInput; using Avalonia.OpenGL.Egl; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using Avalonia.Platform.Storage; using Avalonia.Rendering.Composition; using Avalonia.Win32.DirectX; @@ -75,7 +76,7 @@ namespace Avalonia.Win32 private readonly WindowsMouseDevice _mouseDevice; private readonly PenDevice _penDevice; private readonly FramebufferManager _framebuffer; - private readonly object? _glSurface; + private readonly IPlatformRenderSurface? _glSurface; private readonly bool _wmPointerEnabled; private readonly Win32NativeControlHost _nativeControlHost; @@ -505,10 +506,10 @@ namespace Avalonia.Win32 return result == 0; } - public IEnumerable Surfaces + public IPlatformRenderSurface[] Surfaces => _glSurface is null ? - new object[] { Handle, _framebuffer } : - new object[] { Handle, _glSurface, _framebuffer }; + [(IPlatformRenderSurface)Handle, _framebuffer] : + [(IPlatformRenderSurface)Handle, _glSurface, _framebuffer]; public PixelPoint Position { diff --git a/src/iOS/Avalonia.iOS/AvaloniaView.cs b/src/iOS/Avalonia.iOS/AvaloniaView.cs index 7e85ccfefe..eb4603e8b1 100644 --- a/src/iOS/Avalonia.iOS/AvaloniaView.cs +++ b/src/iOS/Avalonia.iOS/AvaloniaView.cs @@ -12,6 +12,7 @@ using Avalonia.Input.Platform; using Avalonia.Input.Raw; using Avalonia.Input.TextInput; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using Avalonia.Platform.Storage; using Avalonia.Rendering.Composition; using CoreAnimation; @@ -104,14 +105,14 @@ namespace Avalonia.iOS OpenGLES.EAGLDrawableProperty.RetainedBacking, false, OpenGLES.EAGLDrawableProperty.ColorFormat, OpenGLES.EAGLColorFormat.RGBA8 ); - _topLevelImpl.Surfaces = new[] { new Eagl.EaglLayerSurface(eaglLayer) }; + _topLevelImpl.Surfaces = [new Eagl.EaglLayerSurface(eaglLayer)]; } else #endif if (l is CAMetalLayer metalLayer) { metalLayer.Opaque = false; - _topLevelImpl.Surfaces = new[] { new Metal.MetalPlatformSurface(metalLayer, this) }; + _topLevelImpl.Surfaces = [new Metal.MetalPlatformSurface(metalLayer, this)]; } } @@ -239,7 +240,7 @@ namespace Avalonia.iOS public Size ClientSize => new Size(_view.Bounds.Width, _view.Bounds.Height); public Size? FrameSize => null; public double RenderScaling => _view.ContentScaleFactor; - public IEnumerable Surfaces { get; set; } = Array.Empty(); + public IPlatformRenderSurface[] Surfaces { get; set; } = []; public Action? Input { get; set; } public Action? Paint { get; set; } public Action? Resized { get; set; } diff --git a/src/iOS/Avalonia.iOS/Eagl/EaglLayerSurface.cs b/src/iOS/Avalonia.iOS/Eagl/EaglLayerSurface.cs index fb0015476a..dd3f969de4 100644 --- a/src/iOS/Avalonia.iOS/Eagl/EaglLayerSurface.cs +++ b/src/iOS/Avalonia.iOS/Eagl/EaglLayerSurface.cs @@ -3,6 +3,7 @@ using System.Runtime.Versioning; using System.Threading; using Avalonia.OpenGL; using Avalonia.OpenGL.Surfaces; +using Avalonia.Platform; using CoreAnimation; namespace Avalonia.iOS.Eagl @@ -70,9 +71,8 @@ namespace Avalonia.iOS.Eagl _fbo.Dispose(); } - public IGlPlatformSurfaceRenderingSession BeginDraw(PixelSize? expectedPixelSize) + public IGlPlatformSurfaceRenderingSession BeginDraw(IRenderTarget.RenderTargetSceneInfo sceneInfo) { - // TODO: use expectedPixelSize CheckThread(); var restoreContext = _ctx.MakeCurrent(); _fbo.Bind(); diff --git a/src/iOS/Avalonia.iOS/Stubs.cs b/src/iOS/Avalonia.iOS/Stubs.cs index d0eb86a496..c78823cd81 100644 --- a/src/iOS/Avalonia.iOS/Stubs.cs +++ b/src/iOS/Avalonia.iOS/Stubs.cs @@ -7,7 +7,7 @@ namespace Avalonia.iOS { internal class CursorFactoryStub : ICursorFactory { - public ICursorImpl CreateCursor(IBitmapImpl cursor, PixelPoint hotSpot) => new CursorImplStub(); + public ICursorImpl CreateCursor(Avalonia.Media.Imaging.Bitmap cursor, PixelPoint hotSpot) => new CursorImplStub(); ICursorImpl ICursorFactory.GetCursor(StandardCursorType cursorType) => new CursorImplStub(); private class CursorImplStub : ICursorImpl diff --git a/tests/Avalonia.Benchmarks/Compositor/CompositionTargetUpdate.cs b/tests/Avalonia.Benchmarks/Compositor/CompositionTargetUpdate.cs index a066b7a4ab..7451e3c843 100644 --- a/tests/Avalonia.Benchmarks/Compositor/CompositionTargetUpdate.cs +++ b/tests/Avalonia.Benchmarks/Compositor/CompositionTargetUpdate.cs @@ -1,6 +1,6 @@ using System; using System.Runtime.InteropServices; -using Avalonia.Controls.Platform.Surfaces; +using Avalonia.Platform.Surfaces; using Avalonia.Media; using Avalonia.Platform; using Avalonia.Rendering; diff --git a/tests/Avalonia.Controls.UnitTests/CursorFactoryMock.cs b/tests/Avalonia.Controls.UnitTests/CursorFactoryMock.cs index ee4264e6b9..1cf857f436 100644 --- a/tests/Avalonia.Controls.UnitTests/CursorFactoryMock.cs +++ b/tests/Avalonia.Controls.UnitTests/CursorFactoryMock.cs @@ -1,4 +1,5 @@ using Avalonia.Input; +using Avalonia.Media.Imaging; using Avalonia.Platform; namespace Avalonia.Controls.UnitTests @@ -10,7 +11,7 @@ namespace Avalonia.Controls.UnitTests return new MockCursorImpl(); } - public ICursorImpl CreateCursor(IBitmapImpl cursor, PixelPoint hotSpot) + public ICursorImpl CreateCursor(Bitmap cursor, PixelPoint hotSpot) { return new MockCursorImpl(); } diff --git a/tests/Avalonia.RenderTests/Composition/DirectFbCompositionTests.cs b/tests/Avalonia.RenderTests/Composition/DirectFbCompositionTests.cs index 3a48bafaad..588785cf69 100644 --- a/tests/Avalonia.RenderTests/Composition/DirectFbCompositionTests.cs +++ b/tests/Avalonia.RenderTests/Composition/DirectFbCompositionTests.cs @@ -4,7 +4,7 @@ using System.IO; using System.Runtime.CompilerServices; using System.Threading.Tasks; using Avalonia.Controls; -using Avalonia.Controls.Platform.Surfaces; +using Avalonia.Platform.Surfaces; using Avalonia.Controls.Primitives; using Avalonia.Controls.Shapes; using Avalonia.Layout; @@ -86,13 +86,11 @@ public class DirectFbCompositionTests : TestBase fb.RowBytes, new Vector(96, 96), PixelFormat.Rgba8888, AlphaFormat.Premul, null); bool previousFrameIsRetained = false; - IFramebufferRenderTarget rt = advertised - ? new FuncRetainedFramebufferRenderTarget((out FramebufferLockProperties props) => - { - props = new() { PreviousFrameIsRetained = previousFrameIsRetained }; - return LockFb(); - }) - : new FuncFramebufferRenderTarget(LockFb); + IFramebufferRenderTarget rt = new FuncFramebufferRenderTarget((_, out props) => + { + props = new() { PreviousFrameIsRetained = previousFrameIsRetained }; + return LockFb(); + }, advertised); using var renderer = new CompositingRenderer(root, compositor, () => new[] { new FuncFramebufferSurface(() => rt) }); diff --git a/tests/Avalonia.RenderTests/Media/BitmapTests.cs b/tests/Avalonia.RenderTests/Media/BitmapTests.cs index 54e336a6f4..cd5713b9a2 100644 --- a/tests/Avalonia.RenderTests/Media/BitmapTests.cs +++ b/tests/Avalonia.RenderTests/Media/BitmapTests.cs @@ -4,10 +4,10 @@ using System; using System.IO; using System.Runtime.CompilerServices; using System.Runtime.InteropServices; -using Avalonia.Controls.Platform.Surfaces; using Avalonia.Media; using Avalonia.Media.Imaging; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using Xunit; using Path = System.IO.Path; @@ -70,8 +70,8 @@ namespace Avalonia.Skia.RenderTests var fb = new Framebuffer(fmt, AlphaFormat.Premul, new PixelSize(80, 80)); var r = AvaloniaLocator.Current.GetRequiredService(); using(var cpuContext = r.CreateBackendContext(null)) - using (var target = cpuContext.CreateRenderTarget(new object[] { fb })) - using (var ctx = target.CreateDrawingContext(false)) + using (var target = cpuContext.CreateRenderTarget(new IPlatformRenderSurface[] { fb })) + using (var ctx = target.CreateDrawingContext(new IRenderTarget.RenderTargetSceneInfo(fb.Size, 1), out _)) { ctx.Clear(Colors.Transparent); ctx.PushOpacity(0.8, new Rect(0, 0, 80, 80)); diff --git a/tests/Avalonia.RenderTests/TestBase.cs b/tests/Avalonia.RenderTests/TestBase.cs index 550fe16e3e..6152c782f4 100644 --- a/tests/Avalonia.RenderTests/TestBase.cs +++ b/tests/Avalonia.RenderTests/TestBase.cs @@ -13,7 +13,6 @@ using System.Collections.Generic; using System.Linq; using System.Reactive.Disposables; using System.Threading; -using Avalonia.Controls.Platform.Surfaces; using Avalonia.Media; using Avalonia.Rendering.Composition; using Avalonia.Skia; diff --git a/tests/Avalonia.RenderTests/TestRenderHelper.cs b/tests/Avalonia.RenderTests/TestRenderHelper.cs index 4112edacbf..68cf05e9b9 100644 --- a/tests/Avalonia.RenderTests/TestRenderHelper.cs +++ b/tests/Avalonia.RenderTests/TestRenderHelper.cs @@ -13,7 +13,7 @@ using System.Collections.Generic; using System.Linq; using System.Reactive.Disposables; using System.Threading; -using Avalonia.Controls.Platform.Surfaces; +using Avalonia.Platform.Surfaces; using Avalonia.Media; using Avalonia.Rendering.Composition; using Avalonia.Threading; diff --git a/tests/Avalonia.UnitTests/CompositorTestServices.cs b/tests/Avalonia.UnitTests/CompositorTestServices.cs index e227b9622b..e90e1cff0e 100644 --- a/tests/Avalonia.UnitTests/CompositorTestServices.cs +++ b/tests/Avalonia.UnitTests/CompositorTestServices.cs @@ -4,13 +4,13 @@ using System.Linq; using System.Runtime.InteropServices; using Avalonia.Controls; using Avalonia.Controls.Embedding; -using Avalonia.Controls.Platform.Surfaces; using Avalonia.Controls.Presenters; using Avalonia.Controls.Templates; using Avalonia.Data; using Avalonia.Input; using Avalonia.Input.Raw; using Avalonia.Platform; +using Avalonia.Platform.Surfaces; using Avalonia.Rendering; using Avalonia.Rendering.Composition; using Avalonia.Threading; @@ -160,7 +160,7 @@ public class CompositorTestServices : IDisposable public IPlatformHandle? Handle => null; public Size ClientSize { get; } public double RenderScaling => 1; - public IEnumerable Surfaces { get; } = new[] { new DummyFramebufferSurface() }; + public IPlatformRenderSurface[] Surfaces { get; } = [new DummyFramebufferSurface()]; public Action? Input { get; set; } public Action? Paint { get; set; } public Action? Resized { get; set; } diff --git a/tests/Avalonia.UnitTests/TestRoot.cs b/tests/Avalonia.UnitTests/TestRoot.cs index 2424188140..ed91463346 100644 --- a/tests/Avalonia.UnitTests/TestRoot.cs +++ b/tests/Avalonia.UnitTests/TestRoot.cs @@ -95,12 +95,15 @@ namespace Avalonia.UnitTests { var layerDc = new Mock(); var layer = new Mock(); - layer.Setup(x => x.CreateDrawingContext(It.IsAny())).Returns(layerDc.Object); + layer.Setup(x => x.CreateDrawingContext()).Returns(layerDc.Object); return layer.Object; }); var result = new Mock(); - result.Setup(x => x.CreateDrawingContext(It.IsAny())).Returns(dc.Object); + result.Setup(x => x.CreateDrawingContext(It.IsAny(), + out It.Ref.IsAny)) + .Returns(dc.Object); + return result.Object; }