aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--backend/drm/drm.c12
-rw-r--r--include/wlr/interfaces/wlr_output.h2
-rw-r--r--include/wlr/types/wlr_output.h14
-rw-r--r--types/wlr_output.c11
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) {