Make xf86SetDesiredModes aware of current output configuration

By adding a new output callback, ->get_crtc, xf86SetDesiredModes is able to
avoid turning off outputs & CRTCs if the current output<->CRTC mappings are the
same as the desired configuration.  This helps avoid flickering displays at
startup time, which speeds things up a little and looks better.
This commit is contained in:
Jesse Barnes 2008-03-17 14:13:09 -07:00
parent bee2ddf35f
commit ba85caacb5
3 changed files with 77 additions and 18 deletions

View File

@ -2033,6 +2033,72 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow)
return TRUE;
}
/*
* Check the CRTC we're going to map each output to vs. it's current
* CRTC. If they don't match, we have to disable the output and the CRTC
* since the driver will have to re-route things.
*/
static void
xf86PrepareOutputs (ScrnInfoPtr scrn)
{
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
int o;
for (o = 0; o < config->num_output; o++) {
xf86OutputPtr output = config->output[o];
#if RANDR_GET_CRTC_INTERFACE
/* If we can't get the current CRTC, play it safe */
if (!output->funcs->get_crtc) {
(*output->funcs->dpms)(output, DPMSModeOff);
continue;
}
/* Disable outputs that are unused or will be re-routed */
if (output->crtc != (*output->funcs->get_crtc)(output) ||
output->crtc == NULL)
#endif
(*output->funcs->dpms)(output, DPMSModeOff);
}
}
static void
xf86PrepareCrtcs (ScrnInfoPtr scrn)
{
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
int c;
for (c = 0; c < config->num_crtc; c++) {
#if RANDR_GET_CRTC_INTERFACE
xf86CrtcPtr crtc = config->crtc[c];
xf86OutputPtr output = NULL;
uint32_t desired_outputs = 0, current_outputs = 0;
int o;
for (o = 0; o < config->num_output; o++) {
output = config->output[o];
if (output->crtc == crtc)
desired_outputs |= (1<<o);
/* If we can't tell where it's mapped, force it off */
if (!output->funcs->get_crtc) {
desired_outputs = 0;
break;
}
if ((*output->funcs->get_crtc)(output) == crtc)
current_outputs |= (1<<o);
}
/*
* If mappings are different or the CRTC is unused,
* we need to disable it
*/
if (desired_outputs != current_outputs ||
!desired_outputs)
(*crtc->funcs->dpms)(crtc, DPMSModeOff);
#else
(*crtc->funcs->dpms)(crtc, DPMSModeOff);
#endif
}
}
/*
* Using the desired mode information in each crtc, set
* modes (used in EnterVT functions, or at server startup)
@ -2042,25 +2108,10 @@ _X_EXPORT Bool
xf86SetDesiredModes (ScrnInfoPtr scrn)
{
xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn);
int c, o;
int c;
/*
* Turn off everything so mode setting is done
* with hardware in a consistent state
*/
for (o = 0; o < config->num_output; o++)
{
xf86OutputPtr output = config->output[o];
(*output->funcs->dpms)(output, DPMSModeOff);
}
for (c = 0; c < config->num_crtc; c++)
{
xf86CrtcPtr crtc = config->crtc[c];
crtc->funcs->dpms(crtc, DPMSModeOff);
memset(&crtc->mode, 0, sizeof(crtc->mode));
}
xf86PrepareOutputs(scrn);
xf86PrepareCrtcs(scrn);
for (c = 0; c < config->num_crtc; c++)
{

View File

@ -424,6 +424,13 @@ typedef struct _xf86OutputFuncs {
Bool
(*get_property)(xf86OutputPtr output,
Atom property);
#endif
#ifdef RANDR_GET_CRTC_INTERFACE
/**
* Callback to get current CRTC for a given output
*/
xf86CrtcPtr
(*get_crtc)(xf86OutputPtr output);
#endif
/**
* Clean up driver-specific bits of the output

View File

@ -55,6 +55,7 @@
#define RANDR_10_INTERFACE 1
#define RANDR_12_INTERFACE 1
#define RANDR_13_INTERFACE 1 /* requires RANDR_12_INTERFACE */
#define RANDR_GET_CRTC_INTERFACE 1
#define RANDR_INTERFACE_VERSION 0x0103