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 <subdiff@gmail.com>
This commit is contained in:
Roman Gilg 2020-07-11 19:15:46 +02:00
parent f8211095c3
commit 932c6baca2
3 changed files with 53 additions and 29 deletions

View File

@ -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);
}
}

View File

@ -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

View File

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