From 78389fe72225f9baf7def744825323f54ac4ee8e Mon Sep 17 00:00:00 2001 From: emersion Date: Sat, 29 Sep 2018 22:38:13 +0200 Subject: [PATCH] output: add present event --- backend/drm/drm.c | 12 ++++++++++-- include/wlr/interfaces/wlr_output.h | 2 ++ include/wlr/types/wlr_output.h | 14 ++++++++++++++ types/wlr_output.c | 11 +++++++++++ 4 files changed, 37 insertions(+), 2 deletions(-) diff --git a/backend/drm/drm.c b/backend/drm/drm.c index fa9a95ae..ace0835e 100644 --- a/backend/drm/drm.c +++ b/backend/drm/drm.c @@ -1149,8 +1149,8 @@ void scan_drm_connectors(struct wlr_drm_backend *drm) { } static void page_flip_handler(int fd, unsigned seq, - unsigned tv_sec, unsigned tv_usec, void *user) { - struct wlr_drm_connector *conn = user; + unsigned tv_sec, unsigned tv_usec, void *data) { + struct wlr_drm_connector *conn = data; struct wlr_drm_backend *drm = get_drm_backend_from_backend(conn->output.backend); @@ -1170,6 +1170,14 @@ static void page_flip_handler(int fd, unsigned seq, post_drm_surface(&conn->crtc->primary->mgpu_surf); } + struct timespec present_time = { + .tv_sec = tv_sec, + .tv_nsec = tv_usec * 1000, + }; + uint32_t present_flags = WLR_OUTPUT_PRESENT_VSYNC | + WLR_OUTPUT_PRESENT_HW_CLOCK | WLR_OUTPUT_PRESENT_HW_COMPLETION; + wlr_output_send_present(&conn->output, &present_time, seq, present_flags); + if (drm->session->active) { wlr_output_send_frame(&conn->output); } diff --git a/include/wlr/interfaces/wlr_output.h b/include/wlr/interfaces/wlr_output.h index bfb3bc9d..b06c5db0 100644 --- a/include/wlr/interfaces/wlr_output.h +++ b/include/wlr/interfaces/wlr_output.h @@ -45,5 +45,7 @@ void wlr_output_update_enabled(struct wlr_output *output, bool enabled); void wlr_output_update_needs_swap(struct wlr_output *output); void wlr_output_damage_whole(struct wlr_output *output); void wlr_output_send_frame(struct wlr_output *output); +void wlr_output_send_present(struct wlr_output *output, struct timespec *when, + unsigned seq, uint32_t flags); #endif diff --git a/include/wlr/types/wlr_output.h b/include/wlr/types/wlr_output.h index 96394ba4..a794d4b2 100644 --- a/include/wlr/types/wlr_output.h +++ b/include/wlr/types/wlr_output.h @@ -91,6 +91,7 @@ struct wlr_output { struct wl_signal frame; struct wl_signal needs_swap; struct wl_signal swap_buffers; // wlr_output_event_swap_buffers + struct wl_signal present; // wlr_output_event_present struct wl_signal enable; struct wl_signal mode; struct wl_signal scale; @@ -123,6 +124,19 @@ struct wlr_output_event_swap_buffers { pixman_region32_t *damage; }; +enum wlr_output_present_flag { + WLR_OUTPUT_PRESENT_VSYNC = 0x1, + WLR_OUTPUT_PRESENT_HW_CLOCK = 0x2, + WLR_OUTPUT_PRESENT_HW_COMPLETION = 0x4, +}; + +struct wlr_output_event_present { + struct wlr_output *output; + struct timespec *when; + unsigned seq; + uint32_t flags; // enum wlr_output_present_flag +}; + struct wlr_surface; /** diff --git a/types/wlr_output.c b/types/wlr_output.c index ac10cf7e..99d769e3 100644 --- a/types/wlr_output.c +++ b/types/wlr_output.c @@ -560,6 +560,17 @@ void wlr_output_schedule_frame(struct wlr_output *output) { wl_event_loop_add_idle(ev, schedule_frame_handle_idle_timer, output); } +void wlr_output_send_present(struct wlr_output *output, struct timespec *when, + unsigned seq, uint32_t flags) { + struct wlr_output_event_present event = { + .output = output, + .when = when, + .seq = seq, + .flags = flags, + }; + wlr_signal_emit_safe(&output->events.present, &event); +} + bool wlr_output_set_gamma(struct wlr_output *output, size_t size, const uint16_t *r, const uint16_t *g, const uint16_t *b) { if (!output->impl->set_gamma) {