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

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