Browse Source

Render target/surface housekeeping (#20811)

* Render target/surface housekeeping

* diff and build

* build and stuff

* really

* Make more APIs private

* Apply suggestions from code review

Co-authored-by: Julien Lebosquain <julien@lebosquain.net>

* Address review comments

---------

Co-authored-by: Julien Lebosquain <julien@lebosquain.net>
pull/20817/head
Nikita Tsukanov 3 weeks ago
committed by GitHub
parent
commit
b2ecb21e03
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 40
      api/Avalonia.LinuxFramebuffer.nupkg.xml
  2. 62
      api/Avalonia.Skia.nupkg.xml
  3. 458
      api/Avalonia.nupkg.xml
  4. 2
      src/Android/Avalonia.Android/CursorFactory.cs
  5. 2
      src/Android/Avalonia.Android/Platform/SkiaPlatform/FramebufferManager.cs
  6. 3
      src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs
  7. 5
      src/Android/Avalonia.Android/Platform/Vulkan/VulkanSupport.cs
  8. 2
      src/Avalonia.Base/Input/Cursor.cs
  9. 26
      src/Avalonia.Base/Media/Imaging/Bitmap.cs
  10. 2
      src/Avalonia.Base/Media/Imaging/RenderTargetBitmap.cs
  11. 3
      src/Avalonia.Base/Platform/ICursorFactory.cs
  12. 12
      src/Avalonia.Base/Platform/IDrawingContextImpl.cs
  13. 8
      src/Avalonia.Base/Platform/IPlatformRenderInterface.cs
  14. 18
      src/Avalonia.Base/Platform/IRenderTarget.cs
  15. 3
      src/Avalonia.Base/Platform/IRenderTargetBitmapImpl.cs
  16. 66
      src/Avalonia.Base/Platform/Surfaces/IFramebufferPlatformSurface.cs
  17. 15
      src/Avalonia.Base/Platform/Surfaces/IPlatformRenderSurface.cs
  18. 4
      src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs
  19. 4
      src/Avalonia.Base/Rendering/Composition/Compositor.Factories.cs
  20. 15
      src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionTarget.cs
  21. 2
      src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual/ServerCompositionVisualCache.cs
  22. 2
      src/Avalonia.Base/Rendering/Composition/Server/ServerCompositor.UserApis.cs
  23. 8
      src/Avalonia.Base/Rendering/Composition/Server/ServerCompositor.cs
  24. 10
      src/Avalonia.Base/Rendering/PlatformRenderInterfaceContextManager.cs
  25. 3
      src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevelImpl.cs
  26. 3
      src/Avalonia.Controls/Platform/IPlatformNativeSurfaceHandle.cs
  27. 3
      src/Avalonia.Controls/Platform/ITopLevelImpl.cs
  28. 86
      src/Avalonia.Controls/Platform/Surfaces/IFramebufferPlatformSurface.cs
  29. 4
      src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.cs
  30. 6
      src/Avalonia.DesignerSupport/Remote/Stubs.cs
  31. 5
      src/Avalonia.Metal/IMetalDevice.cs
  32. 2
      src/Avalonia.Native/AvaloniaNativeGlPlatformGraphics.cs
  33. 3
      src/Avalonia.Native/Cursor.cs
  34. 1
      src/Avalonia.Native/DeferredFramebuffer.cs
  35. 15
      src/Avalonia.Native/TopLevelImpl.cs
  36. 3
      src/Avalonia.OpenGL/Egl/EglGlPlatformSurface.cs
  37. 7
      src/Avalonia.OpenGL/Egl/EglGlPlatformSurfaceBase.cs
  38. 5
      src/Avalonia.OpenGL/IGlContext.cs
  39. 10
      src/Avalonia.OpenGL/IGlContextExternalObjectsFeature.cs
  40. 4
      src/Avalonia.OpenGL/Surfaces/IGlPlatformSurface.cs
  41. 9
      src/Avalonia.OpenGL/Surfaces/IGlPlatformSurfaceRenderTarget.cs
  42. 3
      src/Avalonia.Vulkan/IVulkanDevice.cs
  43. 7
      src/Avalonia.Vulkan/IVulkanPlatformSurface.cs
  44. 3
      src/Avalonia.Vulkan/IVulkanRenderTarget.cs
  45. 3
      src/Avalonia.Vulkan/VulkanContext.cs
  46. 8
      src/Avalonia.X11/Glx/GlxGlPlatformSurface.cs
  47. 5
      src/Avalonia.X11/Vulkan/VulkanSupport.cs
  48. 29
      src/Avalonia.X11/X11CursorFactory.cs
  49. 11
      src/Avalonia.X11/X11FramebufferSurface.cs
  50. 31
      src/Avalonia.X11/X11IconLoader.cs
  51. 5
      src/Avalonia.X11/X11Window.cs
  52. 3
      src/Browser/Avalonia.Browser/BrowserTopLevelImpl.cs
  53. 2
      src/Browser/Avalonia.Browser/Cursor.cs
  54. 5
      src/Browser/Avalonia.Browser/Rendering/BrowserSoftwareRenderTarget.cs
  55. 5
      src/Browser/Avalonia.Browser/Rendering/BrowserSurface.cs
  56. 3
      src/Browser/Avalonia.Browser/Rendering/BrowserWebGlRenderTarget.cs
  57. 7
      src/Browser/Avalonia.Browser/Rendering/RenderTargetBrowserSurface.cs
  58. 11
      src/Headless/Avalonia.Headless/HeadlessPlatformRenderInterface.cs
  59. 3
      src/Headless/Avalonia.Headless/HeadlessPlatformStubs.cs
  60. 6
      src/Headless/Avalonia.Headless/HeadlessWindowImpl.cs
  61. 5
      src/Linux/Avalonia.LinuxFramebuffer/FramebufferToplevelImpl.cs
  62. 4
      src/Linux/Avalonia.LinuxFramebuffer/Output/DrmOutput.cs
  63. 8
      src/Linux/Avalonia.LinuxFramebuffer/Output/FbdevOutput.cs
  64. 4
      src/Linux/Avalonia.LinuxFramebuffer/Output/IOutputBackend.cs
  65. 3
      src/Linux/Avalonia.LinuxFramebuffer/Stubs.cs
  66. 14
      src/Skia/Avalonia.Skia/DrawingContextImpl.cs
  67. 30
      src/Skia/Avalonia.Skia/FramebufferRenderTarget.cs
  68. 12
      src/Skia/Avalonia.Skia/Gpu/ISkiaGpu.cs
  69. 7
      src/Skia/Avalonia.Skia/Gpu/ISkiaGpuRenderTarget.cs
  70. 20
      src/Skia/Avalonia.Skia/Gpu/Metal/SkiaMetalGpu.cs
  71. 7
      src/Skia/Avalonia.Skia/Gpu/OpenGl/GlRenderTarget.cs
  72. 24
      src/Skia/Avalonia.Skia/Gpu/OpenGl/GlSkiaGpu.cs
  73. 18
      src/Skia/Avalonia.Skia/Gpu/SkiaGpuRenderTarget.cs
  74. 18
      src/Skia/Avalonia.Skia/Gpu/Vulkan/VulkanSkiaGpu.cs
  75. 5
      src/Skia/Avalonia.Skia/Gpu/Vulkan/VulkanSkiaRenderTarget.cs
  76. 17
      src/Skia/Avalonia.Skia/RenderTargetBitmapImpl.cs
  77. 25
      src/Skia/Avalonia.Skia/SkiaBackendContext.cs
  78. 17
      src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs
  79. 2
      src/Windows/Avalonia.Win32/CursorFactory.cs
  80. 4
      src/Windows/Avalonia.Win32/DComposition/DirectCompositionConnection.cs
  81. 4
      src/Windows/Avalonia.Win32/DirectX/DxgiConnection.cs
  82. 3
      src/Windows/Avalonia.Win32/DirectX/DxgiRenderTarget.cs
  83. 3
      src/Windows/Avalonia.Win32/DirectX/IDirect3D11TexturePlatformSurface.cs
  84. 2
      src/Windows/Avalonia.Win32/FramebufferManager.cs
  85. 4
      src/Windows/Avalonia.Win32/IWindowsSurfaceFactory.cs
  86. 9
      src/Windows/Avalonia.Win32/Interop/Win32Icon.cs
  87. 8
      src/Windows/Avalonia.Win32/OpenGl/Angle/AngleD3DTextureFeature.cs
  88. 3
      src/Windows/Avalonia.Win32/OpenGl/WglGlPlatformSurface.cs
  89. 5
      src/Windows/Avalonia.Win32/Vulkan/VulkanSupport.cs
  90. 4
      src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositorConnection.cs
  91. 9
      src/Windows/Avalonia.Win32/WindowImpl.cs
  92. 7
      src/iOS/Avalonia.iOS/AvaloniaView.cs
  93. 4
      src/iOS/Avalonia.iOS/Eagl/EaglLayerSurface.cs
  94. 2
      src/iOS/Avalonia.iOS/Stubs.cs
  95. 2
      tests/Avalonia.Benchmarks/Compositor/CompositionTargetUpdate.cs
  96. 3
      tests/Avalonia.Controls.UnitTests/CursorFactoryMock.cs
  97. 14
      tests/Avalonia.RenderTests/Composition/DirectFbCompositionTests.cs
  98. 6
      tests/Avalonia.RenderTests/Media/BitmapTests.cs
  99. 1
      tests/Avalonia.RenderTests/TestBase.cs
  100. 2
      tests/Avalonia.RenderTests/TestRenderHelper.cs

40
api/Avalonia.LinuxFramebuffer.nupkg.xml

@ -0,0 +1,40 @@
<?xml version="1.0" encoding="utf-8"?>
<!-- https://learn.microsoft.com/dotnet/fundamentals/package-validation/diagnostic-ids -->
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.LinuxFramebuffer.FbdevOutput.CreateFramebufferRenderTarget</Target>
<Left>baseline/Avalonia.LinuxFramebuffer/lib/net10.0/Avalonia.LinuxFramebuffer.dll</Left>
<Right>current/Avalonia.LinuxFramebuffer/lib/net10.0/Avalonia.LinuxFramebuffer.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.LinuxFramebuffer.FbdevOutput.Lock</Target>
<Left>baseline/Avalonia.LinuxFramebuffer/lib/net10.0/Avalonia.LinuxFramebuffer.dll</Left>
<Right>current/Avalonia.LinuxFramebuffer/lib/net10.0/Avalonia.LinuxFramebuffer.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.LinuxFramebuffer.FbdevOutput.CreateFramebufferRenderTarget</Target>
<Left>baseline/Avalonia.LinuxFramebuffer/lib/net8.0/Avalonia.LinuxFramebuffer.dll</Left>
<Right>current/Avalonia.LinuxFramebuffer/lib/net8.0/Avalonia.LinuxFramebuffer.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.LinuxFramebuffer.FbdevOutput.Lock</Target>
<Left>baseline/Avalonia.LinuxFramebuffer/lib/net8.0/Avalonia.LinuxFramebuffer.dll</Left>
<Right>current/Avalonia.LinuxFramebuffer/lib/net8.0/Avalonia.LinuxFramebuffer.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0008</DiagnosticId>
<Target>T:Avalonia.LinuxFramebuffer.FbdevOutput</Target>
<Left>baseline/Avalonia.LinuxFramebuffer/lib/net10.0/Avalonia.LinuxFramebuffer.dll</Left>
<Right>current/Avalonia.LinuxFramebuffer/lib/net10.0/Avalonia.LinuxFramebuffer.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0008</DiagnosticId>
<Target>T:Avalonia.LinuxFramebuffer.FbdevOutput</Target>
<Left>baseline/Avalonia.LinuxFramebuffer/lib/net8.0/Avalonia.LinuxFramebuffer.dll</Left>
<Right>current/Avalonia.LinuxFramebuffer/lib/net8.0/Avalonia.LinuxFramebuffer.dll</Right>
</Suppression>
</Suppressions>

62
api/Avalonia.Skia.nupkg.xml

@ -1,6 +1,12 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- https://learn.microsoft.com/dotnet/fundamentals/package-validation/diagnostic-ids --> <!-- https://learn.microsoft.com/dotnet/fundamentals/package-validation/diagnostic-ids -->
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Avalonia.Skia.ISkiaGpu</Target>
<Left>baseline/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Left>
<Right>current/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0001</DiagnosticId> <DiagnosticId>CP0001</DiagnosticId>
<Target>T:Avalonia.Skia.ISkiaGpuRenderTarget2</Target> <Target>T:Avalonia.Skia.ISkiaGpuRenderTarget2</Target>
@ -13,6 +19,12 @@
<Left>baseline/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Left> <Left>baseline/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Left>
<Right>current/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Right> <Right>current/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Avalonia.Skia.ISkiaGpu</Target>
<Left>baseline/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll</Left>
<Right>current/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0001</DiagnosticId> <DiagnosticId>CP0001</DiagnosticId>
<Target>T:Avalonia.Skia.ISkiaGpuRenderTarget2</Target> <Target>T:Avalonia.Skia.ISkiaGpuRenderTarget2</Target>
@ -31,30 +43,66 @@
<Left>baseline/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Left> <Left>baseline/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Left>
<Right>current/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Right> <Right>current/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Skia.ISkiaGpu.TryCreateRenderTarget(System.Collections.Generic.IEnumerable{System.Object})</Target>
<Left>baseline/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Left>
<Right>current/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0002</DiagnosticId> <DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Skia.ISkiaGpuRenderTarget.BeginRenderingSession</Target> <Target>M:Avalonia.Skia.ISkiaGpuRenderTarget.BeginRenderingSession</Target>
<Left>baseline/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Left> <Left>baseline/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Left>
<Right>current/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Right> <Right>current/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Skia.ISkiaGpuRenderTarget.BeginRenderingSession(System.Nullable{Avalonia.PixelSize})</Target>
<Left>baseline/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Left>
<Right>current/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0002</DiagnosticId> <DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Skia.Helpers.DrawingContextHelper.WrapSkiaCanvas(SkiaSharp.SKCanvas,Avalonia.Vector)</Target> <Target>M:Avalonia.Skia.Helpers.DrawingContextHelper.WrapSkiaCanvas(SkiaSharp.SKCanvas,Avalonia.Vector)</Target>
<Left>baseline/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll</Left> <Left>baseline/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll</Left>
<Right>current/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll</Right> <Right>current/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Skia.ISkiaGpu.TryCreateRenderTarget(System.Collections.Generic.IEnumerable{System.Object})</Target>
<Left>baseline/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll</Left>
<Right>current/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0002</DiagnosticId> <DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Skia.ISkiaGpuRenderTarget.BeginRenderingSession</Target> <Target>M:Avalonia.Skia.ISkiaGpuRenderTarget.BeginRenderingSession</Target>
<Left>baseline/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll</Left> <Left>baseline/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll</Left>
<Right>current/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll</Right> <Right>current/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Skia.ISkiaGpuRenderTarget.BeginRenderingSession(System.Nullable{Avalonia.PixelSize})</Target>
<Left>baseline/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll</Left>
<Right>current/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Skia.ISkiaGpu.TryCreateRenderTarget(System.Collections.Generic.IEnumerable{Avalonia.Platform.Surfaces.IPlatformRenderSurface})</Target>
<Left>baseline/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Left>
<Right>current/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0006</DiagnosticId> <DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Skia.ISkiaGpu.TryGetGrContext</Target> <Target>M:Avalonia.Skia.ISkiaGpu.TryGetGrContext</Target>
<Left>baseline/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Left> <Left>baseline/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Left>
<Right>current/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Right> <Right>current/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Skia.ISkiaGpuRenderTarget.BeginRenderingSession(Avalonia.Platform.IRenderTarget.RenderTargetSceneInfo)</Target>
<Left>baseline/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Left>
<Right>current/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0006</DiagnosticId> <DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Skia.ISkiaGpuRenderTarget.BeginRenderingSession(System.Nullable{Avalonia.PixelSize})</Target> <Target>M:Avalonia.Skia.ISkiaGpuRenderTarget.BeginRenderingSession(System.Nullable{Avalonia.PixelSize})</Target>
@ -67,12 +115,24 @@
<Left>baseline/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Left> <Left>baseline/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Left>
<Right>current/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Right> <Right>current/Avalonia.Skia/lib/net10.0/Avalonia.Skia.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Skia.ISkiaGpu.TryCreateRenderTarget(System.Collections.Generic.IEnumerable{Avalonia.Platform.Surfaces.IPlatformRenderSurface})</Target>
<Left>baseline/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll</Left>
<Right>current/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0006</DiagnosticId> <DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Skia.ISkiaGpu.TryGetGrContext</Target> <Target>M:Avalonia.Skia.ISkiaGpu.TryGetGrContext</Target>
<Left>baseline/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll</Left> <Left>baseline/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll</Left>
<Right>current/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll</Right> <Right>current/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Skia.ISkiaGpuRenderTarget.BeginRenderingSession(Avalonia.Platform.IRenderTarget.RenderTargetSceneInfo)</Target>
<Left>baseline/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll</Left>
<Right>current/Avalonia.Skia/lib/net8.0/Avalonia.Skia.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0006</DiagnosticId> <DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Skia.ISkiaGpuRenderTarget.BeginRenderingSession(System.Nullable{Avalonia.PixelSize})</Target> <Target>M:Avalonia.Skia.ISkiaGpuRenderTarget.BeginRenderingSession(System.Nullable{Avalonia.PixelSize})</Target>

458
api/Avalonia.nupkg.xml

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<!-- https://learn.microsoft.com/dotnet/fundamentals/package-validation/diagnostic-ids --> <!-- https://learn.microsoft.com/dotnet/fundamentals/package-validation/diagnostic-ids -->
<Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema"> <Suppressions xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xsd="http://www.w3.org/2001/XMLSchema">
<Suppression> <Suppression>
@ -337,6 +337,36 @@
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left> <Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right> <Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Avalonia.Controls.Platform.Surfaces.FramebufferLockProperties</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Avalonia.Controls.Platform.Surfaces.FuncFramebufferRenderTarget</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Avalonia.Controls.Platform.Surfaces.IFramebufferPlatformSurface</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Avalonia.Controls.Platform.Surfaces.IFramebufferRenderTarget</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Avalonia.Controls.Platform.Surfaces.IFramebufferRenderTargetWithProperties</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0001</DiagnosticId> <DiagnosticId>CP0001</DiagnosticId>
<Target>T:Avalonia.Controls.Primitives.ChromeOverlayLayer</Target> <Target>T:Avalonia.Controls.Primitives.ChromeOverlayLayer</Target>
@ -769,6 +799,36 @@
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left> <Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right> <Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Avalonia.Controls.Platform.Surfaces.FramebufferLockProperties</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Avalonia.Controls.Platform.Surfaces.FuncFramebufferRenderTarget</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Avalonia.Controls.Platform.Surfaces.IFramebufferPlatformSurface</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Avalonia.Controls.Platform.Surfaces.IFramebufferRenderTarget</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0001</DiagnosticId>
<Target>T:Avalonia.Controls.Platform.Surfaces.IFramebufferRenderTargetWithProperties</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0001</DiagnosticId> <DiagnosticId>CP0001</DiagnosticId>
<Target>T:Avalonia.Controls.Primitives.ChromeOverlayLayer</Target> <Target>T:Avalonia.Controls.Primitives.ChromeOverlayLayer</Target>
@ -1417,6 +1477,12 @@
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left> <Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right> <Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Platform.ICursorFactory.CreateCursor(Avalonia.Platform.IBitmapImpl,Avalonia.PixelPoint)</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0002</DiagnosticId> <DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Platform.IDrawingContextImplWithEffects.PushEffect(Avalonia.Media.IEffect)</Target> <Target>M:Avalonia.Platform.IDrawingContextImplWithEffects.PushEffect(Avalonia.Media.IEffect)</Target>
@ -1459,6 +1525,24 @@
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left> <Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right> <Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Platform.IPlatformRenderInterfaceContext.CreateRenderTarget(System.Collections.Generic.IEnumerable{System.Object})</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Platform.IRenderTarget.CreateDrawingContext(Avalonia.PixelSize,Avalonia.Platform.RenderTargetDrawingContextProperties@)</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Platform.IRenderTarget.CreateDrawingContext(System.Boolean)</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0002</DiagnosticId> <DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Platform.LockedFramebuffer.#ctor(System.IntPtr,Avalonia.PixelSize,System.Int32,Avalonia.Vector,Avalonia.Platform.PixelFormat,System.Action)</Target> <Target>M:Avalonia.Platform.LockedFramebuffer.#ctor(System.IntPtr,Avalonia.PixelSize,System.Int32,Avalonia.Vector,Avalonia.Platform.PixelFormat,System.Action)</Target>
@ -1735,6 +1819,12 @@
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left> <Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right> <Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Controls.Embedding.Offscreen.OffscreenTopLevelImplBase.get_Surfaces</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0002</DiagnosticId> <DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Controls.Generators.ItemContainerGenerator.ContainerFromIndex(System.Int32)</Target> <Target>M:Avalonia.Controls.Generators.ItemContainerGenerator.ContainerFromIndex(System.Int32)</Target>
@ -2029,6 +2119,12 @@
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left> <Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right> <Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Platform.ITopLevelImpl.get_Surfaces</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0002</DiagnosticId> <DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Platform.IWindowImpl.GetWindowsZOrder(System.Span{Avalonia.Controls.Window},System.Span{System.Int64})</Target> <Target>M:Avalonia.Platform.IWindowImpl.GetWindowsZOrder(System.Span{Avalonia.Controls.Window},System.Span{System.Int64})</Target>
@ -2137,18 +2233,66 @@
<Left>baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Left> <Left>baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Right> <Right>current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.OpenGL.Egl.EglPlatformSurfaceRenderTargetBase.BeginDraw(System.Nullable{Avalonia.PixelSize})</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0002</DiagnosticId> <DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.OpenGL.Egl.EglPlatformSurfaceRenderTargetBase.BeginDrawCore</Target> <Target>M:Avalonia.OpenGL.Egl.EglPlatformSurfaceRenderTargetBase.BeginDrawCore</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Left> <Left>baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Right> <Right>current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.OpenGL.Egl.EglPlatformSurfaceRenderTargetBase.BeginDrawCore(System.Nullable{Avalonia.PixelSize})</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.OpenGL.IGlPlatformSurfaceRenderTargetFactory.CanRenderToSurface(Avalonia.OpenGL.IGlContext,System.Object)</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.OpenGL.IGlPlatformSurfaceRenderTargetFactory.CreateRenderTarget(Avalonia.OpenGL.IGlContext,System.Object)</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0002</DiagnosticId> <DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.OpenGL.Surfaces.IGlPlatformSurfaceRenderTarget.BeginDraw</Target> <Target>M:Avalonia.OpenGL.Surfaces.IGlPlatformSurfaceRenderTarget.BeginDraw</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Left> <Left>baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Right> <Right>current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.OpenGL.Surfaces.IGlPlatformSurfaceRenderTarget.BeginDraw(System.Nullable{Avalonia.PixelSize})</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Vulkan.IVulkanKhrSurfacePlatformSurfaceFactory.CanRenderToSurface(Avalonia.Vulkan.IVulkanPlatformGraphicsContext,System.Object)</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Vulkan.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Vulkan.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Vulkan.IVulkanKhrSurfacePlatformSurfaceFactory.CreateSurface(Avalonia.Vulkan.IVulkanPlatformGraphicsContext,System.Object)</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Vulkan.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Vulkan.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Vulkan.IVulkanPlatformGraphicsContext.CreateRenderTarget(System.Collections.Generic.IEnumerable{System.Object})</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Vulkan.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Vulkan.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0002</DiagnosticId> <DiagnosticId>CP0002</DiagnosticId>
<Target>F:Avalonia.Media.Fonts.FontCollectionBase._glyphTypefaceCache</Target> <Target>F:Avalonia.Media.Fonts.FontCollectionBase._glyphTypefaceCache</Target>
@ -2731,6 +2875,12 @@
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left> <Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right> <Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Platform.ICursorFactory.CreateCursor(Avalonia.Platform.IBitmapImpl,Avalonia.PixelPoint)</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0002</DiagnosticId> <DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Platform.IDrawingContextImplWithEffects.PushEffect(Avalonia.Media.IEffect)</Target> <Target>M:Avalonia.Platform.IDrawingContextImplWithEffects.PushEffect(Avalonia.Media.IEffect)</Target>
@ -2773,6 +2923,24 @@
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left> <Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right> <Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Platform.IPlatformRenderInterfaceContext.CreateRenderTarget(System.Collections.Generic.IEnumerable{System.Object})</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Platform.IRenderTarget.CreateDrawingContext(Avalonia.PixelSize,Avalonia.Platform.RenderTargetDrawingContextProperties@)</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Platform.IRenderTarget.CreateDrawingContext(System.Boolean)</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0002</DiagnosticId> <DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Platform.LockedFramebuffer.#ctor(System.IntPtr,Avalonia.PixelSize,System.Int32,Avalonia.Vector,Avalonia.Platform.PixelFormat,System.Action)</Target> <Target>M:Avalonia.Platform.LockedFramebuffer.#ctor(System.IntPtr,Avalonia.PixelSize,System.Int32,Avalonia.Vector,Avalonia.Platform.PixelFormat,System.Action)</Target>
@ -3049,6 +3217,12 @@
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left> <Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right> <Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Controls.Embedding.Offscreen.OffscreenTopLevelImplBase.get_Surfaces</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0002</DiagnosticId> <DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Controls.Generators.ItemContainerGenerator.ContainerFromIndex(System.Int32)</Target> <Target>M:Avalonia.Controls.Generators.ItemContainerGenerator.ContainerFromIndex(System.Int32)</Target>
@ -3343,6 +3517,12 @@
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left> <Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right> <Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Platform.ITopLevelImpl.get_Surfaces</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0002</DiagnosticId> <DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Platform.IWindowImpl.GetWindowsZOrder(System.Span{Avalonia.Controls.Window},System.Span{System.Int64})</Target> <Target>M:Avalonia.Platform.IWindowImpl.GetWindowsZOrder(System.Span{Avalonia.Controls.Window},System.Span{System.Int64})</Target>
@ -3457,18 +3637,66 @@
<Left>baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Left> <Left>baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Right> <Right>current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.OpenGL.Egl.EglPlatformSurfaceRenderTargetBase.BeginDraw(System.Nullable{Avalonia.PixelSize})</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0002</DiagnosticId> <DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.OpenGL.Egl.EglPlatformSurfaceRenderTargetBase.BeginDrawCore</Target> <Target>M:Avalonia.OpenGL.Egl.EglPlatformSurfaceRenderTargetBase.BeginDrawCore</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Left> <Left>baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Right> <Right>current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.OpenGL.Egl.EglPlatformSurfaceRenderTargetBase.BeginDrawCore(System.Nullable{Avalonia.PixelSize})</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.OpenGL.IGlPlatformSurfaceRenderTargetFactory.CanRenderToSurface(Avalonia.OpenGL.IGlContext,System.Object)</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.OpenGL.IGlPlatformSurfaceRenderTargetFactory.CreateRenderTarget(Avalonia.OpenGL.IGlContext,System.Object)</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0002</DiagnosticId> <DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.OpenGL.Surfaces.IGlPlatformSurfaceRenderTarget.BeginDraw</Target> <Target>M:Avalonia.OpenGL.Surfaces.IGlPlatformSurfaceRenderTarget.BeginDraw</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Left> <Left>baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Right> <Right>current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.OpenGL.Surfaces.IGlPlatformSurfaceRenderTarget.BeginDraw(System.Nullable{Avalonia.PixelSize})</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Vulkan.IVulkanKhrSurfacePlatformSurfaceFactory.CanRenderToSurface(Avalonia.Vulkan.IVulkanPlatformGraphicsContext,System.Object)</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Vulkan.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Vulkan.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Vulkan.IVulkanKhrSurfacePlatformSurfaceFactory.CreateSurface(Avalonia.Vulkan.IVulkanPlatformGraphicsContext,System.Object)</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Vulkan.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Vulkan.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0002</DiagnosticId>
<Target>M:Avalonia.Vulkan.IVulkanPlatformGraphicsContext.CreateRenderTarget(System.Collections.Generic.IEnumerable{System.Object})</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Vulkan.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Vulkan.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0002</DiagnosticId> <DiagnosticId>CP0002</DiagnosticId>
<Target>F:Avalonia.Media.Fonts.FontCollectionBase._glyphTypefaceCache</Target> <Target>F:Avalonia.Media.Fonts.FontCollectionBase._glyphTypefaceCache</Target>
@ -3511,12 +3739,48 @@
<Left>baseline/netstandard2.0/Avalonia.Base.dll</Left> <Left>baseline/netstandard2.0/Avalonia.Base.dll</Left>
<Right>target/netstandard2.0/Avalonia.Base.dll</Right> <Right>target/netstandard2.0/Avalonia.Base.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0005</DiagnosticId>
<Target>M:Avalonia.Controls.Embedding.Offscreen.OffscreenTopLevelImplBase.get_Surfaces</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0005</DiagnosticId>
<Target>P:Avalonia.Controls.Embedding.Offscreen.OffscreenTopLevelImplBase.Surfaces</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0005</DiagnosticId>
<Target>M:Avalonia.OpenGL.Egl.EglPlatformSurfaceRenderTargetBase.BeginDrawCore(Avalonia.Platform.IRenderTarget.RenderTargetSceneInfo)</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0005</DiagnosticId> <DiagnosticId>CP0005</DiagnosticId>
<Target>M:Avalonia.OpenGL.Egl.EglPlatformSurfaceRenderTargetBase.BeginDrawCore(System.Nullable{Avalonia.PixelSize})</Target> <Target>M:Avalonia.OpenGL.Egl.EglPlatformSurfaceRenderTargetBase.BeginDrawCore(System.Nullable{Avalonia.PixelSize})</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Left> <Left>baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Right> <Right>current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0005</DiagnosticId>
<Target>M:Avalonia.Controls.Embedding.Offscreen.OffscreenTopLevelImplBase.get_Surfaces</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0005</DiagnosticId>
<Target>P:Avalonia.Controls.Embedding.Offscreen.OffscreenTopLevelImplBase.Surfaces</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0005</DiagnosticId>
<Target>M:Avalonia.OpenGL.Egl.EglPlatformSurfaceRenderTargetBase.BeginDrawCore(Avalonia.Platform.IRenderTarget.RenderTargetSceneInfo)</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0005</DiagnosticId> <DiagnosticId>CP0005</DiagnosticId>
<Target>M:Avalonia.OpenGL.Egl.EglPlatformSurfaceRenderTargetBase.BeginDrawCore(System.Nullable{Avalonia.PixelSize})</Target> <Target>M:Avalonia.OpenGL.Egl.EglPlatformSurfaceRenderTargetBase.BeginDrawCore(System.Nullable{Avalonia.PixelSize})</Target>
@ -3529,6 +3793,12 @@
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left> <Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right> <Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Platform.ICursorFactory.CreateCursor(Avalonia.Media.Imaging.Bitmap,Avalonia.PixelPoint)</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0006</DiagnosticId> <DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Platform.IDrawingContextImpl.PopTextOptions</Target> <Target>M:Avalonia.Platform.IDrawingContextImpl.PopTextOptions</Target>
@ -3547,6 +3817,12 @@
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left> <Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right> <Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Platform.IDrawingContextLayerImpl.CreateDrawingContext</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0006</DiagnosticId> <DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Platform.IFontManagerImpl.TryMatchCharacter(System.Int32,Avalonia.Media.FontStyle,Avalonia.Media.FontWeight,Avalonia.Media.FontStretch,System.String,System.Globalization.CultureInfo,Avalonia.Media.Typeface@)</Target> <Target>M:Avalonia.Platform.IFontManagerImpl.TryMatchCharacter(System.Int32,Avalonia.Media.FontStyle,Avalonia.Media.FontWeight,Avalonia.Media.FontStretch,System.String,System.Globalization.CultureInfo,Avalonia.Media.Typeface@)</Target>
@ -3583,18 +3859,42 @@
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left> <Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right> <Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Platform.IPlatformRenderInterfaceContext.CreateRenderTarget(System.Collections.Generic.IEnumerable{Avalonia.Platform.Surfaces.IPlatformRenderSurface})</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0006</DiagnosticId> <DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Platform.IRenderTarget.CreateDrawingContext(Avalonia.PixelSize,Avalonia.Platform.RenderTargetDrawingContextProperties@)</Target> <Target>M:Avalonia.Platform.IRenderTarget.CreateDrawingContext(Avalonia.PixelSize,Avalonia.Platform.RenderTargetDrawingContextProperties@)</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left> <Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right> <Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Platform.IRenderTarget.CreateDrawingContext(Avalonia.Platform.IRenderTarget.RenderTargetSceneInfo,Avalonia.Platform.RenderTargetDrawingContextProperties@)</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Platform.IRenderTargetBitmapImpl.CreateDrawingContext</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0006</DiagnosticId> <DiagnosticId>CP0006</DiagnosticId>
<Target>P:Avalonia.Input.IInputRoot.FocusRoot</Target> <Target>P:Avalonia.Input.IInputRoot.FocusRoot</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left> <Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right> <Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>P:Avalonia.Platform.IDrawingContextLayerImpl.IsCorrupted</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0006</DiagnosticId> <DiagnosticId>CP0006</DiagnosticId>
<Target>P:Avalonia.Platform.ILockedFramebuffer.AlphaFormat</Target> <Target>P:Avalonia.Platform.ILockedFramebuffer.AlphaFormat</Target>
@ -3631,12 +3931,36 @@
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left> <Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right> <Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>P:Avalonia.Platform.ITopLevelImpl.Surfaces</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0006</DiagnosticId> <DiagnosticId>CP0006</DiagnosticId>
<Target>P:Avalonia.Platform.IWindowImpl.RequestedDrawnDecorations</Target> <Target>P:Avalonia.Platform.IWindowImpl.RequestedDrawnDecorations</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left> <Left>baseline/Avalonia/lib/net10.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right> <Right>current/Avalonia/lib/net10.0/Avalonia.Controls.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.OpenGL.IGlPlatformSurfaceRenderTargetFactory.CanRenderToSurface(Avalonia.OpenGL.IGlContext,Avalonia.Platform.Surfaces.IPlatformRenderSurface)</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.OpenGL.IGlPlatformSurfaceRenderTargetFactory.CreateRenderTarget(Avalonia.OpenGL.IGlContext,Avalonia.Platform.Surfaces.IPlatformRenderSurface)</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.OpenGL.Surfaces.IGlPlatformSurfaceRenderTarget.BeginDraw(Avalonia.Platform.IRenderTarget.RenderTargetSceneInfo)</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0006</DiagnosticId> <DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.OpenGL.Surfaces.IGlPlatformSurfaceRenderTarget.BeginDraw(System.Nullable{Avalonia.PixelSize})</Target> <Target>M:Avalonia.OpenGL.Surfaces.IGlPlatformSurfaceRenderTarget.BeginDraw(System.Nullable{Avalonia.PixelSize})</Target>
@ -3649,6 +3973,24 @@
<Left>baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Left> <Left>baseline/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Right> <Right>current/Avalonia/lib/net10.0/Avalonia.OpenGL.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Vulkan.IVulkanKhrSurfacePlatformSurfaceFactory.CanRenderToSurface(Avalonia.Vulkan.IVulkanPlatformGraphicsContext,Avalonia.Platform.Surfaces.IPlatformRenderSurface)</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Vulkan.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Vulkan.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Vulkan.IVulkanKhrSurfacePlatformSurfaceFactory.CreateSurface(Avalonia.Vulkan.IVulkanPlatformGraphicsContext,Avalonia.Platform.Surfaces.IPlatformRenderSurface)</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Vulkan.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Vulkan.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Vulkan.IVulkanPlatformGraphicsContext.CreateRenderTarget(System.Collections.Generic.IEnumerable{Avalonia.Platform.Surfaces.IPlatformRenderSurface})</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Vulkan.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Vulkan.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0006</DiagnosticId> <DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Input.Platform.IClipboard.SetDataAsync(Avalonia.Input.IAsyncDataTransfer)</Target> <Target>M:Avalonia.Input.Platform.IClipboard.SetDataAsync(Avalonia.Input.IAsyncDataTransfer)</Target>
@ -3739,6 +4081,12 @@
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left> <Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right> <Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Platform.ICursorFactory.CreateCursor(Avalonia.Media.Imaging.Bitmap,Avalonia.PixelPoint)</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0006</DiagnosticId> <DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Platform.IDrawingContextImpl.PopTextOptions</Target> <Target>M:Avalonia.Platform.IDrawingContextImpl.PopTextOptions</Target>
@ -3757,6 +4105,12 @@
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left> <Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right> <Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Platform.IDrawingContextLayerImpl.CreateDrawingContext</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0006</DiagnosticId> <DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Platform.IFontManagerImpl.TryMatchCharacter(System.Int32,Avalonia.Media.FontStyle,Avalonia.Media.FontWeight,Avalonia.Media.FontStretch,System.String,System.Globalization.CultureInfo,Avalonia.Media.Typeface@)</Target> <Target>M:Avalonia.Platform.IFontManagerImpl.TryMatchCharacter(System.Int32,Avalonia.Media.FontStyle,Avalonia.Media.FontWeight,Avalonia.Media.FontStretch,System.String,System.Globalization.CultureInfo,Avalonia.Media.Typeface@)</Target>
@ -3793,6 +4147,12 @@
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left> <Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right> <Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Platform.IPlatformRenderInterfaceContext.CreateRenderTarget(System.Collections.Generic.IEnumerable{Avalonia.Platform.Surfaces.IPlatformRenderSurface})</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0006</DiagnosticId> <DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Platform.IPlatformRenderInterfaceImportedImage.SnapshotWithTimelineSemaphores(Avalonia.Platform.IPlatformRenderInterfaceImportedSemaphore,System.UInt64,Avalonia.Platform.IPlatformRenderInterfaceImportedSemaphore,System.UInt64)</Target> <Target>M:Avalonia.Platform.IPlatformRenderInterfaceImportedImage.SnapshotWithTimelineSemaphores(Avalonia.Platform.IPlatformRenderInterfaceImportedSemaphore,System.UInt64,Avalonia.Platform.IPlatformRenderInterfaceImportedSemaphore,System.UInt64)</Target>
@ -3805,6 +4165,18 @@
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left> <Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right> <Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Platform.IRenderTarget.CreateDrawingContext(Avalonia.Platform.IRenderTarget.RenderTargetSceneInfo,Avalonia.Platform.RenderTargetDrawingContextProperties@)</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Platform.IRenderTargetBitmapImpl.CreateDrawingContext</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0006</DiagnosticId> <DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Platform.Storage.IStorageProvider.SaveFilePickerWithResultAsync(Avalonia.Platform.Storage.FilePickerSaveOptions)</Target> <Target>M:Avalonia.Platform.Storage.IStorageProvider.SaveFilePickerWithResultAsync(Avalonia.Platform.Storage.FilePickerSaveOptions)</Target>
@ -3817,6 +4189,12 @@
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left> <Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right> <Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>P:Avalonia.Platform.IDrawingContextLayerImpl.IsCorrupted</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0006</DiagnosticId> <DiagnosticId>CP0006</DiagnosticId>
<Target>P:Avalonia.Platform.ILockedFramebuffer.AlphaFormat</Target> <Target>P:Avalonia.Platform.ILockedFramebuffer.AlphaFormat</Target>
@ -3853,6 +4231,12 @@
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left> <Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right> <Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>P:Avalonia.Platform.ITopLevelImpl.Surfaces</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Controls.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Controls.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0006</DiagnosticId> <DiagnosticId>CP0006</DiagnosticId>
<Target>P:Avalonia.Platform.IWindowImpl.RequestedDrawnDecorations</Target> <Target>P:Avalonia.Platform.IWindowImpl.RequestedDrawnDecorations</Target>
@ -3871,6 +4255,24 @@
<Left>baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Left> <Left>baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Right> <Right>current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.OpenGL.IGlPlatformSurfaceRenderTargetFactory.CanRenderToSurface(Avalonia.OpenGL.IGlContext,Avalonia.Platform.Surfaces.IPlatformRenderSurface)</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.OpenGL.IGlPlatformSurfaceRenderTargetFactory.CreateRenderTarget(Avalonia.OpenGL.IGlContext,Avalonia.Platform.Surfaces.IPlatformRenderSurface)</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.OpenGL.Surfaces.IGlPlatformSurfaceRenderTarget.BeginDraw(Avalonia.Platform.IRenderTarget.RenderTargetSceneInfo)</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0006</DiagnosticId> <DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.OpenGL.Surfaces.IGlPlatformSurfaceRenderTarget.BeginDraw(System.Nullable{Avalonia.PixelSize})</Target> <Target>M:Avalonia.OpenGL.Surfaces.IGlPlatformSurfaceRenderTarget.BeginDraw(System.Nullable{Avalonia.PixelSize})</Target>
@ -3889,6 +4291,24 @@
<Left>baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Left> <Left>baseline/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Right> <Right>current/Avalonia/lib/net8.0/Avalonia.OpenGL.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Vulkan.IVulkanKhrSurfacePlatformSurfaceFactory.CanRenderToSurface(Avalonia.Vulkan.IVulkanPlatformGraphicsContext,Avalonia.Platform.Surfaces.IPlatformRenderSurface)</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Vulkan.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Vulkan.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Vulkan.IVulkanKhrSurfacePlatformSurfaceFactory.CreateSurface(Avalonia.Vulkan.IVulkanPlatformGraphicsContext,Avalonia.Platform.Surfaces.IPlatformRenderSurface)</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Vulkan.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Vulkan.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Vulkan.IVulkanPlatformGraphicsContext.CreateRenderTarget(System.Collections.Generic.IEnumerable{Avalonia.Platform.Surfaces.IPlatformRenderSurface})</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Vulkan.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Vulkan.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0006</DiagnosticId> <DiagnosticId>CP0006</DiagnosticId>
<Target>M:Avalonia.Input.Platform.IClipboard.SetDataAsync(Avalonia.Input.IAsyncDataTransfer)</Target> <Target>M:Avalonia.Input.Platform.IClipboard.SetDataAsync(Avalonia.Input.IAsyncDataTransfer)</Target>
@ -3985,6 +4405,18 @@
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left> <Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right> <Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0008</DiagnosticId>
<Target>T:Avalonia.Platform.IDrawingContextLayerImpl</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0008</DiagnosticId>
<Target>T:Avalonia.Platform.IDrawingContextLayerWithRenderContextAffinityImpl</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0008</DiagnosticId> <DiagnosticId>CP0008</DiagnosticId>
<Target>T:Avalonia.Platform.IPlatformGraphicsContext</Target> <Target>T:Avalonia.Platform.IPlatformGraphicsContext</Target>
@ -4003,6 +4435,12 @@
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left> <Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right> <Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0008</DiagnosticId>
<Target>T:Avalonia.Platform.IRenderTargetBitmapImpl</Target>
<Left>baseline/Avalonia/lib/net10.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net10.0/Avalonia.Base.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0008</DiagnosticId> <DiagnosticId>CP0008</DiagnosticId>
<Target>T:Avalonia.Platform.IWriteableBitmapImpl</Target> <Target>T:Avalonia.Platform.IWriteableBitmapImpl</Target>
@ -4153,6 +4591,18 @@
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left> <Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right> <Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0008</DiagnosticId>
<Target>T:Avalonia.Platform.IDrawingContextLayerImpl</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
</Suppression>
<Suppression>
<DiagnosticId>CP0008</DiagnosticId>
<Target>T:Avalonia.Platform.IDrawingContextLayerWithRenderContextAffinityImpl</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0008</DiagnosticId> <DiagnosticId>CP0008</DiagnosticId>
<Target>T:Avalonia.Platform.IPlatformGraphicsContext</Target> <Target>T:Avalonia.Platform.IPlatformGraphicsContext</Target>
@ -4171,6 +4621,12 @@
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left> <Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right> <Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
</Suppression> </Suppression>
<Suppression>
<DiagnosticId>CP0008</DiagnosticId>
<Target>T:Avalonia.Platform.IRenderTargetBitmapImpl</Target>
<Left>baseline/Avalonia/lib/net8.0/Avalonia.Base.dll</Left>
<Right>current/Avalonia/lib/net8.0/Avalonia.Base.dll</Right>
</Suppression>
<Suppression> <Suppression>
<DiagnosticId>CP0008</DiagnosticId> <DiagnosticId>CP0008</DiagnosticId>
<Target>T:Avalonia.Platform.IWriteableBitmapImpl</Target> <Target>T:Avalonia.Platform.IWriteableBitmapImpl</Target>

2
src/Android/Avalonia.Android/CursorFactory.cs

@ -5,7 +5,7 @@ namespace Avalonia.Android
{ {
internal class CursorFactory : ICursorFactory 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; public ICursorImpl GetCursor(StandardCursorType cursorType) => CursorImpl.ZeroCursor;

2
src/Android/Avalonia.Android/Platform/SkiaPlatform/FramebufferManager.cs

@ -1,5 +1,5 @@
using System; using System;
using Avalonia.Controls.Platform.Surfaces; using Avalonia.Platform.Surfaces;
using Avalonia.Platform; using Avalonia.Platform;
namespace Avalonia.Android.Platform.SkiaPlatform namespace Avalonia.Android.Platform.SkiaPlatform

3
src/Android/Avalonia.Android/Platform/SkiaPlatform/TopLevelImpl.cs

@ -18,6 +18,7 @@ using Avalonia.Input.Raw;
using Avalonia.Input.TextInput; using Avalonia.Input.TextInput;
using Avalonia.OpenGL.Egl; using Avalonia.OpenGL.Egl;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using Avalonia.Platform.Storage; using Avalonia.Platform.Storage;
using Avalonia.Rendering.Composition; using Avalonia.Rendering.Composition;
using Java.Lang; using Java.Lang;
@ -96,7 +97,7 @@ namespace Avalonia.Android.Platform.SkiaPlatform
public double DesktopScaling => RenderScaling; public double DesktopScaling => RenderScaling;
public IPlatformHandle Handle { get; } public IPlatformHandle Handle { get; }
public IEnumerable<object> Surfaces { get; } public IPlatformRenderSurface[] Surfaces { get; }
public Compositor Compositor => AndroidPlatform.Compositor ?? public Compositor Compositor => AndroidPlatform.Compositor ??
throw new InvalidOperationException("Android backend wasn't initialized. Make sure .UseAndroid() was executed."); throw new InvalidOperationException("Android backend wasn't initialized. Make sure .UseAndroid() was executed.");

5
src/Android/Avalonia.Android/Platform/Vulkan/VulkanSupport.cs

@ -2,6 +2,7 @@
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using Avalonia.Vulkan; using Avalonia.Vulkan;
namespace Avalonia.Android.Platform.Vulkan namespace Avalonia.Android.Platform.Vulkan
@ -24,10 +25,10 @@ namespace Avalonia.Android.Platform.Vulkan
internal class VulkanSurfaceFactory : IVulkanKhrSurfacePlatformSurfaceFactory internal class VulkanSurfaceFactory : IVulkanKhrSurfacePlatformSurfaceFactory
{ {
public bool CanRenderToSurface(IVulkanPlatformGraphicsContext context, object surface) => public bool CanRenderToSurface(IVulkanPlatformGraphicsContext context, IPlatformRenderSurface surface) =>
surface is INativePlatformHandleSurface handle; surface is INativePlatformHandleSurface handle;
public IVulkanKhrSurfacePlatformSurface CreateSurface(IVulkanPlatformGraphicsContext context, object handle) => public IVulkanKhrSurfacePlatformSurface CreateSurface(IVulkanPlatformGraphicsContext context, IPlatformRenderSurface handle) =>
new AndroidVulkanSurface((INativePlatformHandleSurface)handle); new AndroidVulkanSurface((INativePlatformHandleSurface)handle);
} }

2
src/Avalonia.Base/Input/Cursor.cs

@ -56,7 +56,7 @@ namespace Avalonia.Input
} }
public Cursor(Bitmap cursor, PixelPoint hotSpot) public Cursor(Bitmap cursor, PixelPoint hotSpot)
: this(GetCursorFactory().CreateCursor(cursor.PlatformImpl.Item, hotSpot), "BitmapCursor") : this(GetCursorFactory().CreateCursor(cursor, hotSpot), "BitmapCursor")
{ {
} }

26
src/Avalonia.Base/Media/Imaging/Bitmap.cs

@ -178,12 +178,8 @@ namespace Avalonia.Media.Imaging
public virtual AlphaFormat? AlphaFormat => (PlatformImpl.Item as IReadableBitmapImpl)?.AlphaFormat; public virtual AlphaFormat? AlphaFormat => (PlatformImpl.Item as IReadableBitmapImpl)?.AlphaFormat;
private protected unsafe void CopyPixelsCore(PixelRect sourceRect, IntPtr buffer, int bufferSize, int stride, private PixelRect ValidateSourceRect(PixelRect sourceRect)
ILockedFramebuffer fb)
{ {
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)) if ((sourceRect.Width <= 0 || sourceRect.Height <= 0) && (sourceRect.X != 0 || sourceRect.Y != 0))
throw new ArgumentOutOfRangeException(nameof(sourceRect)); throw new ArgumentOutOfRangeException(nameof(sourceRect));
@ -197,6 +193,16 @@ namespace Avalonia.Media.Imaging
if (sourceRect.Right > PixelSize.Width || sourceRect.Bottom > PixelSize.Height) if (sourceRect.Right > PixelSize.Width || sourceRect.Bottom > PixelSize.Height)
throw new ArgumentOutOfRangeException(nameof(sourceRect)); 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); int minStride = checked(((sourceRect.Width * fb.Format.BitsPerPixel) + 7) / 8);
if (stride < minStride) if (stride < minStride)
@ -223,7 +229,9 @@ namespace Avalonia.Media.Imaging
|| PlatformImpl.Item is not IReadableBitmapImpl readable || PlatformImpl.Item is not IReadableBitmapImpl readable
|| Format != readable.Format || Format != readable.Format
) )
{
throw new NotSupportedException("CopyPixels is not supported for this bitmap type"); throw new NotSupportedException("CopyPixels is not supported for this bitmap type");
}
if (_isTranscoded) if (_isTranscoded)
throw new NotSupportedException("CopyPixels is not supported for transcoded bitmaps"); 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) 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) if (buffer.Format != readable.Format || buffer.AlphaFormat != readable.AlphaFormat)

