diff --git a/src/loader/loader_wayland_helper.c b/src/loader/loader_wayland_helper.c index 5953f3e7bed..825e0882304 100644 --- a/src/loader/loader_wayland_helper.c +++ b/src/loader/loader_wayland_helper.c @@ -163,3 +163,19 @@ loader_wayland_dispatch(struct wl_display *wl_display, queue, &remaining_timeout); } + +void +loader_wayland_wrap_buffer(struct loader_wayland_buffer *lwb, + struct wl_buffer *wl_buffer) +{ + lwb->buffer = wl_buffer; + lwb->id = wl_proxy_get_id((struct wl_proxy *)wl_buffer); +} + +void +loader_wayland_buffer_destroy(struct loader_wayland_buffer *lwb) +{ + wl_buffer_destroy(lwb->buffer); + lwb->buffer = NULL; + lwb->id = 0; +} diff --git a/src/loader/loader_wayland_helper.h b/src/loader/loader_wayland_helper.h index 0d7c49a15f2..ba206628c2c 100644 --- a/src/loader/loader_wayland_helper.h +++ b/src/loader/loader_wayland_helper.h @@ -26,6 +26,11 @@ #include #include +struct loader_wayland_buffer { + struct wl_buffer *buffer; + uint32_t id; +}; + #ifndef HAVE_WL_DISPATCH_QUEUE_TIMEOUT int wl_display_dispatch_queue_timeout(struct wl_display *display, @@ -44,4 +49,11 @@ loader_wayland_dispatch(struct wl_display *display, struct wl_event_queue *queue, struct timespec *end_time); +void +loader_wayland_wrap_buffer(struct loader_wayland_buffer *lwb, + struct wl_buffer *wl_buffer); + +void +loader_wayland_buffer_destroy(struct loader_wayland_buffer *lwb); + #endif diff --git a/src/vulkan/wsi/wsi_common_wayland.c b/src/vulkan/wsi/wsi_common_wayland.c index 50a39bdeef7..22858caee4a 100644 --- a/src/vulkan/wsi/wsi_common_wayland.c +++ b/src/vulkan/wsi/wsi_common_wayland.c @@ -158,7 +158,7 @@ struct wsi_wayland { struct wsi_wl_image { struct wsi_image base; - struct wl_buffer *buffer; + struct loader_wayland_buffer wayland_buffer; bool busy; int shm_fd; void *shm_ptr; @@ -3015,7 +3015,8 @@ wsi_wl_swapchain_queue_present(struct wsi_swapchain *wsi_chain, } assert(image_index < chain->base.image_count); - wl_surface_attach(wsi_wl_surface->surface, chain->images[image_index].buffer, 0, 0); + wl_surface_attach(wsi_wl_surface->surface, + chain->images[image_index].wayland_buffer.buffer, 0, 0); if (wl_surface_get_version(wsi_wl_surface->surface) >= WL_SURFACE_DAMAGE_BUFFER_SINCE_VERSION) { if (damage && damage->pRectangles && damage->rectangleCount > 0) { @@ -3046,8 +3047,7 @@ wsi_wl_swapchain_queue_present(struct wsi_swapchain *wsi_chain, id->present_id = present_id; id->alloc = chain->wsi_wl_surface->display->wsi_wl->alloc; id->flow_id = flow_id; - id->buffer_id = - wl_proxy_get_id((struct wl_proxy *)chain->images[image_index].buffer); + id->buffer_id = chain->images[image_index].wayland_buffer.id; id->submission_time = os_time_get_nano(); @@ -3187,7 +3187,7 @@ buffer_handle_release(void *data, struct wl_buffer *buffer) { struct wsi_wl_image *image = data; - assert(image->buffer == buffer); + assert(image->wayland_buffer.buffer == buffer); image->busy = false; } @@ -3247,10 +3247,12 @@ wsi_wl_image_init(struct wsi_wl_swapchain *chain, image->shm_fd, image->shm_size); wl_proxy_set_queue((struct wl_proxy *)pool, display->queue); - image->buffer = wl_shm_pool_create_buffer(pool, 0, chain->extent.width, - chain->extent.height, - image->base.row_pitches[0], - chain->shm_format); + struct wl_buffer *buffer = + wl_shm_pool_create_buffer(pool, 0, chain->extent.width, + chain->extent.height, + image->base.row_pitches[0], + chain->shm_format); + loader_wayland_wrap_buffer(&image->wayland_buffer, buffer); wl_shm_pool_destroy(pool); break; } @@ -3273,13 +3275,14 @@ wsi_wl_image_init(struct wsi_wl_swapchain *chain, image->base.drm_modifier & 0xffffffff); } - image->buffer = + struct wl_buffer *buffer = zwp_linux_buffer_params_v1_create_immed(params, chain->extent.width, chain->extent.height, chain->drm_format, 0); zwp_linux_buffer_params_v1_destroy(params); + loader_wayland_wrap_buffer(&image->wayland_buffer, buffer); if (chain->base.image_info.explicit_sync) { for (uint32_t i = 0; i < WSI_ES_COUNT; i++) { @@ -3298,12 +3301,12 @@ wsi_wl_image_init(struct wsi_wl_swapchain *chain, unreachable("Invalid buffer type"); } - if (!image->buffer) + if (!image->wayland_buffer.buffer) goto fail_image; /* No need to listen for release if we are explicit sync. */ if (!chain->base.image_info.explicit_sync) - wl_buffer_add_listener(image->buffer, &buffer_listener, image); + wl_buffer_add_listener(image->wayland_buffer.buffer, &buffer_listener, image); return VK_SUCCESS; @@ -3325,8 +3328,8 @@ wsi_wl_swapchain_images_free(struct wsi_wl_swapchain *chain) if (chain->images[i].wl_syncobj_timeline[j]) wp_linux_drm_syncobj_timeline_v1_destroy(chain->images[i].wl_syncobj_timeline[j]); } - if (chain->images[i].buffer) { - wl_buffer_destroy(chain->images[i].buffer); + if (chain->images[i].wayland_buffer.buffer) { + loader_wayland_buffer_destroy(&chain->images[i].wayland_buffer); wsi_destroy_image(&chain->base, &chain->images[i].base); if (chain->images[i].shm_size) { close(chain->images[i].shm_fd);