From f3df9b1f30e8ed15a3b3fc5157f0b8c183297219 Mon Sep 17 00:00:00 2001 From: Tim Miller Date: Mon, 9 Mar 2026 18:41:53 +0900 Subject: [PATCH] [Metal] Dispose GRBackendRenderTarget and @autoreleasepool for metal objects (#20815) * Add @autoreleasepool to release memory * Pass in and dispose GRBackendRenderTarget * Use Macros --- native/Avalonia.Native/src/OSX/metal.mm | 15 +++++++++------ src/Skia/Avalonia.Skia/Gpu/Metal/SkiaMetalGpu.cs | 13 +++++++++---- 2 files changed, 18 insertions(+), 10 deletions(-) diff --git a/native/Avalonia.Native/src/OSX/metal.mm b/native/Avalonia.Native/src/OSX/metal.mm index 33aa2aeb53..517872b147 100644 --- a/native/Avalonia.Native/src/OSX/metal.mm +++ b/native/Avalonia.Native/src/OSX/metal.mm @@ -87,11 +87,12 @@ public: return (__bridge void*) queue; } - HRESULT ImportIOSurface(void *handle, AvnPixelFormat pixelFormat, IAvnMetalTexture **ppv) override { + HRESULT ImportIOSurface(void *handle, AvnPixelFormat pixelFormat, IAvnMetalTexture **ppv) override { + START_COM_ARP_CALL; auto surf = (IOSurfaceRef)handle; auto width = IOSurfaceGetWidth(surf); auto height = IOSurfaceGetHeight(surf); - + auto desc = [MTLTextureDescriptor new]; if(pixelFormat == kAvnRgba8888) desc.pixelFormat = MTLPixelFormatRGBA8Unorm; @@ -106,13 +107,12 @@ public: desc.mipmapLevelCount = 1; desc.sampleCount = 1; desc.usage = MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget; - + auto texture = [device newTextureWithDescriptor:desc iosurface:surf plane:0]; if(texture == nullptr) return E_FAIL; *ppv = new AvnMetalTexture(texture); return S_OK; - } HRESULT ImportSharedEvent(void *mtlSharedEventInstance, IAvnMTLSharedEvent**ppv) override { @@ -132,11 +132,12 @@ public: HRESULT SignalOrWait(IAvnMTLSharedEvent *ev, uint64_t value, bool wait) { + START_ARP_CALL; if (@available(macOS 12.0, *)) { auto e = dynamic_cast(ev); if(e == nullptr) - return E_FAIL;; + return E_FAIL; auto buf = [queue commandBuffer]; if(wait) [buf encodeWaitForEvent:e->GetEvent() value:value]; @@ -204,6 +205,7 @@ public: ~AvnMetalRenderSession() { + START_ARP_CALL; auto buffer = [_queue commandBuffer]; [buffer presentDrawable: _drawable]; [buffer commit]; @@ -227,6 +229,7 @@ public: } HRESULT BeginDrawing(IAvnMetalRenderingSession **ret) override { + START_COM_ARP_CALL; if([NSThread isMainThread]) { // Flush all existing rendering @@ -289,7 +292,7 @@ class AvnMetalDisplay : public ComSingleObject false; @@ -118,14 +118,17 @@ internal class SkiaMetalGpu : ISkiaGpu private readonly SkiaMetalGpu _gpu; private SKSurface? _surface; private IMetalPlatformSurfaceRenderingSession? _session; + private GRBackendRenderTarget? _backendTarget; - public SkiaMetalRenderSession(SkiaMetalGpu gpu, + public SkiaMetalRenderSession(SkiaMetalGpu gpu, SKSurface surface, - IMetalPlatformSurfaceRenderingSession session) + IMetalPlatformSurfaceRenderingSession session, + GRBackendRenderTarget backendTarget) { _gpu = gpu; _surface = surface; _session = session; + _backendTarget = backendTarget; } public void Dispose() @@ -133,11 +136,13 @@ internal class SkiaMetalGpu : ISkiaGpu _surface?.Canvas.Flush(); _surface?.Flush(); _gpu._context?.Flush(); - + _surface?.Dispose(); _surface = null; _session?.Dispose(); _session = null; + _backendTarget?.Dispose(); + _backendTarget = null; } public GRContext GrContext => _gpu._context!;