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.
This commit is contained in:
Adam Jackson 2008-05-16 10:31:58 -04:00
parent a4bbe1c8bc
commit 96111c1547

View File

@ -1593,7 +1593,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);
@ -1601,23 +1692,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 */
@ -1782,25 +1861,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,