[mutter] kms: Post pending updates per device



commit 2df632736718df8466bde3cfca32d0ed421d02ad
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Fri Oct 2 10:38:57 2020 +0200

    kms: Post pending updates per device
    
    Instead of a "post all pending updates", pass an update specific to a
    single device. This gets rid of the awkward "combine feedback" function,
    and makes it possible to queue updates to a multiple devices without
    always posting them together.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>

 src/backends/native/meta-cursor-renderer-native.c |  36 ++++---
 src/backends/native/meta-kms.c                    | 114 +++++++++-------------
 src/backends/native/meta-kms.h                    |   5 +-
 src/backends/native/meta-monitor-manager-kms.c    |  17 ++--
 src/backends/native/meta-renderer-native.c        |  69 +++++++------
 5 files changed, 123 insertions(+), 118 deletions(-)
---
diff --git a/src/backends/native/meta-cursor-renderer-native.c 
b/src/backends/native/meta-cursor-renderer-native.c
index 2e89a3f0e4..96e032f35d 100644
--- a/src/backends/native/meta-cursor-renderer-native.c
+++ b/src/backends/native/meta-cursor-renderer-native.c
@@ -544,7 +544,6 @@ update_hw_cursor (MetaCursorRendererNative *native,
   GList *l;
   graphene_rect_t rect;
   gboolean painted = FALSE;
-  g_autoptr (MetaKmsFeedback) feedback = NULL;
 
   if (cursor_sprite)
     rect = meta_cursor_renderer_calculate_rect (renderer, cursor_sprite);
@@ -589,23 +588,36 @@ update_hw_cursor (MetaCursorRendererNative *native,
       painted = painted || data.out_painted;
     }
 
-  feedback = meta_kms_post_pending_updates_sync (kms);
-  if (meta_kms_feedback_get_result (feedback) != META_KMS_FEEDBACK_PASSED)
+  for (l = meta_kms_get_devices (kms); l; l = l->next)
     {
-      for (l = meta_kms_feedback_get_failed_planes (feedback); l; l = l->next)
+      MetaKmsDevice *kms_device = l->data;
+      MetaKmsUpdate *kms_update;
+      g_autoptr (MetaKmsFeedback) feedback = NULL;
+
+      kms_update = meta_kms_get_pending_update (kms, kms_device);
+      if (!kms_update)
+        continue;
+
+      feedback = meta_kms_post_pending_update_sync (kms, kms_device);
+      if (meta_kms_feedback_get_result (feedback) != META_KMS_FEEDBACK_PASSED)
         {
-          MetaKmsPlaneFeedback *plane_feedback = l->data;
+          GList *k;
 
-          if (!g_error_matches (plane_feedback->error,
-                                G_IO_ERROR,
-                                G_IO_ERROR_PERMISSION_DENIED))
+          for (k = meta_kms_feedback_get_failed_planes (feedback); k; k = k->next)
             {
-              disable_hw_cursor_for_crtc (plane_feedback->crtc,
-                                          plane_feedback->error);
+              MetaKmsPlaneFeedback *plane_feedback = k->data;
+
+              if (!g_error_matches (plane_feedback->error,
+                                    G_IO_ERROR,
+                                    G_IO_ERROR_PERMISSION_DENIED))
+                {
+                  disable_hw_cursor_for_crtc (plane_feedback->crtc,
+                                              plane_feedback->error);
+                }
             }
-        }
 
-      priv->has_hw_cursor = FALSE;
+          priv->has_hw_cursor = FALSE;
+        }
     }
 
   priv->hw_state_invalidated = FALSE;
diff --git a/src/backends/native/meta-kms.c b/src/backends/native/meta-kms.c
index f658dda1fd..f4c2b6848b 100644
--- a/src/backends/native/meta-kms.c
+++ b/src/backends/native/meta-kms.c
@@ -210,95 +210,65 @@ meta_kms_get_pending_update (MetaKms       *kms,
   return NULL;
 }
 
