mirror of
https://github.com/brl/mutter.git
synced 2024-11-28 19:10:43 -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;
|
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
|
static gboolean
|
||||||
is_crtc_assigned (MetaCrtc *crtc,
|
is_crtc_assigned (MetaCrtc *crtc,
|
||||||
GPtrArray *crtc_infos)
|
GPtrArray *crtc_infos)
|
||||||
@ -95,7 +111,8 @@ is_crtc_assigned (MetaCrtc *crtc,
|
|||||||
|
|
||||||
static MetaCrtc *
|
static MetaCrtc *
|
||||||
find_unassigned_crtc (MetaOutput *output,
|
find_unassigned_crtc (MetaOutput *output,
|
||||||
GPtrArray *crtc_infos)
|
GPtrArray *crtc_infos,
|
||||||
|
GArray *reserved_crtcs)
|
||||||
{
|
{
|
||||||
MetaCrtc *crtc;
|
MetaCrtc *crtc;
|
||||||
unsigned int i;
|
unsigned int i;
|
||||||
@ -104,6 +121,21 @@ find_unassigned_crtc (MetaOutput *output,
|
|||||||
if (crtc && !is_crtc_assigned (crtc, crtc_infos))
|
if (crtc && !is_crtc_assigned (crtc, crtc_infos))
|
||||||
return crtc;
|
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++)
|
for (i = 0; i < output->n_possible_crtcs; i++)
|
||||||
{
|
{
|
||||||
crtc = output->possible_crtcs[i];
|
crtc = output->possible_crtcs[i];
|
||||||
@ -124,6 +156,7 @@ typedef struct
|
|||||||
MetaMonitorConfig *monitor_config;
|
MetaMonitorConfig *monitor_config;
|
||||||
GPtrArray *crtc_infos;
|
GPtrArray *crtc_infos;
|
||||||
GPtrArray *output_infos;
|
GPtrArray *output_infos;
|
||||||
|
GArray *reserved_crtcs;
|
||||||
} MonitorAssignmentData;
|
} MonitorAssignmentData;
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
@ -147,7 +180,8 @@ assign_monitor_crtc (MetaMonitor *monitor,
|
|||||||
|
|
||||||
output = monitor_crtc_mode->output;
|
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)
|
if (!crtc)
|
||||||
{
|
{
|
||||||
MetaMonitorSpec *monitor_spec = meta_monitor_get_spec (monitor);
|
MetaMonitorSpec *monitor_spec = meta_monitor_get_spec (monitor);
|
||||||
@ -229,6 +263,7 @@ assign_monitor_crtcs (MetaMonitorManager *manager,
|
|||||||
MetaMonitorConfig *monitor_config,
|
MetaMonitorConfig *monitor_config,
|
||||||
GPtrArray *crtc_infos,
|
GPtrArray *crtc_infos,
|
||||||
GPtrArray *output_infos,
|
GPtrArray *output_infos,
|
||||||
|
GArray *reserved_crtcs,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
MetaMonitorSpec *monitor_spec = monitor_config->monitor_spec;
|
MetaMonitorSpec *monitor_spec = monitor_config->monitor_spec;
|
||||||
@ -262,7 +297,8 @@ assign_monitor_crtcs (MetaMonitorManager *manager,
|
|||||||
.logical_monitor_config = logical_monitor_config,
|
.logical_monitor_config = logical_monitor_config,
|
||||||
.monitor_config = monitor_config,
|
.monitor_config = monitor_config,
|
||||||
.crtc_infos = crtc_infos,
|
.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,
|
if (!meta_monitor_mode_foreach_crtc (monitor, monitor_mode,
|
||||||
assign_monitor_crtc,
|
assign_monitor_crtc,
|
||||||
@ -278,6 +314,7 @@ assign_logical_monitor_crtcs (MetaMonitorManager *manager,
|
|||||||
MetaLogicalMonitorConfig *logical_monitor_config,
|
MetaLogicalMonitorConfig *logical_monitor_config,
|
||||||
GPtrArray *crtc_infos,
|
GPtrArray *crtc_infos,
|
||||||
GPtrArray *output_infos,
|
GPtrArray *output_infos,
|
||||||
|
GArray *reserved_crtcs,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
GList *l;
|
GList *l;
|
||||||
@ -290,7 +327,7 @@ assign_logical_monitor_crtcs (MetaMonitorManager *manager,
|
|||||||
logical_monitor_config,
|
logical_monitor_config,
|
||||||
monitor_config,
|
monitor_config,
|
||||||
crtc_infos, output_infos,
|
crtc_infos, output_infos,
|
||||||
error))
|
reserved_crtcs, error))
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -306,12 +343,40 @@ meta_monitor_config_manager_assign (MetaMonitorManager *manager,
|
|||||||
{
|
{
|
||||||
GPtrArray *crtc_infos;
|
GPtrArray *crtc_infos;
|
||||||
GPtrArray *output_infos;
|
GPtrArray *output_infos;
|
||||||
|
GArray *reserved_crtcs;
|
||||||
GList *l;
|
GList *l;
|
||||||
|
|
||||||
crtc_infos =
|
crtc_infos =
|
||||||
g_ptr_array_new_with_free_func ((GDestroyNotify) meta_crtc_info_free);
|
g_ptr_array_new_with_free_func ((GDestroyNotify) meta_crtc_info_free);
|
||||||
output_infos =
|
output_infos =
|
||||||
g_ptr_array_new_with_free_func ((GDestroyNotify) meta_output_info_free);
|
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)
|
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,
|
if (!assign_logical_monitor_crtcs (manager, logical_monitor_config,
|
||||||
crtc_infos, output_infos,
|
crtc_infos, output_infos,
|
||||||
error))
|
reserved_crtcs, error))
|
||||||
{
|
{
|
||||||
g_ptr_array_free (crtc_infos, TRUE);
|
g_ptr_array_free (crtc_infos, TRUE);
|
||||||
g_ptr_array_free (output_infos, TRUE);
|
g_ptr_array_free (output_infos, TRUE);
|
||||||
|
g_array_free (reserved_crtcs, TRUE);
|
||||||
return FALSE;
|
return FALSE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_array_free (reserved_crtcs, TRUE);
|
||||||
|
|
||||||
*out_crtc_infos = crtc_infos;
|
*out_crtc_infos = crtc_infos;
|
||||||
*out_output_infos = output_infos;
|
*out_output_infos = output_infos;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user