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

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