2
src/Avalonia.Base/Media/Imaging/RenderTargetBitmap.cs

@ -77,7 +77,7 @@ namespace Avalonia.Media.Imaging
/// <returns>The drawing context.</returns> /// <returns>The drawing context.</returns>
public DrawingContext CreateDrawingContext(bool clear) public DrawingContext CreateDrawingContext(bool clear)
{ {
var platform = PlatformImpl.Item.CreateDrawingContext(true); var platform = PlatformImpl.Item.CreateDrawingContext();
if(clear) if(clear)
platform.Clear(Colors.Transparent); platform.Clear(Colors.Transparent);
return new PlatformDrawingContext(platform); return new PlatformDrawingContext(platform);

3
src/Avalonia.Base/Platform/ICursorFactory.cs

@ -1,4 +1,5 @@
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Media.Imaging;
using Avalonia.Metadata; using Avalonia.Metadata;
#nullable enable #nullable enable
@ -9,6 +10,6 @@ namespace Avalonia.Platform
public interface ICursorFactory public interface ICursorFactory
{ {
ICursorImpl GetCursor(StandardCursorType cursorType); ICursorImpl GetCursor(StandardCursorType cursorType);
ICursorImpl CreateCursor(IBitmapImpl cursor, PixelPoint hotSpot); ICursorImpl CreateCursor(Bitmap cursor, PixelPoint hotSpot);
} }
} }

