core: disable realtime scheduling by default

And add a --realtime option for enabling it.

Signed-off-by: Yuxuan Shui <yshuiv7@gmail.com>
This commit is contained in:
Yuxuan Shui 2024-03-03 01:24:26 +00:00
parent cc8e0a9848
commit 615924cc4a
No known key found for this signature in database
GPG Key ID: D3A4405BE6CC17F4
5 changed files with 25 additions and 8 deletions

View File

@ -152,6 +152,8 @@ typedef struct options {
bool no_x_selection;
/// Window type option override.
win_option_t wintype_option[NUM_WINTYPES];
/// Whether to set realtime scheduling policy for the compositor process.
bool use_realtime_scheduling;
// === VSync & software optimization ===
/// VSync method to use;

View File

@ -185,6 +185,8 @@ static const struct picom_option picom_options[] = {
"you want to attach a debugger to picom"},
{"no-ewmh-fullscreen" , no_argument , 803, NULL , "Do not use EWMH to detect fullscreen windows. Reverts to checking if a "
"window is fullscreen based only on its size and coordinates."},
{"realtime" , no_argument , 804, NULL , "Enable realtime scheduling. This might reduce latency, but might also cause "
"other issues. Disable this if you see the compositor being killed."},
};
// clang-format on
@ -750,6 +752,7 @@ bool get_cfg(options_t *opt, int argc, char *const *argv, bool shadow_enable,
break;
P_CASEBOOL(802, debug_mode);
P_CASEBOOL(803, no_ewmh_fullscreen);
P_CASEBOOL(804, use_realtime_scheduling);
default: usage(argv[0], 1); break;
#undef P_CASEBOOL
}

View File

@ -1569,8 +1569,9 @@ static bool redirect_start(session_t *ps) {
(enum vblank_scheduler_type)ps->o.debug_options.force_vblank_scheduler;
}
log_info("Using vblank scheduler: %s.", vblank_scheduler_str[scheduler_type]);
ps->vblank_scheduler = vblank_scheduler_new(
ps->loop, &ps->c, session_get_target_window(ps), scheduler_type);
ps->vblank_scheduler =
vblank_scheduler_new(ps->loop, &ps->c, session_get_target_window(ps),
scheduler_type, ps->o.use_realtime_scheduling);
if (!ps->vblank_scheduler) {
return false;
}
@ -2740,7 +2741,10 @@ static void session_destroy(session_t *ps) {
* @param ps current session
*/
static void session_run(session_t *ps) {
set_rr_scheduling();
if (ps->o.use_realtime_scheduling) {
set_rr_scheduling();
}
// In benchmark mode, we want draw_timer handler to always be active
if (ps->o.benchmark) {
ev_timer_set(&ps->draw_timer, 0, 0);

View File

@ -47,6 +47,7 @@ struct vblank_scheduler {
xcb_window_t target_window;
enum vblank_scheduler_type type;
bool vblank_event_requested;
bool use_realtime_scheduling;
};
struct present_vblank_scheduler {
@ -92,6 +93,7 @@ struct sgi_video_sync_vblank_scheduler {
struct sgi_video_sync_thread_args {
struct sgi_video_sync_vblank_scheduler *self;
int start_status;
bool use_realtime_scheduling;
pthread_mutex_t start_mtx;
pthread_cond_t start_cnd;
};
@ -184,7 +186,11 @@ static void *sgi_video_sync_thread(void *data) {
}
log_init_tls();
set_rr_scheduling();
if (args->use_realtime_scheduling) {
set_rr_scheduling();
}
pthread_mutex_lock(&args->start_mtx);
args->start_status = 0;
pthread_cond_signal(&args->start_cnd);
@ -258,6 +264,7 @@ static bool sgi_video_sync_scheduler_init(struct vblank_scheduler *base) {
auto args = (struct sgi_video_sync_thread_args){
.self = self,
.start_status = -1,
.use_realtime_scheduling = base->use_realtime_scheduling,
};
bool succeeded = true;
pthread_mutex_init(&args.start_mtx, NULL);
@ -543,8 +550,8 @@ void vblank_scheduler_free(struct vblank_scheduler *self) {
}
struct vblank_scheduler *
vblank_scheduler_new(struct ev_loop *loop, struct x_connection *c,
xcb_window_t target_window, enum vblank_scheduler_type type) {
vblank_scheduler_new(struct ev_loop *loop, struct x_connection *c, xcb_window_t target_window,
enum vblank_scheduler_type type, bool use_realtime_scheduling) {
size_t object_size = vblank_scheduler_ops[type].size;
auto init_fn = vblank_scheduler_ops[type].init;
if (!object_size || !init_fn) {
@ -557,6 +564,7 @@ vblank_scheduler_new(struct ev_loop *loop, struct x_connection *c,
self->target_window = target_window;
self->c = c;
self->loop = loop;
self->use_realtime_scheduling = use_realtime_scheduling;
init_fn(self);
return self;
}

View File

@ -40,8 +40,8 @@ typedef enum vblank_callback_action (*vblank_callback_t)(struct vblank_event *ev
bool vblank_scheduler_schedule(struct vblank_scheduler *self, vblank_callback_t cb,
void *user_data);
struct vblank_scheduler *
vblank_scheduler_new(struct ev_loop *loop, struct x_connection *c,
xcb_window_t target_window, enum vblank_scheduler_type type);
vblank_scheduler_new(struct ev_loop *loop, struct x_connection *c, xcb_window_t target_window,
enum vblank_scheduler_type type, bool use_realtime_scheduling);
void vblank_scheduler_free(struct vblank_scheduler *);
bool vblank_handle_x_events(struct vblank_scheduler *self);