Compare commits

..

1 Commits

Author SHA1 Message Date
Carlos Garnacho
18c85c9ffb 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
2019-09-04 16:29:04 +02:00
6 changed files with 195 additions and 166 deletions

28
NEWS
View File

@@ -1,31 +1,3 @@
3.33.92
=======
* Turn MetaShapedTexture into a ClutterContent implementation [Georges; !409]
* Restore inhibit shortcut for overlay key [Olivier; #734]
* Misc. pointer a11y improvements [Jonas D., Olivier; !746, !747, !745, !761]
* Fix position of drag surfaces [Robert; !684]
* Implement subsurface.place_below() for parents [Robert; !664]
* Add meta_window_actor_get_image() [Jonas Å.; !752]
* Revert faulty optimization from !719 [Jonas Å.; #735]
* Add additional sysprof trace points [Jonas Å.; !757, !765]
* Remove GLX "threaded swap wait" used on Nvidia [Daniel; !602]
* Implement geometric picking [Daniel; !189]
* Fix lost keyboard focus after DND [Olivier; #747]
* Misc. bug fixes and cleanups [Florian, Carlos, Piotr, Hans, Georges, Robert,
Ray, Mart, Rémi; !740, !672, !749, !751, !753, !730, !755, !756, !750, !715,
#738944, !657, !768]
Contributors:
Jonas Ådahl, Rémi Bernon, Piotr Drąg, Jonas Dreßler, Olivier Fourdan,
Carlos Garnacho, Hans de Goede, Robert Mader, Florian Müllner,
Georges Basile Stavracas Neto, Mart Raudsepp, Ray Strode, Daniel van Vugt
Translators:
Piotr Drąg [pl], Марко Костић [sr], Rūdolfs Mazurs [lv], Matej Urbančič [sl],
Balázs Úr [hu], Fran Dieguez [gl], Jordi Mas [ca], Anders Jonsson [sv],
Trần Ngọc Quân [vi], Tim Sabsch [de], Fabio Tomat [fur], Goran Vidović [hr],
Marek Černocký [cs]
3.33.91
=======
* Fix primary selection copy and paste between X11 and wayland [Hans; #702]

View File

@@ -1,5 +1,5 @@
project('mutter', 'c',
version: '3.33.92',
version: '3.33.91',
meson_version: '>= 0.50.0',
license: 'GPLv2+'
)

View File

@@ -388,4 +388,10 @@ gboolean meta_monitor_has_aspect_as_size (MetaMonitor *monitor);
char * meta_monitor_manager_get_vendor_name (MetaMonitorManager *manager,
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 */

View File

@@ -483,6 +483,158 @@ meta_monitor_manager_ensure_initial_config (MetaMonitorManager *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
meta_monitor_manager_apply_monitors_config (MetaMonitorManager *manager,
MetaMonitorsConfig *config,

View File

@@ -77,6 +77,8 @@ struct _MetaMonitorManagerKms
guint hotplug_handler_id;
guint removed_handler_id;
guint logical_monitors_invalid : 1;
};
struct _MetaMonitorManagerKmsClass
@@ -322,6 +324,7 @@ meta_monitor_manager_kms_apply_monitors_config (MetaMonitorManager *manager
MetaMonitorsConfigMethod method,
GError **error)
{
MetaMonitorManagerKms *manager_kms = META_MONITOR_MANAGER_KMS (manager);
GPtrArray *crtc_infos;
GPtrArray *output_infos;
@@ -345,6 +348,26 @@ meta_monitor_manager_kms_apply_monitors_config (MetaMonitorManager *manager
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,
(MetaCrtcInfo **) crtc_infos->pdata,
crtc_infos->len,
@@ -356,6 +379,7 @@ meta_monitor_manager_kms_apply_monitors_config (MetaMonitorManager *manager
update_screen_size (manager, config);
meta_monitor_manager_rebuild (manager, config);
manager_kms->logical_monitors_invalid = FALSE;
return TRUE;
}
@@ -474,6 +498,13 @@ meta_monitor_manager_kms_set_crtc_gamma (MetaMonitorManager *manager,
static void
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_on_hotplug (manager);
}

View File

@@ -240,103 +240,6 @@ xrandr_set_crtc_config (MetaMonitorManagerXrandr *manager_xrandr,
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 *
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);
}
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
apply_crtc_assignments (MetaMonitorManager *manager,
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
* just update the logical state.
*/
if (is_assignments_changed (manager,
(MetaCrtcInfo **) crtc_infos->pdata,
crtc_infos->len,
(MetaOutputInfo **) output_infos->pdata,
output_infos->len))
if (meta_monitor_manager_get_has_changed (manager,
(MetaCrtcInfo **) crtc_infos->pdata,
crtc_infos->len,
(MetaOutputInfo **) output_infos->pdata,
output_infos->len))
{
apply_crtc_assignments (manager,
TRUE,