[PATCH] modes: improve aspect ratio match for classic drivers

Adam Jackson ajax at redhat.com
Mon Oct 4 12:59:37 PDT 2010


From: Olivier Fourdan <ofourdan at redhat.com>

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).

Originally reported as http://bugzilla.redhat.com/604057

Signed-off-by: Adam Jackson <ajax at redhat.com>
---
 hw/xfree86/common/xf86Mode.c |   64 ++++++++++++++++++++++++++++++++++++++---
 1 files changed, 59 insertions(+), 5 deletions(-)

diff --git a/hw/xfree86/common/xf86Mode.c b/hw/xfree86/common/xf86Mode.c
index 7bdf79a..514a2e2 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);
+	    }
 	}
     }
 
-- 
1.7.2.2



More information about the xorg-devel mailing list