Skip to content

Commit

Permalink
Avoid no-op output reconfiguring
Browse files Browse the repository at this point in the history
When an output command doesn't actually change anything in the output
config the processing will still all be done and cause other changes.
Notably if you run a command like:

	output * dpms on

even if it does nothing it will still cause all the inputs to be
reconfigured and very noticeable amounts of input latency to occur.

To fix this save the current output config in the output data and on
configure, if the config is the same just return without doing anything
else.

Fixes swaywm#6280
  • Loading branch information
pedrocr committed May 18, 2021
1 parent eca5759 commit 45ad83b
Show file tree
Hide file tree
Showing 3 changed files with 75 additions and 0 deletions.
4 changes: 4 additions & 0 deletions include/sway/config.h
Original file line number Diff line number Diff line change
Expand Up @@ -636,6 +636,10 @@ struct output_config *new_output_config(const char *name);

void merge_output_config(struct output_config *dst, struct output_config *src);

struct output_config *duplicate_output_config(const struct output_config *src);

bool compare_output_config(struct output_config *dst, struct output_config *src);

bool apply_output_config(struct output_config *oc, struct sway_output *output);

bool test_output_config(struct output_config *oc, struct sway_output *output);
Expand Down
2 changes: 2 additions & 0 deletions include/sway/output.h
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,8 @@ struct sway_output {
uint32_t refresh_nsec;
int max_render_time; // In milliseconds
struct wl_event_source *repaint_timer;

struct output_config *current_config;
};

struct sway_output *output_create(struct wlr_output *wlr_output);
Expand Down
69 changes: 69 additions & 0 deletions sway/config/output.c
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,65 @@ void merge_output_config(struct output_config *dst, struct output_config *src) {
}
}

struct output_config *duplicate_output_config(const struct output_config *src) {
struct output_config *oc = calloc(1, sizeof(struct output_config));
if (oc == NULL) {
return NULL;
}
oc->name = strdup(src->name);
if (oc->name == NULL) {
free(oc);
return NULL;
}
oc->enabled = src->enabled;
oc->width = src->width;
oc->height = src->height;
oc->refresh_rate = src->refresh_rate;
oc->custom_mode = src->custom_mode;
oc->x = src->x;
oc->y = src->y;
oc->scale = src->scale;
oc->scale_filter = src->scale_filter;
oc->transform = src->transform;
oc->subpixel = src->subpixel;
oc->max_render_time = src->max_render_time;
oc->adaptive_sync = src->adaptive_sync;
if (src->background) {
oc->background = strdup(src->background);
}
if (src->background_option) {
oc->background_option = strdup(src->background_option);
}
if (src->background_fallback) {
oc->background_fallback = strdup(src->background_fallback);
}
oc->dpms_state = src->dpms_state;
return oc;
}

bool compare_output_config(struct output_config *dst, struct output_config *src) {
return dst->enabled == src->enabled &&
dst->width == src->width &&
dst->height == src->height &&
dst->x == src->x &&
dst->y == src->y &&
dst->scale == src->scale &&
dst->scale_filter == src->scale_filter &&
dst->subpixel == src->subpixel &&
dst->refresh_rate == src->refresh_rate &&
dst->custom_mode == src->custom_mode &&
dst->transform == src->transform &&
dst->max_render_time == src->max_render_time &&
dst->adaptive_sync == src->adaptive_sync &&
(dst->background == src->background ||
!strcmp(dst->background, src->background)) &&
(dst->background_option == src->background_option ||
!strcmp(dst->background_option, src->background_option)) &&
(dst->background_fallback == src->background_fallback ||
!strcmp(dst->background_fallback, src->background_fallback)) &&
dst->dpms_state == src->dpms_state;
}

static void merge_wildcard_on_all(struct output_config *wildcard) {
for (int i = 0; i < config->output_configs->length; i++) {
struct output_config *oc = config->output_configs->items[i];
Expand Down Expand Up @@ -397,6 +456,16 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) {

struct wlr_output *wlr_output = output->wlr_output;

if (output->current_config && compare_output_config(oc, output->current_config)) {
// The output config is unchanged so bail out early
sway_log(SWAY_DEBUG, "Config for output %s is unchanged", wlr_output->name);
return true;
}
if (output->current_config) {
free_output_config(output->current_config);
}
output->current_config = duplicate_output_config(oc);

// Flag to prevent the output mode event handler from calling us
output->enabling = (!oc || oc->enabled);

Expand Down

0 comments on commit 45ad83b

Please sign in to comment.