[mutter] kms: Add way to preserve failed update



commit 3bad37482d1125499126fe4818cecb6147a0f691
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Fri Oct 2 16:48:34 2020 +0200

    kms: Add way to preserve failed update
    
    When we e.g. try to post an direct client buffer scanout update, it
    might arbitrarily fail; when this happen we still will want to post the
    rest of the update when we try again after having composited the primary
    plane. To do this, add a way to preserve the metadata of an update if it
    failed, only dropping the failed plane assignments. This involves
    unlocking a previously locked MetaKmsUpdate, so that e.g. a new primary
    plane can be assigned.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>

 src/backends/native/meta-cursor-renderer-native.c |  6 +++-
 src/backends/native/meta-kms-update-private.h     |  5 +++
 src/backends/native/meta-kms-update.c             | 26 ++++++++++++++++
 src/backends/native/meta-kms.c                    | 37 ++++++++++++++++++++---
 src/backends/native/meta-kms.h                    | 11 +++++--
 src/backends/native/meta-monitor-manager-kms.c    | 10 ++++--
 src/backends/native/meta-renderer-native.c        | 16 ++++++++--
 7 files changed, 98 insertions(+), 13 deletions(-)
---
diff --git a/src/backends/native/meta-cursor-renderer-native.c 
b/src/backends/native/meta-cursor-renderer-native.c
index 43f974f473..781d719b8e 100644
--- a/src/backends/native/meta-cursor-renderer-native.c
+++ b/src/backends/native/meta-cursor-renderer-native.c
@@ -1079,9 +1079,13 @@ meta_cursor_renderer_native_update_cursor (MetaCursorRenderer *renderer,
       for (l = meta_kms_get_devices (kms); l; l = l->next)
         {
           MetaKmsDevice *kms_device = l->data;
+          MetaKmsUpdateFlag flags;
           g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
 
-          kms_feedback = meta_kms_post_pending_update_sync (kms, kms_device);
+          flags = META_KMS_UPDATE_FLAG_NONE;
+          kms_feedback = meta_kms_post_pending_update_sync (kms,
+                                                            kms_device,
+                                                            flags);
           on_kms_update_result (kms_feedback, renderer);
         }
     }
