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
This commit is contained in:
parent
ac34281b8a
commit
75815dbb37
|
@ -626,6 +626,78 @@ drmmode_output_mode_valid(xf86OutputPtr output, DisplayModePtr pModes)
|
||||||
return MODE_OK;
|
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
|
static DisplayModePtr
|
||||||
drmmode_output_get_modes(xf86OutputPtr output)
|
drmmode_output_get_modes(xf86OutputPtr output)
|
||||||
{
|
{
|
||||||
|
@ -666,7 +738,8 @@ drmmode_output_get_modes(xf86OutputPtr output)
|
||||||
Modes = xf86ModesAdd(Modes, Mode);
|
Modes = xf86ModesAdd(Modes, Mode);
|
||||||
|
|
||||||
}
|
}
|
||||||
return Modes;
|
|
||||||
|
return drmmode_output_add_gtf_modes(output, Modes);
|
||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
|
|
Loading…
Reference in New Issue