mirror of
https://github.com/swaywm/sway.git
synced 2024-11-24 08:51:27 +00:00
config/output: Only apply changes if needed
Instead of just setting things in the wlr_output_state and committing whatever the result is, try to only make changes if the new config differs from the current state and bail out if no changes were made.
This commit is contained in:
parent
4e28bce6d0
commit
ee2d4a22e0
|
@ -253,11 +253,17 @@ static void set_mode(struct wlr_output *output, struct wlr_output_state *pending
|
||||||
mhz = mhz <= 0 ? INT_MAX : mhz;
|
mhz = mhz <= 0 ? INT_MAX : mhz;
|
||||||
|
|
||||||
if (wl_list_empty(&output->modes) || custom) {
|
if (wl_list_empty(&output->modes) || custom) {
|
||||||
|
// Check if the current mode is similar to the custom mode specified.
|
||||||
|
// This is a bit ugly as we do not have a mode object to compare.
|
||||||
|
if (!output->current_mode || output->current_mode->preferred ||
|
||||||
|
output->width != width || output->height != height ||
|
||||||
|
(refresh_rate > 0 && output->refresh != mhz)) {
|
||||||
sway_log(SWAY_DEBUG, "Assigning custom mode to %s", output->name);
|
sway_log(SWAY_DEBUG, "Assigning custom mode to %s", output->name);
|
||||||
wlr_output_state_set_custom_mode(pending, width, height,
|
wlr_output_state_set_custom_mode(pending, width, height,
|
||||||
refresh_rate > 0 ? mhz : 0);
|
refresh_rate > 0 ? mhz : 0);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
struct wlr_output_mode *mode, *best = NULL;
|
struct wlr_output_mode *mode, *best = NULL;
|
||||||
int best_diff_mhz = INT_MAX;
|
int best_diff_mhz = INT_MAX;
|
||||||
|
@ -287,8 +293,10 @@ static void set_mode(struct wlr_output *output, struct wlr_output_state *pending
|
||||||
width, height, refresh_rate,
|
width, height, refresh_rate,
|
||||||
best->width, best->height, best->refresh / 1000.f);
|
best->width, best->height, best->refresh / 1000.f);
|
||||||
}
|
}
|
||||||
|
if (best != output->current_mode) {
|
||||||
wlr_output_state_set_mode(pending, best);
|
wlr_output_state_set_mode(pending, best);
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static void set_modeline(struct wlr_output *output,
|
static void set_modeline(struct wlr_output *output,
|
||||||
struct wlr_output_state *pending, drmModeModeInfo *drm_mode) {
|
struct wlr_output_state *pending, drmModeModeInfo *drm_mode) {
|
||||||
|
@ -299,7 +307,7 @@ static void set_modeline(struct wlr_output *output,
|
||||||
}
|
}
|
||||||
sway_log(SWAY_DEBUG, "Assigning custom modeline to %s", output->name);
|
sway_log(SWAY_DEBUG, "Assigning custom modeline to %s", output->name);
|
||||||
struct wlr_output_mode *mode = wlr_drm_connector_add_mode(output, drm_mode);
|
struct wlr_output_mode *mode = wlr_drm_connector_add_mode(output, drm_mode);
|
||||||
if (mode) {
|
if (mode && mode != output->current_mode) {
|
||||||
wlr_output_state_set_mode(pending, mode);
|
wlr_output_state_set_mode(pending, mode);
|
||||||
}
|
}
|
||||||
#else
|
#else
|
||||||
|
@ -396,7 +404,9 @@ static void queue_output_config(struct output_config *oc,
|
||||||
|
|
||||||
struct wlr_output *wlr_output = output->wlr_output;
|
struct wlr_output *wlr_output = output->wlr_output;
|
||||||
|
|
||||||
if (oc && (!oc->enabled || oc->power == 0)) {
|
bool needs_enabled = oc == NULL || (oc->enabled || oc->power == 1);
|
||||||
|
if (needs_enabled != wlr_output->enabled) {
|
||||||
|
if (!needs_enabled) {
|
||||||
sway_log(SWAY_DEBUG, "Turning off output %s", wlr_output->name);
|
sway_log(SWAY_DEBUG, "Turning off output %s", wlr_output->name);
|
||||||
wlr_output_state_set_enabled(pending, false);
|
wlr_output_state_set_enabled(pending, false);
|
||||||
return;
|
return;
|
||||||
|
@ -404,6 +414,7 @@ static void queue_output_config(struct output_config *oc,
|
||||||
|
|
||||||
sway_log(SWAY_DEBUG, "Turning on output %s", wlr_output->name);
|
sway_log(SWAY_DEBUG, "Turning on output %s", wlr_output->name);
|
||||||
wlr_output_state_set_enabled(pending, true);
|
wlr_output_state_set_enabled(pending, true);
|
||||||
|
}
|
||||||
|
|
||||||
if (oc && oc->drm_mode.type != 0 && oc->drm_mode.type != (uint32_t) -1) {
|
if (oc && oc->drm_mode.type != 0 && oc->drm_mode.type != (uint32_t) -1) {
|
||||||
sway_log(SWAY_DEBUG, "Set %s modeline",
|
sway_log(SWAY_DEBUG, "Set %s modeline",
|
||||||
|
@ -418,6 +429,7 @@ static void queue_output_config(struct output_config *oc,
|
||||||
sway_log(SWAY_DEBUG, "Set preferred mode");
|
sway_log(SWAY_DEBUG, "Set preferred mode");
|
||||||
struct wlr_output_mode *preferred_mode =
|
struct wlr_output_mode *preferred_mode =
|
||||||
wlr_output_preferred_mode(wlr_output);
|
wlr_output_preferred_mode(wlr_output);
|
||||||
|
if (preferred_mode != wlr_output->current_mode) {
|
||||||
wlr_output_state_set_mode(pending, preferred_mode);
|
wlr_output_state_set_mode(pending, preferred_mode);
|
||||||
|
|
||||||
if (!wlr_output_test_state(wlr_output, pending)) {
|
if (!wlr_output_test_state(wlr_output, pending)) {
|
||||||
|
@ -436,8 +448,10 @@ static void queue_output_config(struct output_config *oc,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
if (oc && (oc->subpixel != WL_OUTPUT_SUBPIXEL_UNKNOWN || config->reloading)) {
|
if (oc && (oc->subpixel != WL_OUTPUT_SUBPIXEL_UNKNOWN &&
|
||||||
|
oc->subpixel != wlr_output->subpixel)) {
|
||||||
sway_log(SWAY_DEBUG, "Set %s subpixel to %s", oc->name,
|
sway_log(SWAY_DEBUG, "Set %s subpixel to %s", oc->name,
|
||||||
sway_wl_output_subpixel_to_string(oc->subpixel));
|
sway_wl_output_subpixel_to_string(oc->subpixel));
|
||||||
wlr_output_state_set_subpixel(pending, oc->subpixel);
|
wlr_output_state_set_subpixel(pending, oc->subpixel);
|
||||||
|
@ -481,7 +495,8 @@ static void queue_output_config(struct output_config *oc,
|
||||||
wlr_output_state_set_scale(pending, scale);
|
wlr_output_state_set_scale(pending, scale);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (oc && oc->adaptive_sync != -1) {
|
bool adaptive_sync_enabled = wlr_output->adaptive_sync_status == WLR_OUTPUT_ADAPTIVE_SYNC_ENABLED;
|
||||||
|
if (oc && oc->adaptive_sync != -1 && oc->adaptive_sync != adaptive_sync_enabled) {
|
||||||
sway_log(SWAY_DEBUG, "Set %s adaptive sync to %d", wlr_output->name,
|
sway_log(SWAY_DEBUG, "Set %s adaptive sync to %d", wlr_output->name,
|
||||||
oc->adaptive_sync);
|
oc->adaptive_sync);
|
||||||
wlr_output_state_set_adaptive_sync_enabled(pending, oc->adaptive_sync == 1);
|
wlr_output_state_set_adaptive_sync_enabled(pending, oc->adaptive_sync == 1);
|
||||||
|
@ -498,6 +513,10 @@ static void queue_output_config(struct output_config *oc,
|
||||||
for (size_t i = 0; fmts[i] != DRM_FORMAT_INVALID; i++) {
|
for (size_t i = 0; fmts[i] != DRM_FORMAT_INVALID; i++) {
|
||||||
wlr_output_state_set_render_format(pending, fmts[i]);
|
wlr_output_state_set_render_format(pending, fmts[i]);
|
||||||
if (wlr_output_test_state(wlr_output, pending)) {
|
if (wlr_output_test_state(wlr_output, pending)) {
|
||||||
|
if (pending->render_format == wlr_output->render_format) {
|
||||||
|
// No change, undo the committed flag
|
||||||
|
pending->committed &= ~WLR_OUTPUT_STATE_RENDER_FORMAT;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -521,6 +540,11 @@ bool apply_output_config(struct output_config *oc, struct sway_output *output) {
|
||||||
struct wlr_output_state pending = {0};
|
struct wlr_output_state pending = {0};
|
||||||
queue_output_config(oc, output, &pending);
|
queue_output_config(oc, output, &pending);
|
||||||
|
|
||||||
|
if (pending.committed == 0) {
|
||||||
|
// No change
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
sway_log(SWAY_DEBUG, "Committing output %s", wlr_output->name);
|
sway_log(SWAY_DEBUG, "Committing output %s", wlr_output->name);
|
||||||
if (!wlr_output_commit_state(wlr_output, &pending)) {
|
if (!wlr_output_commit_state(wlr_output, &pending)) {
|
||||||
// Failed to commit output changes, maybe the output is missing a CRTC.
|
// Failed to commit output changes, maybe the output is missing a CRTC.
|
||||||
|
|
Loading…
Reference in a new issue