xserver: Branch 'master' - 3 commits

Alex Deucher agd5f at kemper.freedesktop.org
Thu Nov 13 12:05:08 PST 2008


 hw/xfree86/modes/xf86Crtc.c |  162 ++++++++++++++++++++++++++------------------
 1 file changed, 99 insertions(+), 63 deletions(-)

New commits:
commit ba4e08244ed3923eecf26842dfc1df17c696e053
Merge: 81fd17f... 5bad5d2...
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Thu Nov 13 15:04:18 2008 -0500

    Merge branch 'master' of git+ssh://agd5f@git.freedesktop.org/git/xorg/./xserver

commit 81fd17f5f49cdd2c10d0bf3b7ddeb8b5953886a5
Author: Alex Deucher <alexdeucher at gmail.com>
Date:   Thu Nov 13 15:00:30 2008 -0500

    Only add default modes if EDID supports continuous-frequency
    
    When an EDID is present, only add the default mode pool if the
    continuous-frequency bit is set in the EDID.  Should fix bugs
    like 18512.

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index 74ffce3..251b800 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -1418,7 +1418,7 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
     {
 	xf86OutputPtr	    output = config->output[o];
 	DisplayModePtr	    mode;
-	DisplayModePtr	    config_modes = NULL, output_modes, default_modes;
+	DisplayModePtr	    config_modes = NULL, output_modes, default_modes = NULL;
 	char		    *preferred_mode;
 	xf86MonPtr	    edid_monitor;
 	XF86ConfMonitorPtr  conf_monitor;
@@ -1426,6 +1426,7 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
 	int		    min_clock = 0;
 	int		    max_clock = 0;
 	double		    clock;
+	Bool                add_default_modes = TRUE;
 	enum { sync_config, sync_edid, sync_default } sync_source = sync_default;
 	
 	while (output->probed_modes != NULL)
@@ -1476,6 +1477,11 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
 	    int			    i;
 	    Bool		    set_hsync = mon_rec.nHsync == 0;
 	    Bool		    set_vrefresh = mon_rec.nVrefresh == 0;
+	    struct disp_features    *features = &edid_monitor->features;
+
+	    /* if display is not continuous-frequency, don't add default modes */
+	    if (!GTF_SUPPORTED(features->msc))
+		add_default_modes = FALSE;
 
 	    for (i = 0; i < sizeof (edid_monitor->det_mon) / sizeof (edid_monitor->det_mon[0]); i++)
 	    {
@@ -1532,8 +1538,10 @@ xf86ProbeOutputModes (ScrnInfoPtr scrn, int maxX, int maxY)
 	    mon_rec.vrefresh[0].hi = 62.0;
 	    mon_rec.nVrefresh = 1;
 	}
-	default_modes = xf86GetDefaultModes (output->interlaceAllowed,
-					     output->doubleScanAllowed);
+
+	if (add_default_modes)
+	    default_modes = xf86GetDefaultModes (output->interlaceAllowed,
+						 output->doubleScanAllowed);
 
 	/*
 	 * If this is not an RB monitor, remove RB modes from the default
commit c232f3d673fb00d7fceb8e82741349d64e5ac0ad
Author: Adam Jackson <ajax at nwnk.net>
Date:   Thu Nov 13 14:58:21 2008 -0500

    xf86TargetExact should try harder if there's only one monitor attached.
    
    If there's no preferred mode, but only one monitor, pick the
    biggest mode for its aspect ratio, assuming one exists.

diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c
index f072109..74ffce3 100644
--- a/hw/xfree86/modes/xf86Crtc.c
+++ b/hw/xfree86/modes/xf86Crtc.c
@@ -1820,6 +1820,66 @@ nextEnabledOutput(xf86CrtcConfigPtr config, Bool *enabled, int *index)
 }
 
 static Bool
+aspectMatch(float a, float b)
+{
+    return fabs(1 - (a / b)) < 0.05;
+}
+
+static DisplayModePtr
+nextAspectMode(xf86OutputPtr o, DisplayModePtr last, float aspect)
+{
+    DisplayModePtr m = NULL;
+
+    if (!o)
+	return NULL;
+
+    if (!last)
+	m = o->probed_modes;
+    else
+	m = last->next;
+
+    for (; m; m = m->next)
+	if (aspectMatch(aspect, (float)m->HDisplay / (float)m->VDisplay))
+	    return m;
+
+    return NULL;
+}
+
+static DisplayModePtr
+bestModeForAspect(xf86CrtcConfigPtr config, Bool *enabled, float aspect)
+{
+    int o = -1, p;
+    DisplayModePtr mode = NULL, test = NULL, match = NULL;
+
+    if (!nextEnabledOutput(config, enabled, &o))
+	return NULL;
+    while ((mode = nextAspectMode(config->output[o], mode, aspect))) {
+	test = mode;
+	for (p = o; nextEnabledOutput(config, enabled, &p); ) {
+	    test = xf86OutputFindClosestMode(config->output[p], mode);
+	    if (!test)
+		break;
+	    if (test->HDisplay != mode->HDisplay ||
+		    test->VDisplay != mode->VDisplay) {
+		test = NULL;
+		break;
+	    }
+	}
+
+	/* if we didn't match it on all outputs, try the next one */
+	if (!test)
+	    continue;
+
+	/* if it's bigger than the last one, save it */
+	if (!match || (test->HDisplay > match->HDisplay))
+	    match = test;
+    }
+
+    /* return the biggest one found */
+    return match;
+}
+
+static Bool
 xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
 		    DisplayModePtr *modes, Bool *enabled,
 		    int width, int height)
