summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdam Jackson <ajax@redhat.com>2008-05-16 10:31:58 -0400
committerAdam Jackson <ajax@redhat.com>2008-05-16 11:11:40 -0400
commitbd50c41f6f479822ec595e02b3ae7a2f6060ba06 (patch)
tree93b7f22413e7ee663e32614538df35b1dda585e3
parent0b031442fe7a04ac8c935ab5858854436f3f3d3c (diff)
Redo RANDR compatibility output selection.
Old logic was just the first one that happened to have an associated CRTC. The new logic tries to find one that's definitely connected, has probed modes, and has the largest candidate mode. (cherry picked from commit 96111c154713600dd534dd82104ac18b91466202)
-rw-r--r--hw/xfree86/modes/xf86Crtc.c132
1 files changed, 96 insertions, 36 deletions
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 0e6dd6315..e6dd2dee1 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -1584,7 +1584,98 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
_X_EXPORT void
xf86RandR12GetOriginalVirtualSize(ScrnInfoPtr scrn, int *x, int *y);
-_X_EXPORT void
+static DisplayModePtr
+biggestMode(DisplayModePtr a, DisplayModePtr b)
+{
+ int A, B;
+
+ if (!a)
+ return b;
+ if (!b)
+ return a;
+
+ A = a->HDisplay * a->VDisplay;
+ B = b->HDisplay * b->VDisplay;
+
+ if (A > B)
+ return a;
+
+ return b;
+}
+
+static xf86OutputPtr
+SetCompatOutput(xf86CrtcConfigPtr config)
+{
+ xf86OutputPtr output = NULL, test = NULL;
+ DisplayModePtr maxmode = NULL, testmode, mode;
+ int o, compat = -1, count, mincount = 0;
+
+ /* Look for one that's definitely connected */
+ for (o = 0; o < config->num_output; o++)
+ {
+ test = config->output[o];
+ if (!test->crtc)
+ continue;
+ if (test->status != XF86OutputStatusConnected)
+ continue;
+ if (!test->probed_modes)
+ continue;
+
+ testmode = mode = test->probed_modes;
+ for (count = 0; mode; mode = mode->next, count++)
+ testmode = biggestMode(testmode, mode);
+
+ if (!output) {
+ output = test;
+ compat = o;
+ maxmode = testmode;
+ mincount = count;
+ } else if (maxmode == biggestMode(maxmode, testmode)) {
+ output = test;
+ compat = o;
+ maxmode = testmode;
+ mincount = count;
+ } else if ((maxmode->HDisplay == testmode->HDisplay) &&
+ (maxmode->VDisplay == testmode->VDisplay) &&
+ count <= mincount) {
+ output = test;
+ compat = o;
+ maxmode = testmode;
+ mincount = count;
+ }
+ }
+
+ /* If we didn't find one, take anything we can get */
+ if (!output)
+ {
+ for (o = 0; o < config->num_output; o++)
+ {
+ test = config->output[o];
+ if (!test->crtc)
+ continue;
+ if (!test->probed_modes)
+ continue;
+
+ if (!output) {
+ output = test;
+ compat = o;
+ } else if (test->probed_modes->HDisplay < output->probed_modes->HDisplay) {
+ output = test;
+ compat = o;
+ }
+ }
+ }
+
+ if (compat >= 0) {
+ config->compat_output = compat;
+ } else {
+ /* Don't change the compat output when no valid outputs found */
+ output = config->output[config->compat_output];
+ }
+
+ return output;
+}
+
xf86SetScrnInfoModes (ScrnInfoPtr scrn)
{
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
@@ -1592,23 +1683,11 @@ xf86SetScrnInfoModes (ScrnInfoPtr scrn)
xf86CrtcPtr crtc;
DisplayModePtr last, mode;
- output = config->output[config->compat_output];
- if (!output->crtc)
- {
- int o;
+ output = SetCompatOutput(config);
+
+ if (!output)
+ return; /* punt */
- output = NULL;
- for (o = 0; o < config->num_output; o++)
- if (config->output[o]->crtc)
- {
- config->compat_output = o;
- output = config->output[o];
- break;
- }
- /* no outputs are active, punt and leave things as they are */
- if (!output)
- return;
- }
crtc = output->crtc;
/* Clear any existing modes from scrn->modes */
@@ -1773,25 +1852,6 @@ bestModeForAspect(xf86CrtcConfigPtr config, Bool *enabled, float aspect)
return match;
}
-static DisplayModePtr
-biggestMode(DisplayModePtr a, DisplayModePtr b)
-{
- int A, B;
-
- if (!a)
- return b;
- if (!b)
- return a;
-
- A = a->HDisplay * a->VDisplay;
- B = b->HDisplay * b->VDisplay;
-
- if (A > B)
- return a;
-
- return b;
-}
-
static Bool
xf86TargetAspect(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
DisplayModePtr *modes, Bool *enabled,