diff --git a/include/sway/output.h b/include/sway/output.h index ea59c9cd3..7a27a224e 100644 --- a/include/sway/output.h +++ b/include/sway/output.h @@ -19,6 +19,8 @@ struct sway_output_state { struct sway_workspace *active_workspace; }; +#define MAX_RENDER_TIME_AUTO -2 + struct sway_output { struct sway_node node; @@ -66,7 +68,7 @@ struct sway_output { struct wlr_color_transform *color_transform; struct wlr_ext_workspace_group_handle_v1 *ext_workspace_group; - int max_render_time; // In milliseconds + int max_render_time; bool allow_tearing; bool hdr; diff --git a/sway/commands/output/max_render_time.c b/sway/commands/output/max_render_time.c index 2d3cebe30..303490109 100644 --- a/sway/commands/output/max_render_time.c +++ b/sway/commands/output/max_render_time.c @@ -1,6 +1,7 @@ #include #include "sway/commands.h" #include "sway/config.h" +#include "sway/output.h" struct cmd_results *output_cmd_max_render_time(int argc, char **argv) { if (!config->handler_context.output_config) { @@ -13,6 +14,8 @@ struct cmd_results *output_cmd_max_render_time(int argc, char **argv) { int max_render_time; if (!strcmp(*argv, "off")) { max_render_time = 0; + } else if (!strcmp(*argv, "auto")) { + max_render_time = MAX_RENDER_TIME_AUTO; } else { char *end; max_render_time = strtol(*argv, &end, 10); diff --git a/sway/config/output.c b/sway/config/output.c index 5983f2e5d..0e1b53aba 100644 --- a/sway/config/output.c +++ b/sway/config/output.c @@ -684,8 +684,11 @@ static bool finalize_output_config(struct output_config *oc, struct sway_output } output->color_transform = config_applied->color_transform; - output_set_max_render_time(output, - oc && oc->max_render_time > 0 ? oc->max_render_time : 0); + int max_render_time = 0; + if (oc && (oc->max_render_time > 0 || oc->max_render_time == MAX_RENDER_TIME_AUTO)) { + max_render_time = oc->max_render_time; + } + output_set_max_render_time(output, max_render_time); output->allow_tearing = oc && oc->allow_tearing > 0; output->hdr = applied->image_description != NULL; diff --git a/sway/desktop/output.c b/sway/desktop/output.c index 2d25cac88..fc384f678 100644 --- a/sway/desktop/output.c +++ b/sway/desktop/output.c @@ -317,7 +317,6 @@ struct sway_timer_frame_scheduler { struct wl_event_source *timer; bool frame_pending; - bool needs_frame; struct wl_listener present; }; @@ -333,25 +332,15 @@ static void timed_frame_scheduler_destroy(struct wlr_frame_scheduler *wlr_schedu free(scheduler); } -static void timed_frame_scheduler_trigger_frame( - struct sway_timer_frame_scheduler *scheduler) { - if (!scheduler->needs_frame) { - return; - } - scheduler->needs_frame = false; - wl_signal_emit_mutable(&scheduler->base.events.frame, NULL); -} - static void timed_frame_scheduler_handle_idle(void *data) { struct sway_timer_frame_scheduler *scheduler = data; scheduler->idle = NULL; - timed_frame_scheduler_trigger_frame(scheduler); + wlr_frame_scheduler_emit_frame(&scheduler->base); } static void timed_frame_scheduler_schedule_frame(struct wlr_frame_scheduler *wlr_scheduler) { struct sway_timer_frame_scheduler *scheduler = wl_container_of(wlr_scheduler, scheduler, base); - scheduler->needs_frame = true; if (scheduler->idle != NULL || scheduler->frame_pending) { return; } @@ -367,7 +356,7 @@ static const struct wlr_frame_scheduler_impl timed_frame_scheduler_impl = { static int timed_frame_scheduler_handle_timer(void *data) { struct sway_timer_frame_scheduler *scheduler = data; scheduler->frame_pending = false; - timed_frame_scheduler_trigger_frame(scheduler); + wlr_frame_scheduler_emit_frame(&scheduler->base); return 0; } @@ -393,7 +382,7 @@ static void timed_frame_scheduler_handle_present(struct wl_listener *listener, v // If the delay is less than 1 millisecond (which is the least we can wait) // then just render right away. if (delay < 1) { - timed_frame_scheduler_trigger_frame(scheduler); + wlr_frame_scheduler_emit_frame(&scheduler->base); } else { scheduler->frame_pending = true; wl_event_source_timer_update(scheduler->timer, delay); @@ -471,7 +460,9 @@ void output_set_max_render_time(struct sway_output *output, int max_render_time) output->max_render_time = max_render_time; struct wlr_frame_scheduler *scheduler; - if (max_render_time != 0) { + if (max_render_time == MAX_RENDER_TIME_AUTO) { + scheduler = wlr_predictive_frame_scheduler_create(output->wlr_output); + } else if (max_render_time > 0) { scheduler = timed_frame_scheduler_create(output->wlr_output, max_render_time); } else { scheduler = wlr_frame_scheduler_autocreate(output->wlr_output);