xf86-video-modesetting: src/drmmode_display.c

Chris Wilson ickle at kemper.freedesktop.org
Thu Feb 28 02:18:03 PST 2013


 src/drmmode_display.c |   75 +++++++++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 74 insertions(+), 1 deletion(-)

New commits:
commit 06618a9b3d9585508b0debd18d5b981636f98c54
Author: Chris Wilson <chris at chris-wilson.co.uk>
Date:   Mon Dec 3 13:25:19 2012 +0000

    Add missing GTF modes
    
    A fixed-mode output device like a panel will often only inform of its
    preferred mode through its EDID. However, the driver will adjust user
    specified modes for display through use of a panel-fitter allowing
    greater flexibility in upscaling. This is often used by games to set a
    low resolution for performance and use the panel fitter to fill the
    screen.
    
    v2: Use the presence of the 'scaling mode' connector property as an
    indication that a panel fitter is attached to that pipe.
    
    Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=55564

diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 63cecc3..e8ebef1 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -626,6 +626,78 @@ drmmode_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes)
 	return MODE_OK;
 }
 
+static Bool
+has_panel_fitter(xf86OutputPtr output)
+{
+	drmmode_output_private_ptr drmmode_output = output->driver_private;
+	drmModeConnectorPtr koutput = drmmode_output->mode_output;
+	drmmode_ptr drmmode = drmmode_output->drmmode;
+	int i;
+
+	/* Presume that if the output supports scaling, then we have a
+	 * panel fitter capable of adjust any mode to suit.
+	 */
+	for (i = 0; i < koutput->count_props; i++) {
+		drmModePropertyPtr props;
+		Bool found = FALSE;
+
+		props = drmModeGetProperty(drmmode->fd, koutput->props[i]);
+		if (props) {
+			found = strcmp(props->name, "scaling mode") == 0;
+			drmModeFreeProperty(props);
+		}
+
+		if (found)
+			return TRUE;
+	}
+
+	return FALSE;
+}
+
+static DisplayModePtr
+drmmode_output_add_gtf_modes(xf86OutputPtr output,
+			     DisplayModePtr Modes)
+{
+	xf86MonPtr mon = output->MonInfo;
+	DisplayModePtr i, m, preferred = NULL;
+	int max_x = 0, max_y = 0;
+	float max_vrefresh = 0.0;
+
+	if (mon && GTF_SUPPORTED(mon->features.msc))
+		return Modes;
+
+	if (!has_panel_fitter(output))
+		return Modes;
+
+	for (m = Modes; m; m = m->next) {
+		if (m->type & M_T_PREFERRED)
+			preferred = m;
+		max_x = max(max_x, m->HDisplay);
+		max_y = max(max_y, m->VDisplay);
+		max_vrefresh = max(max_vrefresh, xf86ModeVRefresh(m));
+	}
+
+	max_vrefresh = max(max_vrefresh, 60.0);
+	max_vrefresh *= (1 + SYNC_TOLERANCE);
+
+	m = xf86GetDefaultModes();
+	xf86ValidateModesSize(output->scrn, m, max_x, max_y, 0);
+
+	for (i = m; i; i = i->next) {
+		if (xf86ModeVRefresh(i) > max_vrefresh)
+			i->status = MODE_VSYNC;
+		if (preferred &&
+		    i->HDisplay >= preferred->HDisplay &&
+		    i->VDisplay >= preferred->VDisplay &&
+		    xf86ModeVRefresh(i) >= xf86ModeVRefresh(preferred))
+			i->status = MODE_VSYNC;
+	}
+
+	xf86PruneInvalidModes(output->scrn, &m, FALSE);
+
+	return xf86ModesAdd(Modes, m);
+}
+
 static DisplayModePtr
 drmmode_output_get_modes(xf86OutputPtr output)
 {
@@ -666,7 +738,8 @@ drmmode_output_get_modes(xf86OutputPtr output)
 		Modes = xf86ModesAdd(Modes, Mode);
 
 	}
-	return Modes;
+
+	return drmmode_output_add_gtf_modes(output, Modes);
 }
 
 static void


More information about the xorg-commit mailing list