monitor-manager-xrandr: Set CRTC config even if it might be redundant

This optimization breaks our use of XRRScreenResources' timestamps to
detect hotplugs in case one of the outputs is disconnected and the
remaining ones don't need any mode, position or transform adjustments.

In that scenario, when applying the new configuration, we resize the X
screen but never call XRRSetCrtcConfig() and since XRRSetScreenSize()
doesn't take a timestamp and the X server doesn't update its last set
timestamp, when we next get a RRScreenChangeNotify and update
ourselves, XRRScreenResources.timestamp will still be smaller than
XRRScreenResources.configTimestamp which makes us think we're seeing a
new hotplug. We just don't enter an endless loop because the screen
size that we keep applying is always the same and the X server
short-circuits and stops sending us RRScreenChangeNotifys.

Always calling XRRSetCrtcConfig() ensures that the last set timestamp
will be bigger than configTimestamp in the next event and thus making
us trigger the monitors-changed signal properly.

Note that the X server already does basically the same checks that
we're removing here, so doing this shouldn't be a significant
efficiency loss. See

http://cgit.freedesktop.org/xorg/xserver/tree/randr/rrcrtc.c?h=server-1.16-branch#n539
This commit is contained in:
Rui Matos 2014-12-10 15:55:12 +01:00
parent b1ac83d3b6
commit 5a86286aba

View File

@ -888,26 +888,12 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
unsigned 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++)
{ {
MetaOutput *output; MetaOutput *output;
@ -916,21 +902,10 @@ meta_monitor_manager_xrandr_apply_configuration (MetaMonitorManager *manager,
output->is_dirty = TRUE; output->is_dirty = TRUE;
output->crtc = crtc; output->crtc = crtc;
new_controlled_mask |= 1UL << j;
outputs[j] = output->winsys_id; outputs[j] = output->winsys_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;
}
ok = XRRSetCrtcConfig (manager_xrandr->xdisplay, ok = XRRSetCrtcConfig (manager_xrandr->xdisplay,
manager_xrandr->resources, manager_xrandr->resources,
(XID)crtc->crtc_id, (XID)crtc->crtc_id,