-static void
-meta_kms_predict_states_in_impl (MetaKms       *kms,
-                                 MetaKmsUpdate *update)
-{
-  meta_assert_in_kms_impl (kms);
-
-  g_list_foreach (kms->devices,
-                  (GFunc) meta_kms_device_predict_states_in_impl,
-                  update);
-}
-
-static MetaKmsFeedback *
-combine_feedbacks (MetaKmsFeedback *feedback,
-                   MetaKmsFeedback *other_feedback)
+static MetaKmsUpdate *
+meta_kms_take_pending_update (MetaKms       *kms,
+                              MetaKmsDevice *device)
 {
-  GList *failed_planes;
-  MetaKmsFeedback *new_feedback;
-  const GError *error;
-
-  if (!feedback)
-    return other_feedback;
-
-  failed_planes =
-    g_list_concat (meta_kms_feedback_get_failed_planes (feedback),
-                   meta_kms_feedback_get_failed_planes (other_feedback));
-  error = meta_kms_feedback_get_error (feedback);
-  if (!error)
-    error = meta_kms_feedback_get_error (other_feedback);
+  GList *l;
 
-  if (error)
-    {
-      new_feedback = meta_kms_feedback_new_failed (failed_planes,
-                                                   g_error_copy (error));
-    }
-  else
+  for (l = kms->pending_updates; l; l = l->next)
     {
-      new_feedback = meta_kms_feedback_new_passed ();
-    }
+      MetaKmsUpdate *update = l->data;
 
-  meta_kms_feedback_free (feedback);
-  meta_kms_feedback_free (other_feedback);
+      if (meta_kms_update_get_device (update) == device)
+        {
+          kms->pending_updates = g_list_delete_link (kms->pending_updates, l);
+          return update;
+        }
+    }
 
-  return new_feedback;
+  return NULL;
 }
 
 static gpointer
-meta_kms_process_updates_in_impl (MetaKmsImpl  *impl,
-                                  gpointer      user_data,
-                                  GError      **error)
+meta_kms_process_update_in_impl (MetaKmsImpl  *impl,
+                                 gpointer      user_data,
+                                 GError      **error)
 {
-  GList *updates = user_data;
-  MetaKmsFeedback *feedback = NULL;
-  GList *l;
+  MetaKmsFeedback *feedback;
+  MetaKmsUpdate *update = user_data;
 
-  for (l = updates; l; l = l->next)
-    {
-      MetaKmsUpdate *update = l->data;
-      MetaKmsFeedback *device_feedback;
-
-      device_feedback = meta_kms_impl_process_update (impl, update);
-      feedback = combine_feedbacks (feedback, device_feedback);
-      meta_kms_predict_states_in_impl (meta_kms_impl_get_kms (impl), update);
-    }
-
-  g_list_free_full (updates, (GDestroyNotify) meta_kms_update_free);
+  feedback = meta_kms_impl_process_update (impl, update);
+  meta_kms_device_predict_states_in_impl (meta_kms_update_get_device (update),
+                                          update);
 
   return feedback;
 }
 
-static MetaKmsFeedback *
-meta_kms_post_updates_sync (MetaKms *kms,
-                            GList   *updates)
+MetaKmsFeedback *
+meta_kms_post_pending_update_sync (MetaKms       *kms,
+                                   MetaKmsDevice *device)
 {
-  g_list_foreach (updates, (GFunc) meta_kms_update_seal, NULL);
+  MetaKmsUpdate *update;
+  MetaKmsFeedback *feedback;
 
   COGL_TRACE_BEGIN_SCOPED (MetaKmsPostUpdateSync,
                            "KMS (post update)");
 
-  return meta_kms_run_impl_task_sync (kms,
-                                      meta_kms_process_updates_in_impl,
-                                      updates,
-                                      NULL);
-}
+  update = meta_kms_take_pending_update (kms, device);
+  if (!update)
+    return NULL;
 
-MetaKmsFeedback *
-meta_kms_post_pending_updates_sync (MetaKms *kms)
-{
-  return meta_kms_post_updates_sync (kms,
-                                     g_steal_pointer (&kms->pending_updates));
+  meta_kms_update_seal (update);
+
+  feedback = meta_kms_run_impl_task_sync (kms,
+                                          meta_kms_process_update_in_impl,
+                                          update,
+                                          NULL);
+
+  meta_kms_update_free (update);
+
+  return feedback;
 }
 
 static gpointer
@@ -584,6 +554,12 @@ meta_kms_get_backend (MetaKms *kms)
   return kms->backend;
 }
 
+GList *
+meta_kms_get_devices (MetaKms *kms)
+{
+  return kms->devices;
+}
+
 MetaKmsDevice *
 meta_kms_create_device (MetaKms            *kms,
                         const char         *path,
diff --git a/src/backends/native/meta-kms.h b/src/backends/native/meta-kms.h
index 237ecbce90..97876d3709 100644
--- a/src/backends/native/meta-kms.h
+++ b/src/backends/native/meta-kms.h
@@ -34,12 +34,15 @@ MetaKmsUpdate * meta_kms_ensure_pending_update (MetaKms       *kms,
 MetaKmsUpdate * meta_kms_get_pending_update (MetaKms       *kms,
                                              MetaKmsDevice *device);
 
-MetaKmsFeedback * meta_kms_post_pending_updates_sync (MetaKms *kms);
+MetaKmsFeedback * meta_kms_post_pending_update_sync (MetaKms       *kms,
+                                                     MetaKmsDevice *device);
 
 void meta_kms_discard_pending_page_flips (MetaKms *kms);
 
 MetaBackend * meta_kms_get_backend (MetaKms *kms);
 
+GList * meta_kms_get_devices (MetaKms *kms);
+
 MetaKmsDevice * meta_kms_create_device (MetaKms            *kms,
                                         const char         *path,
                                         MetaKmsDeviceFlag   flags,
diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c
index d6a40688af..16e3423ded 100644
--- a/src/backends/native/meta-monitor-manager-kms.c
+++ b/src/backends/native/meta-monitor-manager-kms.c
@@ -122,7 +122,6 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager,
   MetaKms *kms = meta_backend_native_get_kms (backend_native);
   uint64_t state;
   GList *l;
-  g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
 
   switch (mode) {
   case META_POWER_SAVE_ON:
@@ -146,16 +145,18 @@ meta_monitor_manager_kms_set_power_save_mode (MetaMonitorManager *manager,
       MetaGpuKms *gpu_kms = l->data;
       MetaKmsDevice *kms_device = meta_gpu_kms_get_kms_device (gpu_kms);
       MetaKmsUpdate *kms_update;
+      g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
 
       kms_update = meta_kms_ensure_pending_update (kms, kms_device);
       meta_gpu_kms_set_power_save_mode (gpu_kms, state, kms_update);
-    }
 
-  kms_feedback = meta_kms_post_pending_updates_sync (kms);
-  if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED)
-    {
-      g_warning ("Failed to set DPMS: %s",
-                 meta_kms_feedback_get_error (kms_feedback)->message);
+      kms_feedback = meta_kms_post_pending_update_sync (kms, kms_device);
+      if (meta_kms_feedback_get_result (kms_feedback) !=
+          META_KMS_FEEDBACK_PASSED)
+        {
+          g_warning ("Failed to set DPMS: %s",
+                     meta_kms_feedback_get_error (kms_feedback)->message);
+        }
     }
 }
 
@@ -433,7 +434,7 @@ meta_monitor_manager_kms_set_crtc_gamma (MetaMonitorManager *manager,
   g_debug ("Setting CRTC (%" G_GUINT64_FORMAT ") gamma to %s",
            meta_crtc_get_id (crtc), gamma_ramp_string);
 
-  kms_feedback = meta_kms_post_pending_updates_sync (kms);
+  kms_feedback = meta_kms_post_pending_update_sync (kms, kms_device);
   if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED)
     {
       g_warning ("Failed to set CRTC gamma: %s",
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index c32cea3d37..d49076303f 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -1867,24 +1867,24 @@ ensure_crtc_modes (CoglOnscreen *onscreen)
     }
 }
 
-static gboolean
+static void
 unset_disabled_crtcs (MetaBackend *backend,
                       MetaKms     *kms)
 {
-  gboolean did_mode_set = FALSE;
   GList *l;
 
   for (l = meta_backend_get_gpus (backend); l; l = l->next)
     {
       MetaGpu *gpu = l->data;
+      MetaKmsDevice *kms_device =
+        meta_gpu_kms_get_kms_device (META_GPU_KMS (gpu));
       GList *k;
+      gboolean did_mode_set = FALSE;
+      g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
 
       for (k = meta_gpu_get_crtcs (gpu); k; k = k->next)
         {
           MetaCrtc *crtc = k->data;
-          MetaKmsCrtc *kms_crtc =
-            meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc));
-          MetaKmsDevice *kms_device = meta_kms_crtc_get_device (kms_crtc);
           MetaKmsUpdate *kms_update;
 
           if (meta_crtc_get_config (crtc))
@@ -1895,23 +1895,20 @@ unset_disabled_crtcs (MetaBackend *backend,
 
           did_mode_set = TRUE;
         }
-    }
 
-  return did_mode_set;
-}
-
-static void
-post_pending_updates (MetaKms *kms)
-{
-  g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
+      if (!did_mode_set)
+        continue;
 
-  kms_feedback = meta_kms_post_pending_updates_sync (kms);
-  if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED)
-    {
-      const GError *error = meta_kms_feedback_get_error (kms_feedback);
+      kms_feedback = meta_kms_post_pending_update_sync (kms, kms_device);
+      if (meta_kms_feedback_get_result (kms_feedback) !=
+          META_KMS_FEEDBACK_PASSED)
+        {
+          const GError *error = meta_kms_feedback_get_error (kms_feedback);
 
-      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED))
-        g_warning ("Failed to post KMS update: %s", error->message);
+          if (!g_error_matches (error, G_IO_ERROR,
+                                G_IO_ERROR_PERMISSION_DENIED))
+            g_warning ("Failed to post KMS update: %s", error->message);
+        }
     }
 }
 
@@ -1942,6 +1939,8 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen  *onscreen,
   MetaPowerSave power_save_mode;
   g_autoptr (GError) error = NULL;
   MetaDrmBufferGbm *buffer_gbm;
+  MetaKmsCrtc *kms_crtc;
+  MetaKmsDevice *kms_device;
   g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
 
   COGL_TRACE_BEGIN_SCOPED (MetaRendererNativeSwapBuffers,
@@ -2008,7 +2007,22 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen  *onscreen,
 
   COGL_TRACE_BEGIN (MetaRendererNativePostKmsUpdate,
                     "Onscreen (post pending update)");
-  post_pending_updates (kms);
+  kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (onscreen_native->crtc));
+  kms_device = meta_kms_crtc_get_device (kms_crtc);
+  kms_feedback = meta_kms_post_pending_update_sync (kms, kms_device);
+  if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED)
+    {
+      const GError *error = meta_kms_feedback_get_error (kms_feedback);
+      MetaGpuKms *gpu_kms =
+        META_GPU_KMS (meta_crtc_get_gpu (onscreen_native->crtc));
+      int64_t now_ns;
+
+      if (!g_error_matches (error, G_IO_ERROR, G_IO_ERROR_PERMISSION_DENIED))
+        g_warning ("Failed to post KMS update: %s", error->message);
+
+      now_ns = meta_gpu_kms_get_current_time_ns (gpu_kms);
+      notify_view_crtc_presented (onscreen_native->view, kms_crtc, now_ns);
+    }
   COGL_TRACE_END (MetaRendererNativePostKmsUpdate);
 }
 
@@ -2157,6 +2171,8 @@ meta_onscreen_native_direct_scanout (CoglOnscreen   *onscreen,
   MetaMonitorManager *monitor_manager =
     meta_backend_get_monitor_manager (backend);
   MetaPowerSave power_save_mode;
+  MetaKmsCrtc *kms_crtc;
+  MetaKmsDevice *kms_device;
   g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
 
   power_save_mode = meta_monitor_manager_get_power_save_mode (monitor_manager);
@@ -2179,7 +2195,9 @@ meta_onscreen_native_direct_scanout (CoglOnscreen   *onscreen,
   meta_onscreen_native_flip_crtcs (onscreen,
                                    META_KMS_PAGE_FLIP_FLAG_NO_DISCARD_FEEDBACK);
 
-  kms_feedback = meta_kms_post_pending_updates_sync (kms);
+  kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (onscreen_native->crtc));
+  kms_device = meta_kms_crtc_get_device (kms_crtc);
+  kms_feedback = meta_kms_post_pending_update_sync (kms, kms_device);
   if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED)
     {
       const GError *feedback_error = meta_kms_feedback_get_error (kms_feedback);
@@ -3010,16 +3028,12 @@ meta_renderer_native_finish_frame (MetaRendererNative *renderer_native)
   MetaBackend *backend = meta_renderer_get_backend (renderer);
   MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
   MetaKms *kms = meta_backend_native_get_kms (backend_native);
-  gboolean did_mode_set = FALSE;
 
   if (renderer_native->pending_unset_disabled_crtcs)
     {
-      did_mode_set = unset_disabled_crtcs (backend, kms);
+      unset_disabled_crtcs (backend, kms);
       renderer_native->pending_unset_disabled_crtcs = FALSE;
     }
-
-  if (did_mode_set)
-    post_pending_updates (kms);
 }
 
 static gboolean
@@ -3603,8 +3617,7 @@ meta_renderer_native_reset_modes (MetaRendererNative *renderer_native)
   MetaBackendNative *backend_native = META_BACKEND_NATIVE (backend);
   MetaKms *kms = meta_backend_native_get_kms (backend_native);
 
-  if (unset_disabled_crtcs (backend, kms))
-    post_pending_updates (kms);
+  unset_disabled_crtcs (backend, kms);
 }
 
 static MetaGpuKms *


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