12
src/Avalonia.Base/Platform/IDrawingContextImpl.cs

@ -228,7 +228,7 @@ namespace Avalonia.Platform
(T?)context.GetFeature(typeof(T)); (T?)context.GetFeature(typeof(T));
} }
public interface IDrawingContextLayerImpl : IRenderTargetBitmapImpl public interface IDrawingContextLayerImpl : IBitmapImpl
{ {
/// <summary> /// <summary>
/// Does optimized blit with Src blend mode. /// Does optimized blit with Src blend mode.
@ -240,6 +240,16 @@ namespace Avalonia.Platform
/// Returns true if layer supports optimized blit. /// Returns true if layer supports optimized blit.
/// </summary> /// </summary>
bool CanBlit { get; } bool CanBlit { get; }
/// <summary>
/// Indicates if the render target is no longer usable and needs to be recreated
/// </summary>
bool IsCorrupted { get; }
/// <summary>
/// Creates drawing context. It matches the properties of the original drawing context this layer was created from.
/// </summary>
IDrawingContextImpl CreateDrawingContext();
} }
public interface IDrawingContextLayerWithRenderContextAffinityImpl : IDrawingContextLayerImpl public interface IDrawingContextLayerWithRenderContextAffinityImpl : IDrawingContextLayerImpl

8
src/Avalonia.Base/Platform/IPlatformRenderInterface.cs

@ -5,6 +5,7 @@ using Avalonia.Media;
using Avalonia.Media.Imaging; using Avalonia.Media.Imaging;
using Avalonia.Media.TextFormatting; using Avalonia.Media.TextFormatting;
using Avalonia.Metadata; using Avalonia.Metadata;
using Avalonia.Platform.Surfaces;
namespace Avalonia.Platform namespace Avalonia.Platform
{ {
@ -214,7 +215,7 @@ namespace Avalonia.Platform
/// The list of native platform surfaces that can be used for output. /// The list of native platform surfaces that can be used for output.
/// </param> /// </param>
/// <returns>An <see cref="IRenderTarget"/>.</returns> /// <returns>An <see cref="IRenderTarget"/>.</returns>
IRenderTarget CreateRenderTarget(IEnumerable<object> surfaces); IRenderTarget CreateRenderTarget(IEnumerable<IPlatformRenderSurface> surfaces);
/// <summary> /// <summary>
/// Creates an offscreen render target /// Creates an offscreen render target
@ -239,5 +240,10 @@ namespace Avalonia.Platform
/// Maximum supported offscreen render target pixel size, or null if no limit /// Maximum supported offscreen render target pixel size, or null if no limit
/// </summary> /// </summary>
public PixelSize? MaxOffscreenRenderTargetPixelSize { get; } public PixelSize? MaxOffscreenRenderTargetPixelSize { get; }
/// <summary>
/// Checks if a render target can be created for the given surfaces and the preferred surface is ready
/// </summary>
bool IsReadyToCreateRenderTarget(IEnumerable<IPlatformRenderSurface> surfaces) => true;
} }
} }

18
src/Avalonia.Base/Platform/IRenderTarget.cs

@ -25,16 +25,18 @@ namespace Avalonia.Platform
/// <summary> /// <summary>
/// Creates an <see cref="IDrawingContextImpl"/> for a rendering session. /// Creates an <see cref="IDrawingContextImpl"/> for a rendering session.
/// </summary> /// </summary>
/// <param name="useScaledDrawing">Apply DPI reported by the render target as a hidden transform matrix</param> /// <param name="sceneInfo">Information about the scene that's about to be rendered into this render target.
IDrawingContextImpl CreateDrawingContext(bool useScaledDrawing); /// This is expected to be reported to the underlying platform and affect the framebuffer size, however
/// the implementation may choose to ignore that information.
/// </param>
/// <param name="properties">Returns various properties about the returned drawing context</param>
IDrawingContextImpl CreateDrawingContext(RenderTargetSceneInfo sceneInfo, out RenderTargetDrawingContextProperties properties);
/// <summary> /// <summary>
/// Creates an <see cref="IDrawingContextImpl"/> for a rendering session. /// Indicates if the render target is currently ready to be rendered to
/// </summary> /// </summary>
/// <param name="expectedPixelSize">The pixel size of the surface</param> bool IsReady => true;
/// <param name="properties">Returns various properties about the returned drawing context</param>
IDrawingContextImpl CreateDrawingContext( public record struct RenderTargetSceneInfo(PixelSize Size, double Scaling);
PixelSize expectedPixelSize,
out RenderTargetDrawingContextProperties properties);
} }
} }

3
src/Avalonia.Base/Platform/IRenderTargetBitmapImpl.cs

@ -7,7 +7,8 @@ namespace Avalonia.Platform
/// <see cref="Avalonia.Media.Imaging.RenderTargetBitmap"/>. /// <see cref="Avalonia.Media.Imaging.RenderTargetBitmap"/>.
/// </summary> /// </summary>
[Unstable] [Unstable]
public interface IRenderTargetBitmapImpl : IBitmapImpl, IRenderTarget public interface IRenderTargetBitmapImpl : IReadableBitmapImpl
{ {
IDrawingContextImpl CreateDrawingContext();
} }
} }

66
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
{
/// <summary>
/// Provides a framebuffer descriptor for drawing.
/// </summary>
/// <remarks>
/// Contents should be drawn on actual window after disposing
/// </remarks>
ILockedFramebuffer Lock(IRenderTarget.RenderTargetSceneInfo sceneInfo, out FramebufferLockProperties properties);
bool RetainsFrameContents => false;
}
[PrivateApi]
public record struct FramebufferLockProperties(bool PreviousFrameIsRetained);
/// <summary>
/// For simple cases when framebuffer is always available
/// </summary>
public class FuncFramebufferRenderTarget : IFramebufferRenderTarget
{
public delegate ILockedFramebuffer LockFramebufferDelegate(IRenderTarget.RenderTargetSceneInfo sceneInfo, out FramebufferLockProperties properties);
private readonly LockFramebufferDelegate _lockFramebuffer;
public FuncFramebufferRenderTarget(Func<ILockedFramebuffer> 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; }
}
}

15
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;
}

4
src/Avalonia.Base/Rendering/Composition/CompositingRenderer.cs

