xserver: Branch 'master' - 5 commits

Adam Jackson ajax at kemper.freedesktop.org
Fri May 16 08:10:23 PDT 2008


 hw/xfree86/modes/xf86Crtc.c    |  267 ++++++++++++++++++++++++++++++-----------
 hw/xfree86/modes/xf86RandR12.c |    4 
 2 files changed, 200 insertions(+), 71 deletions(-)

New commits:
commit aad1c37b0951eae216ac323c5d8bfc6fbcf096bd
Author: Adam Jackson <ajax at redhat.com>
Date:   Fri May 16 10:52:41 2008 -0400

    RANDR 1.1 compat: remove senseless comparison against the virtual size.

diff --git a/hw/xfree86/modes/xf86RandR12.c b/hw/xfree86/modes/xf86RandR12.c
index 4767f26..6c4ab43 100644
--- a/hw/xfree86/modes/xf86RandR12.c
+++ b/hw/xfree86/modes/xf86RandR12.c
@@ -129,9 +129,7 @@ xf86RandR12GetInfo (ScreenPtr pScreen, Rotation *rotations)
 	    return FALSE;
 	RRRegisterRate (pScreen, pSize, refresh);
 
-	if (xf86ModesEqual(mode, scrp->currentMode) &&
-	    mode->HDisplay == scrp->virtualX &&
-	    mode->VDisplay == scrp->virtualY)
+	if (xf86ModesEqual(mode, scrp->currentMode))
 	{
 	    RRSetCurrentConfig (pScreen, randrp->rotation, refresh, pSize);
 	}
commit 14726b776d6cebb7d864b6ffa7554e1ce5637d5c
Author: Adam Jackson <ajax at redhat.com>
Date:   Fri May 16 10:51:32 2008 -0400

    xf86SetDesiredModes(): Skip disabled CRTCs first thing.

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 1a49cb5..58c3512 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -2244,6 +2244,10 @@ xf86SetDesiredModes (ScrnInfoPtr scrn)
 	xf86OutputPtr	output = NULL;
 	int		o;
 
+	/* Skip disabled CRTCs */
+	if (!crtc->enabled)
+	    continue;
+
 	if (config->output[config->compat_output]->crtc == crtc)
 	    output = config->output[config->compat_output];
 	else
@@ -2255,9 +2259,7 @@ xf86SetDesiredModes (ScrnInfoPtr scrn)
 		    break;
 		}
 	}
-	/*
-	 * Skip disabled crtcs
-	 */
+	/* paranoia */
 	if (!output)
 	    continue;
 
commit 459f34b089aca4f4eee9752600c3a9e4f4e343ab
Author: Adam Jackson <ajax at redhat.com>
Date:   Fri May 16 10:48:00 2008 -0400

    Fix initial mode selection even harder.
    
    The first guess used to be "is the preferred mode for one output the
    preferred mode on all outputs".  Instead, do "find the largest mode that's
    preferred for at least one output and available on all outputs".

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 1b6bb9f..1a49cb5 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -1760,46 +1760,65 @@ nextEnabledOutput(xf86CrtcConfigPtr config, Bool *enabled, int *index)
 }
 
 static Bool
-xf86TargetExact(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
-		DisplayModePtr *modes, Bool *enabled,
-		int width, int height)
+xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
+		    DisplayModePtr *modes, Bool *enabled,
+		    int width, int height)
 {
-    int o;
-    int pref_width = 0, pref_height = 0;
-    DisplayModePtr *preferred;
+    int o, p;
+    int max_pref_width = 0, max_pref_height = 0;
+    DisplayModePtr *preferred, *preferred_match;
     Bool ret = FALSE;
 
     preferred = xnfcalloc(config->num_output, sizeof(DisplayModePtr));
+    preferred_match = xnfcalloc(config->num_output, sizeof(DisplayModePtr));
+
+    /* Check if the preferred mode is available on all outputs */
+    for (p = -1; nextEnabledOutput(config, enabled, &p); ) {
+	Rotation r = config->output[p]->initial_rotation;
+	DisplayModePtr mode;
+	if ((preferred[p] = xf86OutputHasPreferredMode(config->output[p],
+			width, height))) {
+	    int pref_width = xf86ModeWidth(preferred[p], r);
+	    int pref_height = xf86ModeHeight(preferred[p], r);
+	    Bool all_match = TRUE;
+
+	    for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
+		Bool match = FALSE;
+		xf86OutputPtr output = config->output[o];
+		if (o == p)
+		    continue;
 
-    /* Find all the preferred modes; fail if any outputs lack them */
-    for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
-	preferred[o] =
-	    xf86OutputHasPreferredMode(config->output[o], width, height);
+		for (mode = output->probed_modes; mode; mode = mode->next) {
+		    Rotation r = output->initial_rotation;
+		    if (xf86ModeWidth(mode, r) == pref_width &&
+			    xf86ModeHeight(mode, r) == pref_height) {
+			preferred[o] = mode;
+			match = TRUE;
+		    }
+		}
 
-	if (!preferred[o])
-	    goto out;
-    }
+		all_match &= match;
+	    }
 
-    /* check that they're all the same size */
-    for (o = -1; nextEnabledOutput(config, enabled, &o); ) {
-	Rotation r = config->output[o]->initial_rotation;
-	if (!pref_width) {
-	    pref_width = xf86ModeWidth(preferred[o], r);
-	    pref_height = xf86ModeHeight(preferred[o], r);
-	} else {
-	    if (pref_width != xf86ModeWidth(preferred[o], r))
-		goto out;
-	    if (pref_height != xf86ModeHeight(preferred[o], r))
-		goto out;
+	    if (all_match &&
+		    (pref_width*pref_height > max_pref_width*max_pref_height)) {
+		for (o = -1; nextEnabledOutput(config, enabled, &o); )
+		    preferred_match[o] = preferred[o];
+		max_pref_width = pref_width;
+		max_pref_height = pref_height;
+		ret = TRUE;
+	    }
 	}
     }
 
-    /* oh good, they match.  stash the selected modes and return. */
-    memcpy(modes, preferred, config->num_output * sizeof(DisplayModePtr));
-    ret = TRUE;
+    if (ret) {
+	/* oh good, there is a match.  stash the selected modes and return. */
+	memcpy(modes, preferred_match,
+		config->num_output * sizeof(DisplayModePtr));
+    }
 
-out:
     xfree(preferred);
+    xfree(preferred_match);
     return ret;
 }
 
