MonitorXrandr: skip CRTC reconfigurations that have no effect

If we're attempting to reconfigure the CRTCs to the same parameter,
skip the X call, as in some drivers a modeset can take time and
cause flicker.

https://bugzilla.gnome.org/show_bug.cgi?id=706672
This commit is contained in:
Giovanni Campagna 2013-08-23 17:25:44 +02:00
parent d99c0ad384
commit d36f544069

View File

@ -777,17 +777,51 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
{ {
MetaMonitorMode *mode; MetaMonitorMode *mode;
XID *outputs; XID *outputs;
int j, n_outputs; unsigned int j, n_outputs;
int width, height; int width, height;
Status ok; Status ok;
unsigned long old_controlled_mask;
unsigned long new_controlled_mask;
mode = crtc_info->mode; mode = crtc_info->mode;
n_outputs = crtc_info->outputs->len; n_outputs = crtc_info->outputs->len;
outputs = g_new (XID, n_outputs); outputs = g_new (XID, n_outputs);
old_controlled_mask = 0;
for (j = 0; j < manager->n_outputs; j++)
{
MetaOutput *output;
output = &manager->outputs[j];
if (output->crtc == crtc)
old_controlled_mask |= 1UL << j;
}
new_controlled_mask = 0;
for (j = 0; j < n_outputs; j++) for (j = 0; j < n_outputs; j++)
outputs[j] = ((MetaOutput**)crtc_info->outputs->pdata)[j]->output_id; {
MetaOutput *output;
output = ((MetaOutput**)crtc_info->outputs->pdata)[j];
output->is_dirty = TRUE;
output->crtc = crtc;
new_controlled_mask |= 1UL << j;
outputs[j] = output->output_id;
}
if (crtc->current_mode == mode &&
crtc->rect.x == crtc_info->x &&
crtc->rect.y == crtc_info->y &&
crtc->transform == crtc_info->transform &&
old_controlled_mask == new_controlled_mask)
{
/* No change */
goto next;
}
meta_error_trap_push (meta_get_display ()); meta_error_trap_push (meta_get_display ());
ok = XRRSetCrtcConfig (manager_xrandr->xdisplay, ok = XRRSetCrtcConfig (manager_xrandr->xdisplay,
@ -806,11 +840,9 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
(unsigned)(crtc->crtc_id), (unsigned)(mode->mode_id), (unsigned)(crtc->crtc_id), (unsigned)(mode->mode_id),
mode->width, mode->height, (float)mode->refresh_rate, mode->width, mode->height, (float)mode->refresh_rate,
crtc_info->x, crtc_info->y, crtc_info->transform); crtc_info->x, crtc_info->y, crtc_info->transform);
continue; goto next;
} }
g_free (outputs);
if (meta_monitor_transform_is_rotated (crtc_info->transform)) if (meta_monitor_transform_is_rotated (crtc_info->transform))
{ {
width = mode->height; width = mode->height;
@ -829,15 +861,8 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
crtc->current_mode = mode; crtc->current_mode = mode;
crtc->transform = crtc_info->transform; crtc->transform = crtc_info->transform;
for (j = 0; j < n_outputs; j++) next:
{ g_free (outputs);
MetaOutput *output;
output = ((MetaOutput**)crtc_info->outputs->pdata)[j];
output->is_dirty = TRUE;
output->crtc = crtc;
}
} }
} }