mirror of
https://github.com/brl/mutter.git
synced 2024-11-24 17:10:40 -05:00
monitor-config-manager: respect other outputs' CRTC
We should not only take the old CRTC for an output whenever possible, but we should also assign one that is 'free', i.e. one that another monitor (to be processed after this one) isn't using, so that that monitor can use the same CRTC. https://gitlab.gnome.org/GNOME/mutter/issues/373
This commit is contained in:
parent
f4f823f238
commit
6975c8b424
@ -76,6 +76,22 @@ meta_monitor_config_manager_get_store (MetaMonitorConfigManager *config_manager)
|
||||
return config_manager->config_store;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_crtc_reserved (MetaCrtc *crtc,
|
||||
GArray *reserved_crtcs)
|
||||
{
|
||||
unsigned int i;
|
||||
|
||||
for (i = 0; i < reserved_crtcs->len; i++)
|
||||
{
|
||||
glong id = g_array_index (reserved_crtcs, glong, i);
|
||||
if (id == crtc->crtc_id)
|
||||
return TRUE;
|
||||
}
|
||||
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
static gboolean
|
||||
is_crtc_assigned (MetaCrtc *crtc,
|
||||
GPtrArray *crtc_infos)
|
||||
@ -95,7 +111,8 @@ is_crtc_assigned (MetaCrtc *crtc,
|
||||
|
||||
static MetaCrtc *
|
||||
find_unassigned_crtc (MetaOutput *output,
|
||||
GPtrArray *crtc_infos)
|
||||
GPtrArray *crtc_infos,
|
||||
GArray *reserved_crtcs)
|
||||
{
|
||||
MetaCrtc *crtc;
|
||||
unsigned int i;
|
||||
@ -104,6 +121,21 @@ find_unassigned_crtc (MetaOutput *output,
|
||||
if (crtc && !is_crtc_assigned (crtc, crtc_infos))
|
||||
return crtc;
|
||||
|
||||
/* then try to assign a CRTC that wasn't used */
|
||||
for (i = 0; i < output->n_possible_crtcs; i++)
|
||||
{
|
||||
crtc = output->possible_crtcs[i];
|
||||
|
||||
if (is_crtc_assigned (crtc, crtc_infos))
|
||||
continue;
|
||||
|
||||
if (is_crtc_reserved (crtc, reserved_crtcs))
|
||||
continue;
|
||||
|
||||
return crtc;
|
||||
}
|
||||
|
||||
/* finally just give a CRTC that we haven't assigned */
|
||||
for (i = 0; i < output->n_possible_crtcs; i++)
|
||||
{
|
||||
crtc = output->possible_crtcs[i];
|
||||
@ -124,6 +156,7 @@ typedef struct
|
||||
MetaMonitorConfig *monitor_config;
|
||||
GPtrArray *crtc_infos;
|
||||
GPtrArray *output_infos;
|
||||
GArray *reserved_crtcs;
|
||||
} MonitorAssignmentData;
|
||||
|
||||
static gboolean
|
||||
@ -147,7 +180,8 @@ assign_monitor_crtc (MetaMonitor *monitor,
|
||||
|
||||
output = monitor_crtc_mode->output;
|
||||
|
||||
crtc = find_unassigned_crtc (output, data->crtc_infos);
|
||||
crtc = find_unassigned_crtc (output, data->crtc_infos, data->reserved_crtcs);
|
||||
|
||||
if (!crtc)
|
||||
{
|
||||
MetaMonitorSpec *monitor_spec = meta_monitor_get_spec (monitor);
|
||||
@ -229,6 +263,7 @@ assign_monitor_crtcs (MetaMonitorManager *manager,
|
||||
MetaMonitorConfig *monitor_config,
|
||||
GPtrArray *crtc_infos,
|
||||
GPtrArray *output_infos,
|
||||
GArray *reserved_crtcs,
|
||||
GError **error)
|
||||
{
|
||||
MetaMonitorSpec *monitor_spec = monitor_config->monitor_spec;
|
||||
@ -262,7 +297,8 @@ assign_monitor_crtcs (MetaMonitorManager *manager,
|
||||
.logical_monitor_config = logical_monitor_config,
|
||||
.monitor_config = monitor_config,
|
||||
.crtc_infos = crtc_infos,
|
||||
.output_infos = output_infos
|
||||
.output_infos = output_infos,
|
||||
.reserved_crtcs = reserved_crtcs
|
||||
};
|
||||
if (!meta_monitor_mode_foreach_crtc (monitor, monitor_mode,
|
||||
assign_monitor_crtc,
|
||||
@ -278,6 +314,7 @@ assign_logical_monitor_crtcs (MetaMonitorManager *manager,
|
||||
MetaLogicalMonitorConfig *logical_monitor_config,
|
||||
GPtrArray *crtc_infos,
|
||||
GPtrArray *output_infos,
|
||||
GArray *reserved_crtcs,
|
||||
GError **error)
|
||||
{
|
||||
GList *l;
|
||||
@ -290,7 +327,7 @@ assign_logical_monitor_crtcs (MetaMonitorManager *manager,
|
||||
logical_monitor_config,
|
||||
monitor_config,
|
||||
crtc_infos, output_infos,
|
||||
error))
|
||||
reserved_crtcs, error))
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
@ -306,12 +343,40 @@ meta_monitor_config_manager_assign (MetaMonitorManager *manager,
|
||||
{
|
||||
GPtrArray *crtc_infos;
|
||||
GPtrArray *output_infos;
|
||||
GArray *reserved_crtcs;
|
||||
GList *l;
|
||||
|
||||
crtc_infos =
|
||||
g_ptr_array_new_with_free_func ((GDestroyNotify) meta_crtc_info_free);
|
||||
output_infos =
|
||||
g_ptr_array_new_with_free_func ((GDestroyNotify) meta_output_info_free);
|
||||
reserved_crtcs = g_array_new (FALSE, FALSE, sizeof (glong));
|
||||
|
||||
for (l = config->logical_monitor_configs; l; l = l->next)
|
||||
{
|
||||
MetaLogicalMonitorConfig *logical_monitor_config = l->data;
|
||||
GList *k;
|
||||
|
||||
for (k = logical_monitor_config->monitor_configs; k; k = k->next)
|
||||
{
|
||||
MetaMonitorConfig *monitor_config = k->data;
|
||||
MetaMonitorSpec *monitor_spec = monitor_config->monitor_spec;
|
||||
MetaMonitor *monitor;
|
||||
GList *o;
|
||||
|
||||
monitor = meta_monitor_manager_get_monitor_from_spec (manager, monitor_spec);
|
||||
|
||||
for (o = meta_monitor_get_outputs (monitor); o; o = o->next)
|
||||
{
|
||||
MetaOutput *output = o->data;
|
||||
MetaCrtc *crtc;
|
||||
|
||||
crtc = meta_output_get_assigned_crtc (output);
|
||||
if (crtc)
|
||||
g_array_append_val (reserved_crtcs, crtc->crtc_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for (l = config->logical_monitor_configs; l; l = l->next)
|
||||
{
|
||||
@ -319,14 +384,17 @@ meta_monitor_config_manager_assign (MetaMonitorManager *manager,
|
||||
|
||||
if (!assign_logical_monitor_crtcs (manager, logical_monitor_config,
|
||||
crtc_infos, output_infos,
|
||||
error))
|
||||
reserved_crtcs, error))
|
||||
{
|
||||
g_ptr_array_free (crtc_infos, TRUE);
|
||||
g_ptr_array_free (output_infos, TRUE);
|
||||
g_array_free (reserved_crtcs, TRUE);
|
||||
return FALSE;
|
||||
}
|
||||
}
|
||||
|
||||
g_array_free (reserved_crtcs, TRUE);
|
||||
|
||||
*out_crtc_infos = crtc_infos;
|
||||
*out_output_infos = output_infos;
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user