[PATCH] Add missing GTF modes
Chris Wilson
chris at chris-wilson.co.uk
Mon Dec 3 05:34:55 PST 2012
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.
XXX: is it same to assume that all LVDS/eDP panels have a fitter?
Bugzilla: https://bugs.freedesktop.org/show_bug.cgi?id=55564
---
src/drmmode_display.c | 58 ++++++++++++++++++++++++++++++++++++++++++++++++-
1 file changed, 57 insertions(+), 1 deletion(-)
diff --git a/src/drmmode_display.c b/src/drmmode_display.c
index 8d760c2..9d6323a 100644
--- a/src/drmmode_display.c
+++ b/src/drmmode_display.c
@@ -611,6 +611,61 @@ 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;
+ int type = koutput->connector_type;
+ /* XXX dumb KMS parameter? */
+ return (type == DRM_MODE_CONNECTOR_LVDS ||
+ type == DRM_MODE_CONNECTOR_eDP);
+}
+
+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)
{
@@ -651,7 +706,8 @@ drmmode_output_get_modes(xf86OutputPtr output)
Modes = xf86ModesAdd(Modes, Mode);
}
- return Modes;
+
+ return drmmode_output_add_gtf_modes(output, Modes);
}
static void
--
1.7.10.4
More information about the xorg-devel
mailing list