mirror of
https://github.com/brl/mutter.git
synced 2025-02-17 21:54:10 +00:00
backends: Compare gpu/crtc/output configurations before applying
This spares us from visible flickering whenever an unchanged configuration is reapplied, eg. after lid open. The code in the X11 paths that did the same comparisons has been removed in favor of the generic checks. https://bugzilla.gnome.org/show_bug.cgi?id=791879
This commit is contained in:
parent
bcfac0d6dc
commit
18c85c9ffb
@ -388,4 +388,10 @@ gboolean meta_monitor_has_aspect_as_size (MetaMonitor *monitor);
|
|||||||
char * meta_monitor_manager_get_vendor_name (MetaMonitorManager *manager,
|
char * meta_monitor_manager_get_vendor_name (MetaMonitorManager *manager,
|
||||||
const char *vendor);
|
const char *vendor);
|
||||||
|
|
||||||
|
gboolean meta_monitor_manager_get_has_changed (MetaMonitorManager *manager,
|
||||||
|
MetaCrtcInfo **crtc_infos,
|
||||||
|
unsigned int n_crtc_infos,
|
||||||
|
MetaOutputInfo **output_infos,
|
||||||
|
unsigned int n_output_infos);
|
||||||
|
|
||||||
#endif /* META_MONITOR_MANAGER_PRIVATE_H */
|
#endif /* META_MONITOR_MANAGER_PRIVATE_H */
|
||||||
|
@ -483,6 +483,158 @@ meta_monitor_manager_ensure_initial_config (MetaMonitorManager *manager)
|
|||||||
META_MONITOR_MANAGER_GET_CLASS (manager)->ensure_initial_config (manager);
|
META_MONITOR_MANAGER_GET_CLASS (manager)->ensure_initial_config (manager);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
is_crtc_assignment_changed (MetaCrtc *crtc,
|
||||||
|
MetaCrtcInfo **crtc_infos,
|
||||||
|
unsigned int n_crtc_infos)
|
||||||
|
{
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < n_crtc_infos; i++)
|
||||||
|
{
|
||||||
|
MetaCrtcInfo *crtc_info = crtc_infos[i];
|
||||||
|
unsigned int j;
|
||||||
|
|
||||||
|
if (crtc_info->crtc != crtc)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (crtc->current_mode != crtc_info->mode)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (crtc->rect.x != crtc_info->x)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (crtc->rect.y != crtc_info->y)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (crtc->transform != crtc_info->transform)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
for (j = 0; j < crtc_info->outputs->len; j++)
|
||||||
|
{
|
||||||
|
MetaOutput *output = ((MetaOutput**) crtc_info->outputs->pdata)[j];
|
||||||
|
MetaCrtc *assigned_crtc;
|
||||||
|
|
||||||
|
assigned_crtc = meta_output_get_assigned_crtc (output);
|
||||||
|
if (assigned_crtc != crtc)
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return crtc->current_mode != NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
is_output_assignment_changed (MetaOutput *output,
|
||||||
|
MetaCrtcInfo **crtc_infos,
|
||||||
|
unsigned int n_crtc_infos,
|
||||||
|
MetaOutputInfo **output_infos,
|
||||||
|
unsigned int n_output_infos)
|
||||||
|
{
|
||||||
|
MetaCrtc *assigned_crtc;
|
||||||
|
gboolean output_is_found = FALSE;
|
||||||
|
unsigned int i;
|
||||||
|
|
||||||
|
for (i = 0; i < n_output_infos; i++)
|
||||||
|
{
|
||||||
|
MetaOutputInfo *output_info = output_infos[i];
|
||||||
|
|
||||||
|
if (output_info->output != output)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
if (output->is_primary != output_info->is_primary)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (output->is_presentation != output_info->is_presentation)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
if (output->is_underscanning != output_info->is_underscanning)
|
||||||
|
return TRUE;
|
||||||
|
|
||||||
|
output_is_found = TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
assigned_crtc = meta_output_get_assigned_crtc (output);
|
||||||
|
|
||||||
|
if (!output_is_found)
|
||||||
|
return assigned_crtc != NULL;
|
||||||
|
|
||||||
|
for (i = 0; i < n_crtc_infos; i++)
|
||||||
|
{
|
||||||
|
MetaCrtcInfo *crtc_info = crtc_infos[i];
|
||||||
|
unsigned int j;
|
||||||
|
|
||||||
|
for (j = 0; j < crtc_info->outputs->len; j++)
|
||||||
|
{
|
||||||
|
MetaOutput *crtc_info_output =
|
||||||
|
((MetaOutput**) crtc_info->outputs->pdata)[j];
|
||||||
|
|
||||||
|
if (crtc_info_output == output &&
|
||||||
|
crtc_info->crtc == assigned_crtc)
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
static gboolean
|
||||||
|
is_assignments_changed (MetaMonitorManager *manager,
|
||||||
|
MetaGpu *gpu,
|
||||||
|
MetaCrtcInfo **crtc_infos,
|
||||||
|
unsigned int n_crtc_infos,
|
||||||
|
MetaOutputInfo **output_infos,
|
||||||
|
unsigned int n_output_infos)
|
||||||
|
{
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
for (l = meta_gpu_get_crtcs (gpu); l; l = l->next)
|
||||||
|
{
|
||||||
|
MetaCrtc *crtc = l->data;
|
||||||
|
|
||||||
|
if (is_crtc_assignment_changed (crtc, crtc_infos, n_crtc_infos))
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
for (l = meta_gpu_get_outputs (gpu); l; l = l->next)
|
||||||
|
{
|
||||||
|
MetaOutput *output = l->data;
|
||||||
|
|
||||||
|
if (is_output_assignment_changed (output,
|
||||||
|
crtc_infos,
|
||||||
|
n_crtc_infos,
|
||||||
|
output_infos,
|
||||||
|
n_output_infos))
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
gboolean
|
||||||
|
meta_monitor_manager_get_has_changed (MetaMonitorManager *manager,
|
||||||
|
MetaCrtcInfo **crtc_infos,
|
||||||
|
unsigned int n_crtc_infos,
|
||||||
|
MetaOutputInfo **output_infos,
|
||||||
|
unsigned int n_output_infos)
|
||||||
|
{
|
||||||
|
GList *gpus;
|
||||||
|
GList *l;
|
||||||
|
|
||||||
|
gpus = meta_backend_get_gpus (manager->backend);
|
||||||
|
for (l = gpus; l; l = l->next)
|
||||||
|
{
|
||||||
|
if (is_assignments_changed (manager, l->data,
|
||||||
|
crtc_infos, n_crtc_infos,
|
||||||
|
output_infos, n_output_infos))
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
|
return FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
static gboolean
|
static gboolean
|
||||||
meta_monitor_manager_apply_monitors_config (MetaMonitorManager *manager,
|
meta_monitor_manager_apply_monitors_config (MetaMonitorManager *manager,
|
||||||
MetaMonitorsConfig *config,
|
MetaMonitorsConfig *config,
|
||||||
|
@ -77,6 +77,8 @@ struct _MetaMonitorManagerKms
|
|||||||
|
|
||||||
guint hotplug_handler_id;
|
guint hotplug_handler_id;
|
||||||
guint removed_handler_id;
|
guint removed_handler_id;
|
||||||
|
|
||||||
|
guint logical_monitors_invalid : 1;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct _MetaMonitorManagerKmsClass
|
struct _MetaMonitorManagerKmsClass
|
||||||
@ -322,6 +324,7 @@ meta_monitor_manager_kms_apply_monitors_config (MetaMonitorManager *manager
|
|||||||
MetaMonitorsConfigMethod method,
|
MetaMonitorsConfigMethod method,
|
||||||
GError **error)
|
GError **error)
|
||||||
{
|
{
|
||||||
|
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
|
||||||
GPtrArray *crtc_infos;
|
GPtrArray *crtc_infos;
|
||||||
GPtrArray *output_infos;
|
GPtrArray *output_infos;
|
||||||
|
|
||||||
@ -345,6 +348,26 @@ meta_monitor_manager_kms_apply_monitors_config (MetaMonitorManager *manager
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!meta_monitor_manager_get_has_changed (manager,
|
||||||
|
(MetaCrtcInfo **) crtc_infos->pdata,
|
||||||
|
crtc_infos->len,
|
||||||
|
(MetaOutputInfo **) output_infos->pdata,
|
||||||
|
output_infos->len))
|
||||||
|
{
|
||||||
|
/* Rebuild logical monitors if invalid, i.e. after
|
||||||
|
* meta_monitor_manager_read_current_state().
|
||||||
|
*/
|
||||||
|
if (manager_kms->logical_monitors_invalid)
|
||||||
|
{
|
||||||
|
meta_monitor_manager_rebuild (manager, config);
|
||||||
|
manager_kms->logical_monitors_invalid = FALSE;
|
||||||
|
}
|
||||||
|
|
||||||
|
g_ptr_array_free (crtc_infos, TRUE);
|
||||||
|
g_ptr_array_free (output_infos, TRUE);
|
||||||
|
return TRUE;
|
||||||
|
}
|
||||||
|
|
||||||
apply_crtc_assignments (manager,
|
apply_crtc_assignments (manager,
|
||||||
(MetaCrtcInfo **) crtc_infos->pdata,
|
(MetaCrtcInfo **) crtc_infos->pdata,
|
||||||
crtc_infos->len,
|
crtc_infos->len,
|
||||||
@ -356,6 +379,7 @@ meta_monitor_manager_kms_apply_monitors_config (MetaMonitorManager *manager
|
|||||||
|
|
||||||
update_screen_size (manager, config);
|
update_screen_size (manager, config);
|
||||||
meta_monitor_manager_rebuild (manager, config);
|
meta_monitor_manager_rebuild (manager, config);
|
||||||
|
manager_kms->logical_monitors_invalid = FALSE;
|
||||||
|
|
||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
@ -474,6 +498,13 @@ meta_monitor_manager_kms_set_crtc_gamma (MetaMonitorManager *manager,
|
|||||||
static void
|
static void
|
||||||
handle_hotplug_event (MetaMonitorManager *manager)
|
handle_hotplug_event (MetaMonitorManager *manager)
|
||||||
{
|
{
|
||||||
|
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
|
||||||
|
|
||||||
|
/* read_current_state() will rebuild monitors, leaving MetaLogicalMonitors
|
||||||
|
* with stale pointers to those. We will need to rebuild those even though
|
||||||
|
* the configuration might not have actually changed (eg. tty switch).
|
||||||
|
*/
|
||||||
|
manager_kms->logical_monitors_invalid = TRUE;
|
||||||
meta_monitor_manager_read_current_state (manager);
|
meta_monitor_manager_read_current_state (manager);
|
||||||
meta_monitor_manager_on_hotplug (manager);
|
meta_monitor_manager_on_hotplug (manager);
|
||||||
}
|
}
|
||||||
|
@ -240,103 +240,6 @@ xrandr_set_crtc_config (MetaMonitorManagerXrandr *manager_xrandr,
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
is_crtc_assignment_changed (MetaCrtc *crtc,
|
|
||||||
MetaCrtcInfo **crtc_infos,
|
|
||||||
unsigned int n_crtc_infos)
|
|
||||||
{
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
for (i = 0; i < n_crtc_infos; i++)
|
|
||||||
{
|
|
||||||
MetaCrtcInfo *crtc_info = crtc_infos[i];
|
|
||||||
unsigned int j;
|
|
||||||
|
|
||||||
if (crtc_info->crtc != crtc)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (crtc->current_mode != crtc_info->mode)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
if (crtc->rect.x != crtc_info->x)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
if (crtc->rect.y != crtc_info->y)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
if (crtc->transform != crtc_info->transform)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
for (j = 0; j < crtc_info->outputs->len; j++)
|
|
||||||
{
|
|
||||||
MetaOutput *output = ((MetaOutput**) crtc_info->outputs->pdata)[j];
|
|
||||||
MetaCrtc *assigned_crtc;
|
|
||||||
|
|
||||||
assigned_crtc = meta_output_get_assigned_crtc (output);
|
|
||||||
if (assigned_crtc != crtc)
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return crtc->current_mode != NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
is_output_assignment_changed (MetaOutput *output,
|
|
||||||
MetaCrtcInfo **crtc_infos,
|
|
||||||
unsigned int n_crtc_infos,
|
|
||||||
MetaOutputInfo **output_infos,
|
|
||||||
unsigned int n_output_infos)
|
|
||||||
{
|
|
||||||
MetaCrtc *assigned_crtc;
|
|
||||||
gboolean output_is_found = FALSE;
|
|
||||||
unsigned int i;
|
|
||||||
|
|
||||||
for (i = 0; i < n_output_infos; i++)
|
|
||||||
{
|
|
||||||
MetaOutputInfo *output_info = output_infos[i];
|
|
||||||
|
|
||||||
if (output_info->output != output)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
if (output->is_primary != output_info->is_primary)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
if (output->is_presentation != output_info->is_presentation)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
if (output->is_underscanning != output_info->is_underscanning)
|
|
||||||
return TRUE;
|
|
||||||
|
|
||||||
output_is_found = TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
assigned_crtc = meta_output_get_assigned_crtc (output);
|
|
||||||
|
|
||||||
if (!output_is_found)
|
|
||||||
return assigned_crtc != NULL;
|
|
||||||
|
|
||||||
for (i = 0; i < n_crtc_infos; i++)
|
|
||||||
{
|
|
||||||
MetaCrtcInfo *crtc_info = crtc_infos[i];
|
|
||||||
unsigned int j;
|
|
||||||
|
|
||||||
for (j = 0; j < crtc_info->outputs->len; j++)
|
|
||||||
{
|
|
||||||
MetaOutput *crtc_info_output =
|
|
||||||
((MetaOutput**) crtc_info->outputs->pdata)[j];
|
|
||||||
|
|
||||||
if (crtc_info_output == output &&
|
|
||||||
crtc_info->crtc == assigned_crtc)
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static MetaGpu *
|
static MetaGpu *
|
||||||
meta_monitor_manager_xrandr_get_gpu (MetaMonitorManagerXrandr *manager_xrandr)
|
meta_monitor_manager_xrandr_get_gpu (MetaMonitorManagerXrandr *manager_xrandr)
|
||||||
{
|
{
|
||||||
@ -346,41 +249,6 @@ meta_monitor_manager_xrandr_get_gpu (MetaMonitorManagerXrandr *manager_xrandr)
|
|||||||
return META_GPU (meta_backend_get_gpus (backend)->data);
|
return META_GPU (meta_backend_get_gpus (backend)->data);
|
||||||
}
|
}
|
||||||
|
|
||||||
static gboolean
|
|
||||||
is_assignments_changed (MetaMonitorManager *manager,
|
|
||||||
MetaCrtcInfo **crtc_infos,
|
|
||||||
unsigned int n_crtc_infos,
|
|
||||||
MetaOutputInfo **output_infos,
|
|
||||||
unsigned int n_output_infos)
|
|
||||||
{
|
|
||||||
MetaMonitorManagerXrandr *manager_xrandr =
|
|
||||||
META_MONITOR_MANAGER_XRANDR (manager);
|
|
||||||
MetaGpu *gpu = meta_monitor_manager_xrandr_get_gpu (manager_xrandr);
|
|
||||||
GList *l;
|
|
||||||
|
|
||||||
for (l = meta_gpu_get_crtcs (gpu); l; l = l->next)
|
|
||||||
{
|
|
||||||
MetaCrtc *crtc = l->data;
|
|
||||||
|
|
||||||
if (is_crtc_assignment_changed (crtc, crtc_infos, n_crtc_infos))
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
for (l = meta_gpu_get_outputs (gpu); l; l = l->next)
|
|
||||||
{
|
|
||||||
MetaOutput *output = l->data;
|
|
||||||
|
|
||||||
if (is_output_assignment_changed (output,
|
|
||||||
crtc_infos,
|
|
||||||
n_crtc_infos,
|
|
||||||
output_infos,
|
|
||||||
n_output_infos))
|
|
||||||
return TRUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
apply_crtc_assignments (MetaMonitorManager *manager,
|
apply_crtc_assignments (MetaMonitorManager *manager,
|
||||||
gboolean save_timestamp,
|
gboolean save_timestamp,
|
||||||
@ -651,11 +519,11 @@ meta_monitor_manager_xrandr_apply_monitors_config (MetaMonitorManager *mana
|
|||||||
* must check that our new assignment actually changes anything, otherwise
|
* must check that our new assignment actually changes anything, otherwise
|
||||||
* just update the logical state.
|
* just update the logical state.
|
||||||
*/
|
*/
|
||||||
if (is_assignments_changed (manager,
|
if (meta_monitor_manager_get_has_changed (manager,
|
||||||
(MetaCrtcInfo **) crtc_infos->pdata,
|
(MetaCrtcInfo **) crtc_infos->pdata,
|
||||||
crtc_infos->len,
|
crtc_infos->len,
|
||||||
(MetaOutputInfo **) output_infos->pdata,
|
(MetaOutputInfo **) output_infos->pdata,
|
||||||
output_infos->len))
|
output_infos->len))
|
||||||
{
|
{
|
||||||
apply_crtc_assignments (manager,
|
apply_crtc_assignments (manager,
|
||||||
TRUE,
|
TRUE,
|
||||||
|
Loading…
x
Reference in New Issue
Block a user