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) {