@ -8,6 +8,8 @@ using System.Threading.Tasks;
using Avalonia.Collections; using Avalonia.Collections;
using Avalonia.Collections.Pooled; using Avalonia.Collections.Pooled;
using Avalonia.Diagnostics; using Avalonia.Diagnostics;
using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.Rendering.Composition.Drawing; using Avalonia.Rendering.Composition.Drawing;
using Avalonia.Threading; using Avalonia.Threading;
@ -48,7 +50,7 @@ internal class CompositingRenderer : IRendererWithCompositor, IHitTester
/// <param name="surfaces"> /// <param name="surfaces">
/// A function returning the list of native platform's surfaces that can be consumed by rendering subsystems. /// A function returning the list of native platform's surfaces that can be consumed by rendering subsystems.
/// </param> /// </param>
public CompositingRenderer(IPresentationSource root, Compositor compositor, Func<IEnumerable<object>> surfaces) public CompositingRenderer(IPresentationSource root, Compositor compositor, Func<IEnumerable<IPlatformRenderSurface>> surfaces)
{ {
_root = root; _root = root;
_compositor = compositor; _compositor = compositor;

4
src/Avalonia.Base/Rendering/Composition/Compositor.Factories.cs

@ -1,5 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using Avalonia.Rendering.Composition.Animations; using Avalonia.Rendering.Composition.Animations;
using Avalonia.Rendering.Composition.Server; using Avalonia.Rendering.Composition.Server;
@ -12,7 +14,7 @@ public partial class Compositor
/// </summary> /// </summary>
/// <param name="surfaces">A factory method to create IRenderTarget to be called from the render thread</param> /// <param name="surfaces">A factory method to create IRenderTarget to be called from the render thread</param>
/// <returns></returns> /// <returns></returns>
internal CompositionTarget CreateCompositionTarget(Func<IEnumerable<object>> surfaces) internal CompositionTarget CreateCompositionTarget(Func<IEnumerable<IPlatformRenderSurface>> surfaces)
{ {
return new CompositionTarget(this, new ServerCompositionTarget(_server, surfaces)); return new CompositionTarget(this, new ServerCompositionTarget(_server, surfaces));
} }

15
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionTarget.cs

@ -8,6 +8,7 @@ using Avalonia.Media;
using Avalonia.Media.Imaging; using Avalonia.Media.Imaging;
using Avalonia.Media.Immutable; using Avalonia.Media.Immutable;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using Avalonia.Rendering.Composition.Transport; using Avalonia.Rendering.Composition.Transport;
using Avalonia.Utilities; using Avalonia.Utilities;
@ -20,7 +21,7 @@ namespace Avalonia.Rendering.Composition.Server
internal partial class ServerCompositionTarget : IDisposable internal partial class ServerCompositionTarget : IDisposable
{ {
private readonly ServerCompositor _compositor; private readonly ServerCompositor _compositor;
private readonly Func<IEnumerable<object>> _surfaces; private readonly Func<IEnumerable<IPlatformRenderSurface>> _surfaces;
private CompositionTargetOverlays _overlays; private CompositionTargetOverlays _overlays;
private static long s_nextId = 1; private static long s_nextId = 1;
private IRenderTarget? _renderTarget; private IRenderTarget? _renderTarget;
@ -39,7 +40,7 @@ namespace Avalonia.Rendering.Composition.Server
public int RenderedVisuals { get; set; } public int RenderedVisuals { get; set; }
public int VisitedVisuals { get; set; } public int VisitedVisuals { get; set; }
public ServerCompositionTarget(ServerCompositor compositor, Func<IEnumerable<object>> surfaces) public ServerCompositionTarget(ServerCompositor compositor, Func<IEnumerable<IPlatformRenderSurface>> surfaces)
: base(compositor) : base(compositor)
{ {
_compositor = compositor; _compositor = compositor;
@ -141,6 +142,8 @@ namespace Avalonia.Rendering.Composition.Server
try try
{ {
if (_renderTarget == null && !_compositor.IsReadyToCreateRenderTarget(_surfaces()))
return;
_renderTarget ??= _compositor.CreateRenderTarget(_surfaces()); _renderTarget ??= _compositor.CreateRenderTarget(_surfaces());
} }
catch (RenderTargetNotReadyException) catch (RenderTargetNotReadyException)
@ -160,13 +163,15 @@ namespace Avalonia.Rendering.Composition.Server
if (!_redrawRequested) if (!_redrawRequested)
return; return;
if (!_renderTarget.IsReady)
return;
var needLayer = _overlays.RequireLayer // Check if we don't need overlays 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 // Check if render target can be rendered to directly and preserves the previous frame
|| !(_renderTarget.Properties.RetainsPreviousFrameContents || !(_renderTarget.Properties.RetainsPreviousFrameContents
&& _renderTarget.Properties.IsSuitableForDirectRendering); && _renderTarget.Properties.IsSuitableForDirectRendering);
using (var renderTargetContext = _renderTarget.CreateDrawingContext( using (var renderTargetContext = _renderTarget.CreateDrawingContext(new(PixelSize, Scaling), out var properties))
this.PixelSize, out var properties))
using (var renderTiming = Diagnostic.BeginCompositorRenderPass()) using (var renderTiming = Diagnostic.BeginCompositorRenderPass())
{ {
var fullRedraw = false; var fullRedraw = false;
@ -203,7 +208,7 @@ namespace Avalonia.Rendering.Composition.Server
DirtyRects.FinalizeFrame(renderBounds); DirtyRects.FinalizeFrame(renderBounds);
if (_layer != null) if (_layer != null)
{ {
using (var context = _layer.CreateDrawingContext(false)) using (var context = _layer.CreateDrawingContext())
RenderRootToContextWithClip(context, Root); RenderRootToContextWithClip(context, Root);
renderTargetContext.Clear(Colors.Transparent); renderTargetContext.Clear(Colors.Transparent);

2
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositionVisual/ServerCompositionVisualCache.cs

@ -193,7 +193,7 @@ internal class ServerCompositionVisualCache
// Render to layer if needed // Render to layer if needed
if (!_dirtyRectTracker.IsEmpty) if (!_dirtyRectTracker.IsEmpty)
{ {
using var ctx = _layer.CreateDrawingContext(false); using var ctx = _layer.CreateDrawingContext();
using (_needsFullReRender ? null : _dirtyRectTracker.BeginDraw(ctx)) using (_needsFullReRender ? null : _dirtyRectTracker.BeginDraw(ctx))
{ {
ctx.Clear(Colors.Transparent); ctx.Clear(Colors.Transparent);

2
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositor.UserApis.cs

@ -62,7 +62,7 @@ internal partial class ServerCompositor
try try
{ {
target = RenderInterface.Value.CreateOffscreenRenderTarget(pixelSize, new(scaling, scaling), true); target = RenderInterface.Value.CreateOffscreenRenderTarget(pixelSize, new(scaling, scaling), true);
using (var canvas = target.CreateDrawingContext(false)) using (var canvas = target.CreateDrawingContext())
{ {
canvas.Transform = scaleTransform; canvas.Transform = scaleTransform;
visual.Render(canvas, LtrbRect.Infinite, null, renderChildren); visual.Render(canvas, LtrbRect.Infinite, null, renderChildren);

8
src/Avalonia.Base/Rendering/Composition/Server/ServerCompositor.cs

@ -4,6 +4,7 @@ using System.Diagnostics;
using System.Threading; using System.Threading;
using Avalonia.Logging; using Avalonia.Logging;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using Avalonia.Rendering.Composition.Animations; using Avalonia.Rendering.Composition.Animations;
using Avalonia.Rendering.Composition.Expressions; using Avalonia.Rendering.Composition.Expressions;
using Avalonia.Rendering.Composition.Transport; using Avalonia.Rendering.Composition.Transport;
@ -274,12 +275,17 @@ namespace Avalonia.Rendering.Composition.Server
_activeTargets.Remove(target); _activeTargets.Remove(target);
} }
public IRenderTarget CreateRenderTarget(IEnumerable<object> surfaces) public IRenderTarget CreateRenderTarget(IEnumerable<IPlatformRenderSurface> surfaces)
{ {
using (RenderInterface.EnsureCurrent()) using (RenderInterface.EnsureCurrent())
return RenderInterface.CreateRenderTarget(surfaces); return RenderInterface.CreateRenderTarget(surfaces);
} }
public bool IsReadyToCreateRenderTarget(IEnumerable<IPlatformRenderSurface> surfaces)
{
return RenderInterface.IsReadyToCreateRenderTarget(surfaces);
}
public bool CheckAccess() => _safeThread == Thread.CurrentThread; public bool CheckAccess() => _safeThread == Thread.CurrentThread;
public void VerifyAccess() public void VerifyAccess()
{ {

10
src/Avalonia.Base/Rendering/PlatformRenderInterfaceContextManager.cs

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using Avalonia.Metadata; using Avalonia.Metadata;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using Avalonia.Reactive; using Avalonia.Reactive;
namespace Avalonia.Rendering; namespace Avalonia.Rendering;
@ -77,9 +78,16 @@ internal class PlatformRenderInterfaceContextManager
return Disposable.Empty; return Disposable.Empty;
} }
public IRenderTarget CreateRenderTarget(IEnumerable<object> surfaces) public IRenderTarget CreateRenderTarget(IEnumerable<IPlatformRenderSurface> surfaces)
{ {
EnsureValidBackendContext(); EnsureValidBackendContext();
return _backend!.CreateRenderTarget(surfaces); return _backend!.CreateRenderTarget(surfaces);
} }
public bool IsReadyToCreateRenderTarget(IEnumerable<IPlatformRenderSurface> surfaces)
{
if (_backend == null)
return IsReady;
return _backend.IsReadyToCreateRenderTarget(surfaces);
}
} }

3
src/Avalonia.Controls/Embedding/Offscreen/OffscreenTopLevelImpl.cs

@ -4,6 +4,7 @@ using Avalonia.Input;
using Avalonia.Input.Raw; using Avalonia.Input.Raw;
using Avalonia.Metadata; using Avalonia.Metadata;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using Avalonia.Rendering.Composition; using Avalonia.Rendering.Composition;
namespace Avalonia.Controls.Embedding.Offscreen namespace Avalonia.Controls.Embedding.Offscreen
@ -27,7 +28,7 @@ namespace Avalonia.Controls.Embedding.Offscreen
public OffscreenTopLevelImplBase() public OffscreenTopLevelImplBase()
=> Compositor = new Compositor(null); => Compositor = new Compositor(null);
public abstract IEnumerable<object> Surfaces { get; } public abstract IPlatformRenderSurface[] Surfaces { get; }
public virtual double DesktopScaling => _scaling; public virtual double DesktopScaling => _scaling;

3
src/Avalonia.Controls/Platform/IPlatformNativeSurfaceHandle.cs

@ -1,10 +1,11 @@
using System; using System;
using Avalonia.Platform.Surfaces;
using Avalonia.Metadata; using Avalonia.Metadata;
namespace Avalonia.Platform namespace Avalonia.Platform
{ {
[Unstable] [Unstable]
public interface INativePlatformHandleSurface : IPlatformHandle public interface INativePlatformHandleSurface : IPlatformHandle, IPlatformRenderSurface
{ {
PixelSize Size { get; } PixelSize Size { get; }
double Scaling { get; } double Scaling { get; }

3
src/Avalonia.Controls/Platform/ITopLevelImpl.cs

@ -4,6 +4,7 @@ using Avalonia.Controls;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Input.Raw; using Avalonia.Input.Raw;
using Avalonia.Metadata; using Avalonia.Metadata;
using Avalonia.Platform.Surfaces;
using Avalonia.Rendering.Composition; using Avalonia.Rendering.Composition;
namespace Avalonia.Platform namespace Avalonia.Platform
@ -48,7 +49,7 @@ namespace Avalonia.Platform
/// If you have some rendering platform that's tied to your particular windowing platform, /// If you have some rendering platform that's tied to your particular windowing platform,
/// just expose some toolkit-specific object (e. g. Func&lt;Gdk.Drawable&gt; in case of GTK#+Cairo) /// just expose some toolkit-specific object (e. g. Func&lt;Gdk.Drawable&gt; in case of GTK#+Cairo)
/// </remarks> /// </remarks>
IEnumerable<object> Surfaces { get; } IPlatformRenderSurface[] Surfaces { get; }
/// <summary> /// <summary>
/// Gets or sets a method called when the toplevel receives input. /// Gets or sets a method called when the toplevel receives input.

86
src/Avalonia.Controls/Platform/Surfaces/IFramebufferPlatformSurface.cs

@ -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
{
/// <summary>
/// Provides a framebuffer descriptor for drawing.
/// </summary>
/// <remarks>
/// Contents should be drawn on actual window after disposing
/// </remarks>
ILockedFramebuffer Lock();
}
[PrivateApi]
public interface IFramebufferRenderTargetWithProperties : IFramebufferRenderTarget
{
/// <summary>
/// Provides a framebuffer descriptor for drawing.
/// </summary>
/// <remarks>
/// Contents should be drawn on actual window after disposing
/// </remarks>
ILockedFramebuffer Lock(out FramebufferLockProperties properties);
bool RetainsFrameContents { get; }
}
[PrivateApi]
public record struct FramebufferLockProperties(bool PreviousFrameIsRetained);
/// <summary>
/// For simple cases when framebuffer is always available
/// </summary>
public class FuncFramebufferRenderTarget : IFramebufferRenderTarget
{
private readonly Func<ILockedFramebuffer> _lockFramebuffer;
public FuncFramebufferRenderTarget(Func<ILockedFramebuffer> 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;
}
}

4
src/Avalonia.Controls/Remote/Server/RemoteServerTopLevelImpl.cs

@ -1,12 +1,12 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Avalonia.Controls.Embedding.Offscreen; using Avalonia.Controls.Embedding.Offscreen;
using Avalonia.Controls.Platform.Surfaces;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Input.Raw; using Avalonia.Input.Raw;
using Avalonia.Layout; using Avalonia.Layout;
using Avalonia.Metadata; using Avalonia.Metadata;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using Avalonia.Remote.Protocol; using Avalonia.Remote.Protocol;
using Avalonia.Remote.Protocol.Input; using Avalonia.Remote.Protocol.Input;
using Avalonia.Remote.Protocol.Viewport; using Avalonia.Remote.Protocol.Viewport;
@ -270,7 +270,7 @@ namespace Avalonia.Controls.Remote.Server
return l.DesiredSize; return l.DesiredSize;
} }
public override IEnumerable<object> Surfaces => new[] { this }; public override IPlatformRenderSurface[] Surfaces => [this];
private Framebuffer GetOrCreateFramebuffer() private Framebuffer GetOrCreateFramebuffer()
{ {

6
src/Avalonia.DesignerSupport/Remote/Stubs.cs

@ -10,7 +10,9 @@ using Avalonia.Controls.Primitives.PopupPositioning;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Input.Platform; using Avalonia.Input.Platform;
using Avalonia.Input.Raw; using Avalonia.Input.Raw;
using Avalonia.Media.Imaging;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using Avalonia.Platform.Storage; using Avalonia.Platform.Storage;
using Avalonia.Platform.Storage.FileIO; using Avalonia.Platform.Storage.FileIO;
using Avalonia.Rendering; using Avalonia.Rendering;
@ -28,7 +30,7 @@ namespace Avalonia.DesignerSupport.Remote
public Size? FrameSize => null; public Size? FrameSize => null;
public double RenderScaling { get; } = 1.0; public double RenderScaling { get; } = 1.0;
public double DesktopScaling => 1.0; public double DesktopScaling => 1.0;
public IEnumerable<object> Surfaces => []; public IPlatformRenderSurface[] Surfaces => [];
public Action<RawInputEventArgs>? Input { get; set; } public Action<RawInputEventArgs>? Input { get; set; }
public Action<Rect>? Paint { get; set; } public Action<Rect>? Paint { get; set; }
public Action<Size, WindowResizeReason>? Resized { get; set; } public Action<Size, WindowResizeReason>? Resized { get; set; }
@ -235,7 +237,7 @@ namespace Avalonia.DesignerSupport.Remote
class CursorFactoryStub : ICursorFactory class CursorFactoryStub : ICursorFactory
{ {
public ICursorImpl GetCursor(StandardCursorType cursorType) => new CursorStub(); 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 private class CursorStub : ICursorImpl
{ {

5
src/Avalonia.Metal/IMetalDevice.cs

@ -1,6 +1,7 @@
using System; using System;
using Avalonia.Metadata; using Avalonia.Metadata;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
namespace Avalonia.Metal; namespace Avalonia.Metal;
@ -13,13 +14,13 @@ public interface IMetalDevice : IPlatformGraphicsContext
} }
[PrivateApi] [PrivateApi]
public interface IMetalPlatformSurface public interface IMetalPlatformSurface : IPlatformRenderSurface
{ {
IMetalPlatformSurfaceRenderTarget CreateMetalRenderTarget(IMetalDevice device); IMetalPlatformSurfaceRenderTarget CreateMetalRenderTarget(IMetalDevice device);
} }
[PrivateApi] [PrivateApi]
public interface IMetalPlatformSurfaceRenderTarget : IDisposable public interface IMetalPlatformSurfaceRenderTarget : IDisposable, IPlatformRenderSurfaceRenderTarget
{ {
IMetalPlatformSurfaceRenderingSession BeginRendering(); IMetalPlatformSurfaceRenderingSession BeginRendering();
} }

2
src/Avalonia.Native/AvaloniaNativeGlPlatformGraphics.cs

@ -175,7 +175,7 @@ namespace Avalonia.Native
public bool IsCorrupted => false; public bool IsCorrupted => false;
public IGlPlatformSurfaceRenderingSession BeginDraw(PixelSize? expectedPixelSize) public IGlPlatformSurfaceRenderingSession BeginDraw(IRenderTarget.RenderTargetSceneInfo sceneInfo)
{ {
// TODO: use expectedPixelSize // TODO: use expectedPixelSize
ObjectDisposedException.ThrowIf(_target is null, this); ObjectDisposedException.ThrowIf(_target is null, this);

3
src/Avalonia.Native/Cursor.cs

@ -1,6 +1,7 @@
using System; using System;
using System.IO; using System.IO;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Media.Imaging;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Native.Interop; using Avalonia.Native.Interop;
@ -40,7 +41,7 @@ namespace Avalonia.Native
return new AvaloniaNativeCursor( cursor ); 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()) using(var ms = new MemoryStream())
{ {

1
src/Avalonia.Native/DeferredFramebuffer.cs

@ -1,6 +1,5 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Avalonia.Controls.Platform.Surfaces;
using Avalonia.Native.Interop; using Avalonia.Native.Interop;
using Avalonia.Platform; using Avalonia.Platform;

15
src/Avalonia.Native/TopLevelImpl.cs

@ -4,13 +4,13 @@ using System.Runtime.InteropServices;
using Avalonia.Automation.Peers; using Avalonia.Automation.Peers;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Platform; using Avalonia.Controls.Platform;
using Avalonia.Controls.Platform.Surfaces;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Input.Platform; using Avalonia.Input.Platform;
using Avalonia.Input.Raw; using Avalonia.Input.Raw;
using Avalonia.Input.TextInput; using Avalonia.Input.TextInput;
using Avalonia.Native.Interop; using Avalonia.Native.Interop;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using Avalonia.Platform.Storage; using Avalonia.Platform.Storage;
using Avalonia.Platform.Storage.FileIO; using Avalonia.Platform.Storage.FileIO;
using Avalonia.Rendering.Composition; using Avalonia.Rendering.Composition;
@ -80,7 +80,7 @@ internal class TopLevelImpl : ITopLevelImpl, IFramebufferPlatformSurface
protected MacOSTopLevelHandle? _handle; protected MacOSTopLevelHandle? _handle;
private object _syncRoot = new object(); private object _syncRoot = new object();
private IEnumerable<object>? _surfaces; private IPlatformRenderSurface[]? _surfaces;
public TopLevelImpl(IAvaloniaNativeFactory factory) public TopLevelImpl(IAvaloniaNativeFactory factory)
{ {
@ -99,7 +99,7 @@ internal class TopLevelImpl : ITopLevelImpl, IFramebufferPlatformSurface
_savedScaling = Native?.Scaling ?? 1; _savedScaling = Native?.Scaling ?? 1;
_nativeControlHost = new NativeControlHostImpl(Native!.CreateNativeControlHost()); _nativeControlHost = new NativeControlHostImpl(Native!.CreateNativeControlHost());
_platformBehaviorInhibition = new PlatformBehaviorInhibition(Factory.CreatePlatformBehaviorInhibition()); _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); InputMethod = new AvaloniaNativeTextInputMethod(Native);
} }
@ -134,7 +134,7 @@ internal class TopLevelImpl : ITopLevelImpl, IFramebufferPlatformSurface
} }
public double RenderScaling => _savedScaling; public double RenderScaling => _savedScaling;
public IEnumerable<object> Surfaces => _surfaces ?? Array.Empty<object>(); public IPlatformRenderSurface[] Surfaces => _surfaces ?? [];
public Action<RawInputEventArgs>? Input { get; set; } public Action<RawInputEventArgs>? Input { get; set; }
public Action<Rect>? Paint { get; set; } public Action<Rect>? Paint { get; set; }
public Action<Size, WindowResizeReason>? Resized { get; set; } public Action<Size, WindowResizeReason>? 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); ObjectDisposedException.ThrowIf(_target is null, this);
properties = default;
var w = Math.Max(_parent._savedLogicalSize.Width * _parent._savedScaling, 1); var w = Math.Max(_parent._savedLogicalSize.Width * _parent._savedScaling, 1);
var h = Math.Max(_parent._savedLogicalSize.Height * _parent._savedScaling, 1); var h = Math.Max(_parent._savedLogicalSize.Height * _parent._savedScaling, 1);
var dpi = _parent._savedScaling * 96; var dpi = _parent._savedScaling * 96;
@ -580,5 +581,7 @@ internal class TopLevelImpl : ITopLevelImpl, IFramebufferPlatformSurface
} }
}, (int)w, (int)h, new Vector(dpi, dpi)); }, (int)w, (int)h, new Vector(dpi, dpi));
} }
public bool RetainsFrameContents => false;
} }
} }

3
src/Avalonia.OpenGL/Egl/EglGlPlatformSurface.cs

@ -1,6 +1,7 @@
using System; using System;
using Avalonia.Metadata; using Avalonia.Metadata;
using Avalonia.OpenGL.Surfaces; using Avalonia.OpenGL.Surfaces;
using Avalonia.Platform;
namespace Avalonia.OpenGL.Egl namespace Avalonia.OpenGL.Egl
{ {
@ -54,7 +55,7 @@ namespace Avalonia.OpenGL.Egl
public override void Dispose() => _glSurface?.Dispose(); public override void Dispose() => _glSurface?.Dispose();
public override IGlPlatformSurfaceRenderingSession BeginDrawCore(PixelSize? expectedPixelSize) public override IGlPlatformSurfaceRenderingSession BeginDrawCore(IRenderTarget.RenderTargetSceneInfo sceneInfo)
{ {
// TODO: use expectedPixelSize // TODO: use expectedPixelSize
if (_info.Size != _currentSize if (_info.Size != _currentSize

7
src/Avalonia.OpenGL/Egl/EglGlPlatformSurfaceBase.cs

@ -1,5 +1,6 @@
using System; using System;
using Avalonia.OpenGL.Surfaces; using Avalonia.OpenGL.Surfaces;
using Avalonia.Platform;
namespace Avalonia.OpenGL.Egl 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) if (Context.IsLost)
throw new RenderTargetCorruptedException(); throw new RenderTargetCorruptedException();
return BeginDrawCore(expectedPixelSize); return BeginDrawCore(sceneInfo);
} }
private protected virtual bool SkipWaits => false; private protected virtual bool SkipWaits => false;
public abstract IGlPlatformSurfaceRenderingSession BeginDrawCore(PixelSize? expectedPixelSize); public abstract IGlPlatformSurfaceRenderingSession BeginDrawCore(IRenderTarget.RenderTargetSceneInfo sceneInfo);
protected IGlPlatformSurfaceRenderingSession BeginDraw(EglSurface surface, protected IGlPlatformSurfaceRenderingSession BeginDraw(EglSurface surface,
PixelSize size, double scaling, Action? onFinish = null, bool isYFlipped = false) PixelSize size, double scaling, Action? onFinish = null, bool isYFlipped = false)

5
src/Avalonia.OpenGL/IGlContext.cs

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using Avalonia.OpenGL.Surfaces; using Avalonia.OpenGL.Surfaces;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
namespace Avalonia.OpenGL namespace Avalonia.OpenGL
{ {
@ -19,7 +20,7 @@ namespace Avalonia.OpenGL
public interface IGlPlatformSurfaceRenderTargetFactory public interface IGlPlatformSurfaceRenderTargetFactory
{ {
bool CanRenderToSurface(IGlContext context, object surface); bool CanRenderToSurface(IGlContext context, IPlatformRenderSurface surface);
IGlPlatformSurfaceRenderTarget CreateRenderTarget(IGlContext context, object surface); IGlPlatformSurfaceRenderTarget CreateRenderTarget(IGlContext context, IPlatformRenderSurface surface);
} }
} }

10
src/Avalonia.OpenGL/IGlContextExternalObjectsFeature.cs

@ -6,8 +6,7 @@ using Avalonia.Rendering.Composition;
namespace Avalonia.OpenGL; namespace Avalonia.OpenGL;
//TODO12: Make private and expose IBitmapImpl-based import API for composition visuals [PrivateApi]
[NotClientImplementable]
public interface IGlContextExternalObjectsFeature public interface IGlContextExternalObjectsFeature
{ {
IReadOnlyList<string> SupportedImportableExternalImageTypes { get; } IReadOnlyList<string> SupportedImportableExternalImageTypes { get; }
@ -26,8 +25,7 @@ public interface IGlContextExternalObjectsFeature
public byte[]? DeviceUuid { get; } public byte[]? DeviceUuid { get; }
} }
//TODO12: Make private and expose IBitmapImpl-based import API for composition visuals [PrivateApi]
[NotClientImplementable]
public interface IGlExternalSemaphore : IDisposable public interface IGlExternalSemaphore : IDisposable
{ {
void WaitSemaphore(IGlExternalImageTexture texture); void WaitSemaphore(IGlExternalImageTexture texture);
@ -36,12 +34,13 @@ public interface IGlExternalSemaphore : IDisposable
void SignalTimelineSemaphore(IGlExternalImageTexture texture, ulong value); void SignalTimelineSemaphore(IGlExternalImageTexture texture, ulong value);
} }
[PrivateApi]
public interface IGlExportableExternalSemaphore : IGlExternalSemaphore public interface IGlExportableExternalSemaphore : IGlExternalSemaphore
{ {
IPlatformHandle GetHandle(); IPlatformHandle GetHandle();
} }
[NotClientImplementable] [PrivateApi]
public interface IGlExternalImageTexture : IDisposable public interface IGlExternalImageTexture : IDisposable
{ {
void AcquireKeyedMutex(uint key); void AcquireKeyedMutex(uint key);
@ -56,6 +55,7 @@ public interface IGlExternalImageTexture : IDisposable
PlatformGraphicsExternalImageProperties Properties { get; } PlatformGraphicsExternalImageProperties Properties { get; }
} }
[PrivateApi]
public interface IGlExportableExternalImageTexture : IGlExternalImageTexture public interface IGlExportableExternalImageTexture : IGlExternalImageTexture
{ {
IPlatformHandle GetHandle(); IPlatformHandle GetHandle();

4
src/Avalonia.OpenGL/Surfaces/IGlPlatformSurface.cs

@ -1,6 +1,8 @@
using Avalonia.Platform.Surfaces;
namespace Avalonia.OpenGL.Surfaces namespace Avalonia.OpenGL.Surfaces
{ {
public interface IGlPlatformSurface public interface IGlPlatformSurface : IPlatformRenderSurface
{ {
IGlPlatformSurfaceRenderTarget CreateGlRenderTarget(IGlContext context); IGlPlatformSurfaceRenderTarget CreateGlRenderTarget(IGlContext context);
} }

9
src/Avalonia.OpenGL/Surfaces/IGlPlatformSurfaceRenderTarget.cs

@ -1,11 +1,14 @@
using System; using System;
using Avalonia.Metadata;
using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
namespace Avalonia.OpenGL.Surfaces namespace Avalonia.OpenGL.Surfaces
{ {
public interface IGlPlatformSurfaceRenderTarget : IDisposable [PrivateApi]
public interface IGlPlatformSurfaceRenderTarget : IDisposable, IPlatformRenderSurfaceRenderTarget
{ {
bool IsCorrupted { get; } bool IsCorrupted { get; }
IGlPlatformSurfaceRenderingSession BeginDraw(IRenderTarget.RenderTargetSceneInfo sceneInfo);
IGlPlatformSurfaceRenderingSession BeginDraw(PixelSize? expectedPixelSize);
} }
} }

3
src/Avalonia.Vulkan/IVulkanDevice.cs

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using Avalonia.Metadata; using Avalonia.Metadata;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using Avalonia.Vulkan.UnmanagedInterop; using Avalonia.Vulkan.UnmanagedInterop;
namespace Avalonia.Vulkan; namespace Avalonia.Vulkan;
@ -37,5 +38,5 @@ public interface IVulkanPlatformGraphicsContext : IPlatformGraphicsContext
internal VkInstance InstanceHandle { get; } internal VkInstance InstanceHandle { get; }
internal VkQueue MainQueueHandle { get; } internal VkQueue MainQueueHandle { get; }
internal uint GraphicsQueueFamilyIndex { get; } internal uint GraphicsQueueFamilyIndex { get; }
IVulkanRenderTarget CreateRenderTarget(IEnumerable<object> surfaces); IVulkanRenderTarget CreateRenderTarget(IEnumerable<IPlatformRenderSurface> surfaces);
} }

7
src/Avalonia.Vulkan/IVulkanPlatformSurface.cs

@ -1,7 +1,8 @@
using System; using System;
using Avalonia.Platform.Surfaces;
namespace Avalonia.Vulkan; namespace Avalonia.Vulkan;
public interface IVulkanKhrSurfacePlatformSurface : IDisposable public interface IVulkanKhrSurfacePlatformSurface : IDisposable, IPlatformRenderSurface
{ {
double Scaling { get; } double Scaling { get; }
PixelSize Size { get; } PixelSize Size { get; }
@ -10,6 +11,6 @@ public interface IVulkanKhrSurfacePlatformSurface : IDisposable
public interface IVulkanKhrSurfacePlatformSurfaceFactory public interface IVulkanKhrSurfacePlatformSurfaceFactory
{ {
bool CanRenderToSurface(IVulkanPlatformGraphicsContext context, object surface); bool CanRenderToSurface(IVulkanPlatformGraphicsContext context, IPlatformRenderSurface surface);
IVulkanKhrSurfacePlatformSurface CreateSurface(IVulkanPlatformGraphicsContext context, object surface); IVulkanKhrSurfacePlatformSurface CreateSurface(IVulkanPlatformGraphicsContext context, IPlatformRenderSurface surface);
} }

3
src/Avalonia.Vulkan/IVulkanRenderTarget.cs

@ -1,10 +1,11 @@
using System; using System;
using Avalonia.Platform.Surfaces;
using Avalonia.Metadata; using Avalonia.Metadata;
namespace Avalonia.Vulkan; namespace Avalonia.Vulkan;
[NotClientImplementable] [NotClientImplementable]
public interface IVulkanRenderTarget : IDisposable public interface IVulkanRenderTarget : IDisposable, IPlatformRenderSurfaceRenderTarget
{ {
IVulkanRenderSession BeginDraw(); IVulkanRenderSession BeginDraw();
} }

3
src/Avalonia.Vulkan/VulkanContext.cs

@ -1,6 +1,7 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Avalonia.Platform.Surfaces;
using Avalonia.Vulkan.UnmanagedInterop; using Avalonia.Vulkan.UnmanagedInterop;
namespace Avalonia.Vulkan; namespace Avalonia.Vulkan;
@ -54,7 +55,7 @@ internal class VulkanContext : IVulkanPlatformGraphicsContext
public VulkanInstanceApi InstanceApi { get; } public VulkanInstanceApi InstanceApi { get; }
public VulkanDeviceApi DeviceApi { get; } public VulkanDeviceApi DeviceApi { get; }
public IVulkanRenderTarget CreateRenderTarget(IEnumerable<object> surfaces) public IVulkanRenderTarget CreateRenderTarget(IEnumerable<IPlatformRenderSurface> surfaces)
{ {
foreach (var surf in surfaces) foreach (var surf in surfaces)
{ {

8
src/Avalonia.X11/Glx/GlxGlPlatformSurface.cs

@ -2,6 +2,7 @@ using System;
using Avalonia.OpenGL; using Avalonia.OpenGL;
using Avalonia.OpenGL.Egl; using Avalonia.OpenGL.Egl;
using Avalonia.OpenGL.Surfaces; using Avalonia.OpenGL.Surfaces;
using Avalonia.Platform;
using static Avalonia.OpenGL.GlConsts; using static Avalonia.OpenGL.GlConsts;
namespace Avalonia.X11.Glx namespace Avalonia.X11.Glx
@ -39,11 +40,10 @@ namespace Avalonia.X11.Glx
} }
public bool IsCorrupted => false; public bool IsCorrupted => false;
public IGlPlatformSurfaceRenderingSession BeginDraw(IRenderTarget.RenderTargetSceneInfo sceneInfo)
public IGlPlatformSurfaceRenderingSession BeginDraw(PixelSize? expectedSize)
{ {
var size = expectedSize ?? _info.Size; var size = sceneInfo.Size;
if (expectedSize.HasValue) //if (expectedSize.HasValue)
{ {
XLib.XConfigureResizeWindow(_context.Display.X11Info.DeferredDisplay, XLib.XConfigureResizeWindow(_context.Display.X11Info.DeferredDisplay,
_info.Handle, size.Width, size.Height); _info.Handle, size.Width, size.Height);

5
src/Avalonia.X11/Vulkan/VulkanSupport.cs

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using Avalonia.Vulkan; using Avalonia.Vulkan;
namespace Avalonia.X11.Vulkan; namespace Avalonia.X11.Vulkan;
@ -41,10 +42,10 @@ internal class VulkanSupport
_display = display; _display = display;
} }
public bool CanRenderToSurface(IVulkanPlatformGraphicsContext context, object surface) => public bool CanRenderToSurface(IVulkanPlatformGraphicsContext context, IPlatformRenderSurface surface) =>
surface is INativePlatformHandleSurface handle && handle.HandleDescriptor == "XID"; 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); new XidSurface(_display, (INativePlatformHandleSurface)handle);
} }

29
src/Avalonia.X11/X11CursorFactory.cs

@ -1,8 +1,8 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Avalonia.Controls.Platform.Surfaces;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Media.Imaging;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Internal; using Avalonia.Platform.Internal;
@ -71,7 +71,7 @@ namespace Avalonia.X11
return new CursorImpl(handle); 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); 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); 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 IntPtr _display;
private readonly PixelSize _pixelSize; private readonly PixelSize _pixelSize;
private readonly UnmanagedBlob _blob; private readonly UnmanagedBlob _blob;
public XImageCursor(IntPtr display, IBitmapImpl bitmap, PixelPoint hotSpot) public XImageCursor(IntPtr display, Bitmap bitmap, PixelPoint hotSpot)
{ {
var size = Marshal.SizeOf<XcursorImage>() + var size = Marshal.SizeOf<XcursorImage>() +
(bitmap.PixelSize.Width * bitmap.PixelSize.Height * 4); (bitmap.PixelSize.Width * bitmap.PixelSize.Height * 4);
@ -109,13 +109,10 @@ namespace Avalonia.X11
image->yhot = hotSpot.Y; image->yhot = hotSpot.Y;
image->pixels = (IntPtr)(image + 1); image->pixels = (IntPtr)(image + 1);
using (var cpuContext = platformRenderInterface.CreateBackendContext(null)) bitmap.CopyPixels(new LockedFramebuffer(
using (var renderTarget = cpuContext.CreateRenderTarget(new[] { this })) _blob.Address + Marshal.SizeOf<XcursorImage>(),
using (var ctx = renderTarget.CreateDrawingContext(true)) _pixelSize, _pixelSize.Width * 4,
{ new Vector(96, 96), PixelFormat.Bgra8888, AlphaFormat.Premul, null));
var r = new Rect(_pixelSize.ToSize(1));
ctx.DrawBitmap(bitmap, 1, r, r);
}
Handle = XLib.XcursorImageLoadCursor(display, _blob.Address); Handle = XLib.XcursorImageLoadCursor(display, _blob.Address);
} }
@ -127,16 +124,6 @@ namespace Avalonia.X11
XLib.XFreeCursor(_display, Handle); XLib.XFreeCursor(_display, Handle);
_blob.Dispose(); _blob.Dispose();
} }
public ILockedFramebuffer Lock()
{
return new LockedFramebuffer(
_blob.Address + Marshal.SizeOf<XcursorImage>(),
_pixelSize, _pixelSize.Width * 4,
new Vector(96, 96), PixelFormat.Bgra8888, AlphaFormat.Premul, null);
}
public IFramebufferRenderTarget CreateFramebufferRenderTarget() => new FuncFramebufferRenderTarget(Lock);
} }
private nint GetCursorHandleCached(StandardCursorType type) private nint GetCursorHandleCached(StandardCursorType type)

11
src/Avalonia.X11/X11FramebufferSurface.cs

@ -1,5 +1,5 @@
using System; using System;
using Avalonia.Controls.Platform.Surfaces; using Avalonia.Platform.Surfaces;
using Avalonia.Platform; using Avalonia.Platform;
using static Avalonia.X11.XLib; using static Avalonia.X11.XLib;
namespace Avalonia.X11 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); XLockDisplay(_display);
XGetGeometry(_display, _xid, out var root, out var x, out var y, out var width, out var height, 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); return _fb!.Lock(new Vector(96, 96), Blit);
} }
public IFramebufferRenderTarget CreateFramebufferRenderTarget() public IFramebufferRenderTarget CreateFramebufferRenderTarget() => new FuncFramebufferRenderTarget(Lock, _retain);
{
return _retain
? new FuncRetainedFramebufferRenderTarget(Lock)
: new FuncFramebufferRenderTarget(() => Lock(out _));
}
} }
} }

31
src/Avalonia.X11/X11IconLoader.cs

@ -1,7 +1,6 @@
using System; using System;
using System.IO; using System.IO;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Avalonia.Controls.Platform.Surfaces;
using Avalonia.Media.Imaging; using Avalonia.Media.Imaging;
using Avalonia.Platform; 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 _width;
private int _height; private int _height;
private uint[]? _bdata;
public UIntPtr[] Data { get; } public UIntPtr[] Data { get; }
public X11IconData(Bitmap bitmap) public X11IconData(Bitmap bitmap)
{ {
_width = Math.Min(bitmap.PixelSize.Width, 128); _width = Math.Min(bitmap.PixelSize.Width, 128);
_height = Math.Min(bitmap.PixelSize.Height, 128); _height = Math.Min(bitmap.PixelSize.Height, 128);
_bdata = new uint[_width * _height]; var pixels = new uint[_width * _height];
using(var cpuContext = AvaloniaLocator.Current.GetRequiredService<IPlatformRenderInterface>().CreateBackendContext(null))
using(var rt = cpuContext.CreateRenderTarget(new[]{this})) fixed (void* pPixels = pixels)
using (var ctx = rt.CreateDrawingContext(true)) bitmap.CopyPixels(new LockedFramebuffer((IntPtr)pPixels, new PixelSize(_width, _height), _width * 4,
ctx.DrawBitmap(bitmap.PlatformImpl.Item, 1, new Rect(bitmap.Size), new Vector(96, 96), PixelFormat.Bgra8888, AlphaFormat.Premul, null));
new Rect(0, 0, _width, _height));
Data = new UIntPtr[_width * _height + 2]; Data = new UIntPtr[_width * _height + 2];
Data[0] = new UIntPtr((uint)_width); Data[0] = new UIntPtr((uint)_width);
Data[1] = new UIntPtr((uint)_height); Data[1] = new UIntPtr((uint)_height);
@ -53,10 +52,10 @@ namespace Avalonia.X11
{ {
var r = y * _width; var r = y * _width;
for (var x = 0; x < _width; x++) 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) public void Save(Stream outputStream)
@ -78,15 +77,5 @@ namespace Avalonia.X11
wr.Save(outputStream); 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);
} }
} }

