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

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