diff options
author | Jesse Barnes <jbarnes@jbarnes-t61.(none)> | 2008-03-17 14:13:09 -0700 |
---|---|---|
committer | Jesse Barnes <jbarnes@jbarnes-t61.(none)> | 2008-03-17 14:13:09 -0700 |
commit | ba85caacb565b9aa0aeace52a362350304b0566d (patch) | |
tree | dbb1dede18cfba3f6ef458a29f21fe50b8a8afa9 /hw | |
parent | bee2ddf35f75086cee951142098637f2c756b96b (diff) |
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.
Diffstat (limited to 'hw')
-rw-r--r-- | hw/xfree86/modes/xf86Crtc.c | 87 | ||||
-rw-r--r-- | hw/xfree86/modes/xf86Crtc.h | 7 |
2 files changed, 76 insertions, 18 deletions
diff --git a/hw/xfree86/modes/xf86Crtc.c b/hw/xfree86/modes/xf86Crtc.c index 6b845b7c9..536b53033 100644 --- a/hw/xfree86/modes/xf86Crtc.c +++ b/hw/xfree86/modes/xf86Crtc.c @@ -2034,6 +2034,72 @@ xf86InitialConfiguration (ScrnInfoPtr scrn, Bool canGrow) } /* + * 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,26 +2108,11 @@ _X_EXPORT Bool xf86SetDesiredModes (ScrnInfoPtr scrn) { xf86CrtcConfigPtr config = XF86_CRTC_CONFIG_PTR(scrn); - int c, o; - - /* - * 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); - } + int c; - for (c = 0; c < config->num_crtc; c++) - { - xf86CrtcPtr crtc = config->crtc[c]; + xf86PrepareOutputs(scrn); + xf86PrepareCrtcs(scrn); - crtc->funcs->dpms(crtc, DPMSModeOff); - memset(&crtc->mode, 0, sizeof(crtc->mode)); - } - for (c = 0; c < config->num_crtc; c++) { xf86CrtcPtr crtc = config->crtc[c]; diff --git a/hw/xfree86/modes/xf86Crtc.h b/hw/xfree86/modes/xf86Crtc.h index a542e7f39..2d723a5cd 100644 --- a/hw/xfree86/modes/xf86Crtc.h +++ b/hw/xfree86/modes/xf86Crtc.h @@ -425,6 +425,13 @@ typedef struct _xf86OutputFuncs { (*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 */ |