Browse Source

[Metal] Dispose GRBackendRenderTarget and @autoreleasepool for metal objects (#20815)

* Add @autoreleasepool to release memory

* Pass in and dispose GRBackendRenderTarget

* Use Macros
pull/20934/head
Tim Miller 2 weeks ago
committed by GitHub
parent
commit
f3df9b1f30
No known key found for this signature in database GPG Key ID: B5690EEEBB952194
  1. 15
      native/Avalonia.Native/src/OSX/metal.mm
  2. 13
      src/Skia/Avalonia.Skia/Gpu/Metal/SkiaMetalGpu.cs

15
native/Avalonia.Native/src/OSX/metal.mm

@ -87,11 +87,12 @@ public:
return (__bridge void*) queue; 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 surf = (IOSurfaceRef)handle;
auto width = IOSurfaceGetWidth(surf); auto width = IOSurfaceGetWidth(surf);
auto height = IOSurfaceGetHeight(surf); auto height = IOSurfaceGetHeight(surf);
auto desc = [MTLTextureDescriptor new]; auto desc = [MTLTextureDescriptor new];
if(pixelFormat == kAvnRgba8888) if(pixelFormat == kAvnRgba8888)
desc.pixelFormat = MTLPixelFormatRGBA8Unorm; desc.pixelFormat = MTLPixelFormatRGBA8Unorm;
@ -106,13 +107,12 @@ public:
desc.mipmapLevelCount = 1; desc.mipmapLevelCount = 1;
desc.sampleCount = 1; desc.sampleCount = 1;
desc.usage = MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget; desc.usage = MTLTextureUsageShaderRead | MTLTextureUsageRenderTarget;
auto texture = [device newTextureWithDescriptor:desc iosurface:surf plane:0]; auto texture = [device newTextureWithDescriptor:desc iosurface:surf plane:0];
if(texture == nullptr) if(texture == nullptr)
return E_FAIL; return E_FAIL;
*ppv = new AvnMetalTexture(texture); *ppv = new AvnMetalTexture(texture);
return S_OK; return S_OK;
} }
HRESULT ImportSharedEvent(void *mtlSharedEventInstance, IAvnMTLSharedEvent**ppv) override { HRESULT ImportSharedEvent(void *mtlSharedEventInstance, IAvnMTLSharedEvent**ppv) override {
@ -132,11 +132,12 @@ public:
HRESULT SignalOrWait(IAvnMTLSharedEvent *ev, uint64_t value, bool wait) HRESULT SignalOrWait(IAvnMTLSharedEvent *ev, uint64_t value, bool wait)
{ {
START_ARP_CALL;
if (@available(macOS 12.0, *)) if (@available(macOS 12.0, *))
{ {
auto e = dynamic_cast<AvnMTLSharedEvent*>(ev); auto e = dynamic_cast<AvnMTLSharedEvent*>(ev);
if(e == nullptr) if(e == nullptr)
return E_FAIL;; return E_FAIL;
auto buf = [queue commandBuffer]; auto buf = [queue commandBuffer];
if(wait) if(wait)
[buf encodeWaitForEvent:e->GetEvent() value:value]; [buf encodeWaitForEvent:e->GetEvent() value:value];
@ -204,6 +205,7 @@ public:
~AvnMetalRenderSession() ~AvnMetalRenderSession()
{ {
START_ARP_CALL;
auto buffer = [_queue commandBuffer]; auto buffer = [_queue commandBuffer];
[buffer presentDrawable: _drawable]; [buffer presentDrawable: _drawable];
[buffer commit]; [buffer commit];
@ -227,6 +229,7 @@ public:
} }
HRESULT BeginDrawing(IAvnMetalRenderingSession **ret) override { HRESULT BeginDrawing(IAvnMetalRenderingSession **ret) override {
START_COM_ARP_CALL;
if([NSThread isMainThread]) if([NSThread isMainThread])
{ {
// Flush all existing rendering // Flush all existing rendering
@ -289,7 +292,7 @@ class AvnMetalDisplay : public ComSingleObject<IAvnMetalDisplay, &IID_IAvnMetalD
public: public:
FORWARD_IUNKNOWN() FORWARD_IUNKNOWN()
HRESULT CreateDevice(IAvnMetalDevice **ret) override { HRESULT CreateDevice(IAvnMetalDevice **ret) override {
START_COM_ARP_CALL;
auto device = MTLCreateSystemDefaultDevice(); auto device = MTLCreateSystemDefaultDevice();
if(device == nil) { if(device == nil) {
ret = nil; ret = nil;

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

@ -105,7 +105,7 @@ internal class SkiaMetalGpu : ISkiaGpu
session.IsYFlipped ? GRSurfaceOrigin.BottomLeft : GRSurfaceOrigin.TopLeft, session.IsYFlipped ? GRSurfaceOrigin.BottomLeft : GRSurfaceOrigin.TopLeft,
SKColorType.Bgra8888); SKColorType.Bgra8888);
return new SkiaMetalRenderSession(_gpu, surface, session); return new SkiaMetalRenderSession(_gpu, surface, session, backendTarget);
} }
public bool IsCorrupted => false; public bool IsCorrupted => false;
@ -118,14 +118,17 @@ internal class SkiaMetalGpu : ISkiaGpu
private readonly SkiaMetalGpu _gpu; private readonly SkiaMetalGpu _gpu;
private SKSurface? _surface; private SKSurface? _surface;
private IMetalPlatformSurfaceRenderingSession? _session; private IMetalPlatformSurfaceRenderingSession? _session;
private GRBackendRenderTarget? _backendTarget;
public SkiaMetalRenderSession(SkiaMetalGpu gpu, public SkiaMetalRenderSession(SkiaMetalGpu gpu,
SKSurface surface, SKSurface surface,
IMetalPlatformSurfaceRenderingSession session) IMetalPlatformSurfaceRenderingSession session,
GRBackendRenderTarget backendTarget)
{ {
_gpu = gpu; _gpu = gpu;
_surface = surface; _surface = surface;
_session = session; _session = session;
_backendTarget = backendTarget;
} }
public void Dispose() public void Dispose()
@ -133,11 +136,13 @@ internal class SkiaMetalGpu : ISkiaGpu
_surface?.Canvas.Flush(); _surface?.Canvas.Flush();
_surface?.Flush(); _surface?.Flush();
_gpu._context?.Flush(); _gpu._context?.Flush();
_surface?.Dispose(); _surface?.Dispose();
_surface = null; _surface = null;
_session?.Dispose(); _session?.Dispose();
_session = null; _session = null;
_backendTarget?.Dispose();
_backendTarget = null;
} }
public GRContext GrContext => _gpu._context!; public GRContext GrContext => _gpu._context!;

Loading…
Cancel
Save