diff options
author | Simon Ser <contact@emersion.fr> | 2020-12-13 12:54:05 +0100 |
---|---|---|
committer | Simon Ser <contact@emersion.fr> | 2020-12-18 10:37:08 +0100 |
commit | 0aefa186906420f2a8f37f2f823a533c9187e7f5 (patch) | |
tree | b20a77dc1fe1d425a14315622c8d907767fe711e | |
parent | f0c1b32120563e6a9a770a458b397f0021b9e639 (diff) |
backend/x11: send more precise output present events
Instead of sending dummy output present events, use the X11 Present
extension to send more precise events.
-rw-r--r-- | backend/x11/output.c | 38 |
1 files changed, 33 insertions, 5 deletions
diff --git a/backend/x11/output.c b/backend/x11/output.c index c7cf1b63..cba9f600 100644 --- a/backend/x11/output.c +++ b/backend/x11/output.c @@ -19,6 +19,7 @@ #include "render/swapchain.h" #include "render/wlr_renderer.h" #include "util/signal.h" +#include "util/time.h" static int signal_frame(void *data) { struct wlr_x11_output *output = data; @@ -239,8 +240,6 @@ static bool output_commit_buffer(struct wlr_x11_output *output) { wlr_swapchain_set_buffer_submitted(output->swapchain, x11_buffer->buffer); - wlr_output_send_present(&output->wlr_output, NULL); - return true; error: @@ -379,7 +378,8 @@ struct wlr_output *wlr_x11_output_create(struct wlr_backend *backend) { }; xcb_input_xi_select_events(x11->xcb, output->win, 1, &xinput_mask.head); - uint32_t present_mask = XCB_PRESENT_EVENT_MASK_IDLE_NOTIFY; + uint32_t present_mask = XCB_PRESENT_EVENT_MASK_IDLE_NOTIFY | + XCB_PRESENT_EVENT_MASK_COMPLETE_NOTIFY; xcb_present_select_input(x11->xcb, x11->present_event_id, output->win, present_mask); @@ -482,13 +482,14 @@ static struct wlr_x11_buffer *get_x11_buffer(struct wlr_x11_output *output, void handle_x11_present_event(struct wlr_x11_backend *x11, xcb_ge_generic_event_t *event) { + struct wlr_x11_output *output; + switch (event->event_type) { case XCB_PRESENT_EVENT_IDLE_NOTIFY:; xcb_present_idle_notify_event_t *idle_notify = (xcb_present_idle_notify_event_t *)event; - struct wlr_x11_output *output = - get_x11_output_from_window_id(x11, idle_notify->window); + output = get_x11_output_from_window_id(x11, idle_notify->window); if (!output) { wlr_log(WLR_DEBUG, "Got PresentIdleNotify event for unknown window"); return; @@ -503,6 +504,33 @@ void handle_x11_present_event(struct wlr_x11_backend *x11, destroy_x11_buffer(buffer); break; + case XCB_PRESENT_COMPLETE_NOTIFY:; + xcb_present_complete_notify_event_t *complete_notify = + (xcb_present_complete_notify_event_t *)event; + + output = get_x11_output_from_window_id(x11, complete_notify->window); + if (!output) { + wlr_log(WLR_DEBUG, "Got PresentCompleteNotify event for unknown window"); + return; + } + + struct timespec t; + timespec_from_nsec(&t, complete_notify->ust * 1000); + + uint32_t flags = 0; + if (complete_notify->mode == XCB_PRESENT_COMPLETE_MODE_FLIP) { + flags |= WLR_OUTPUT_PRESENT_ZERO_COPY; + } + + struct wlr_output_event_present present_event = { + .output = &output->wlr_output, + .commit_seq = complete_notify->serial, + .when = &t, + .seq = complete_notify->msc, + .flags = flags, + }; + wlr_output_send_present(&output->wlr_output, &present_event); + break; default: wlr_log(WLR_DEBUG, "Unhandled Present event %"PRIu16, event->event_type); } |