wsi/metal: Disable reference counting

Reviewed-By: Aleksi Sapon <aleksi.sapon@autodesk.com>
Acked-By: Yiwei Zhang <zzyiwei@chromium.org>
Part-of: <https://gitlab.freedesktop.org/mesa/mesa/-/merge_requests/37493>
This commit is contained in:
Aitor Camacho 2025-10-01 14:49:35 +02:00 committed by Marge Bot
parent 507d9af1b9
commit a1c8b21774
4 changed files with 36 additions and 42 deletions

View file

@ -19,7 +19,6 @@ project(
if host_machine.system() == 'darwin'
add_languages('objc', native : false)
add_project_arguments('-fobjc-arc', language : 'objc')
libname_prefix = 'lib'
libname_suffix = 'dylib'
elif host_machine.system() == 'windows'
@ -2197,6 +2196,9 @@ endif
add_project_arguments(pre_args, language : ['c', 'cpp'])
add_project_arguments(c_cpp_args, language : ['c', 'cpp'])
if host_machine.system() == 'darwin'
add_project_arguments(pre_args, language : ['objc'])
endif
add_project_arguments(c_args, language : ['c'])
add_project_arguments(cpp_args, language : ['cpp'])

View file

@ -272,7 +272,7 @@ wsi_metal_surface_get_present_rectangles(VkIcdSurfaceBase *surface,
struct wsi_metal_image {
struct wsi_image base;
CAMetalDrawableBridged *drawable;
CAMetalDrawable *drawable;
};
struct wsi_metal_swapchain {
@ -317,7 +317,7 @@ wsi_metal_swapchain_acquire_next_image(struct wsi_swapchain *wsi_chain,
while (1) {
/* Try to acquire an drawable. Unfortunately we might block for up to 1 second. */
CAMetalDrawableBridged *drawable = wsi_metal_layer_acquire_drawable(chain->surface->pLayer);
CAMetalDrawable *drawable = wsi_metal_layer_acquire_drawable(chain->surface->pLayer);
if (drawable) {
uint32_t i = (chain->current_image_index++) % chain->base.image_count;
*image_index = i;
@ -363,9 +363,14 @@ wsi_metal_swapchain_destroy(struct wsi_swapchain *wsi_chain,
(struct wsi_metal_swapchain *)wsi_chain;
for (uint32_t i = 0; i < chain->base.image_count; i++) {
wsi_metal_layer_cancel_present(chain->blit_context, &chain->images[i].drawable);
if (chain->images[i].base.image != VK_NULL_HANDLE)
wsi_destroy_image(&chain->base, &chain->images[i].base);
struct wsi_metal_image *image = &chain->images[i];
if (image->drawable) {
wsi_metal_release_drawable(image->drawable);
image->drawable = NULL;
}
if (image->base.image != VK_NULL_HANDLE)
wsi_destroy_image(&chain->base, &image->base);
}
wsi_destroy_metal_layer_blit_context(chain->blit_context);

View file

@ -13,7 +13,7 @@
#include <stdint.h>
#include <stdbool.h>
typedef void CAMetalDrawableBridged;
typedef void CAMetalDrawable;
void
wsi_metal_layer_size(const CAMetalLayer *metal_layer,
@ -25,9 +25,12 @@ wsi_metal_layer_configure(const CAMetalLayer *metal_layer,
VkFormat format, VkColorSpaceKHR color_space,
bool enable_opaque, bool enable_immediate);
CAMetalDrawableBridged *
CAMetalDrawable *
wsi_metal_layer_acquire_drawable(const CAMetalLayer *metal_layer);
void
wsi_metal_release_drawable(CAMetalDrawable *drawable_ptr);
struct wsi_metal_layer_blit_context;
struct wsi_metal_layer_blit_context *
@ -38,11 +41,7 @@ wsi_destroy_metal_layer_blit_context(struct wsi_metal_layer_blit_context *contex
void
wsi_metal_layer_blit_and_present(struct wsi_metal_layer_blit_context *context,
CAMetalDrawableBridged **drawable_ptr, void *buffer,
CAMetalDrawable **drawable_ptr, void *buffer,
uint32_t width, uint32_t height, uint32_t row_pitch);
void
wsi_metal_layer_cancel_present(struct wsi_metal_layer_blit_context *context,
CAMetalDrawableBridged **drawable_ptr);
#endif // WSI_COMMON_METAL_LAYER_H

View file

@ -135,15 +135,21 @@ wsi_metal_layer_configure(const CAMetalLayer *metal_layer,
return VK_SUCCESS;
}
CAMetalDrawableBridged *
CAMetalDrawable *
wsi_metal_layer_acquire_drawable(const CAMetalLayer *metal_layer)
{
@autoreleasepool {
id<CAMetalDrawable> drawable = [metal_layer nextDrawable];
return (__bridge_retained CAMetalDrawableBridged *)drawable;
return (CAMetalDrawable *)[drawable retain];
}
}
void
wsi_metal_release_drawable(CAMetalDrawable *drawable_ptr)
{
[(id<CAMetalDrawable>)drawable_ptr release];
}
struct wsi_metal_layer_blit_context {
id<MTLDevice> device;
id<MTLCommandQueue> commandQueue;
@ -166,29 +172,29 @@ wsi_create_metal_layer_blit_context()
void
wsi_destroy_metal_layer_blit_context(struct wsi_metal_layer_blit_context *context)
{
@autoreleasepool {
context->device = nil;
context->commandQueue = nil;
free(context);
}
[context->commandQueue release];
[context->device release];
context->device = nil;
context->commandQueue = nil;
free(context);
}
void
wsi_metal_layer_blit_and_present(struct wsi_metal_layer_blit_context *context,
CAMetalDrawableBridged **drawable_ptr, void *buffer,
CAMetalDrawable **drawable_ptr, void *buffer,
uint32_t width, uint32_t height, uint32_t row_pitch)
{
@autoreleasepool {
id<CAMetalDrawable> drawable = (__bridge_transfer id<CAMetalDrawable>)*drawable_ptr;
id<CAMetalDrawable> drawable = [(id<CAMetalDrawable>)*drawable_ptr autorelease];
id<MTLCommandBuffer> commandBuffer = [context->commandQueue commandBuffer];
id<MTLBlitCommandEncoder> commandEncoder = [commandBuffer blitCommandEncoder];
NSUInteger image_size = height * row_pitch;
id<MTLBuffer> image_buffer = [context->device newBufferWithBytesNoCopy:buffer
id<MTLBuffer> image_buffer = [[context->device newBufferWithBytesNoCopy:buffer
length:image_size
options:MTLResourceStorageModeShared
deallocator:nil];
deallocator:nil] autorelease];
[commandEncoder copyFromBuffer:image_buffer
sourceOffset:0
@ -206,21 +212,3 @@ wsi_metal_layer_blit_and_present(struct wsi_metal_layer_blit_context *context,
*drawable_ptr = nil;
}
}
void
wsi_metal_layer_cancel_present(struct wsi_metal_layer_blit_context *context,
CAMetalDrawableBridged **drawable_ptr)
{
@autoreleasepool {
id<CAMetalDrawable> drawable = (__bridge_transfer id<CAMetalDrawable>)*drawable_ptr;
if (drawable == nil)
return;
/* We need to present the drawable to release it... */
id<MTLCommandBuffer> commandBuffer = [context->commandQueue commandBuffer];
[commandBuffer presentDrawable:drawable];
[commandBuffer commit];
*drawable_ptr = nil;
}
}