diff --git a/src/backends/native/meta-kms-update-private.h b/src/backends/native/meta-kms-update-private.h
index 8f4f780cb6..2a16758362 100644
--- a/src/backends/native/meta-kms-update-private.h
+++ b/src/backends/native/meta-kms-update-private.h
@@ -112,6 +112,8 @@ MetaKmsFeedback * meta_kms_feedback_new_failed (GList  *failed_planes,
 
 void meta_kms_update_lock (MetaKmsUpdate *update);
 
+void meta_kms_update_unlock (MetaKmsUpdate *update);
+
 gboolean meta_kms_update_is_locked (MetaKmsUpdate *update);
 
 MetaKmsDevice * meta_kms_update_get_device (MetaKmsUpdate *update);
@@ -136,6 +138,9 @@ void meta_kms_update_get_custom_page_flip_func (MetaKmsUpdate             *updat
                                                 MetaKmsCustomPageFlipFunc *custom_page_flip_func,
                                                 gpointer                  *custom_page_flip_user_data);
 
+void meta_kms_update_drop_plane_assignment (MetaKmsUpdate *update,
+                                            MetaKmsPlane  *plane);
+
 GList * meta_kms_update_take_result_listeners (MetaKmsUpdate *update);
 
 void meta_kms_result_listener_notify (MetaKmsResultListener *listener,
diff --git a/src/backends/native/meta-kms-update.c b/src/backends/native/meta-kms-update.c
index 5815bc6663..197ebc3bd3 100644
--- a/src/backends/native/meta-kms-update.c
+++ b/src/backends/native/meta-kms-update.c
@@ -141,6 +141,26 @@ meta_kms_mode_set_free (MetaKmsModeSet *mode_set)
   g_free (mode_set);
 }
 
+void
+meta_kms_update_drop_plane_assignment (MetaKmsUpdate *update,
+                                       MetaKmsPlane  *plane)
+{
+  GList *l;
+
+  for (l = update->plane_assignments; l; l = l->next)
+    {
+      MetaKmsPlaneAssignment *plane_assignment = l->data;
+
+      if (plane_assignment->plane == plane)
+        {
+          update->plane_assignments =
+            g_list_delete_link (update->plane_assignments, l);
+          meta_kms_plane_assignment_free (plane_assignment);
+          return;
+        }
+    }
+}
+
 MetaKmsPlaneAssignment *
 meta_kms_update_assign_plane (MetaKmsUpdate          *update,
                               MetaKmsCrtc            *crtc,
@@ -469,6 +489,12 @@ meta_kms_update_lock (MetaKmsUpdate *update)
   update->is_locked = TRUE;
 }
 
+void
+meta_kms_update_unlock (MetaKmsUpdate *update)
+{
+  update->is_locked = FALSE;
+}
+
 gboolean
 meta_kms_update_is_locked (MetaKmsUpdate *update)
 {
diff --git a/src/backends/native/meta-kms.c b/src/backends/native/meta-kms.c
index 18b45506ed..15fc6f2ef2 100644
--- a/src/backends/native/meta-kms.c
+++ b/src/backends/native/meta-kms.c
@@ -177,6 +177,13 @@ struct _MetaKms
 
 G_DEFINE_TYPE (MetaKms, meta_kms, G_TYPE_OBJECT)
 
+static void
+meta_kms_add_pending_update (MetaKms       *kms,
+                             MetaKmsUpdate *update)
+{
+  kms->pending_updates = g_list_prepend (kms->pending_updates, update);
+}
+
 MetaKmsUpdate *
 meta_kms_ensure_pending_update (MetaKms       *kms,
                                 MetaKmsDevice *device)
@@ -188,7 +195,7 @@ meta_kms_ensure_pending_update (MetaKms       *kms,
     return update;
 
   update = meta_kms_update_new (device);
-  kms->pending_updates = g_list_prepend (kms->pending_updates, update);
+  meta_kms_add_pending_update (kms, update);
 
   return update;
 }
@@ -246,8 +253,9 @@ meta_kms_process_update_in_impl (MetaKmsImpl  *impl,
 }
 
 MetaKmsFeedback *
-meta_kms_post_pending_update_sync (MetaKms       *kms,
-                                   MetaKmsDevice *device)
+meta_kms_post_pending_update_sync (MetaKms           *kms,
+                                   MetaKmsDevice     *device,
+                                   MetaKmsUpdateFlag  flags)
 {
   MetaKmsUpdate *update;
   MetaKmsFeedback *feedback;
@@ -270,6 +278,27 @@ meta_kms_post_pending_update_sync (MetaKms       *kms,
 
   result_listeners = meta_kms_update_take_result_listeners (update);
 
+  if (feedback->error &&
+      flags & META_KMS_UPDATE_FLAG_PRESERVE_ON_ERROR)
+    {
+      GList *l;
+
+      meta_kms_update_unlock (update);
+
+      for (l = feedback->failed_planes; l; l = l->next)
+        {
+          MetaKmsPlane *plane = l->data;
+
+          meta_kms_update_drop_plane_assignment (update, plane);
+        }
+
+      meta_kms_add_pending_update (kms, update);
+    }
+  else
+    {
+      meta_kms_update_free (update);
+    }
+
   for (l = result_listeners; l; l = l->next)
     {
       MetaKmsResultListener *listener = l->data;
@@ -279,8 +308,6 @@ meta_kms_post_pending_update_sync (MetaKms       *kms,
     }
   g_list_free (result_listeners);
 
-  meta_kms_update_free (update);
-
   return feedback;
 }
 
diff --git a/src/backends/native/meta-kms.h b/src/backends/native/meta-kms.h
index 97876d3709..792279e84a 100644
--- a/src/backends/native/meta-kms.h
+++ b/src/backends/native/meta-kms.h
@@ -25,6 +25,12 @@
 #include "backends/meta-backend-private.h"
 #include "backends/native/meta-kms-types.h"
 
+typedef enum _MetaKmsUpdateFlag
+{
+  META_KMS_UPDATE_FLAG_NONE = 0,
+  META_KMS_UPDATE_FLAG_PRESERVE_ON_ERROR = 1 << 0,
+} MetaKmsUpdateFlag;
+
 #define META_TYPE_KMS (meta_kms_get_type ())
 G_DECLARE_FINAL_TYPE (MetaKms, meta_kms, META, KMS, GObject)
 
@@ -34,8 +40,9 @@ MetaKmsUpdate * meta_kms_ensure_pending_update (MetaKms       *kms,
 MetaKmsUpdate * meta_kms_get_pending_update (MetaKms       *kms,
                                              MetaKmsDevice *device);
 
-MetaKmsFeedback * meta_kms_post_pending_update_sync (MetaKms       *kms,
-                                                     MetaKmsDevice *device);
+MetaKmsFeedback * meta_kms_post_pending_update_sync (MetaKms           *kms,
+                                                     MetaKmsDevice     *device,
+                                                     MetaKmsUpdateFlag  flags);
 
 void meta_kms_discard_pending_page_flips (MetaKms *kms);
 
diff --git a/src/backends/native/meta-monitor-manager-kms.c b/src/backends/native/meta-monitor-manager-kms.c
index 16e3423ded..f3881862f1 100644
--- a/src/backends/native/meta-monitor-manager-kms.c
+++ b/src/backends/native/meta-monitor-manager-kms.c
@@ -145,12 +145,16 @@ 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;
+      MetaKmsUpdateFlag flags;
       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_update_sync (kms, kms_device);
+      flags = META_KMS_UPDATE_FLAG_NONE;
+      kms_feedback = meta_kms_post_pending_update_sync (kms,
+                                                        kms_device,
+                                                        flags);
       if (meta_kms_feedback_get_result (kms_feedback) !=
           META_KMS_FEEDBACK_PASSED)
         {
@@ -423,6 +427,7 @@ meta_monitor_manager_kms_set_crtc_gamma (MetaMonitorManager *manager,
   MetaKmsDevice *kms_device;
   MetaKmsUpdate *kms_update;
   g_autofree char *gamma_ramp_string = NULL;
+  MetaKmsUpdateFlag flags;
   g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
 
   kms_crtc = meta_crtc_kms_get_kms_crtc (META_CRTC_KMS (crtc));
@@ -434,7 +439,8 @@ 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_update_sync (kms, kms_device);
+  flags = META_KMS_UPDATE_FLAG_NONE;
+  kms_feedback = meta_kms_post_pending_update_sync (kms, kms_device, flags);
   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 018e9ca53b..c2b98920be 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -1877,6 +1877,7 @@ unset_disabled_crtcs (MetaBackend *backend,
         meta_gpu_kms_get_kms_device (META_GPU_KMS (gpu));
       GList *k;
       gboolean did_mode_set = FALSE;
+      MetaKmsUpdateFlag flags;
       g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
 
       for (k = meta_gpu_get_crtcs (gpu); k; k = k->next)
@@ -1896,7 +1897,10 @@ unset_disabled_crtcs (MetaBackend *backend,
       if (!did_mode_set)
         continue;
 
-      kms_feedback = meta_kms_post_pending_update_sync (kms, kms_device);
+      flags = META_KMS_UPDATE_FLAG_NONE;
+      kms_feedback = meta_kms_post_pending_update_sync (kms,
+                                                        kms_device,
+                                                        flags);
       if (meta_kms_feedback_get_result (kms_feedback) !=
           META_KMS_FEEDBACK_PASSED)
         {
@@ -1938,6 +1942,7 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen  *onscreen,
   MetaDrmBufferGbm *buffer_gbm;
   MetaKmsCrtc *kms_crtc;
   MetaKmsDevice *kms_device;
+  MetaKmsUpdateFlag flags;
   g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
 
   COGL_TRACE_BEGIN_SCOPED (MetaRendererNativeSwapBuffers,
@@ -2006,7 +2011,9 @@ meta_onscreen_native_swap_buffers_with_damage (CoglOnscreen  *onscreen,
                     "Onscreen (post pending update)");
   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);
+
+  flags = META_KMS_UPDATE_FLAG_NONE;
+  kms_feedback = meta_kms_post_pending_update_sync (kms, kms_device, flags);
   if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED)
     {
       const GError *error = meta_kms_feedback_get_error (kms_feedback);
@@ -2176,6 +2183,7 @@ meta_onscreen_native_direct_scanout (CoglOnscreen   *onscreen,
   MetaPowerSave power_save_mode;
   MetaKmsCrtc *kms_crtc;
   MetaKmsDevice *kms_device;
+  MetaKmsUpdateFlag flags;
   g_autoptr (MetaKmsFeedback) kms_feedback = NULL;
 
   power_save_mode = meta_monitor_manager_get_power_save_mode (monitor_manager);
@@ -2199,7 +2207,9 @@ meta_onscreen_native_direct_scanout (CoglOnscreen   *onscreen,
 
   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);
+
+  flags = META_KMS_UPDATE_FLAG_PRESERVE_ON_ERROR;
+  kms_feedback = meta_kms_post_pending_update_sync (kms, kms_device, flags);
   if (meta_kms_feedback_get_result (kms_feedback) != META_KMS_FEEDBACK_PASSED)
     {
       const GError *feedback_error = meta_kms_feedback_get_error (kms_feedback);


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