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

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