@@ -2025,7 +2044,7 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
 
     if (xf86TargetUserpref(scrn, config, modes, enabled, width, height))
 	xf86DrvMsg(i, X_INFO, "Using user preference for initial modes\n");
-    else if (xf86TargetExact(scrn, config, modes, enabled, width, height))
+    else if (xf86TargetPreferred(scrn, config, modes, enabled, width, height))
 	xf86DrvMsg(i, X_INFO, "Using exact sizes for initial modes\n");
     else if (xf86TargetAspect(scrn, config, modes, enabled, width, height))
 	xf86DrvMsg(i, X_INFO, "Using fuzzy aspect match for initial modes\n");
@@ -2097,6 +2116,8 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
 	    crtc->x = output->initial_x;
 	    crtc->y = output->initial_y;
 	    output->crtc = crtc;
+	} else {
+	    output->crtc = NULL;
 	}
     }
     
commit 96111c154713600dd534dd82104ac18b91466202
Author: Adam Jackson <ajax at redhat.com>
Date:   Fri May 16 10:31:58 2008 -0400

    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.

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 402336f..1b6bb9f 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -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,
commit a4bbe1c8bca08f3df5ff7e50444af6aef7ec8b25
Author: Adam Jackson <ajax at redhat.com>
Date:   Fri May 16 10:25:12 2008 -0400

    Re-add sync range inference from legacy setup to RANDR 1.2.

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 8c2b247..402336f 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -1300,6 +1300,50 @@ preferredMode(ScrnInfoPtr pScrn, xf86OutputPtr output)
     return preferred_mode;
 }
 
+static void
+GuessRangeFromModes(MonPtr mon, DisplayModePtr mode)
+{
+    if (!mon || !mode)
+       return;
+
+    mon->nHsync = 1;
+    mon->hsync[0].lo = 1024.0;
+    mon->hsync[0].hi = 0.0;
+
+    mon->nVrefresh = 1;
+    mon->vrefresh[0].lo = 1024.0;
+    mon->vrefresh[0].hi = 0.0;
+
+    while (mode) {
+	if (!mode->HSync)
+	    mode->HSync = ((float) mode->Clock ) / ((float) mode->HTotal);
+
+	if (!mode->VRefresh)
+	    mode->VRefresh = (1000.0 * ((float) mode->Clock)) / 
+		((float) (mode->HTotal * mode->VTotal));
+
+	if (mode->HSync < mon->hsync[0].lo)
+	    mon->hsync[0].lo = mode->HSync;
+
+	if (mode->HSync > mon->hsync[0].hi)
+	    mon->hsync[0].hi = mode->HSync;
+
+	if (mode->VRefresh < mon->vrefresh[0].lo)
+	    mon->vrefresh[0].lo = mode->VRefresh;
+
+	if (mode->VRefresh > mon->vrefresh[0].hi)
+	    mon->vrefresh[0].hi = mode->VRefresh;
+
+	mode = mode->next;
+    }
+
+    /* stretch out the bottom to fit 640x480 at 60 */
+    if (mon->hsync[0].lo > 31.0)
+       mon->hsync[0].lo = 31.0;
+    if (mon->vrefresh[0].lo > 58.0)
+       mon->vrefresh[0].lo = 58.0;
+}
+
 _X_EXPORT void
 xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
 {
@@ -1417,6 +1461,10 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
 			       OPTUNITS_KHZ, &clock))
 	    max_clock = (int) clock;
 
+	/* If we still don't have a sync range, guess wildly */
+	if (!mon_rec.nHsync || !mon_rec.nVrefresh)
+	    GuessRangeFromModes(&mon_rec, output_modes);
+
 	/*
 	 * These limits will end up setting a 1024x768 at 60Hz mode by default,
 	 * which seems like a fairly good mode to use when nothing else is


More information about the xorg-commit mailing list