5
src/Avalonia.X11/X11Window.cs

@ -16,6 +16,7 @@ using Avalonia.Input.TextInput;
using Avalonia.OpenGL; using Avalonia.OpenGL;
using Avalonia.OpenGL.Egl; using Avalonia.OpenGL.Egl;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using Avalonia.Platform.Storage; using Avalonia.Platform.Storage;
using Avalonia.Rendering.Composition; using Avalonia.Rendering.Composition;
using Avalonia.Threading; using Avalonia.Threading;
@ -211,7 +212,7 @@ namespace Avalonia.X11
SetWmClass(_handle, _platform.Options.WmClass); SetWmClass(_handle, _platform.Options.WmClass);
} }
var surfaces = new List<object> var surfaces = new List<IPlatformRenderSurface>
{ {
new X11FramebufferSurface(_x11.DeferredDisplay, _renderHandle, new X11FramebufferSurface(_x11.DeferredDisplay, _renderHandle,
depth, _platform.Options.UseRetainedFramebuffer ?? false) depth, _platform.Options.UseRetainedFramebuffer ?? false)
@ -481,7 +482,7 @@ namespace Avalonia.X11
public double DesktopScaling => RenderScaling; public double DesktopScaling => RenderScaling;
public IEnumerable<object> Surfaces { get; } public IPlatformRenderSurface[] Surfaces { get; }
public Action<RawInputEventArgs>? Input { get; set; } public Action<RawInputEventArgs>? Input { get; set; }
public Action<Rect>? Paint { get; set; } public Action<Rect>? Paint { get; set; }
public Action<Size, WindowResizeReason>? Resized { get; set; } public Action<Size, WindowResizeReason>? Resized { get; set; }

3
src/Browser/Avalonia.Browser/BrowserTopLevelImpl.cs

@ -14,6 +14,7 @@ using Avalonia.Input.Platform;
using Avalonia.Input.Raw; using Avalonia.Input.Raw;
using Avalonia.Input.TextInput; using Avalonia.Input.TextInput;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using Avalonia.Platform.Storage; using Avalonia.Platform.Storage;
using Avalonia.Rendering.Composition; using Avalonia.Rendering.Composition;
@ -132,7 +133,7 @@ namespace Avalonia.Browser
public Size? FrameSize => null; public Size? FrameSize => null;
public double RenderScaling => _surface?.Scaling ?? 1; public double RenderScaling => _surface?.Scaling ?? 1;
public IEnumerable<object> Surfaces => _surface?.GetRenderSurfaces() ?? []; public IPlatformRenderSurface[] Surfaces => _surface?.GetRenderSurfaces() ?? [];
public Action<RawInputEventArgs>? Input { get; set; } public Action<RawInputEventArgs>? Input { get; set; }
public Action<Rect>? Paint { get; set; } public Action<Rect>? Paint { get; set; }

2
src/Browser/Avalonia.Browser/Cursor.cs

@ -76,7 +76,7 @@ namespace Avalonia.Browser
internal class CssCursorFactory : ICursorFactory 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(); using var imageStream = new MemoryStream();
cursor.Save(imageStream); cursor.Save(imageStream);

5
src/Browser/Avalonia.Browser/Rendering/BrowserSoftwareRenderTarget.cs

@ -1,7 +1,7 @@
using System; using System;
using System.Runtime.InteropServices.JavaScript; using System.Runtime.InteropServices.JavaScript;
using Avalonia.Browser.Interop; using Avalonia.Browser.Interop;
using Avalonia.Controls.Platform.Surfaces; using Avalonia.Platform.Surfaces;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Reactive; using Avalonia.Reactive;
#pragma warning disable CS0169 #pragma warning disable CS0169
@ -38,8 +38,9 @@ partial class BrowserSoftwareRenderTarget : BrowserRenderTarget, IFramebufferPla
_fb = null; _fb = null;
} }
public ILockedFramebuffer Lock() public ILockedFramebuffer Lock(IRenderTarget.RenderTargetSceneInfo sceneInfo, out FramebufferLockProperties properties)
{ {
properties = default;
var (size, scaling) = _parent._sizeGetter(); var (size, scaling) = _parent._sizeGetter();
_parent.UpdateSize(size); _parent.UpdateSize(size);

5
src/Browser/Avalonia.Browser/Rendering/BrowserSurface.cs

@ -8,13 +8,14 @@ using Avalonia.Browser.Interop;
using Avalonia.Browser.Rendering; using Avalonia.Browser.Rendering;
using Avalonia.Logging; using Avalonia.Logging;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using Avalonia.Rendering; using Avalonia.Rendering;
using Avalonia.Rendering.Composition; using Avalonia.Rendering.Composition;
using Avalonia.Threading; using Avalonia.Threading;
namespace Avalonia.Browser.Skia; namespace Avalonia.Browser.Skia;
internal abstract class BrowserSurface : IDisposable internal abstract class BrowserSurface : IDisposable, IPlatformRenderSurface
{ {
protected BrowserSurface(JSObject jsSurface, Compositor compositor) protected BrowserSurface(JSObject jsSurface, Compositor compositor)
{ {
@ -68,5 +69,5 @@ internal abstract class BrowserSurface : IDisposable
ScalingChanged?.Invoke(); ScalingChanged?.Invoke();
} }
public virtual object[] GetRenderSurfaces() => [this]; public virtual IPlatformRenderSurface[] GetRenderSurfaces() => [this];
} }

3
src/Browser/Avalonia.Browser/Rendering/BrowserWebGlRenderTarget.cs

@ -73,9 +73,8 @@ partial class BrowserWebGlRenderTarget : BrowserRenderTarget, IGlPlatformSurface
// No-op // No-op
} }
public IGlPlatformSurfaceRenderingSession BeginDraw(PixelSize? expectedPixelSize) public IGlPlatformSurfaceRenderingSession BeginDraw(IRenderTarget.RenderTargetSceneInfo sceneInfo)
{ {
// TODO: use expectedPixelSize
var s = _target._sizeGetter(); var s = _target._sizeGetter();
_target.UpdateSize(s.Size); _target.UpdateSize(s.Size);
var restoreContext = _target.GlContext.EnsureCurrent(); var restoreContext = _target.GlContext.EnsureCurrent();

7
src/Browser/Avalonia.Browser/Rendering/RenderTargetBrowserSurface.cs

@ -5,6 +5,7 @@ using System.Runtime.InteropServices.JavaScript;
using Avalonia.Browser.Interop; using Avalonia.Browser.Interop;
using Avalonia.Browser.Skia; using Avalonia.Browser.Skia;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using Avalonia.Rendering.Composition; using Avalonia.Rendering.Composition;
namespace Avalonia.Browser.Rendering; 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 [];
return [_graphics.Target]; return [target];
} }
public override void OnSizeChanged(double pixelWidth, double pixelHeight, double dpr) public override void OnSizeChanged(double pixelWidth, double pixelHeight, double dpr)

