Blame SOURCES/0001-xfree86-try-harder-to-span-on-multihead.patch

bd52eb
From 326f992a90dae7a747da45626e588fa3c1dfa5dc Mon Sep 17 00:00:00 2001
bd52eb
From: Ray Strode <rstrode@redhat.com>
bd52eb
Date: Fri, 21 Sep 2018 14:38:31 -0400
bd52eb
Subject: [PATCH xserver] xfree86: try harder to span on multihead
bd52eb
bd52eb
right now if one of the monitors can't give
bd52eb
it's native resolution because of bandwidth limitations,
bd52eb
X decides to avoid spanning and instead clone.
bd52eb
bd52eb
That's suboptimal, spanning is normally the right
bd52eb
thing to do (with the exception of some projector
bd52eb
use cases and other edge cases)
bd52eb
bd52eb
This commit tries harder to make spanning work.
bd52eb
---
bd52eb
 hw/xfree86/modes/xf86Crtc.c | 33 +++++++++++++++++++++++++++++----
bd52eb
 1 file changed, 29 insertions(+), 4 deletions(-)
bd52eb
bd52eb
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
bd52eb
index 37a45bb3a..686cb51b8 100644
bd52eb
--- a/hw/xfree86/modes/xf86Crtc.c
bd52eb
+++ b/hw/xfree86/modes/xf86Crtc.c
bd52eb
@@ -2132,135 +2132,160 @@ bestModeForAspect(xf86CrtcConfigPtr config, Bool *enabled, float aspect)
bd52eb
             if (test->HDisplay != mode->HDisplay ||
bd52eb
                 test->VDisplay != mode->VDisplay) {
bd52eb
                 test = NULL;
bd52eb
                 break;
bd52eb
             }
bd52eb
         }
bd52eb
 
bd52eb
         /* if we didn't match it on all outputs, try the next one */
bd52eb
         if (!test)
bd52eb
             continue;
bd52eb
 
bd52eb
         /* if it's bigger than the last one, save it */
bd52eb
         if (!match || (test->HDisplay > match->HDisplay))
bd52eb
             match = test;
bd52eb
     }
bd52eb
 
bd52eb
     /* return the biggest one found */
bd52eb
     return match;
bd52eb
 }
bd52eb
 
bd52eb
 static int
bd52eb
 numEnabledOutputs(xf86CrtcConfigPtr config, Bool *enabled)
bd52eb
 {
bd52eb
     int i = 0, p;
bd52eb
 
bd52eb
     for (i = 0, p = -1; nextEnabledOutput(config, enabled, &p); i++) ;
bd52eb
 
bd52eb
     return i;
bd52eb
 }
bd52eb
 
bd52eb
+static DisplayModePtr
bd52eb
+findReasonableMode(xf86CrtcConfigPtr config, xf86OutputPtr output, Bool *enabled, int width, int height)
bd52eb
+{
bd52eb
+    DisplayModePtr mode =
bd52eb
+        xf86OutputHasPreferredMode(output, width, height);
bd52eb
+
bd52eb
+    /* if there's no preferred mode, just try to find a reasonable one */
bd52eb
+    if (!mode) {
bd52eb
+        float aspect = 0.0;
bd52eb
+        DisplayModePtr a = NULL, b = NULL;
bd52eb
+
bd52eb
+        if (output->mm_height)
bd52eb
+            aspect = (float) output->mm_width /
bd52eb
+                (float) output->mm_height;
bd52eb
+
bd52eb
+        a = bestModeForAspect(config, enabled, 4.0/3.0);
bd52eb
+        if (aspect)
bd52eb
+            b = bestModeForAspect(config, enabled, aspect);
bd52eb
+
bd52eb
+        mode = biggestMode(a, b);
bd52eb
+    }
bd52eb
+
bd52eb
+    return mode;
bd52eb
+}
bd52eb
+
bd52eb
 static Bool
bd52eb
 xf86TargetRightOf(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
bd52eb
                   DisplayModePtr *modes, Bool *enabled,
bd52eb
                   int width, int height)
