From 6705ea135786089b608bf6825786d6ff5103d51f Mon Sep 17 00:00:00 2001 From: Seunghun Lee Date: Wed, 22 May 2024 15:38:42 +0900 Subject: [PATCH] compositor: Add {sync,desync}_precommit Change-Id: I26e3a066b0e9b6a4a997041d6da40918502b2c6b --- src/bin/server/e_comp_wl.c | 4 -- src/bin/server/e_compositor.c | 91 +++++++++++++++++++++++++++++++++--- src/bin/server/e_compositor_intern.h | 2 + 3 files changed, 87 insertions(+), 10 deletions(-) diff --git a/src/bin/server/e_comp_wl.c b/src/bin/server/e_comp_wl.c index 0621e40..7eb0991 100644 --- a/src/bin/server/e_comp_wl.c +++ b/src/bin/server/e_comp_wl.c @@ -2799,10 +2799,6 @@ _e_comp_wl_surface_state_commit(E_Client *ec, E_Comp_Wl_Surface_State *state) state->frames); state->frames = NULL; - e_presentation_time_container_feedback_discard(&cdata->presentation_container); - e_presentation_time_container_feedback_merge(&cdata->presentation_container, - &state->presentation_container); - buffer = e_pixmap_resource_get(ec->pixmap); /* put state damages into surface */ diff --git a/src/bin/server/e_compositor.c b/src/bin/server/e_compositor.c index 08e0e15..d0b0962 100644 --- a/src/bin/server/e_compositor.c +++ b/src/bin/server/e_compositor.c @@ -62,12 +62,16 @@ struct _E_Subsurface struct wl_listener surface_destroy; struct wl_listener parent_surface_destroy; struct wl_listener cached; + struct wl_listener sync_precommit; + struct wl_listener desync_precommit; struct wl_listener request_move; struct { struct wl_signal destroy; struct wl_signal cached; + struct wl_signal sync_precommit; + struct wl_signal desync_precommit; } events; }; @@ -101,6 +105,8 @@ static void _e_subsurface_place_below_parent(E_Subsurface *sub); static void _e_subsurface_position_update(E_Subsurface *sub); static void _e_subsurface_cb_destroy(struct wl_listener *listener, void *data); static void _e_subsurface_cb_cached(struct wl_listener *listener, void *data); +static void _e_subsurface_cb_sync_precommit(struct wl_listener *listener, void *data); +static void _e_subsurface_cb_desync_precommit(struct wl_listener *listener, void *data); static void _e_subsurface_cb_request_move(struct wl_listener *listener, void *data); static void _e_subsurface_cb_surface_destroy(struct wl_listener *listener, void *data); static void _e_subsurface_cb_parent_surface_destroy(struct wl_listener *listener, void *data); @@ -1280,7 +1286,6 @@ static void _e_surface_cb_commit(struct wl_listener *listener, void *data) { E_Surface *surface; - E_Subsurface *sub; surface = wl_container_of(listener, surface, commit); @@ -1289,11 +1294,7 @@ _e_surface_cb_commit(struct wl_listener *listener, void *data) if (e_comp_wl_remote_surface_commit(surface->ec)) return; - sub = _e_subsurface_from_surface(surface); - if (sub) - _e_subsurface_commit(sub); - else - _e_surface_commit(surface); + _e_surface_commit(surface); } static void @@ -1351,6 +1352,8 @@ _e_subsurface_create(struct ds_subsurface *ds_subsurface, E_Surface *parent_surf wl_signal_init(&sub->events.destroy); wl_signal_init(&sub->events.cached); + wl_signal_init(&sub->events.sync_precommit); + wl_signal_init(&sub->events.desync_precommit); sub->ds_subsurface = ds_subsurface; sub->destroy.notify = _e_subsurface_cb_destroy; @@ -1359,6 +1362,12 @@ _e_subsurface_create(struct ds_subsurface *ds_subsurface, E_Surface *parent_surf sub->cached.notify = _e_subsurface_cb_cached; wl_signal_add(&ds_subsurface->events.cached, &sub->cached); + sub->sync_precommit.notify = _e_subsurface_cb_sync_precommit; + ds_surface_add_sync_precommit_listener(ds_subsurface->surface, &sub->sync_precommit); + + sub->desync_precommit.notify = _e_subsurface_cb_desync_precommit; + ds_surface_add_desync_precommit_listener(ds_subsurface->surface, &sub->desync_precommit); + sub->request_move.notify = _e_subsurface_cb_request_move; wl_signal_add(&ds_subsurface->events.request_move, &sub->request_move); @@ -1390,6 +1399,8 @@ _e_subsurface_destroy(E_Subsurface *sub) wl_signal_emit(&sub->events.destroy, sub); e_comp_wl_client_subsurface_finish(sub->surface->ec); + wl_list_remove(&sub->desync_precommit.link); + wl_list_remove(&sub->sync_precommit.link); wl_list_remove(&sub->request_move.link); wl_list_remove(&sub->parent_surface_destroy.link); wl_list_remove(&sub->cached.link); @@ -1529,6 +1540,60 @@ _e_subsurface_cb_cached(struct wl_listener *listener, void *data) } static void +_e_subsurface_cb_sync_precommit(struct wl_listener *listener, void *data) +{ + E_Subsurface *sub; + + sub = wl_container_of(listener, sub, sync_precommit); + + wl_signal_emit(&sub->events.sync_precommit, sub); + + if (sub->base.cached.has_data) + { + e_presentation_time_container_feedback_discard(&sub->surface->base.presentation_container); + e_presentation_time_container_feedback_merge(&sub->surface->base.presentation_container, + &sub->base.cached.presentation_container); + sub->base.cached.has_data = EINA_FALSE; + } + + // The _e_subsurface_synchronized_check() should be called, because this + // callback could be called due to the wl_subsurface.set_desync() + if (_e_subsurface_synchronized_check(sub)) + { + e_comp_wl_hook_call(E_COMP_WL_HOOK_SUBSURFACE_SYNCHRONIZED_COMMIT, + sub->surface->ec); + } +} + +static void +_e_subsurface_cb_desync_precommit(struct wl_listener *listener, void *data) +{ + E_Subsurface *sub; + + sub = wl_container_of(listener, sub, desync_precommit); + + wl_signal_emit(&sub->events.desync_precommit, sub); + + if (sub->base.cached.has_data) + { + e_presentation_time_container_feedback_discard(&sub->base.cached.presentation_container); + e_presentation_time_container_feedback_merge(&sub->base.cached.presentation_container, + &sub->surface->base.pending.presentation_container); + + e_presentation_time_container_feedback_discard(&sub->surface->base.presentation_container); + e_presentation_time_container_feedback_merge(&sub->surface->base.presentation_container, + &sub->base.cached.presentation_container); + sub->base.cached.has_data = EINA_FALSE; + } + else + { + e_presentation_time_container_feedback_discard(&sub->surface->base.presentation_container); + e_presentation_time_container_feedback_merge(&sub->surface->base.presentation_container, + &sub->surface->base.pending.presentation_container); + } +} + +static void _e_subsurface_cb_request_move(struct wl_listener *listener, void *data) { E_Subsurface *sub; @@ -1647,4 +1712,18 @@ e_subsurface_cached_listener_add(E_Subsurface *subsurface, struct wl_listener *l { EINA_SAFETY_ON_NULL_RETURN(subsurface); wl_signal_add(&subsurface->events.cached, listener); +} + +EINTERN void +e_subsurface_sync_precommit_listener_add(E_Subsurface *subsurface, struct wl_listener *listener) +{ + EINA_SAFETY_ON_NULL_RETURN(subsurface); + wl_signal_add(&subsurface->events.sync_precommit, listener); +} + +EINTERN void +e_subsurface_desync_precommit_listener_add(E_Subsurface *subsurface, struct wl_listener *listener) +{ + EINA_SAFETY_ON_NULL_RETURN(subsurface); + wl_signal_add(&subsurface->events.desync_precommit, listener); } \ No newline at end of file diff --git a/src/bin/server/e_compositor_intern.h b/src/bin/server/e_compositor_intern.h index 4fba049..7bfc445 100644 --- a/src/bin/server/e_compositor_intern.h +++ b/src/bin/server/e_compositor_intern.h @@ -31,5 +31,7 @@ EINTERN E_Subsurface *e_subsurface_from_surface(E_Surface *surface); EINTERN Eina_Bool e_subsurface_position_set(E_Subsurface *subsurface, int x, int y); EINTERN void e_subsurface_destroy_listener_add(E_Subsurface *subsurface, struct wl_listener *listener); EINTERN void e_subsurface_cached_listener_add(E_Subsurface *subsurface, struct wl_listener *listener); +EINTERN void e_subsurface_sync_commit_pre_listener_add(E_Subsurface *subsurface, struct wl_listener *listener); +EINTERN void e_subsurface_desync_commit_pre_listener_add(E_Subsurface *subsurface, struct wl_listener *listener); #endif -- 2.7.4