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

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