mirror of
https://gitlab.freedesktop.org/wlroots/wlroots.git
synced 2026-03-28 07:58:59 -04:00
linux_drm_syncobj_v1: fix handling of empty first commit
As reported in https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4979#note_3385626,bfd6e619fcdid not correctly handle clients that don't immediately follow their call to `wp_linux_drm_syncobj_manager_v1.get_surface` with a commit attaching a buffer Fixes:bfd6e619fc(cherry picked from commitfd870f6d27)
This commit is contained in:
parent
1a9b1292e2
commit
2bfbec4af1
2 changed files with 11 additions and 3 deletions
|
|
@ -20,6 +20,7 @@ struct wlr_linux_drm_syncobj_surface_v1_state {
|
||||||
uint64_t acquire_point;
|
uint64_t acquire_point;
|
||||||
|
|
||||||
struct {
|
struct {
|
||||||
|
bool committed;
|
||||||
struct wlr_drm_syncobj_timeline *release_timeline;
|
struct wlr_drm_syncobj_timeline *release_timeline;
|
||||||
uint64_t release_point;
|
uint64_t release_point;
|
||||||
struct wlr_drm_syncobj_merger *release_merger;
|
struct wlr_drm_syncobj_merger *release_merger;
|
||||||
|
|
|
||||||
|
|
@ -171,19 +171,20 @@ static void surface_synced_move_state(void *_dst, void *_src) {
|
||||||
}
|
}
|
||||||
surface_synced_finish_state(dst);
|
surface_synced_finish_state(dst);
|
||||||
*dst = *src;
|
*dst = *src;
|
||||||
|
dst->committed = true;
|
||||||
*src = (struct wlr_linux_drm_syncobj_surface_v1_state){0};
|
*src = (struct wlr_linux_drm_syncobj_surface_v1_state){0};
|
||||||
}
|
}
|
||||||
|
|
||||||
static void surface_synced_commit(struct wlr_surface_synced *synced) {
|
static void surface_synced_commit(struct wlr_surface_synced *synced) {
|
||||||
struct wlr_linux_drm_syncobj_surface_v1 *surface = wl_container_of(synced, surface, synced);
|
struct wlr_linux_drm_syncobj_surface_v1 *surface = wl_container_of(synced, surface, synced);
|
||||||
|
|
||||||
if (surface->current.release_merger != NULL) {
|
if (!surface->current.committed) {
|
||||||
// ignore commits that did not attach a buffer
|
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
surface->current.release_merger = wlr_drm_syncobj_merger_create(
|
surface->current.release_merger = wlr_drm_syncobj_merger_create(
|
||||||
surface->current.release_timeline, surface->current.release_point);
|
surface->current.release_timeline, surface->current.release_point);
|
||||||
|
surface->current.committed = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -507,7 +508,7 @@ static void release_signaller_handle_buffer_release(struct wl_listener *listener
|
||||||
bool wlr_linux_drm_syncobj_v1_state_signal_release_with_buffer(
|
bool wlr_linux_drm_syncobj_v1_state_signal_release_with_buffer(
|
||||||
struct wlr_linux_drm_syncobj_surface_v1_state *state, struct wlr_buffer *buffer) {
|
struct wlr_linux_drm_syncobj_surface_v1_state *state, struct wlr_buffer *buffer) {
|
||||||
assert(buffer->n_locks > 0);
|
assert(buffer->n_locks > 0);
|
||||||
if (state->release_timeline == NULL) {
|
if (state->release_merger == NULL) {
|
||||||
// This can happen if an existing surface with a buffer has a
|
// This can happen if an existing surface with a buffer has a
|
||||||
// syncobj_surface_v1_state created but no new buffer with release
|
// syncobj_surface_v1_state created but no new buffer with release
|
||||||
// timeline committed.
|
// timeline committed.
|
||||||
|
|
@ -530,6 +531,12 @@ bool wlr_linux_drm_syncobj_v1_state_add_release_point(
|
||||||
struct wlr_linux_drm_syncobj_surface_v1_state *state,
|
struct wlr_linux_drm_syncobj_surface_v1_state *state,
|
||||||
struct wlr_drm_syncobj_timeline *release_timeline, uint64_t release_point,
|
struct wlr_drm_syncobj_timeline *release_timeline, uint64_t release_point,
|
||||||
struct wl_event_loop *event_loop) {
|
struct wl_event_loop *event_loop) {
|
||||||
|
if (state->release_merger == NULL) {
|
||||||
|
// This can happen if an existing surface with a buffer has a
|
||||||
|
// syncobj_surface_v1_state created but no new buffer with release
|
||||||
|
// timeline committed.
|
||||||
|
return true;
|
||||||
|
}
|
||||||
return wlr_drm_syncobj_merger_add(state->release_merger,
|
return wlr_drm_syncobj_merger_add(state->release_merger,
|
||||||
release_timeline, release_point, event_loop);
|
release_timeline, release_point, event_loop);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue