[mutter] kms: Notify about privacy screen changes via predictions



commit 81b28a1d975f2511d8800faa2c187703eb66ce63
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Thu Mar 17 10:33:23 2022 +0100

    kms: Notify about privacy screen changes via predictions
    
    When we change the privacy screen, we added a result listener to the KMS
    update object to notify the upper layer about the privacy screen state
    change. This was slightly awkward as one might have changed the state
    multiple times for a single update, thus it was necessary to remove any
    old result listeners to an update before adding a new one.
    
    Doing this will not be possible when updates are fully async and managed
    by the KMS impl device.
    
    To handle this, instead make the post-commit prediction notify about
    changes that happens in response to a successfully committed update. We
    already predicted the new privacy screen state, so the necessary change
    was to plumb the actual change into a callback which emits the signal if
    there actually was a privacy screen change.
    
    This will then be communicated via the same signal listener that already
    listens to the 'resources-changed' signal.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2340>

 src/backends/meta-monitor-manager-private.h       |  3 --
 src/backends/meta-monitor-manager.c               | 37 ++++---------
 src/backends/native/meta-kms-connector-private.h  |  4 +-
 src/backends/native/meta-kms-connector.c          | 15 +++++-
 src/backends/native/meta-kms-crtc-private.h       |  4 +-
 src/backends/native/meta-kms-crtc.c               |  6 ++-
 src/backends/native/meta-kms-impl-device.c        | 45 +++++++++++++---
 src/backends/native/meta-kms-private.h            |  3 ++
 src/backends/native/meta-kms.c                    |  9 +++-
 src/backends/native/meta-monitor-manager-native.c | 65 -----------------------
 src/backends/native/meta-output-kms.c             | 23 +++++---
 11 files changed, 98 insertions(+), 116 deletions(-)
---
diff --git a/src/backends/meta-monitor-manager-private.h b/src/backends/meta-monitor-manager-private.h
index edf7e45019..e14ab207fa 100644
--- a/src/backends/meta-monitor-manager-private.h
+++ b/src/backends/meta-monitor-manager-private.h
@@ -246,9 +246,6 @@ struct _MetaMonitorManagerClass
                            unsigned short     *green,
                            unsigned short     *blue);
 
-  gboolean (* set_privacy_screen_enabled) (MetaMonitorManager *manager,
-                                           gboolean            enabled);
-
   void (* tiled_monitor_added) (MetaMonitorManager *manager,
                                 MetaMonitor        *monitor);
 
diff --git a/src/backends/meta-monitor-manager.c b/src/backends/meta-monitor-manager.c
index 6d9b7f416b..4230fcd239 100644
--- a/src/backends/meta-monitor-manager.c
+++ b/src/backends/meta-monitor-manager.c
@@ -1009,17 +1009,21 @@ experimental_features_changed (MetaSettings           *settings,
 }
 
 static gboolean
-meta_monitor_manager_real_set_privacy_screen_enabled (MetaMonitorManager *manager,
-                                                      gboolean            enabled)
+ensure_privacy_screen_settings (MetaMonitorManager *manager)
 {
+  MetaSettings *settings = meta_backend_get_settings (manager->backend);
+  gboolean privacy_screen_enabled;
   GList *l;
 
+  privacy_screen_enabled = meta_settings_is_privacy_screen_enabled (settings);
   for (l = manager->monitors; l; l = l->next)
     {
-      g_autoptr (GError) error = NULL;
       MetaMonitor *monitor = l->data;
+      g_autoptr (GError) error = NULL;
 
-      if (!meta_monitor_set_privacy_screen_enabled (monitor, enabled, &error))
+      if (!meta_monitor_set_privacy_screen_enabled (monitor,
+                                                    privacy_screen_enabled,
+                                                    &error))
         {
           if (g_error_matches (error, G_IO_ERROR, G_IO_ERROR_NOT_SUPPORTED))
             continue;
@@ -1033,25 +1037,6 @@ meta_monitor_manager_real_set_privacy_screen_enabled (MetaMonitorManager *manage
   return TRUE;
 }
 
-static gboolean
-set_privacy_screen_enabled (MetaMonitorManager *manager,
-                            gboolean            enabled)
-{
-  MetaMonitorManagerClass *manager_class =
-    META_MONITOR_MANAGER_GET_CLASS (manager);
-
-  return manager_class->set_privacy_screen_enabled (manager, enabled);
-}
-
-static gboolean
-ensure_monitors_settings (MetaMonitorManager *manager)
-{
-  MetaSettings *settings = meta_backend_get_settings (manager->backend);
-
-  return set_privacy_screen_enabled (
-    manager, meta_settings_is_privacy_screen_enabled (settings));
-}
-
 static MetaPrivacyScreenState
 get_global_privacy_screen_state (MetaMonitorManager *manager)
 {
@@ -1098,7 +1083,7 @@ static void
 apply_privacy_screen_settings (MetaMonitorManager *manager)
 {
   if (privacy_screen_needs_update (manager) &&
-      ensure_monitors_settings (manager))
+      ensure_privacy_screen_settings (manager))
     {
       manager->privacy_screen_change_state =
         META_PRIVACY_SCREEN_CHANGE_STATE_PENDING_SETTING;
@@ -1396,8 +1381,6 @@ meta_monitor_manager_class_init (MetaMonitorManagerClass *klass)
 
   klass->read_edid = meta_monitor_manager_real_read_edid;
   klass->read_current_state = meta_monitor_manager_real_read_current_state;
-  klass->set_privacy_screen_enabled =
-    meta_monitor_manager_real_set_privacy_screen_enabled;
 
   signals[MONITORS_CHANGED] =
     g_signal_new ("monitors-changed",
@@ -3619,7 +3602,7 @@ meta_monitor_manager_rebuild (MetaMonitorManager *manager,
 
   meta_monitor_manager_notify_monitors_changed (manager);
 
-  ensure_monitors_settings (manager);
+  ensure_privacy_screen_settings (manager);
 
   g_list_free_full (old_logical_monitors, g_object_unref);
 }
diff --git a/src/backends/native/meta-kms-connector-private.h 
b/src/backends/native/meta-kms-connector-private.h
index e5aa3e332f..e1d9b44cd5 100644
--- a/src/backends/native/meta-kms-connector-private.h
+++ b/src/backends/native/meta-kms-connector-private.h
@@ -106,8 +106,8 @@ MetaKmsResourceChanges meta_kms_connector_update_state (MetaKmsConnector *connec
 
 void meta_kms_connector_disable (MetaKmsConnector *connector);
 
-void meta_kms_connector_predict_state (MetaKmsConnector *connector,
-                                       MetaKmsUpdate    *update);
+MetaKmsResourceChanges meta_kms_connector_predict_state (MetaKmsConnector *connector,
+                                                         MetaKmsUpdate    *update);
 
 MetaKmsConnector * meta_kms_connector_new (MetaKmsImplDevice *impl_device,
                                            drmModeConnector  *drm_connector,
diff --git a/src/backends/native/meta-kms-connector.c b/src/backends/native/meta-kms-connector.c
index 8d77b21150..724f96e36f 100644
--- a/src/backends/native/meta-kms-connector.c
+++ b/src/backends/native/meta-kms-connector.c
@@ -758,7 +758,7 @@ meta_kms_connector_disable (MetaKmsConnector *connector)
   current_state->current_crtc_id = 0;
 }
 
-void
+MetaKmsResourceChanges
 meta_kms_connector_predict_state (MetaKmsConnector *connector,
                                   MetaKmsUpdate    *update)
 {
@@ -766,10 +766,11 @@ meta_kms_connector_predict_state (MetaKmsConnector *connector,
   MetaKmsConnectorState *current_state;
   GList *mode_sets;
   GList *l;
+  MetaKmsResourceChanges changes = META_KMS_RESOURCE_CHANGE_NONE;
 
   current_state = connector->current_state;
   if (!current_state)
-    return;
+    return META_KMS_RESOURCE_CHANGE_NONE;
 
   mode_sets = meta_kms_update_get_mode_sets (update);
   for (l = mode_sets; l; l = l->next)
@@ -812,11 +813,19 @@ meta_kms_connector_predict_state (MetaKmsConnector *connector,
             {
               if (connector_update->privacy_screen.is_enabled)
                 {
+                  if (current_state->privacy_screen_state !=
+                      META_PRIVACY_SCREEN_ENABLED)
+                    changes |= META_KMS_RESOURCE_CHANGE_PRIVACY_SCREEN;
+
                   current_state->privacy_screen_state =
                     META_PRIVACY_SCREEN_ENABLED;
                 }
               else
                 {
+                  if (current_state->privacy_screen_state !=
+                      META_PRIVACY_SCREEN_DISABLED)
+                    changes |= META_KMS_RESOURCE_CHANGE_PRIVACY_SCREEN;
+
                   current_state->privacy_screen_state =
                     META_PRIVACY_SCREEN_DISABLED;
                 }
@@ -826,6 +835,8 @@ meta_kms_connector_predict_state (MetaKmsConnector *connector,
 
   impl_device = meta_kms_device_get_impl_device (connector->device);
   sync_fd_held (connector, impl_device);
+
+  return changes;
 }
 
 static void
diff --git a/src/backends/native/meta-kms-crtc-private.h b/src/backends/native/meta-kms-crtc-private.h
index baf5f4099a..79a5f0fe64 100644
--- a/src/backends/native/meta-kms-crtc-private.h
+++ b/src/backends/native/meta-kms-crtc-private.h
@@ -42,8 +42,8 @@ MetaKmsResourceChanges meta_kms_crtc_update_state (MetaKmsCrtc *crtc);
 
 void meta_kms_crtc_disable (MetaKmsCrtc *crtc);
 
-void meta_kms_crtc_predict_state (MetaKmsCrtc   *crtc,
-                                  MetaKmsUpdate *update);
+MetaKmsResourceChanges meta_kms_crtc_predict_state (MetaKmsCrtc   *crtc,
+                                                    MetaKmsUpdate *update);
 
 uint32_t meta_kms_crtc_get_prop_id (MetaKmsCrtc     *crtc,
                                     MetaKmsCrtcProp  prop);
diff --git a/src/backends/native/meta-kms-crtc.c b/src/backends/native/meta-kms-crtc.c
index ee9e19d2d9..707dfd4b8c 100644
--- a/src/backends/native/meta-kms-crtc.c
+++ b/src/backends/native/meta-kms-crtc.c
@@ -278,13 +278,14 @@ meta_kms_crtc_disable (MetaKmsCrtc *crtc)
   crtc->current_state.drm_mode = (drmModeModeInfo) { 0 };
 }
 
-void
+MetaKmsResourceChanges
 meta_kms_crtc_predict_state (MetaKmsCrtc   *crtc,
                              MetaKmsUpdate *update)
 {
   GList *mode_sets;
   GList *crtc_gammas;
   GList *l;
+  MetaKmsResourceChanges changes = META_KMS_RESOURCE_CHANGE_NONE;
 
   mode_sets = meta_kms_update_get_mode_sets (update);
   for (l = mode_sets; l; l = l->next)
@@ -337,8 +338,11 @@ meta_kms_crtc_predict_state (MetaKmsCrtc   *crtc,
       crtc->current_state.gamma.blue =
         g_memdup2 (gamma->blue, gamma->size * sizeof (uint16_t));
 
+      changes |= META_KMS_RESOURCE_CHANGE_GAMMA;
       break;
     }
+
+  return changes;
 }
 
 static void
diff --git a/src/backends/native/meta-kms-impl-device.c b/src/backends/native/meta-kms-impl-device.c
index 5ef04abc3b..653a96f719 100644
--- a/src/backends/native/meta-kms-impl-device.c
+++ b/src/backends/native/meta-kms-impl-device.c
@@ -914,17 +914,30 @@ err:
   return META_KMS_RESOURCE_CHANGE_FULL;
 }
 
-static void
+static MetaKmsResourceChanges
 meta_kms_impl_device_predict_states (MetaKmsImplDevice *impl_device,
                                      MetaKmsUpdate     *update)
 {
   MetaKmsImplDevicePrivate *priv =
     meta_kms_impl_device_get_instance_private (impl_device);
+  MetaKmsResourceChanges changes = META_KMS_RESOURCE_CHANGE_NONE;
+  GList *l;
 
-  g_list_foreach (priv->crtcs, (GFunc) meta_kms_crtc_predict_state,
-                  update);
-  g_list_foreach (priv->connectors, (GFunc) meta_kms_connector_predict_state,
-                  update);
+  for (l = priv->crtcs; l; l = l->next)
+    {
+      MetaKmsCrtc *crtc = l->data;
+
+      changes |= meta_kms_crtc_predict_state (crtc, update);
+    }
+
+  for (l = priv->connectors; l; l = l->next)
+    {
+      MetaKmsConnector *connector = l->data;
+
+      changes |= meta_kms_connector_predict_state (connector, update);
+    }
+
+  return changes;
 }
 
 void
@@ -944,14 +957,26 @@ meta_kms_impl_device_get_fd (MetaKmsImplDevice *impl_device)
   return meta_device_file_get_fd (priv->device_file);
 }
 
+static void
+emit_resources_changed_callback (MetaKms  *kms,
+                                 gpointer  user_data)
+{
+  MetaKmsResourceChanges changes = GPOINTER_TO_UINT (user_data);
+
+  meta_kms_emit_resources_changed (kms, changes);
+}
+
 MetaKmsFeedback *
 meta_kms_impl_device_process_update (MetaKmsImplDevice *impl_device,
                                      MetaKmsUpdate     *update,
                                      MetaKmsUpdateFlag  flags)
 {
+  MetaKmsImplDevicePrivate *priv =
+    meta_kms_impl_device_get_instance_private (impl_device);
   MetaKmsImplDeviceClass *klass = META_KMS_IMPL_DEVICE_GET_CLASS (impl_device);
   MetaKmsFeedback *feedback;
   g_autoptr (GError) error = NULL;
+  MetaKmsResourceChanges changes = META_KMS_RESOURCE_CHANGE_NONE;
 
   if (!ensure_device_file (impl_device, &error))
     return meta_kms_feedback_new_failed (NULL, g_steal_pointer (&error));
@@ -959,9 +984,17 @@ meta_kms_impl_device_process_update (MetaKmsImplDevice *impl_device,
   meta_kms_impl_device_hold_fd (impl_device);
   feedback = klass->process_update (impl_device, update, flags);
   if (!(flags & META_KMS_UPDATE_FLAG_TEST_ONLY))
-    meta_kms_impl_device_predict_states (impl_device, update);
+    changes = meta_kms_impl_device_predict_states (impl_device, update);
   meta_kms_impl_device_unhold_fd (impl_device);
 
+  if (changes != META_KMS_RESOURCE_CHANGE_NONE)
+    {
+      MetaKms *kms = meta_kms_device_get_kms (priv->device);
+
+      meta_kms_queue_callback (kms,
+                               emit_resources_changed_callback,
+                               GUINT_TO_POINTER (changes), NULL);
+    }
   return feedback;
 }
 
diff --git a/src/backends/native/meta-kms-private.h b/src/backends/native/meta-kms-private.h
index 0c383834bd..615e2bdf7b 100644
--- a/src/backends/native/meta-kms-private.h
+++ b/src/backends/native/meta-kms-private.h
@@ -61,6 +61,9 @@ gboolean meta_kms_in_impl_task (MetaKms *kms);
 
 gboolean meta_kms_is_waiting_for_impl_task (MetaKms *kms);
 
+void meta_kms_emit_resources_changed (MetaKms                *kms,
+                                      MetaKmsResourceChanges  changes);
+
 #define meta_assert_in_kms_impl(kms) \
   g_assert (meta_kms_in_impl_task (kms))
 #define meta_assert_not_in_kms_impl(kms) \
diff --git a/src/backends/native/meta-kms.c b/src/backends/native/meta-kms.c
index 521690a198..21be532a2f 100644
--- a/src/backends/native/meta-kms.c
+++ b/src/backends/native/meta-kms.c
@@ -651,7 +651,7 @@ handle_hotplug_event (MetaKms                *kms,
   changes |= meta_kms_update_states_sync (kms, udev_device);
 
   if (changes != META_KMS_RESOURCE_CHANGE_NONE)
-    g_signal_emit (kms, signals[RESOURCES_CHANGED], 0, changes);
+    meta_kms_emit_resources_changed (kms, changes);
 }
 
 void
@@ -799,3 +799,10 @@ meta_kms_class_init (MetaKmsClass *klass)
                   G_TYPE_NONE, 1,
                   META_TYPE_KMS_RESOURCE_CHANGES);
 }
+
+void
+meta_kms_emit_resources_changed (MetaKms                *kms,
+                                 MetaKmsResourceChanges  changes)
+{
+  g_signal_emit (kms, signals[RESOURCES_CHANGED], 0, changes);
+}
diff --git a/src/backends/native/meta-monitor-manager-native.c 
b/src/backends/native/meta-monitor-manager-native.c
index 4ea5ac6023..90fae7d426 100644
--- a/src/backends/native/meta-monitor-manager-native.c
+++ b/src/backends/native/meta-monitor-manager-native.c
@@ -736,69 +736,6 @@ allocate_virtual_monitor_id (MetaMonitorManagerNative *manager_native)
     }
 }
 
-static void
-on_kms_privacy_screen_update_result (const MetaKmsFeedback *kms_feedback,
-                                     gpointer               user_data)
-{
-  MetaMonitorManager *manager = user_data;
-  MetaBackend *backend = meta_monitor_manager_get_backend (manager);
-  MetaKms *kms = meta_backend_native_get_kms (META_BACKEND_NATIVE (backend));
-
-  if (meta_kms_feedback_get_result (kms_feedback) == META_KMS_FEEDBACK_FAILED)
-    {
-      manager->privacy_screen_change_state =
-        META_PRIVACY_SCREEN_CHANGE_STATE_NONE;
-      return;
-    }
-
-  on_kms_resources_changed (kms,
-                            META_KMS_RESOURCE_CHANGE_PRIVACY_SCREEN,
-                            manager);
-}
-
-static gboolean
-meta_monitor_manager_native_set_privacy_screen_enabled (MetaMonitorManager *manager,
-                                                        gboolean            enabled)
-{
-  MetaMonitorManagerClass *manager_class;
-  MetaBackend *backend = meta_monitor_manager_get_backend (manager);
-  MetaKms *kms = meta_backend_native_get_kms (META_BACKEND_NATIVE (backend));
-  gboolean any_update = FALSE;
-  GList *l;
-
-  manager_class =
-    META_MONITOR_MANAGER_CLASS (meta_monitor_manager_native_parent_class);
-
-  if (!manager_class->set_privacy_screen_enabled (manager, enabled))
-    return FALSE;
-
-  for (l = meta_kms_get_devices (kms); l; l = l->next)
-    {
-      MetaKmsDevice *kms_device = l->data;
-      MetaKmsUpdate *kms_update;
-
-      kms_update = meta_kms_get_pending_update (kms, kms_device);
-
-      if (kms_update)
-        {
-          meta_kms_update_remove_result_listeners (
-            kms_update, on_kms_privacy_screen_update_result, manager);
-          meta_kms_update_add_result_listener (
-            kms_update, on_kms_privacy_screen_update_result, manager);
-          any_update = TRUE;
-       }
-    }
-
-  if (any_update)
-    {
-      ClutterStage *stage = CLUTTER_STAGE (meta_backend_get_stage (backend));
-
-      clutter_stage_schedule_update (stage);
-    }
-
-  return TRUE;
-}
-
 static gboolean
 rebuild_virtual_idle_cb (gpointer user_data)
 {
@@ -956,8 +893,6 @@ meta_monitor_manager_native_class_init (MetaMonitorManagerNativeClass *klass)
     meta_monitor_manager_native_get_crtc_gamma;
   manager_class->set_crtc_gamma =
     meta_monitor_manager_native_set_crtc_gamma;
-  manager_class->set_privacy_screen_enabled =
-    meta_monitor_manager_native_set_privacy_screen_enabled;
   manager_class->is_transform_handled =
     meta_monitor_manager_native_is_transform_handled;
   manager_class->calculate_monitor_mode_scale =
diff --git a/src/backends/native/meta-output-kms.c b/src/backends/native/meta-output-kms.c
index f60d5ad0dd..108567cb1f 100644
--- a/src/backends/native/meta-output-kms.c
+++ b/src/backends/native/meta-output-kms.c
@@ -114,12 +114,15 @@ meta_output_kms_set_privacy_screen_enabled (MetaOutput  *output,
                                             gboolean     enabled,
                                             GError     **error)
 {
-  MetaGpu *gpu;
-  MetaKms *kms;
-  MetaKmsDevice *kms_device;
-  MetaKmsUpdate *kms_update;
+  MetaGpu *gpu = meta_output_get_gpu (output);
+  MetaBackend *backend = meta_gpu_get_backend (gpu);
+  MetaRenderer *renderer = meta_backend_get_renderer (backend);
+  MetaKmsDevice *kms_device = meta_gpu_kms_get_kms_device (META_GPU_KMS (gpu));
+  MetaKms *kms = meta_kms_device_get_kms (kms_device);
   MetaOutputKms *output_kms = META_OUTPUT_KMS (output);
   MetaKmsConnector *connector = meta_output_kms_get_kms_connector (output_kms);
+  MetaKmsUpdate *kms_update;
+  MetaCrtc *crtc;
 
   if (!meta_kms_connector_is_privacy_screen_supported (connector))
     {
@@ -128,13 +131,19 @@ meta_output_kms_set_privacy_screen_enabled (MetaOutput  *output,
       return FALSE;
     }
 
-  gpu = meta_output_get_gpu (META_OUTPUT (output_kms));
-  kms_device = meta_gpu_kms_get_kms_device (META_GPU_KMS (gpu));
-  kms = meta_kms_device_get_kms (kms_device);
   kms_update = meta_kms_ensure_pending_update (kms, kms_device);
 
   meta_kms_update_set_privacy_screen (kms_update, connector, enabled);
 
+  crtc = meta_output_get_assigned_crtc (output);
+  if (crtc)
+    {
+      MetaRendererView *view;
+
+      view = meta_renderer_get_view_for_crtc (renderer, crtc);
+      clutter_stage_view_schedule_update (CLUTTER_STAGE_VIEW (view));
+    }
+
   return TRUE;
 }
 


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]