Add functionality for queuing events as requested by Present. Signed-off-by: Roman Gilg <subd...@gmail.com> --- hw/xwayland/xwayland-present.c | 73 +++++++++++++++++++++++++++++------------- 1 file changed, 51 insertions(+), 22 deletions(-)
diff --git a/hw/xwayland/xwayland-present.c b/hw/xwayland/xwayland-present.c index d08c39e..f8ac5a6 100644 --- a/hw/xwayland/xwayland-present.c +++ b/hw/xwayland/xwayland-present.c @@ -27,7 +27,7 @@ #include <present.h> -#define FRAME_TIMER_IVAL 67 // ~15fps +#define FRAME_TIMER_IVAL 33 // ~30fps static struct xorg_list xwl_present_windows; @@ -227,6 +227,21 @@ xwl_present_get_ust_msc(WindowPtr present_window, uint64_t *ust, uint64_t *msc) return Success; } +static void +xwl_present_reset_present_window(struct xwl_window *xwl_window, WindowPtr present_window) +{ + /* Do not reset if it is the same present_window. But this also means, that + * we always switch to another child window, if it wants to present. + */ + if (xwl_window->present_window == present_window) + return; + + if (xwl_window->present_window) + xwl_present_cleanup(xwl_window->present_window); + xwl_window->present_window = present_window; + xorg_list_add(&xwl_window->present_link, &xwl_present_windows); +} + /* * Queue an event to report back to the Present extension when the specified * MSC has past @@ -237,12 +252,38 @@ xwl_present_queue_vblank(WindowPtr present_window, uint64_t event_id, uint64_t msc) { - /* - * Queuing events is not yet implemented. - * - */ - return BadRequest; - /* */ + struct xwl_window *xwl_window = xwl_window_of_top(present_window); + struct xwl_present_event *event; + + if (!xwl_window) + return BadAlloc; + + if (xwl_window->present_crtc_fake != crtc) + return BadRequest; + + event = malloc(sizeof *event); + if (!event) + return BadAlloc; + + xwl_present_reset_present_window(xwl_window, present_window); + + event->event_id = event_id; + event->xwl_window = xwl_window; + event->buffer = NULL; + event->target_msc = msc; + event->pending = FALSE; + event->abort = FALSE; + + xorg_list_add(&event->list, &xwl_window->present_event_list); + + if (!xwl_window->present_frame_callback && !xwl_window->present_frame_timer_firing) + xwl_window->present_frame_timer = TimerSet(xwl_window->present_frame_timer, + 0, + FRAME_TIMER_IVAL, + &present_frame_timer_callback, + xwl_window); + + return Success; } /* @@ -255,6 +296,9 @@ xwl_present_abort_vblank(WindowPtr present_window, RRCrtcPtr crtc, uint64_t even struct xwl_window *xwl_window = xwl_window_of_top(present_window); struct xwl_present_event *event, *tmp; + if (!xwl_window || !crtc || xwl_window->present_crtc_fake != crtc) + return; + xorg_list_for_each_entry_safe(event, tmp, &xwl_window->present_event_list, list) { if (event->event_id == event_id) { xorg_list_del(&event->list); @@ -309,21 +353,6 @@ xwl_present_check_flip(RRCrtcPtr crtc, return TRUE; } -static void -xwl_present_reset_present_window(struct xwl_window *xwl_window, WindowPtr present_window) -{ - /* Do not reset if it is the same present_window. But this also means, that - * we always switch to another child window, if it wants to present. - */ - if (xwl_window->present_window == present_window) - return; - - if (xwl_window->present_window) - xwl_present_cleanup(xwl_window->present_window); - xwl_window->present_window = present_window; - xorg_list_add(&xwl_window->present_link, &xwl_present_windows); -} - static Bool xwl_present_flip(WindowPtr present_window, RRCrtcPtr crtc, -- 2.7.4 _______________________________________________ xorg-devel@lists.x.org: X.Org development Archives: http://lists.x.org/archives/xorg-devel Info: https://lists.x.org/mailman/listinfo/xorg-devel