mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2025-10-29 05:40:12 -04:00
render/drm_syncobj: Add a callback when ready
The old approach of using a signal is fundamentally broken for a common usecase: When the waiter is ready, it's common to immediately finish and free any resources associated with it. Because of the semantics of wl_signal_emit_mutable() this is UB. wl_signal_emit_mutable() always excepts that the waiter hasn't been freed until the signal has finished being emitted. Instead of over engineering the solution, let's just add a callback required by wlr_drm_syncobj_timeline_waiter_init(). In this callback, the implementation is free to finish() or free() any resource it likes.
This commit is contained in:
parent
211eb9d60e
commit
82223e451a
5 changed files with 21 additions and 19 deletions
|
|
@ -135,7 +135,6 @@ static const struct wp_presentation_feedback_listener
|
|||
};
|
||||
|
||||
static void buffer_remove_drm_syncobj_waiter(struct wlr_wl_buffer *buffer) {
|
||||
wl_list_remove(&buffer->drm_syncobj_ready.link);
|
||||
wlr_drm_syncobj_timeline_waiter_finish(&buffer->drm_syncobj_waiter);
|
||||
buffer->has_drm_syncobj_waiter = false;
|
||||
}
|
||||
|
|
@ -177,8 +176,8 @@ static const struct wl_buffer_listener buffer_listener = {
|
|||
.release = buffer_handle_release,
|
||||
};
|
||||
|
||||
static void buffer_handle_drm_syncobj_ready(struct wl_listener *listener, void *data) {
|
||||
struct wlr_wl_buffer *buffer = wl_container_of(listener, buffer, drm_syncobj_ready);
|
||||
static void buffer_handle_drm_syncobj_ready(struct wlr_drm_syncobj_timeline_waiter *waiter) {
|
||||
struct wlr_wl_buffer *buffer = wl_container_of(waiter, buffer, drm_syncobj_waiter);
|
||||
buffer_remove_drm_syncobj_waiter(buffer);
|
||||
buffer_release(buffer);
|
||||
}
|
||||
|
|
@ -819,14 +818,11 @@ static bool output_commit(struct wlr_output *wlr_output,
|
|||
signal_timeline->wl, signal_point_hi, signal_point_lo);
|
||||
|
||||
if (!wlr_drm_syncobj_timeline_waiter_init(&buffer->drm_syncobj_waiter,
|
||||
signal_timeline->base, signal_point, 0, output->backend->event_loop)) {
|
||||
signal_timeline->base, signal_point, 0, output->backend->event_loop,
|
||||
buffer_handle_drm_syncobj_ready)) {
|
||||
return false;
|
||||
}
|
||||
buffer->has_drm_syncobj_waiter = true;
|
||||
|
||||
buffer->drm_syncobj_ready.notify = buffer_handle_drm_syncobj_ready;
|
||||
wl_signal_add(&buffer->drm_syncobj_waiter.events.ready,
|
||||
&buffer->drm_syncobj_ready);
|
||||
} else {
|
||||
if (output->drm_syncobj_surface_v1 != NULL) {
|
||||
wp_linux_drm_syncobj_surface_v1_destroy(output->drm_syncobj_surface_v1);
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue