From 38fea7c3b4eba61ba808e6fd0f3c46fc238cbbd7 Mon Sep 17 00:00:00 2001
From: Philipp Zabel
Date: Wed, 14 Jun 2023 12:06:43 +0200
Subject: [PATCH] libweston: prefer active, high refresh rate outputs during
surface assignment
Prefer outputs that are not powered off when assigning a surface to an
output. If a surface covers the same area on two outputs, prefer the
one with the higher refresh rate.
Signed-off-by: Philipp Zabel
---
libweston/compositor.c | 31 ++++++++++++++++++++++++++++---
1 file changed, 28 insertions(+), 3 deletions(-)
diff --git a/libweston/compositor.c b/libweston/compositor.c
index df5b58f62..e2e91b071 100644
--- a/libweston/compositor.c
+++ b/libweston/compositor.c
@@ -1149,8 +1149,12 @@ get_view_layer(struct weston_view *view)
* \param es The surface to remap to outputs
*
* Finds the output that is showing the largest amount of one
- * of the surface's various views. This output becomes the
- * surface's primary output for vsync and frame callback purposes.
+ * of the surface's various views. Prefer outputs that are not
+ * powered off when assigning a surface to an output.
+ * If a surface covers the same area on two outputs, prefer the
+ * output with the higher refresh rate.
+ * The assigned output becomes the surface's primary output for
+ * vsync and frame callback purposes.
*
* Also notes all outputs of all of the surface's views
* in the output_mask for the surface.
@@ -1182,7 +1186,28 @@ weston_surface_assign_output(struct weston_surface *es)
mask |= view->output_mask;
- if (area >= max) {
+ /* Do not switch from an active output to an inactive output. */
+ if (new_output &&
+ new_output->power_state != WESTON_OUTPUT_POWER_FORCED_OFF &&
+ view->output->power_state == WESTON_OUTPUT_POWER_FORCED_OFF)
+ continue;
+
+ /*
+ * Do not switch to an output with the same intersection area
+ * but lower refresh rate.
+ */
+ if (area == max && new_output &&
+ new_output->current_mode->refresh > view->output->current_mode->refresh)
+ continue;
+
+ /*
+ * Switch to an output with either larger intersection area or
+ * to an output that is active from an inactive output.
+ */
+ if (area >= max ||
+ (new_output &&
+ new_output->power_state == WESTON_OUTPUT_POWER_FORCED_OFF &&
+ view->output->power_state != WESTON_OUTPUT_POWER_FORCED_OFF)) {
new_output = view->output;
max = area;
}