mirror of
https://github.com/yshui/picom.git
synced 2025-04-14 17:53:25 -04:00
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:
parent
cc8e0a9848
commit
615924cc4a
5 changed files with 25 additions and 8 deletions
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
}
|
||||
|
|
10
src/picom.c
10
src/picom.c
|
@ -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);
|
||||
|
|
14
src/vblank.c
14
src/vblank.c
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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);
|
||||
|
|
Loading…
Add table
Reference in a new issue