From 932c6baca274f57beab51cd0dff1f7fa934e0ed0 Mon Sep 17 00:00:00 2001 From: Roman Gilg Date: Sat, 11 Jul 2020 19:15:46 +0200 Subject: [PATCH] present: Notify via distinct API functions in window mode Notifying Present about events' states was done prior with the single function present_wnmd_event_notify just like in screen mode. But it is more intelligible if at least in window mode we make use of three different functions with names that directly indicate what their purpose is: * present_wnmd_event_notify only for queued events feedback. * present_wnmd_flip_notify for when a presentation occured (flip). * present_wnmd_idle_notify for when the Pixmap of the event can be reused. This is an API-breaking change in regards to window mode. DDX written against the previous version won't work anymore. It is assumed that there only exists the XWayland DDX at the moment using the window mode such that this is not an issue for the overall ecosystem. Signed-off-by: Roman Gilg --- hw/xwayland/xwayland-present.c | 23 ++++++----------- present/present.h | 14 +++++++++++ present/present_wnmd.c | 45 ++++++++++++++++++++++++---------- 3 files changed, 53 insertions(+), 29 deletions(-) diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c index 4f7530e3d..4d148257b 100644 --- a/hw/xwayland/xwayland-present.c +++ b/hw/xwayland/xwayland-present.c @@ -192,10 +192,7 @@ xwl_present_buffer_release(void *data) } if (!event->pending) { - present_wnmd_event_notify(event->xwl_present_window->window, - event->event_id, - event->xwl_present_window->ust, - event->xwl_present_window->msc); + present_wnmd_idle_notify(event->xwl_present_window->window, event->event_id); xwl_present_free_event(event); } } @@ -213,13 +210,12 @@ xwl_present_msc_bump(struct xwl_present_window *xwl_present_window) if (event) { event->pending = FALSE; - present_wnmd_event_notify(xwl_present_window->window, event->event_id, - xwl_present_window->ust, msc); + present_wnmd_flip_notify(xwl_present_window->window, event->event_id, + xwl_present_window->ust, msc); if (!event->pixmap) { /* If the buffer was already released, clean up now */ - present_wnmd_event_notify(xwl_present_window->window, event->event_id, - xwl_present_window->ust, msc); + present_wnmd_idle_notify(xwl_present_window->window, event->event_id); xwl_present_free_event(event); } else { xorg_list_add(&event->list, &xwl_present_window->release_list); @@ -291,17 +287,12 @@ xwl_present_sync_callback(void *data, return; } - present_wnmd_event_notify(xwl_present_window->window, - event->event_id, - xwl_present_window->ust, - xwl_present_window->msc); + present_wnmd_flip_notify(xwl_present_window->window, event->event_id, + xwl_present_window->ust, xwl_present_window->msc); if (!event->pixmap) { /* If the buffer was already released, send the event now again */ - present_wnmd_event_notify(xwl_present_window->window, - event->event_id, - xwl_present_window->ust, - xwl_present_window->msc); + present_wnmd_idle_notify(xwl_present_window->window, event->event_id); xwl_present_free_event(event); } } diff --git a/present/present.h b/present/present.h index 9d0ecb48d..86744a838 100644 --- a/present/present.h +++ b/present/present.h @@ -160,6 +160,7 @@ typedef struct present_wnmd_info { */ extern _X_EXPORT void present_event_notify(uint64_t event_id, uint64_t ust, uint64_t msc); + /* * Called when 'event_id' occurs for 'window'. * 'ust' and 'msc' indicate when the event actually happened @@ -167,6 +168,19 @@ present_event_notify(uint64_t event_id, uint64_t ust, uint64_t msc); extern _X_EXPORT void present_wnmd_event_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uint64_t msc); +/* + * Called when presentation 'event_id' occurs for 'window'. + * 'ust' and 'msc' indicate when the presentation actually happened. + */ +extern _X_EXPORT void +present_wnmd_flip_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uint64_t msc); + +/* + * Called when the flipped Pixmap associated with 'event_id' is not used anymore by the DDX. + */ +extern _X_EXPORT void +present_wnmd_idle_notify(WindowPtr window, uint64_t event_id); + extern _X_EXPORT Bool present_screen_init(ScreenPtr screen, present_screen_info_ptr info); extern _X_EXPORT Bool diff --git a/present/present_wnmd.c b/present/present_wnmd.c index b5a9a995e..2cb3f7523 100644 --- a/present/present_wnmd.c +++ b/present/present_wnmd.c @@ -163,7 +163,7 @@ present_wnmd_flips_stop(WindowPtr window) } static void -present_wnmd_flip_notify(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc) +present_wnmd_flip_notify_vblank(present_vblank_ptr vblank, uint64_t ust, uint64_t crtc_msc) { WindowPtr window = vblank->window; present_window_priv_ptr window_priv = present_window_priv(window); @@ -207,12 +207,6 @@ present_wnmd_event_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uin if (!event_id) return; - if (window_priv->flip_active && window_priv->flip_active->event_id == event_id) { - /* Notify for active flip, means it is allowed to become idle */ - window_priv->flip_active->flip_idler = TRUE; - return; - } - DebugPresent(("\te %" PRIu64 " ust %" PRIu64 " msc %" PRIu64 "\n", event_id, ust, msc)); xorg_list_for_each_entry(vblank, &window_priv->exec_queue, event_queue) { if (event_id == vblank->event_id) { @@ -222,15 +216,40 @@ present_wnmd_event_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uin } xorg_list_for_each_entry(vblank, &window_priv->flip_queue, event_queue) { if (vblank->event_id == event_id) { - if (vblank->queued) { - present_wnmd_execute(vblank, ust, msc); - } else { - assert(vblank->window); - present_wnmd_flip_notify(vblank, ust, msc); - } + assert(vblank->queued); + present_wnmd_execute(vblank, ust, msc); return; } } +} + +void +present_wnmd_flip_notify(WindowPtr window, uint64_t event_id, uint64_t ust, uint64_t msc) +{ + present_window_priv_ptr window_priv = present_window_priv(window); + present_vblank_ptr vblank; + + xorg_list_for_each_entry(vblank, &window_priv->flip_queue, event_queue) { + if (vblank->event_id == event_id) { + assert(!vblank->queued); + assert(vblank->window); + present_wnmd_flip_notify_vblank(vblank, ust, msc); + return; + } + } +} + +void +present_wnmd_idle_notify(WindowPtr window, uint64_t event_id) +{ + present_window_priv_ptr window_priv = present_window_priv(window); + present_vblank_ptr vblank; + + if (window_priv->flip_active && window_priv->flip_active->event_id == event_id) { + /* Active flip is allowed to become idle directly when it becomes unactive again. */ + window_priv->flip_active->flip_idler = TRUE; + return; + } xorg_list_for_each_entry(vblank, &window_priv->idle_queue, event_queue) { if (vblank->event_id == event_id) {