From 0b45b3415b0c2d504d88d2d40beb7e78435073d9 Mon Sep 17 00:00:00 2001 From: Yuxuan Shui Date: Mon, 18 Dec 2023 22:00:51 +0000 Subject: [PATCH] driver: choose sgi_video_sync scheduler for NVIDIA Signed-off-by: Yuxuan Shui --- src/backend/driver.c | 7 +++++++ src/backend/driver.h | 3 +++ src/config.h | 8 ++++++++ src/picom.c | 13 ++++++++----- 4 files changed, 26 insertions(+), 5 deletions(-) diff --git a/src/backend/driver.c b/src/backend/driver.c index b909a62..e2690c4 100644 --- a/src/backend/driver.c +++ b/src/backend/driver.c @@ -19,6 +19,13 @@ void apply_driver_workarounds(struct session *ps, enum driver driver) { } } +enum vblank_scheduler_type choose_vblank_scheduler(enum driver driver) { + if (driver & DRIVER_INTEL) { + return SGI_VIDEO_SYNC_VBLANK_SCHEDULER; + } + return PRESENT_VBLANK_SCHEDULER; +} + enum driver detect_driver(xcb_connection_t *c, backend_t *backend_data, xcb_window_t window) { enum driver ret = 0; // First we try doing backend agnostic detection using RANDR diff --git a/src/backend/driver.h b/src/backend/driver.h index e4cc398..1b0877c 100644 --- a/src/backend/driver.h +++ b/src/backend/driver.h @@ -7,6 +7,7 @@ #include #include +#include "config.h" #include "utils.h" struct session; @@ -41,6 +42,8 @@ enum driver detect_driver(xcb_connection_t *, struct backend_base *, xcb_window_ /// Apply driver specified global workarounds. It's safe to call this multiple times. void apply_driver_workarounds(struct session *ps, enum driver); +/// Choose a vblank scheduler based on the driver. +enum vblank_scheduler_type choose_vblank_scheduler(enum driver driver); // Print driver names to stdout, for diagnostics static inline void print_drivers(enum driver drivers) { diff --git a/src/config.h b/src/config.h index 760088c..996df10 100644 --- a/src/config.h +++ b/src/config.h @@ -83,6 +83,14 @@ enum vblank_scheduler_type { LAST_VBLANK_SCHEDULER, }; +static inline const char *vblank_scheduler_type_str(enum vblank_scheduler_type type) { + switch (type) { + case PRESENT_VBLANK_SCHEDULER: return "present"; + case SGI_VIDEO_SYNC_VBLANK_SCHEDULER: return "sgi_video_sync"; + default: return "invalid"; + } +} + /// Internal, private options for debugging and development use. struct debug_options { /// Try to reduce frame latency by using vblank interval and render time diff --git a/src/picom.c b/src/picom.c index 5a4735a..12aff18 100644 --- a/src/picom.c +++ b/src/picom.c @@ -1485,6 +1485,10 @@ static bool redirect_start(session_t *ps) { ps->frame_pacing = false; } + // Re-detect driver since we now have a backend + ps->drivers = detect_driver(ps->c.c, ps->backend_data, ps->c.screen_info->root); + apply_driver_workarounds(ps, ps->drivers); + if (ps->present_exists && ps->frame_pacing) { // Initialize rendering and frame timing statistics, and frame pacing // states. @@ -1492,11 +1496,14 @@ static bool redirect_start(session_t *ps) { ps->last_msc = 0; ps->last_schedule_delay = 0; render_statistics_reset(&ps->render_stats); - enum vblank_scheduler_type scheduler_type = PRESENT_VBLANK_SCHEDULER; + enum vblank_scheduler_type scheduler_type = + choose_vblank_scheduler(ps->drivers); if (ps->o.debug_options.force_vblank_scheduler != LAST_VBLANK_SCHEDULER) { scheduler_type = (enum vblank_scheduler_type)ps->o.debug_options.force_vblank_scheduler; } + log_info("Using vblank scheduler: %s.", + vblank_scheduler_type_str(scheduler_type)); ps->vblank_scheduler = vblank_scheduler_new( ps->loop, &ps->c, session_get_target_window(ps), scheduler_type); if (!ps->vblank_scheduler) { @@ -1515,10 +1522,6 @@ static bool redirect_start(session_t *ps) { ps->redirected = true; ps->first_frame = true; - // Re-detect driver since we now have a backend - ps->drivers = detect_driver(ps->c.c, ps->backend_data, ps->c.screen_info->root); - apply_driver_workarounds(ps, ps->drivers); - root_damaged(ps); // Repaint the whole screen