From 7bb653bedceb6180a0361ead1c612839e776ce98 Mon Sep 17 00:00:00 2001 From: Olivier Fourdan Date: Mon, 18 Oct 2010 15:59:35 -0400 Subject: modes: improve aspect ratio match for classic drivers After we infer the aspect ratio for the screen, we pick the largest mode matching that aspect ratio from the best mode pool available. We then clamp virtual size to that mode, and run the resulting mode list through the driver's ValidMode hook. In doing so we might filter away our initial guess. If this happens we shrink the default mode to the next largest mode from _any_ mode pool. This is usually wrong, and we should instead pick the next aspect-matched mode from the best available mode pool (as always, user then driver then default). Reviewed-by: Alex Deucher Signed-off-by: Adam Jackson --- hw/xfree86/common/xf86Mode.c | 64 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 59 insertions(+), 5 deletions(-) diff --git a/hw/xfree86/common/xf86Mode.c b/hw/xfree86/common/xf86Mode.c index 7bdf79a68..d03310e20 100644 --- a/hw/xfree86/common/xf86Mode.c +++ b/hw/xfree86/common/xf86Mode.c @@ -1831,8 +1831,6 @@ xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes, numModes++; } -#undef _VIRTUALX - /* * If we estimated the virtual size above, we may have filtered away all * the modes that maximally match that size; scan again to find out and @@ -1847,13 +1845,69 @@ xf86ValidateModes(ScrnInfoPtr scrp, DisplayModePtr availModes, } } if (vx < virtX || vy < virtY) { + const int types[] = { + M_T_BUILTIN | M_T_PREFERRED, + M_T_BUILTIN, + M_T_DRIVER | M_T_PREFERRED, + M_T_DRIVER, + 0 + }; + const int ntypes = sizeof(types) / sizeof(int); + int n; + + /* + * We did not find the estimated virtual size. So now we want to + * find the largest mode available, but we want to search in the + * modes in the order of "types" listed above. + */ + for (n = 0; n < ntypes; n++) { + int type = types[n]; + + vx = 0; vy = 0; + for (p = scrp->modes; p; p = p->next) { + /* scan through the modes in the sort order above */ + if ((p->type & type) != type) + continue; + if (p->HDisplay > vx && p->VDisplay > vy) { + vx = p->HDisplay; + vy = p->VDisplay; + } + } + if (vx && vy) + /* Found one */ + break; + } xf86DrvMsg(scrp->scrnIndex, X_WARNING, "Shrinking virtual size estimate from %dx%d to %dx%d\n", virtX, virtY, vx, vy); - virtX = vx; + virtX = _VIRTUALX(vx); virtY = vy; - linePitch = scanLineWidth(vx, vy, minPitch, apertureSize, - BankFormat, pitchInc); + for (p = scrp->modes; p; p = p->next) { + if (numModes > 0) { + if (p->HDisplay > virtX) + p->status = MODE_VIRTUAL_X; + if (p->VDisplay > virtY) + p->status = MODE_VIRTUAL_Y; + if (p->status != MODE_OK) { + numModes--; + printModeRejectMessage(scrp->scrnIndex, p, p->status); + } + } + } + if (linePitches != NULL) { + for (i = 0; linePitches[i] != 0; i++) { + if ((linePitches[i] >= virtX) && + (linePitches[i] == + scanLineWidth(virtX, virtY, linePitches[i], + apertureSize, BankFormat, pitchInc))) { + linePitch = linePitches[i]; + break; + } + } + } else { + linePitch = scanLineWidth(virtX, virtY, minPitch, + apertureSize, BankFormat, pitchInc); + } } } -- cgit v1.2.3