11
src/Headless/Avalonia.Headless/HeadlessPlatformRenderInterface.cs

@ -8,6 +8,7 @@ using Avalonia.Media;
using Avalonia.Media.Imaging; using Avalonia.Media.Imaging;
using Avalonia.Media.TextFormatting; using Avalonia.Media.TextFormatting;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
namespace Avalonia.Headless namespace Avalonia.Headless
{ {
@ -55,7 +56,7 @@ namespace Avalonia.Headless
public IGeometryImpl CreateCombinedGeometry(GeometryCombineMode combineMode, IGeometryImpl g1, IGeometryImpl g2) public IGeometryImpl CreateCombinedGeometry(GeometryCombineMode combineMode, IGeometryImpl g1, IGeometryImpl g2)
=> new HeadlessGeometryStub(g1.Bounds.Union(g2.Bounds)); => new HeadlessGeometryStub(g1.Bounds.Union(g2.Bounds));
public IRenderTarget CreateRenderTarget(IEnumerable<object> surfaces) => new HeadlessRenderTarget(); public IRenderTarget CreateRenderTarget(IEnumerable<IPlatformRenderSurface> surfaces) => new HeadlessRenderTarget();
public IDrawingContextLayerImpl CreateOffscreenRenderTarget(PixelSize pixelSize, Vector scaling, public IDrawingContextLayerImpl CreateOffscreenRenderTarget(PixelSize pixelSize, Vector scaling,
bool enableTextAntialiasing) => bool enableTextAntialiasing) =>
new HeadlessBitmapStub(pixelSize, scaling * 96); 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; } public Size Size { get; }
@ -405,10 +406,8 @@ namespace Avalonia.Headless
return new HeadlessDrawingContextStub(); return new HeadlessDrawingContextStub();
} }
public IDrawingContextImpl CreateDrawingContext(PixelSize expectedPixelSize, public IDrawingContextImpl CreateDrawingContext()
out RenderTargetDrawingContextProperties properties)
{ {
properties = default;
return new HeadlessDrawingContextStub(); return new HeadlessDrawingContextStub();
} }
@ -603,7 +602,7 @@ namespace Avalonia.Headless
return new HeadlessDrawingContextStub(); return new HeadlessDrawingContextStub();
} }
public IDrawingContextImpl CreateDrawingContext(PixelSize expectedPixelSize, public IDrawingContextImpl CreateDrawingContext(IRenderTarget.RenderTargetSceneInfo sceneInfo,
out RenderTargetDrawingContextProperties properties) out RenderTargetDrawingContextProperties properties)
{ {
properties = default; properties = default;

3
src/Headless/Avalonia.Headless/HeadlessPlatformStubs.cs

@ -13,6 +13,7 @@ using Avalonia.Input;
using Avalonia.Input.Platform; using Avalonia.Input.Platform;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.Media.Fonts; using Avalonia.Media.Fonts;
using Avalonia.Media.Imaging;
using Avalonia.Platform; using Avalonia.Platform;
namespace Avalonia.Headless namespace Avalonia.Headless
@ -60,7 +61,7 @@ namespace Avalonia.Headless
internal class HeadlessCursorFactoryStub : ICursorFactory internal class HeadlessCursorFactoryStub : ICursorFactory
{ {
public ICursorImpl GetCursor(StandardCursorType cursorType) => new CursorStub(); 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 private class CursorStub : ICursorImpl
{ {

6
src/Headless/Avalonia.Headless/HeadlessWindowImpl.cs

@ -3,13 +3,13 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Platform; using Avalonia.Controls.Platform;
using Avalonia.Controls.Platform.Surfaces;
using Avalonia.Controls.Primitives.PopupPositioning; using Avalonia.Controls.Primitives.PopupPositioning;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Input.Platform; using Avalonia.Input.Platform;
using Avalonia.Input.Raw; using Avalonia.Input.Raw;
using Avalonia.Media.Imaging; using Avalonia.Media.Imaging;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using Avalonia.Rendering.Composition; using Avalonia.Rendering.Composition;
using Avalonia.Threading; using Avalonia.Threading;
@ -31,7 +31,7 @@ namespace Avalonia.Headless
public HeadlessWindowImpl(bool isPopup, PixelFormat frameBufferFormat) public HeadlessWindowImpl(bool isPopup, PixelFormat frameBufferFormat)
{ {
IsPopup = isPopup; IsPopup = isPopup;
Surfaces = new object[] { this }; Surfaces = [this];
_keyboard = AvaloniaLocator.Current.GetRequiredService<IKeyboardDevice>(); _keyboard = AvaloniaLocator.Current.GetRequiredService<IKeyboardDevice>();
_screen = new HeadlessScreensStub(); _screen = new HeadlessScreensStub();
_mousePointer = new Pointer(Pointer.GetNextFreeId(), PointerType.Mouse, true); _mousePointer = new Pointer(Pointer.GetNextFreeId(), PointerType.Mouse, true);
@ -51,7 +51,7 @@ namespace Avalonia.Headless
public Size? FrameSize => null; public Size? FrameSize => null;
public double RenderScaling { get; } = 1; public double RenderScaling { get; } = 1;
public double DesktopScaling => RenderScaling; public double DesktopScaling => RenderScaling;
public IEnumerable<object> Surfaces { get; } public IPlatformRenderSurface[] Surfaces { get; }
public Action<RawInputEventArgs>? Input { get; set; } public Action<RawInputEventArgs>? Input { get; set; }
public Action<Rect>? Paint { get; set; } public Action<Rect>? Paint { get; set; }
public Action<Size, WindowResizeReason>? Resized { get; set; } public Action<Size, WindowResizeReason>? Resized { get; set; }

5
src/Linux/Avalonia.LinuxFramebuffer/FramebufferToplevelImpl.cs

@ -6,6 +6,7 @@ using Avalonia.Input.Raw;
using Avalonia.LinuxFramebuffer.Input; using Avalonia.LinuxFramebuffer.Input;
using Avalonia.LinuxFramebuffer.Output; using Avalonia.LinuxFramebuffer.Output;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using Avalonia.Rendering.Composition; using Avalonia.Rendering.Composition;
using Avalonia.Threading; using Avalonia.Threading;
@ -26,7 +27,7 @@ using Avalonia.Rendering.Composition;
_inputQueue = new RawEventGrouper(groupedInput => Input?.Invoke(groupedInput), _inputQueue = new RawEventGrouper(groupedInput => Input?.Invoke(groupedInput),
LinuxFramebufferPlatform.EventGrouperDispatchQueue); LinuxFramebufferPlatform.EventGrouperDispatchQueue);
Surfaces = new object[] { _outputBackend }; Surfaces = [_outputBackend];
_inputBackend.Initialize(this, e => _inputBackend.Initialize(this, e =>
Dispatcher.UIThread.Post(() => _inputQueue.HandleEvent(e), DispatcherPriority.Send )); Dispatcher.UIThread.Post(() => _inputQueue.HandleEvent(e), DispatcherPriority.Send ));
} }
@ -60,7 +61,7 @@ using Avalonia.Rendering.Composition;
public IPopupImpl? CreatePopup() => null; public IPopupImpl? CreatePopup() => null;
public double RenderScaling => _outputBackend.Scaling; public double RenderScaling => _outputBackend.Scaling;
public IEnumerable<object> Surfaces { get; } public IPlatformRenderSurface[] Surfaces { get; }
public Action<RawInputEventArgs>? Input { get; set; } public Action<RawInputEventArgs>? Input { get; set; }
public Action<Rect>? Paint { get; set; } public Action<Rect>? Paint { get; set; }
public Action<Size, WindowResizeReason>? Resized { get; set; } public Action<Size, WindowResizeReason>? Resized { get; set; }

4
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) //Go through two cycles of buffer swapping (there are render artifacts otherwise)
for (var c = 0; c < 2; c++) for (var c = 0; c < 2; c++)
using (CreateGlRenderTarget().BeginDraw(PixelSize)) using (CreateGlRenderTarget().BeginDraw(new IRenderTarget.RenderTargetSceneInfo(PixelSize, 1)))
{ {
_deferredContext.GlInterface.ClearColor(initialBufferSwappingColorR, initialBufferSwappingColorG, _deferredContext.GlInterface.ClearColor(initialBufferSwappingColorR, initialBufferSwappingColorG,
initialBufferSwappingColorB, initialBufferSwappingColorA); initialBufferSwappingColorB, initialBufferSwappingColorA);
@ -511,7 +511,7 @@ namespace Avalonia.LinuxFramebuffer.Output
public bool IsYFlipped => false; public bool IsYFlipped => false;
} }
public IGlPlatformSurfaceRenderingSession BeginDraw(PixelSize? expectedPixelSize) public IGlPlatformSurfaceRenderingSession BeginDraw(IRenderTarget.RenderTargetSceneInfo sceneInfo)
{ {
var clearContext = _parent._deferredContext.MakeCurrent(_parent._eglSurface); var clearContext = _parent._deferredContext.MakeCurrent(_parent._eglSurface);
var gl = _parent._deferredContext.GlInterface; var gl = _parent._deferredContext.GlInterface;

8
src/Linux/Avalonia.LinuxFramebuffer/Output/FbdevOutput.cs

@ -2,7 +2,7 @@
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Text; using System.Text;
using Avalonia.Controls.Platform.Surfaces; using Avalonia.Platform.Surfaces;
using Avalonia.LinuxFramebuffer.Output; using Avalonia.LinuxFramebuffer.Output;
using Avalonia.Platform; using Avalonia.Platform;
@ -162,9 +162,7 @@ namespace Avalonia.LinuxFramebuffer
} }
} }
public ILockedFramebuffer Lock() => Lock(out _); public ILockedFramebuffer Lock(IRenderTarget.RenderTargetSceneInfo _, out FramebufferLockProperties properties)
private ILockedFramebuffer Lock(out FramebufferLockProperties properties)
{ {
if (_fd <= 0) if (_fd <= 0)
throw new ObjectDisposedException("LinuxFramebuffer"); throw new ObjectDisposedException("LinuxFramebuffer");
@ -187,7 +185,7 @@ namespace Avalonia.LinuxFramebuffer
.Lock(new Vector(96, 96) * Scaling); .Lock(new Vector(96, 96) * Scaling);
} }
public IFramebufferRenderTarget CreateFramebufferRenderTarget() => new FuncRetainedFramebufferRenderTarget(Lock); public IFramebufferRenderTarget CreateFramebufferRenderTarget() => new FuncFramebufferRenderTarget(Lock, true);
private void ReleaseUnmanagedResources() private void ReleaseUnmanagedResources()

4
src/Linux/Avalonia.LinuxFramebuffer/Output/IOutputBackend.cs

@ -1,6 +1,8 @@
using Avalonia.Platform.Surfaces;
namespace Avalonia.LinuxFramebuffer.Output namespace Avalonia.LinuxFramebuffer.Output
{ {
public interface IOutputBackend public interface IOutputBackend : IPlatformRenderSurface
{ {
PixelSize PixelSize { get; } PixelSize PixelSize { get; }
double Scaling { get; set; } double Scaling { get; set; }

3
src/Linux/Avalonia.LinuxFramebuffer/Stubs.cs

@ -1,5 +1,6 @@
using System; using System;
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Media.Imaging;
using Avalonia.Platform; using Avalonia.Platform;
namespace Avalonia.LinuxFramebuffer namespace Avalonia.LinuxFramebuffer
@ -7,7 +8,7 @@ namespace Avalonia.LinuxFramebuffer
internal class CursorFactoryStub : ICursorFactory internal class CursorFactoryStub : ICursorFactory
{ {
public ICursorImpl GetCursor(StandardCursorType cursorType) => new CursorStub(); 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 private class CursorStub : ICursorImpl
{ {

14
src/Skia/Avalonia.Skia/DrawingContextImpl.cs

@ -641,7 +641,7 @@ namespace Avalonia.Skia
public IDrawingContextLayerImpl CreateLayer(PixelSize size) public IDrawingContextLayerImpl CreateLayer(PixelSize size)
{ {
CheckLease(); CheckLease();
return CreateRenderTarget(size, true); return CreateRenderTarget(size, true, false);
} }
/// <inheritdoc /> /// <inheritdoc />
@ -1092,11 +1092,11 @@ namespace Avalonia.Skia
{ {
var calc = new TileBrushCalculator(tileBrush, tileBrushImage.PixelSize.ToSizeWithDpi(_intermediateSurfaceDpi), targetBox.Size); var calc = new TileBrushCalculator(tileBrush, tileBrushImage.PixelSize.ToSizeWithDpi(_intermediateSurfaceDpi), targetBox.Size);
var intermediate = CreateRenderTarget( var intermediate = CreateRenderTarget(
PixelSize.FromSizeWithDpi(calc.IntermediateSize, _intermediateSurfaceDpi), false); PixelSize.FromSizeWithDpi(calc.IntermediateSize, _intermediateSurfaceDpi), false, true);
paintWrapper.AddDisposable(intermediate); paintWrapper.AddDisposable(intermediate);
using (var context = intermediate.CreateDrawingContext(true)) using (var context = intermediate.CreateDrawingContext())
{ {
var sourceRect = new Rect(tileBrushImage.PixelSize.ToSizeWithDpi(96)); var sourceRect = new Rect(tileBrushImage.PixelSize.ToSizeWithDpi(96));
var targetRect = new Rect(tileBrushImage.PixelSize.ToSizeWithDpi(_intermediateSurfaceDpi)); var targetRect = new Rect(tileBrushImage.PixelSize.ToSizeWithDpi(_intermediateSurfaceDpi));
@ -1184,9 +1184,9 @@ namespace Avalonia.Skia
if (intermediateSize.Width >= 1 && intermediateSize.Height >= 1) if (intermediateSize.Width >= 1 && intermediateSize.Height >= 1)
{ {
using var intermediate = CreateRenderTarget( 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.PushRenderOptions(RenderOptions);
ctx.Clear(Colors.Transparent); ctx.Clear(Colors.Transparent);
@ -1487,9 +1487,10 @@ namespace Avalonia.Skia
/// </summary> /// </summary>
/// <param name="pixelSize">The size of the render target.</param> /// <param name="pixelSize">The size of the render target.</param>
/// <param name="isLayer">Whether the render target is being created for a layer.</param> /// <param name="isLayer">Whether the render target is being created for a layer.</param>
/// <param name="useScaledDrawing">Auto-scales to DPI</param>
/// <param name="format">Pixel format.</param> /// <param name="format">Pixel format.</param>
/// <returns></returns> /// <returns></returns>
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 var createInfo = new SurfaceRenderTarget.CreateInfo
{ {
@ -1502,6 +1503,7 @@ namespace Avalonia.Skia
Gpu = _gpu, Gpu = _gpu,
Session = _session, Session = _session,
DisableManualFbo = !isLayer, DisableManualFbo = !isLayer,
UseScaledDrawing = useScaledDrawing
}; };
return new SurfaceRenderTarget(createInfo); return new SurfaceRenderTarget(createInfo);

30
src/Skia/Avalonia.Skia/FramebufferRenderTarget.cs

@ -1,8 +1,8 @@
using System; using System;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using Avalonia.Reactive; using Avalonia.Reactive;
using Avalonia.Controls.Platform.Surfaces;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using SkiaSharp; using SkiaSharp;
namespace Avalonia.Skia namespace Avalonia.Skia
@ -12,23 +12,24 @@ namespace Avalonia.Skia
/// </summary> /// </summary>
internal class FramebufferRenderTarget : IRenderTarget internal class FramebufferRenderTarget : IRenderTarget
{ {
private readonly bool _useScaledDrawing;
private SKImageInfo _currentImageInfo; private SKImageInfo _currentImageInfo;
private IntPtr _currentFramebufferAddress; private IntPtr _currentFramebufferAddress;
private SKSurface? _framebufferSurface; private SKSurface? _framebufferSurface;
private PixelFormatConversionShim? _conversionShim; private PixelFormatConversionShim? _conversionShim;
private IDisposable? _preFramebufferCopyHandler; private IDisposable? _preFramebufferCopyHandler;
private IFramebufferRenderTarget? _renderTarget; private IFramebufferRenderTarget? _renderTarget;
private IFramebufferRenderTargetWithProperties? _renderTargetWithProperties;
private bool _hadConversionShim; private bool _hadConversionShim;
/// <summary> /// <summary>
/// Create new framebuffer render target using a target surface. /// Create new framebuffer render target using a target surface.
/// </summary> /// </summary>
/// <param name="platformSurface">Target surface.</param> /// <param name="platformSurface">Target surface.</param>
public FramebufferRenderTarget(IFramebufferPlatformSurface platformSurface) /// <param name="useScaledDrawing">Tells the render target to scale to framebuffer dpi</param>
public FramebufferRenderTarget(IFramebufferPlatformSurface platformSurface, bool useScaledDrawing = false)
{ {
_useScaledDrawing = useScaledDrawing;
_renderTarget = platformSurface.CreateFramebufferRenderTarget(); _renderTarget = platformSurface.CreateFramebufferRenderTarget();
_renderTargetWithProperties = _renderTarget as IFramebufferRenderTargetWithProperties;
} }
/// <inheritdoc /> /// <inheritdoc />
@ -36,35 +37,28 @@ namespace Avalonia.Skia
{ {
_renderTarget?.Dispose(); _renderTarget?.Dispose();
_renderTarget = null; _renderTarget = null;
_renderTargetWithProperties = null;
FreeSurface(); FreeSurface();
} }
public RenderTargetProperties Properties => new() public RenderTargetProperties Properties => new()
{ {
RetainsPreviousFrameContents = !_hadConversionShim RetainsPreviousFrameContents = !_hadConversionShim
&& _renderTargetWithProperties?.RetainsFrameContents == true, && _renderTarget?.RetainsFrameContents == true,
IsSuitableForDirectRendering = true IsSuitableForDirectRendering = true
}; };
/// <inheritdoc />
public IDrawingContextImpl CreateDrawingContext(bool scaleDrawingToDpi) =>
CreateDrawingContextCore(scaleDrawingToDpi, out _);
/// <inheritdoc />
public IDrawingContextImpl CreateDrawingContext(PixelSize expectedPixelSize,
out RenderTargetDrawingContextProperties properties)
=> CreateDrawingContextCore(false, out properties);
IDrawingContextImpl CreateDrawingContextCore(bool scaleDrawingToDpi, /// <inheritdoc />
public IDrawingContextImpl CreateDrawingContext(IRenderTarget.RenderTargetSceneInfo sceneInfo,
out RenderTargetDrawingContextProperties properties) out RenderTargetDrawingContextProperties properties)
{ {
if (_renderTarget == null) if (_renderTarget == null)
throw new ObjectDisposedException(nameof(FramebufferRenderTarget)); throw new ObjectDisposedException(nameof(FramebufferRenderTarget));
FramebufferLockProperties lockProperties = default; var framebuffer = _renderTarget.Lock(sceneInfo, out var lockProperties);
var framebuffer = _renderTargetWithProperties?.Lock(out lockProperties) ?? _renderTarget.Lock();
var framebufferImageInfo = new SKImageInfo(framebuffer.Size.Width, framebuffer.Size.Height, var framebufferImageInfo = new SKImageInfo(framebuffer.Size.Width, framebuffer.Size.Height,
framebuffer.Format.ToSkColorType(), framebuffer.Format.ToSkColorType(),
framebuffer.AlphaFormat.ToSkAlphaType()); framebuffer.AlphaFormat.ToSkAlphaType());
@ -82,7 +76,7 @@ namespace Avalonia.Skia
{ {
Surface = _framebufferSurface, Surface = _framebufferSurface,
Dpi = framebuffer.Dpi, Dpi = framebuffer.Dpi,
ScaleDrawingToDpi = scaleDrawingToDpi ScaleDrawingToDpi = _useScaledDrawing
}; };
properties = new() properties = new()
@ -95,6 +89,8 @@ namespace Avalonia.Skia
public bool IsCorrupted => false; public bool IsCorrupted => false;
public bool IsReady => _renderTarget is not IPlatformRenderSurfaceRenderTarget prs || prs.IsReady;
/// <summary> /// <summary>
/// Check if two images info are compatible. /// Check if two images info are compatible.
/// </summary> /// </summary>

12
src/Skia/Avalonia.Skia/Gpu/ISkiaGpu.cs

@ -1,16 +1,15 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using SkiaSharp; using SkiaSharp;
namespace Avalonia.Skia namespace Avalonia.Skia
{ {
//TODO12: Make it private
/// <summary> /// <summary>
/// Custom Skia gpu instance. /// Custom Skia gpu instance.
/// </summary> /// </summary>
public interface ISkiaGpu : IPlatformGraphicsContext internal interface ISkiaGpu : IPlatformGraphicsContext
{ {
/// <summary> /// <summary>
/// Gets the platform graphics context. /// Gets the platform graphics context.
@ -22,7 +21,12 @@ namespace Avalonia.Skia
/// </summary> /// </summary>
/// <param name="surfaces">Surfaces.</param> /// <param name="surfaces">Surfaces.</param>
/// <returns>Created render target or <see langword="null"/> if it fails.</returns> /// <returns>Created render target or <see langword="null"/> if it fails.</returns>
ISkiaGpuRenderTarget? TryCreateRenderTarget(IEnumerable<object> surfaces); ISkiaGpuRenderTarget? TryCreateRenderTarget(IEnumerable<IPlatformRenderSurface> surfaces);
/// <summary>
/// Checks if a render target can be created for the given surfaces and the preferred surface is ready.
/// </summary>
bool IsReadyToCreateRenderTarget(IEnumerable<IPlatformRenderSurface> surfaces);
/// <summary> /// <summary>
/// Creates an offscreen render target surface /// Creates an offscreen render target surface

7
src/Skia/Avalonia.Skia/Gpu/ISkiaGpuRenderTarget.cs

@ -1,4 +1,5 @@
using System; using System;
using Avalonia.Platform;
namespace Avalonia.Skia namespace Avalonia.Skia
{ {
@ -10,10 +11,12 @@ namespace Avalonia.Skia
/// <summary> /// <summary>
/// Start rendering to this render target. /// Start rendering to this render target.
/// </summary> /// </summary>
/// <param name="expectedPixelSize">The expected size.</param> /// <param name="sceneInfo">Information about the scene that will be rendered.</param>
/// <returns>A render session instance.</returns> /// <returns>A render session instance.</returns>
ISkiaGpuRenderSession BeginRenderingSession(PixelSize? expectedPixelSize); ISkiaGpuRenderSession BeginRenderingSession(IRenderTarget.RenderTargetSceneInfo sceneInfo);
bool IsCorrupted { get; } bool IsCorrupted { get; }
bool IsReady => true;
} }
} }

20
src/Skia/Avalonia.Skia/Gpu/Metal/SkiaMetalGpu.cs

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using Avalonia.Metal; using Avalonia.Metal;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using SkiaSharp; using SkiaSharp;
namespace Avalonia.Skia.Metal; namespace Avalonia.Skia.Metal;
@ -49,7 +50,7 @@ internal class SkiaMetalGpu : ISkiaGpu
public IScopedResource<GRContext> TryGetGrContext() => public IScopedResource<GRContext> TryGetGrContext() =>
ScopedResource<GRContext>.Create(GrContext, EnsureCurrent().Dispose); ScopedResource<GRContext>.Create(GrContext, EnsureCurrent().Dispose);
public ISkiaGpuRenderTarget? TryCreateRenderTarget(IEnumerable<object> surfaces) public ISkiaGpuRenderTarget? TryCreateRenderTarget(IEnumerable<IPlatformRenderSurface> surfaces)
{ {
foreach (var surface in surfaces) foreach (var surface in surfaces)
{ {
@ -63,6 +64,19 @@ internal class SkiaMetalGpu : ISkiaGpu
return null; return null;
} }
public bool IsReadyToCreateRenderTarget(IEnumerable<IPlatformRenderSurface> surfaces)
{
foreach (var surface in surfaces)
{
if (surface is IMetalPlatformSurface)
{
return surface.IsReady;
}
}
return false;
}
public class SkiaMetalRenderTarget : ISkiaGpuRenderTarget public class SkiaMetalRenderTarget : ISkiaGpuRenderTarget
{ {
private readonly SkiaMetalGpu _gpu; private readonly SkiaMetalGpu _gpu;
@ -80,7 +94,7 @@ internal class SkiaMetalGpu : ISkiaGpu
_target = null; _target = null;
} }
public ISkiaGpuRenderSession BeginRenderingSession(PixelSize? expectedPixelSize) public ISkiaGpuRenderSession BeginRenderingSession(IRenderTarget.RenderTargetSceneInfo sceneInfo)
{ {
// TODO: use expectedPixelSize // TODO: use expectedPixelSize
var session = (_target ?? throw new ObjectDisposedException(nameof(SkiaMetalRenderTarget))).BeginRendering(); var session = (_target ?? throw new ObjectDisposedException(nameof(SkiaMetalRenderTarget))).BeginRendering();
@ -95,6 +109,8 @@ internal class SkiaMetalGpu : ISkiaGpu
} }
public bool IsCorrupted => false; public bool IsCorrupted => false;
public bool IsReady => _target?.IsReady ?? false;
} }
internal class SkiaMetalRenderSession : ISkiaGpuRenderSession internal class SkiaMetalRenderSession : ISkiaGpuRenderSession

7
src/Skia/Avalonia.Skia/Gpu/OpenGl/GlRenderTarget.cs

@ -1,6 +1,7 @@
using System; using System;
using Avalonia.OpenGL; using Avalonia.OpenGL;
using Avalonia.OpenGL.Surfaces; using Avalonia.OpenGL.Surfaces;
using Avalonia.Platform;
using SkiaSharp; using SkiaSharp;
using static Avalonia.OpenGL.GlConsts; using static Avalonia.OpenGL.GlConsts;
@ -22,6 +23,8 @@ namespace Avalonia.Skia
public bool IsCorrupted => _surface.IsCorrupted; public bool IsCorrupted => _surface.IsCorrupted;
public bool IsReady => _surface.IsReady;
class GlGpuSession : ISkiaGpuRenderSession class GlGpuSession : ISkiaGpuRenderSession
{ {
private readonly GRBackendRenderTarget _backendRenderTarget; private readonly GRBackendRenderTarget _backendRenderTarget;
@ -56,9 +59,9 @@ namespace Avalonia.Skia
public double ScaleFactor => _glSession.Scaling; 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; bool success = false;
try try

24
src/Skia/Avalonia.Skia/Gpu/OpenGl/GlSkiaGpu.cs

@ -5,6 +5,7 @@ using Avalonia.Logging;
using Avalonia.OpenGL; using Avalonia.OpenGL;
using Avalonia.OpenGL.Surfaces; using Avalonia.OpenGL.Surfaces;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using SkiaSharp; using SkiaSharp;
using static Avalonia.OpenGL.GlConsts; using static Avalonia.OpenGL.GlConsts;
@ -53,13 +54,15 @@ namespace Avalonia.Skia
private class SurfaceWrapper : IGlPlatformSurface private class SurfaceWrapper : IGlPlatformSurface
{ {
private readonly object _surface; private readonly IPlatformRenderSurface _surface;
public SurfaceWrapper( object surface) public SurfaceWrapper(IPlatformRenderSurface surface)
{ {
_surface = surface; _surface = surface;
} }
public bool IsReady => _surface.IsReady;
public IGlPlatformSurfaceRenderTarget CreateGlRenderTarget(IGlContext context) public IGlPlatformSurfaceRenderTarget CreateGlRenderTarget(IGlContext context)
{ {
var feature = context.TryGetFeature<IGlPlatformSurfaceRenderTargetFactory>()!; var feature = context.TryGetFeature<IGlPlatformSurfaceRenderTargetFactory>()!;
@ -67,7 +70,7 @@ namespace Avalonia.Skia
} }
} }
public ISkiaGpuRenderTarget? TryCreateRenderTarget(IEnumerable<object> surfaces) public ISkiaGpuRenderTarget? TryCreateRenderTarget(IEnumerable<IPlatformRenderSurface> surfaces)
{ {
var customRenderTargetFactory = _glContext.TryGetFeature<IGlPlatformSurfaceRenderTargetFactory>(); var customRenderTargetFactory = _glContext.TryGetFeature<IGlPlatformSurfaceRenderTargetFactory>();
foreach (var surface in surfaces) foreach (var surface in surfaces)
@ -85,6 +88,21 @@ namespace Avalonia.Skia
return null; return null;
} }
public bool IsReadyToCreateRenderTarget(IEnumerable<IPlatformRenderSurface> surfaces)
{
var customRenderTargetFactory = _glContext.TryGetFeature<IGlPlatformSurfaceRenderTargetFactory>();
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) public ISkiaSurface? TryCreateSurface(PixelSize size, ISkiaGpuRenderSession? session)
{ {
// Only windows platform needs our FBO trickery // Only windows platform needs our FBO trickery

18
src/Skia/Avalonia.Skia/Gpu/SkiaGpuRenderTarget.cs

@ -1,3 +1,4 @@
using System;
using Avalonia.Platform; using Avalonia.Platform;
namespace Avalonia.Skia namespace Avalonia.Skia
@ -21,27 +22,21 @@ namespace Avalonia.Skia
_renderTarget.Dispose(); _renderTarget.Dispose();
} }
public IDrawingContextImpl CreateDrawingContext(PixelSize expectedPixelSize, public IDrawingContextImpl CreateDrawingContext(bool useScaledDrawing) => throw new InvalidOperationException(
out RenderTargetDrawingContextProperties properties) => "This legacy API is only supported by framebuffer render targets and should be removed from there as well, don't use");
CreateDrawingContextCore(expectedPixelSize, false, out properties);
public IDrawingContextImpl CreateDrawingContext(bool useScaledDrawing) public IDrawingContextImpl CreateDrawingContext(IRenderTarget.RenderTargetSceneInfo sceneInfo,
=> CreateDrawingContextCore(null, useScaledDrawing, out _);
IDrawingContextImpl CreateDrawingContextCore(PixelSize? expectedPixelSize,
bool useScaledDrawing,
out RenderTargetDrawingContextProperties properties) out RenderTargetDrawingContextProperties properties)
{ {
properties = default; properties = default;
var session = _renderTarget.BeginRenderingSession(expectedPixelSize); var session = _renderTarget.BeginRenderingSession(sceneInfo);
var nfo = new DrawingContextImpl.CreateInfo var nfo = new DrawingContextImpl.CreateInfo
{ {
GrContext = session.GrContext, GrContext = session.GrContext,
Surface = session.SkSurface, Surface = session.SkSurface,
Dpi = SkiaPlatform.DefaultDpi * session.ScaleFactor, Dpi = SkiaPlatform.DefaultDpi * session.ScaleFactor,
ScaleDrawingToDpi = useScaledDrawing, ScaleDrawingToDpi = false,
Gpu = _skiaGpu, Gpu = _skiaGpu,
CurrentSession = session CurrentSession = session
}; };
@ -50,6 +45,7 @@ namespace Avalonia.Skia
} }
public bool IsCorrupted => _renderTarget.IsCorrupted; public bool IsCorrupted => _renderTarget.IsCorrupted;
public bool IsReady => _renderTarget.IsReady;
public RenderTargetProperties Properties { get; } public RenderTargetProperties Properties { get; }

18
src/Skia/Avalonia.Skia/Gpu/Vulkan/VulkanSkiaGpu.cs

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using Avalonia.Vulkan; using Avalonia.Vulkan;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using SkiaSharp; using SkiaSharp;
namespace Avalonia.Skia.Vulkan; namespace Avalonia.Skia.Vulkan;
@ -77,12 +78,27 @@ internal class VulkanSkiaGpu : ISkiaGpu
public IDisposable EnsureCurrent() => Vulkan.EnsureCurrent(); public IDisposable EnsureCurrent() => Vulkan.EnsureCurrent();
public ISkiaGpuRenderTarget TryCreateRenderTarget(IEnumerable<object> surfaces) public ISkiaGpuRenderTarget TryCreateRenderTarget(IEnumerable<IPlatformRenderSurface> surfaces)
{ {
var target = Vulkan.CreateRenderTarget(surfaces); var target = Vulkan.CreateRenderTarget(surfaces);
return new VulkanSkiaRenderTarget(this, target); return new VulkanSkiaRenderTarget(this, target);
} }
public bool IsReadyToCreateRenderTarget(IEnumerable<IPlatformRenderSurface> surfaces)
{
var factory = Vulkan.TryGetFeature<IVulkanKhrSurfacePlatformSurfaceFactory>();
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; public ISkiaSurface? TryCreateSurface(PixelSize size, ISkiaGpuRenderSession? session) => null;

5
src/Skia/Avalonia.Skia/Gpu/Vulkan/VulkanSkiaRenderTarget.cs

@ -1,4 +1,5 @@
using System; using System;
using Avalonia.Platform;
using Avalonia.Skia.Helpers; using Avalonia.Skia.Helpers;
using Avalonia.Vulkan; using Avalonia.Vulkan;
using SkiaSharp; using SkiaSharp;
@ -21,7 +22,7 @@ class VulkanSkiaRenderTarget : ISkiaGpuRenderTarget
_target.Dispose(); _target.Dispose();
} }
public ISkiaGpuRenderSession BeginRenderingSession(PixelSize? expectedPixelSize) public ISkiaGpuRenderSession BeginRenderingSession(IRenderTarget.RenderTargetSceneInfo sceneInfo)
{ {
// TODO: use expectedPixelSize // TODO: use expectedPixelSize
var session = _target.BeginDraw(); var session = _target.BeginDraw();
@ -75,6 +76,8 @@ class VulkanSkiaRenderTarget : ISkiaGpuRenderTarget
public bool IsCorrupted => false; public bool IsCorrupted => false;
public bool IsReady => _target.IsReady;
internal class VulkanSkiaRenderSession : ISkiaGpuRenderSession internal class VulkanSkiaRenderSession : ISkiaGpuRenderSession
{ {

17
src/Skia/Avalonia.Skia/RenderTargetBitmapImpl.cs

@ -1,4 +1,4 @@
using Avalonia.Controls.Platform.Surfaces; using Avalonia.Platform.Surfaces;
using Avalonia.Platform; using Avalonia.Platform;
using SkiaSharp; using SkiaSharp;
@ -14,21 +14,16 @@ internal class RenderTargetBitmapImpl : WriteableBitmapImpl,
SKImageInfo.PlatformColorType == SKColorType.Rgba8888 ? PixelFormats.Rgba8888 : PixelFormat.Bgra8888, SKImageInfo.PlatformColorType == SKColorType.Rgba8888 ? PixelFormats.Rgba8888 : PixelFormat.Bgra8888,
Platform.AlphaFormat.Premul) Platform.AlphaFormat.Premul)
{ {
_renderTarget = new FramebufferRenderTarget(this); _renderTarget = new FramebufferRenderTarget(this, true);
} }
public RenderTargetProperties Properties => default; public IDrawingContextImpl CreateDrawingContext()
IDrawingContextImpl IRenderTarget.CreateDrawingContext(bool useScaledDrawing) =>
_renderTarget.CreateDrawingContext(useScaledDrawing);
IDrawingContextImpl IRenderTarget.CreateDrawingContext(PixelSize expectedPixelSize,
out RenderTargetDrawingContextProperties properties)
{ {
properties = default; return _renderTarget.CreateDrawingContext(new IRenderTarget.RenderTargetSceneInfo(
return _renderTarget.CreateDrawingContext(false); PixelSize, Dpi.X / 96.0), out _);
} }
public bool IsCorrupted => false; public bool IsCorrupted => false;
public override void Dispose() public override void Dispose()

25
src/Skia/Avalonia.Skia/SkiaBackendContext.cs

@ -2,9 +2,9 @@ using System;
using System.Collections; using System.Collections;
using System.Collections.Generic; using System.Collections.Generic;
using System.Linq; using System.Linq;
using Avalonia.Controls.Platform.Surfaces;
using Avalonia.OpenGL; using Avalonia.OpenGL;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
namespace Avalonia.Skia; namespace Avalonia.Skia;
@ -47,7 +47,7 @@ internal class SkiaContext : IPlatformRenderInterfaceContext
} }
/// <inheritdoc /> /// <inheritdoc />
public IRenderTarget CreateRenderTarget(IEnumerable<object> surfaces) public IRenderTarget CreateRenderTarget(IEnumerable<IPlatformRenderSurface> surfaces)
{ {
if (surfaces is not IList) if (surfaces is not IList)
surfaces = surfaces.ToList(); 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"); "Don't know how to create a Skia render target from any of provided surfaces");
} }
public bool IsReadyToCreateRenderTarget(IEnumerable<IPlatformRenderSurface> 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; } public PixelSize? MaxOffscreenRenderTargetPixelSize { get; }

17
src/Skia/Avalonia.Skia/SurfaceRenderTarget.cs

@ -10,8 +10,9 @@ namespace Avalonia.Skia
/// <summary> /// <summary>
/// Skia render target that writes to a surface. /// Skia render target that writes to a surface.
/// </summary> /// </summary>
internal class SurfaceRenderTarget : IDrawingContextLayerImpl, IDrawableBitmapImpl, IDrawingContextLayerWithRenderContextAffinityImpl internal class SurfaceRenderTarget : IDrawableBitmapImpl, IDrawingContextLayerWithRenderContextAffinityImpl
{ {
private readonly bool _useScaledDrawing;
private readonly ISkiaSurface _surface; private readonly ISkiaSurface _surface;
private readonly SKCanvas _canvas; private readonly SKCanvas _canvas;
private readonly bool _disableLcdRendering; private readonly bool _disableLcdRendering;
@ -44,6 +45,7 @@ namespace Avalonia.Skia
/// <param name="createInfo">Create info.</param> /// <param name="createInfo">Create info.</param>
public SurfaceRenderTarget(CreateInfo createInfo) public SurfaceRenderTarget(CreateInfo createInfo)
{ {
_useScaledDrawing = createInfo.UseScaledDrawing;
PixelSize = new PixelSize(createInfo.Width, createInfo.Height); PixelSize = new PixelSize(createInfo.Width, createInfo.Height);
Dpi = createInfo.Dpi; Dpi = createInfo.Dpi;
@ -98,7 +100,7 @@ namespace Avalonia.Skia
} }
/// <inheritdoc /> /// <inheritdoc />
public IDrawingContextImpl CreateDrawingContext(bool useScaledDrawing) public IDrawingContextImpl CreateDrawingContext()
{ {
_canvas.RestoreToCount(-1); _canvas.RestoreToCount(-1);
_canvas.ResetMatrix(); _canvas.ResetMatrix();
@ -107,7 +109,7 @@ namespace Avalonia.Skia
{ {
Surface = _surface.Surface, Surface = _surface.Surface,
Dpi = Dpi, Dpi = Dpi,
ScaleDrawingToDpi = useScaledDrawing, ScaleDrawingToDpi = _useScaledDrawing,
DisableSubpixelTextRendering = _disableLcdRendering, DisableSubpixelTextRendering = _disableLcdRendering,
GrContext = _grContext, GrContext = _grContext,
Gpu = _gpu, Gpu = _gpu,
@ -116,15 +118,7 @@ namespace Avalonia.Skia
return new DrawingContextImpl(createInfo, Disposable.Create(() => Version++)); 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 bool IsCorrupted => _gpu?.IsLost == true;
/// <inheritdoc /> /// <inheritdoc />
public Vector Dpi { get; } public Vector Dpi { get; }
@ -241,6 +235,7 @@ namespace Avalonia.Skia
public ISkiaGpuRenderSession? Session; public ISkiaGpuRenderSession? Session;
public bool DisableManualFbo; public bool DisableManualFbo;
public bool UseScaledDrawing;
} }
public bool HasRenderContextAffinity => _grContext != null; public bool HasRenderContextAffinity => _grContext != null;

2
src/Windows/Avalonia.Win32/CursorFactory.cs

@ -90,7 +90,7 @@ namespace Avalonia.Win32
return rv; return rv;
} }
public ICursorImpl CreateCursor(IBitmapImpl cursor, PixelPoint hotSpot) public ICursorImpl CreateCursor(Bitmap cursor, PixelPoint hotSpot)
{ {
return new CursorImpl(new Win32Icon(cursor, hotSpot)); return new CursorImpl(new Win32Icon(cursor, hotSpot));
} }

4
src/Windows/Avalonia.Win32/DComposition/DirectCompositionConnection.cs

@ -4,6 +4,8 @@ using System.Diagnostics;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using Avalonia.Logging; using Avalonia.Logging;
using Avalonia.MicroCom; using Avalonia.MicroCom;
using Avalonia.OpenGL.Egl; using Avalonia.OpenGL.Egl;
@ -125,5 +127,5 @@ internal class DirectCompositionConnection : IRenderTimer, IWindowsSurfaceFactor
} }
public bool RequiresNoRedirectionBitmap => true; public bool RequiresNoRedirectionBitmap => true;
public object CreateSurface(EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo info) => new DirectCompositedWindowSurface(_shared, info); public IPlatformRenderSurface CreateSurface(EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo info) => new DirectCompositedWindowSurface(_shared, info);
} }

4
src/Windows/Avalonia.Win32/DirectX/DxgiConnection.cs

@ -3,6 +3,8 @@ using System.Collections.Generic;
using System.Diagnostics; using System.Diagnostics;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading.Tasks; using System.Threading.Tasks;
using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using Avalonia.Logging; using Avalonia.Logging;
using Avalonia.OpenGL.Egl; using Avalonia.OpenGL.Egl;
using Avalonia.Rendering; using Avalonia.Rendering;
@ -215,6 +217,6 @@ namespace Avalonia.Win32.DirectX
} }
public bool RequiresNoRedirectionBitmap => false; public bool RequiresNoRedirectionBitmap => false;
public object CreateSurface(EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo info) => new DxgiSwapchainWindow(this, info); public IPlatformRenderSurface CreateSurface(EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo info) => new DxgiSwapchainWindow(this, info);
} }
} }

3
src/Windows/Avalonia.Win32/DirectX/DxgiRenderTarget.cs

@ -1,6 +1,7 @@
using System; using System;
using Avalonia.OpenGL.Egl; using Avalonia.OpenGL.Egl;
using Avalonia.OpenGL.Surfaces; using Avalonia.OpenGL.Surfaces;
using Avalonia.Platform;
using Avalonia.Win32.OpenGl.Angle; using Avalonia.Win32.OpenGl.Angle;
using MicroCom.Runtime; using MicroCom.Runtime;
using static Avalonia.Win32.Interop.UnmanagedMethods; using static Avalonia.Win32.Interop.UnmanagedMethods;
@ -76,7 +77,7 @@ namespace Avalonia.Win32.DirectX
} }
/// <inheritdoc /> /// <inheritdoc />
public override IGlPlatformSurfaceRenderingSession BeginDrawCore(PixelSize? expectedPixelSize) public override IGlPlatformSurfaceRenderingSession BeginDrawCore(IRenderTarget.RenderTargetSceneInfo sceneInfo)
{ {
// TODO: use expectedPixelSize // TODO: use expectedPixelSize
if (_swapChain is null) if (_swapChain is null)

3
src/Windows/Avalonia.Win32/DirectX/IDirect3D11TexturePlatformSurface.cs

@ -1,10 +1,11 @@
using System; using System;
using Avalonia.OpenGL; using Avalonia.OpenGL;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
namespace Avalonia.Win32.DirectX; namespace Avalonia.Win32.DirectX;
public interface IDirect3D11TexturePlatformSurface public interface IDirect3D11TexturePlatformSurface : IPlatformRenderSurface
{ {
public IDirect3D11TextureRenderTarget CreateRenderTarget(IPlatformGraphicsContext graphicsContext, IntPtr d3dDevice); public IDirect3D11TextureRenderTarget CreateRenderTarget(IPlatformGraphicsContext graphicsContext, IntPtr d3dDevice);
} }

2
src/Windows/Avalonia.Win32/FramebufferManager.cs

@ -1,6 +1,6 @@
using System; using System;
using System.Threading; using System.Threading;
using Avalonia.Controls.Platform.Surfaces; using Avalonia.Platform.Surfaces;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Internal; using Avalonia.Platform.Internal;
using Avalonia.Win32.Interop; using Avalonia.Win32.Interop;

4
src/Windows/Avalonia.Win32/IWindowsSurfaceFactory.cs

@ -1,4 +1,6 @@
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using Avalonia.OpenGL.Egl; using Avalonia.OpenGL.Egl;
namespace Avalonia.Win32; namespace Avalonia.Win32;
@ -7,5 +9,5 @@ internal interface IWindowsSurfaceFactory
{ {
bool RequiresNoRedirectionBitmap { get; } bool RequiresNoRedirectionBitmap { get; }
object CreateSurface(EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo info); IPlatformRenderSurface CreateSurface(EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo info);
} }

9
src/Windows/Avalonia.Win32/Interop/Win32Icon.cs

@ -16,15 +16,6 @@ internal class Win32Icon : IDisposable
Handle = CreateIcon(bitmap, hotSpot); 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) public Win32Icon(byte[] iconData, PixelSize size = default)
{ {
_bytes = iconData; _bytes = iconData;

8
src/Windows/Avalonia.Win32/OpenGl/Angle/AngleD3DTextureFeature.cs

@ -2,13 +2,15 @@ using System.Runtime.InteropServices;
using Avalonia.OpenGL; using Avalonia.OpenGL;
using Avalonia.OpenGL.Egl; using Avalonia.OpenGL.Egl;
using Avalonia.OpenGL.Surfaces; using Avalonia.OpenGL.Surfaces;
using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using Avalonia.Win32.DirectX; using Avalonia.Win32.DirectX;
namespace Avalonia.Win32.OpenGl.Angle; namespace Avalonia.Win32.OpenGl.Angle;
internal class AngleD3DTextureFeature : IGlPlatformSurfaceRenderTargetFactory internal class AngleD3DTextureFeature : IGlPlatformSurfaceRenderTargetFactory
{ {
public bool CanRenderToSurface(IGlContext context, object surface) => public bool CanRenderToSurface(IGlContext context, IPlatformRenderSurface surface) =>
context is EglContext context is EglContext
{ {
Display: AngleWin32EglDisplay { PlatformApi: AngleOptions.PlatformApi.DirectX11 } Display: AngleWin32EglDisplay { PlatformApi: AngleOptions.PlatformApi.DirectX11 }
@ -27,7 +29,7 @@ internal class AngleD3DTextureFeature : IGlPlatformSurfaceRenderTargetFactory
_target = target; _target = target;
} }
public override IGlPlatformSurfaceRenderingSession BeginDrawCore(PixelSize? expectedPixelSize) public override IGlPlatformSurfaceRenderingSession BeginDrawCore(IRenderTarget.RenderTargetSceneInfo sceneInfo)
{ {
// TODO: use expectedPixelSize // TODO: use expectedPixelSize
var success = false; var success = false;
@ -84,7 +86,7 @@ internal class AngleD3DTextureFeature : IGlPlatformSurfaceRenderTargetFactory
public override bool IsCorrupted => _target.IsCorrupted || base.IsCorrupted; 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 ctx = (EglContext)context;
var angle = (AngleWin32EglDisplay)ctx.Display; var angle = (AngleWin32EglDisplay)ctx.Display;

3
src/Windows/Avalonia.Win32/OpenGl/WglGlPlatformSurface.cs

@ -3,6 +3,7 @@ using System.Diagnostics;
using Avalonia.OpenGL; using Avalonia.OpenGL;
using Avalonia.OpenGL.Egl; using Avalonia.OpenGL.Egl;
using Avalonia.OpenGL.Surfaces; using Avalonia.OpenGL.Surfaces;
using Avalonia.Platform;
using Avalonia.Win32.Interop; using Avalonia.Win32.Interop;
using static Avalonia.OpenGL.GlConsts; using static Avalonia.OpenGL.GlConsts;
using static Avalonia.Win32.Interop.UnmanagedMethods; using static Avalonia.Win32.Interop.UnmanagedMethods;
@ -43,7 +44,7 @@ namespace Avalonia.Win32.OpenGl
WglGdiResourceManager.ReleaseDC(_info.Handle, _hdc); WglGdiResourceManager.ReleaseDC(_info.Handle, _hdc);
} }
public IGlPlatformSurfaceRenderingSession BeginDraw(PixelSize? expectedPixelSize) public IGlPlatformSurfaceRenderingSession BeginDraw(IRenderTarget.RenderTargetSceneInfo sceneInfo)
{ {
// TODO: use expectedPixelSize // TODO: use expectedPixelSize
var oldContext = _context.MakeCurrent(_hdc); var oldContext = _context.MakeCurrent(_hdc);

5
src/Windows/Avalonia.Win32/Vulkan/VulkanSupport.cs

@ -2,6 +2,7 @@ using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using Avalonia.Vulkan; using Avalonia.Vulkan;
using Avalonia.Win32.Interop; using Avalonia.Win32.Interop;
@ -26,10 +27,10 @@ internal class VulkanSupport
internal class VulkanSurfaceFactory : IVulkanKhrSurfacePlatformSurfaceFactory 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"; 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); new HwndVulkanSurface((INativePlatformHandleSurface)handle);
} }

4
src/Windows/Avalonia.Win32/WinRT/Composition/WinUiCompositorConnection.cs

@ -3,6 +3,8 @@ using System.Diagnostics;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using System.Threading; using System.Threading;
using System.Threading.Tasks; using System.Threading.Tasks;
using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using Avalonia.Logging; using Avalonia.Logging;
using Avalonia.MicroCom; using Avalonia.MicroCom;
using Avalonia.OpenGL.Egl; using Avalonia.OpenGL.Egl;
@ -210,5 +212,5 @@ internal class WinUiCompositorConnection : IRenderTimer, Win32.IWindowsSurfaceFa
} }
public bool RequiresNoRedirectionBitmap => true; public bool RequiresNoRedirectionBitmap => true;
public object CreateSurface(EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo info) => new WinUiCompositedWindowSurface(_shared, info); public IPlatformRenderSurface CreateSurface(EglGlPlatformSurface.IEglWindowGlPlatformSurfaceInfo info) => new WinUiCompositedWindowSurface(_shared, info);
} }

9
src/Windows/Avalonia.Win32/WindowImpl.cs

@ -14,6 +14,7 @@ using Avalonia.Input.Raw;
using Avalonia.Input.TextInput; using Avalonia.Input.TextInput;
using Avalonia.OpenGL.Egl; using Avalonia.OpenGL.Egl;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using Avalonia.Platform.Storage; using Avalonia.Platform.Storage;
using Avalonia.Rendering.Composition; using Avalonia.Rendering.Composition;
using Avalonia.Win32.DirectX; using Avalonia.Win32.DirectX;
@ -75,7 +76,7 @@ namespace Avalonia.Win32
private readonly WindowsMouseDevice _mouseDevice; private readonly WindowsMouseDevice _mouseDevice;
private readonly PenDevice _penDevice; private readonly PenDevice _penDevice;
private readonly FramebufferManager _framebuffer; private readonly FramebufferManager _framebuffer;
private readonly object? _glSurface; private readonly IPlatformRenderSurface? _glSurface;
private readonly bool _wmPointerEnabled; private readonly bool _wmPointerEnabled;
private readonly Win32NativeControlHost _nativeControlHost; private readonly Win32NativeControlHost _nativeControlHost;
@ -505,10 +506,10 @@ namespace Avalonia.Win32
return result == 0; return result == 0;
} }
public IEnumerable<object> Surfaces public IPlatformRenderSurface[] Surfaces
=> _glSurface is null ? => _glSurface is null ?
new object[] { Handle, _framebuffer } : [(IPlatformRenderSurface)Handle, _framebuffer] :
new object[] { Handle, _glSurface, _framebuffer }; [(IPlatformRenderSurface)Handle, _glSurface, _framebuffer];
public PixelPoint Position public PixelPoint Position
{ {

7
src/iOS/Avalonia.iOS/AvaloniaView.cs

@ -12,6 +12,7 @@ using Avalonia.Input.Platform;
using Avalonia.Input.Raw; using Avalonia.Input.Raw;
using Avalonia.Input.TextInput; using Avalonia.Input.TextInput;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using Avalonia.Platform.Storage; using Avalonia.Platform.Storage;
using Avalonia.Rendering.Composition; using Avalonia.Rendering.Composition;
using CoreAnimation; using CoreAnimation;
@ -104,14 +105,14 @@ namespace Avalonia.iOS
OpenGLES.EAGLDrawableProperty.RetainedBacking, false, OpenGLES.EAGLDrawableProperty.RetainedBacking, false,
OpenGLES.EAGLDrawableProperty.ColorFormat, OpenGLES.EAGLColorFormat.RGBA8 OpenGLES.EAGLDrawableProperty.ColorFormat, OpenGLES.EAGLColorFormat.RGBA8
); );
_topLevelImpl.Surfaces = new[] { new Eagl.EaglLayerSurface(eaglLayer) }; _topLevelImpl.Surfaces = [new Eagl.EaglLayerSurface(eaglLayer)];
} }
else else
#endif #endif
if (l is CAMetalLayer metalLayer) if (l is CAMetalLayer metalLayer)
{ {
metalLayer.Opaque = false; 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 ClientSize => new Size(_view.Bounds.Width, _view.Bounds.Height);
public Size? FrameSize => null; public Size? FrameSize => null;
public double RenderScaling => _view.ContentScaleFactor; public double RenderScaling => _view.ContentScaleFactor;
public IEnumerable<object> Surfaces { get; set; } = Array.Empty<object>(); public IPlatformRenderSurface[] Surfaces { get; set; } = [];
public Action<RawInputEventArgs>? Input { get; set; } public Action<RawInputEventArgs>? Input { get; set; }
public Action<Rect>? Paint { get; set; } public Action<Rect>? Paint { get; set; }
public Action<Size, WindowResizeReason>? Resized { get; set; } public Action<Size, WindowResizeReason>? Resized { get; set; }

4
src/iOS/Avalonia.iOS/Eagl/EaglLayerSurface.cs

@ -3,6 +3,7 @@ using System.Runtime.Versioning;
using System.Threading; using System.Threading;
using Avalonia.OpenGL; using Avalonia.OpenGL;
using Avalonia.OpenGL.Surfaces; using Avalonia.OpenGL.Surfaces;
using Avalonia.Platform;
using CoreAnimation; using CoreAnimation;
namespace Avalonia.iOS.Eagl namespace Avalonia.iOS.Eagl
@ -70,9 +71,8 @@ namespace Avalonia.iOS.Eagl
_fbo.Dispose(); _fbo.Dispose();
} }
public IGlPlatformSurfaceRenderingSession BeginDraw(PixelSize? expectedPixelSize) public IGlPlatformSurfaceRenderingSession BeginDraw(IRenderTarget.RenderTargetSceneInfo sceneInfo)
{ {
// TODO: use expectedPixelSize
CheckThread(); CheckThread();
var restoreContext = _ctx.MakeCurrent(); var restoreContext = _ctx.MakeCurrent();
_fbo.Bind(); _fbo.Bind();

2
src/iOS/Avalonia.iOS/Stubs.cs

@ -7,7 +7,7 @@ namespace Avalonia.iOS
{ {
internal class CursorFactoryStub : ICursorFactory 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(); ICursorImpl ICursorFactory.GetCursor(StandardCursorType cursorType) => new CursorImplStub();
private class CursorImplStub : ICursorImpl private class CursorImplStub : ICursorImpl

2
tests/Avalonia.Benchmarks/Compositor/CompositionTargetUpdate.cs

@ -1,6 +1,6 @@
using System; using System;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Avalonia.Controls.Platform.Surfaces; using Avalonia.Platform.Surfaces;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Rendering; using Avalonia.Rendering;

3
tests/Avalonia.Controls.UnitTests/CursorFactoryMock.cs

@ -1,4 +1,5 @@
using Avalonia.Input; using Avalonia.Input;
using Avalonia.Media.Imaging;
using Avalonia.Platform; using Avalonia.Platform;
namespace Avalonia.Controls.UnitTests namespace Avalonia.Controls.UnitTests
@ -10,7 +11,7 @@ namespace Avalonia.Controls.UnitTests
return new MockCursorImpl(); return new MockCursorImpl();
} }
public ICursorImpl CreateCursor(IBitmapImpl cursor, PixelPoint hotSpot) public ICursorImpl CreateCursor(Bitmap cursor, PixelPoint hotSpot)
{ {
return new MockCursorImpl(); return new MockCursorImpl();
} }

14
tests/Avalonia.RenderTests/Composition/DirectFbCompositionTests.cs

@ -4,7 +4,7 @@ using System.IO;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Threading.Tasks; using System.Threading.Tasks;
using Avalonia.Controls; using Avalonia.Controls;
using Avalonia.Controls.Platform.Surfaces; using Avalonia.Platform.Surfaces;
using Avalonia.Controls.Primitives; using Avalonia.Controls.Primitives;
using Avalonia.Controls.Shapes; using Avalonia.Controls.Shapes;
using Avalonia.Layout; using Avalonia.Layout;
@ -86,13 +86,11 @@ public class DirectFbCompositionTests : TestBase
fb.RowBytes, new Vector(96, 96), PixelFormat.Rgba8888, AlphaFormat.Premul, null); fb.RowBytes, new Vector(96, 96), PixelFormat.Rgba8888, AlphaFormat.Premul, null);
bool previousFrameIsRetained = false; bool previousFrameIsRetained = false;
IFramebufferRenderTarget rt = advertised IFramebufferRenderTarget rt = new FuncFramebufferRenderTarget((_, out props) =>
? new FuncRetainedFramebufferRenderTarget((out FramebufferLockProperties props) => {
{ props = new() { PreviousFrameIsRetained = previousFrameIsRetained };
props = new() { PreviousFrameIsRetained = previousFrameIsRetained }; return LockFb();
return LockFb(); }, advertised);
})
: new FuncFramebufferRenderTarget(LockFb);
using var renderer = using var renderer =
new CompositingRenderer(root, compositor, () => new[] { new FuncFramebufferSurface(() => rt) }); new CompositingRenderer(root, compositor, () => new[] { new FuncFramebufferSurface(() => rt) });

6
tests/Avalonia.RenderTests/Media/BitmapTests.cs

@ -4,10 +4,10 @@ using System;
using System.IO; using System.IO;
using System.Runtime.CompilerServices; using System.Runtime.CompilerServices;
using System.Runtime.InteropServices; using System.Runtime.InteropServices;
using Avalonia.Controls.Platform.Surfaces;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.Media.Imaging; using Avalonia.Media.Imaging;
using Avalonia.Platform; using Avalonia.Platform;
using Avalonia.Platform.Surfaces;
using Xunit; using Xunit;
using Path = System.IO.Path; 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 fb = new Framebuffer(fmt, AlphaFormat.Premul, new PixelSize(80, 80));
var r = AvaloniaLocator.Current.GetRequiredService<IPlatformRenderInterface>(); var r = AvaloniaLocator.Current.GetRequiredService<IPlatformRenderInterface>();
using(var cpuContext = r.CreateBackendContext(null)) using(var cpuContext = r.CreateBackendContext(null))
using (var target = cpuContext.CreateRenderTarget(new object[] { fb })) using (var target = cpuContext.CreateRenderTarget(new IPlatformRenderSurface[] { fb }))
using (var ctx = target.CreateDrawingContext(false)) using (var ctx = target.CreateDrawingContext(new IRenderTarget.RenderTargetSceneInfo(fb.Size, 1), out _))
{ {
ctx.Clear(Colors.Transparent); ctx.Clear(Colors.Transparent);
ctx.PushOpacity(0.8, new Rect(0, 0, 80, 80)); ctx.PushOpacity(0.8, new Rect(0, 0, 80, 80));

1
tests/Avalonia.RenderTests/TestBase.cs

@ -13,7 +13,6 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Threading; using System.Threading;
using Avalonia.Controls.Platform.Surfaces;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.Rendering.Composition; using Avalonia.Rendering.Composition;
using Avalonia.Skia; using Avalonia.Skia;

2
tests/Avalonia.RenderTests/TestRenderHelper.cs

@ -13,7 +13,7 @@ using System.Collections.Generic;
using System.Linq; using System.Linq;
using System.Reactive.Disposables; using System.Reactive.Disposables;
using System.Threading; using System.Threading;
using Avalonia.Controls.Platform.Surfaces; using Avalonia.Platform.Surfaces;
using Avalonia.Media; using Avalonia.Media;
using Avalonia.Rendering.Composition; using Avalonia.Rendering.Composition;
using Avalonia.Threading; using Avalonia.Threading;

Some files were not shown because too many files changed in this diff

Loading…
Cancel
Save