bd52eb
 {
bd52eb
     int o;
bd52eb
     int w = 0;
bd52eb
     Bool has_tile = FALSE;
bd52eb
     uint32_t configured_outputs;
bd52eb
 
bd52eb
     xf86GetOptValBool(config->options, OPTION_PREFER_CLONEMODE,
bd52eb
                       &scrn->preferClone);
bd52eb
     if (scrn->preferClone)
bd52eb
         return FALSE;
bd52eb
 
bd52eb
     if (numEnabledOutputs(config, enabled) < 2)
bd52eb
         return FALSE;
bd52eb
 
bd52eb
     for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
bd52eb
         DisplayModePtr mode =
bd52eb
-            xf86OutputHasPreferredMode(config->output[o], width, height);
bd52eb
+            findReasonableMode(config, config->output[o], enabled, width, height);
bd52eb
 
bd52eb
         if (!mode)
bd52eb
             return FALSE;
bd52eb
 
bd52eb
         w += mode->HDisplay;
bd52eb
     }
bd52eb
 
bd52eb
     if (w > width)
bd52eb
         return FALSE;
bd52eb
 
bd52eb
     w = 0;
bd52eb
     configured_outputs = 0;
bd52eb
 
bd52eb
     for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
bd52eb
         DisplayModePtr mode =
bd52eb
-            xf86OutputHasPreferredMode(config->output[o], width, height);
bd52eb
+            findReasonableMode(config, config->output[o], enabled, width, height);
bd52eb
 
bd52eb
         if (configured_outputs & (1 << o))
bd52eb
             continue;
bd52eb
 
bd52eb
         if (config->output[o]->tile_info.group_id) {
bd52eb
             has_tile = TRUE;
bd52eb
             continue;
bd52eb
         }
bd52eb
 
bd52eb
         config->output[o]->initial_x = w;
bd52eb
         w += mode->HDisplay;
bd52eb
 
bd52eb
         configured_outputs |= (1 << o);
bd52eb
         modes[o] = mode;
bd52eb
     }
bd52eb
 
bd52eb
     if (has_tile) {
bd52eb
         for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
bd52eb
             int ht, vt, ot;
bd52eb
             int add_x, cur_x = w;
bd52eb
             struct xf86CrtcTileInfo *tile_info = &config->output[o]->tile_info, *this_tile;
bd52eb
             if (configured_outputs & (1 << o))
bd52eb
                 continue;
bd52eb
             if (!tile_info->group_id)
bd52eb
                 continue;
bd52eb
 
bd52eb
             if (tile_info->tile_h_loc != 0 && tile_info->tile_v_loc != 0)
bd52eb
                 continue;
bd52eb
 
bd52eb
             for (ht = 0; ht < tile_info->num_h_tile; ht++) {
bd52eb
                 int cur_y = 0;
bd52eb
                 add_x = 0;
bd52eb
                 for (vt = 0; vt < tile_info->num_v_tile; vt++) {
bd52eb
 
bd52eb
                     for (ot = -1; nextEnabledOutput(config, enabled, &ot); ) {
bd52eb
-
bd52eb
                         DisplayModePtr mode =
bd52eb
-                            xf86OutputHasPreferredMode(config->output[ot], width, height);
bd52eb
+                            findReasonableMode(config, config->output[ot], enabled, width, height);
bd52eb
+
bd52eb
                         if (!config->output[ot]->tile_info.group_id)
bd52eb
                             continue;
bd52eb
 
bd52eb
                         this_tile = &config->output[ot]->tile_info;
bd52eb
                         if (this_tile->group_id != tile_info->group_id)
bd52eb
                             continue;
bd52eb
 
bd52eb
                         if (this_tile->tile_h_loc != ht ||
bd52eb
                             this_tile->tile_v_loc != vt)
bd52eb
                             continue;
bd52eb
 
bd52eb
                         config->output[ot]->initial_x = cur_x;
bd52eb
                         config->output[ot]->initial_y = cur_y;
bd52eb
 
bd52eb
                         if (vt == 0)
bd52eb
                             add_x = this_tile->tile_h_size;
bd52eb
                         cur_y += this_tile->tile_v_size;
bd52eb
                         configured_outputs |= (1 << ot);
bd52eb
                         modes[ot] = mode;
bd52eb
                     }
bd52eb
                 }
bd52eb
                 cur_x += add_x;
bd52eb
             }
bd52eb
             w = cur_x;
bd52eb
         }
bd52eb
     }
bd52eb
     return TRUE;
bd52eb
 }
bd52eb
 
bd52eb
 static Bool
bd52eb
-- 
bd52eb
2.17.1
bd52eb