@@ -1871,75 +1931,43 @@ xf86TargetPreferred(ScrnInfoPtr scrn, xf86CrtcConfigPtr config,
 	}
     }
 
-    if (ret) {
-	/* oh good, there is a match.  stash the selected modes and return. */
-	memcpy(modes, preferred_match,
-		config->num_output * sizeof(DisplayModePtr));
-    }
-
-    xfree(preferred);
-    xfree(preferred_match);
-    return ret;
-}
+    /*
+     * If there's no preferred mode, but only one monitor, pick the
+     * biggest mode for its aspect ratio, assuming one exists.
+     */
+    if (!ret) do {
+	int i = 0;
+	float aspect = 0.0;
 
-static Bool
-aspectMatch(float a, float b)
-{
-    return fabs(1 - (a / b)) < 0.05;
-}
+	/* count the number of enabled outputs */
+	for (i = 0, p = -1; nextEnabledOutput(config, enabled, &p); i++) ;
 
-static DisplayModePtr
-nextAspectMode(xf86OutputPtr o, DisplayModePtr last, float aspect)
-{
-    DisplayModePtr m = NULL;
+	if (i != 1)
+	    break;
 
-    if (!o)
-	return NULL;
+	p = -1;
+	nextEnabledOutput(config, enabled, &p);
+	if (config->output[p]->mm_height)
+	    aspect = (float)config->output[p]->mm_width /
+		     (float)config->output[p]->mm_height;
 
-    if (!last)
-	m = o->probed_modes;
-    else
-	m = last->next;
+	if (aspect)
+	    preferred_match[0] = bestModeForAspect(config, enabled, aspect);
 
-    for (; m; m = m->next)
-	if (aspectMatch(aspect, (float)m->HDisplay / (float)m->VDisplay))
-	    return m;
+	if (preferred_match[0])
+	    ret = TRUE;
 
-    return NULL;
-}
+    } while (0);
 
-static DisplayModePtr
-bestModeForAspect(xf86CrtcConfigPtr config, Bool *enabled, float aspect)
-{
-    int o = -1, p;
-    DisplayModePtr mode = NULL, test = NULL, match = NULL;
-
-    if (!nextEnabledOutput(config, enabled, &o))
-	return NULL;
-    while ((mode = nextAspectMode(config->output[o], mode, aspect))) {
-	test = mode;
-	for (p = o; nextEnabledOutput(config, enabled, &p); ) {
-	    test = xf86OutputFindClosestMode(config->output[p], mode);
-	    if (!test)
-		break;
-	    if (test->HDisplay != mode->HDisplay ||
-		    test->VDisplay != mode->VDisplay) {
-		test = NULL;
-		break;
-	    }
-	}
-
-	/* if we didn't match it on all outputs, try the next one */
-	if (!test)
-	    continue;
-
-	/* if it's bigger than the last one, save it */
-	if (!match || (test->HDisplay > match->HDisplay))
-	    match = test;
+    if (ret) {
+	/* oh good, there is a match.  stash the selected modes and return. */
+	memcpy(modes, preferred_match,
+		config->num_output * sizeof(DisplayModePtr));
     }
 
-    /* return the biggest one found */
-    return match;
+    xfree(preferred);
+    xfree(preferred_match);
+    return ret;
 }
 
 static Bool


More information about the xorg-commit mailing list