[mutter] kms: Allow update passing with failed plane assignments



commit 411ec5fd18b89317017a75bbaadbf353457aaf6c
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Fri Oct 2 15:45:28 2020 +0200

    kms: Allow update passing with failed plane assignments
    
    This will later make it possible to pass cursor plane assignments,
    together with a complete update including the primary plane, but not
    failing the whole update if just processing the cursor plane failed.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>

 src/backends/native/meta-cursor-renderer-native.c | 28 ++++---
 src/backends/native/meta-kms-impl-device-simple.c | 92 +++++++++--------------
 src/backends/native/meta-kms-update-private.h     |  2 +-
 src/backends/native/meta-kms-update.c             |  6 +-
 src/backends/native/meta-kms-update.h             |  1 +
 5 files changed, 55 insertions(+), 74 deletions(-)
---
diff --git a/src/backends/native/meta-cursor-renderer-native.c 
b/src/backends/native/meta-cursor-renderer-native.c
index 96e032f35d..4dc6f4a70c 100644
--- a/src/backends/native/meta-cursor-renderer-native.c
+++ b/src/backends/native/meta-cursor-renderer-native.c
@@ -306,7 +306,7 @@ set_crtc_cursor (MetaCursorRendererNative *native,
     .height = cursor_height,
   };
 
-  flags = META_KMS_ASSIGN_PLANE_FLAG_NONE;
+  flags = META_KMS_ASSIGN_PLANE_FLAG_ALLOW_FAIL;
   crtc_buffer = meta_crtc_kms_get_cursor_renderer_private (crtc_kms);
   if (!priv->hw_state_invalidated && buffer == crtc_buffer)
     flags |= META_KMS_ASSIGN_PLANE_FLAG_FB_UNCHANGED;
@@ -593,31 +593,29 @@ update_hw_cursor (MetaCursorRendererNative *native,
       MetaKmsDevice *kms_device = l->data;
       MetaKmsUpdate *kms_update;
       g_autoptr (MetaKmsFeedback) feedback = NULL;
+      GList *l_feedback;
 
       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)
+      for (l_feedback = meta_kms_feedback_get_failed_planes (feedback);
+           l_feedback;
+           l_feedback = l_feedback->next)
         {
-          GList *k;
+          MetaKmsPlaneFeedback *plane_feedback = l_feedback->data;
 
-          for (k = meta_kms_feedback_get_failed_planes (feedback); k; k = k->next)
+          if (!g_error_matches (plane_feedback->error,
+                                G_IO_ERROR,
+                                G_IO_ERROR_PERMISSION_DENIED))
             {
-              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);
-                }
+              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-impl-device-simple.c 
b/src/backends/native/meta-kms-impl-device-simple.c
index da2df2d617..0e386c479b 100644
--- a/src/backends/native/meta-kms-impl-device-simple.c
+++ b/src/backends/native/meta-kms-impl-device-simple.c
@@ -950,11 +950,12 @@ process_plane_assignment (MetaKmsImplDevice       *impl_device,
   g_assert_not_reached ();
 }
 
-static GList *
-process_plane_assignments (MetaKmsImplDevice *impl_device,
-                           MetaKmsUpdate     *update)
+static gboolean
+process_plane_assignments (MetaKmsImplDevice  *impl_device,
+                           MetaKmsUpdate      *update,
+                           GList             **failed_planes,
+                           GError            **error)
 {
-  GList *failed_planes = NULL;
   GList *l;
 
   for (l = meta_kms_update_get_plane_assignments (update); l; l = l->next)
@@ -964,46 +965,31 @@ process_plane_assignments (MetaKmsImplDevice *impl_device,
 
       if (!process_plane_assignment (impl_device, update, plane_assignment,
                                      &plane_feedback))
-        failed_planes = g_list_prepend (failed_planes, plane_feedback);
-    }
-
-  return failed_planes;
-}
-
-static GList *
-generate_all_failed_feedbacks (MetaKmsUpdate *update)
-{
-  GList *failed_planes = NULL;
-  GList *l;
-
-  for (l = meta_kms_update_get_plane_assignments (update); l; l = l->next)
-    {
-      MetaKmsPlaneAssignment *plane_assignment = l->data;
-      MetaKmsPlane *plane;
-      MetaKmsPlaneType plane_type;
-      MetaKmsPlaneFeedback *plane_feedback;
-
-      plane = plane_assignment->plane;
-      plane_type = meta_kms_plane_get_plane_type (plane);
-      switch (plane_type)
         {
-        case META_KMS_PLANE_TYPE_PRIMARY:
-          continue;
-        case META_KMS_PLANE_TYPE_CURSOR:
-        case META_KMS_PLANE_TYPE_OVERLAY:
-          break;
-        }
+          if (g_error_matches (plane_feedback->error,
+                               G_IO_ERROR,
+                               G_IO_ERROR_PERMISSION_DENIED))
+            {
+              g_propagate_error (error,
+                                 g_steal_pointer (&plane_feedback->error));
+              meta_kms_plane_feedback_free (plane_feedback);
+              return FALSE;
+            }
 
-      plane_feedback =
-        meta_kms_plane_feedback_new_take_error (plane_assignment->plane,
-                                                plane_assignment->crtc,
-                                                g_error_new (G_IO_ERROR,
-                                                             G_IO_ERROR_FAILED,
-                                                             "Discarded"));
-      failed_planes = g_list_prepend (failed_planes, plane_feedback);
+          *failed_planes = g_list_prepend (*failed_planes, plane_feedback);
+          if (plane_assignment->flags & META_KMS_ASSIGN_PLANE_FLAG_ALLOW_FAIL)
+            {
+              continue;
+            }
+          else
+            {
+              g_propagate_error (error, g_error_copy (plane_feedback->error));
+              return FALSE;
+            }
+        }
     }
 
-  return failed_planes;
+  return TRUE;
 }
 
 static MetaKmsFeedback *
@@ -1011,50 +997,42 @@ meta_kms_impl_device_simple_process_update (MetaKmsImplDevice *impl_device,
                                             MetaKmsUpdate     *update)
 {
   GError *error = NULL;
-  GList *failed_planes;
+  GList *failed_planes = NULL;
 
   if (!process_entries (impl_device,
                         update,
                         meta_kms_update_get_connector_updates (update),
                         process_connector_update,
                         &error))
-    goto err_planes_not_assigned;
+    goto err;
 
   if (!process_entries (impl_device,
                         update,
                         meta_kms_update_get_mode_sets (update),
                         process_mode_set,
                         &error))
-    goto err_planes_not_assigned;
+    goto err;
 
   if (!process_entries (impl_device,
                         update,
                         meta_kms_update_get_crtc_gammas (update),
                         process_crtc_gamma,
                         &error))
-    goto err_planes_not_assigned;
+    goto err;
 
-  failed_planes = process_plane_assignments (impl_device, update);
-  if (failed_planes)
-    {
-      g_set_error (&error, G_IO_ERROR, G_IO_ERROR_FAILED,
-                   "Failed to assign one or more planes");
-      goto err_planes_assigned;
-    }
+  if (!process_plane_assignments (impl_device, update, &failed_planes, &error))
+    goto err;
 
   if (!process_entries (impl_device,
                         update,
                         meta_kms_update_get_page_flips (update),
                         process_page_flip,
                         &error))
-    goto err_planes_assigned;
-
-  return meta_kms_feedback_new_passed ();
+    goto err;
 
-err_planes_not_assigned:
-  failed_planes = generate_all_failed_feedbacks (update);
+  return meta_kms_feedback_new_passed (failed_planes);
 
-err_planes_assigned:
+err:
   return meta_kms_feedback_new_failed (failed_planes, error);
 }
 
diff --git a/src/backends/native/meta-kms-update-private.h b/src/backends/native/meta-kms-update-private.h
index 463aaf0cfd..aa1f28ea58 100644
--- a/src/backends/native/meta-kms-update-private.h
+++ b/src/backends/native/meta-kms-update-private.h
@@ -99,7 +99,7 @@ MetaKmsPlaneFeedback * meta_kms_plane_feedback_new_take_error (MetaKmsPlane *pla
                                                                MetaKmsCrtc  *crtc,
                                                                GError       *error);
 
-MetaKmsFeedback * meta_kms_feedback_new_passed (void);
+MetaKmsFeedback * meta_kms_feedback_new_passed (GList *failed_planes);
 
 MetaKmsFeedback * meta_kms_feedback_new_failed (GList  *failed_planes,
                                                 GError *error);
diff --git a/src/backends/native/meta-kms-update.c b/src/backends/native/meta-kms-update.c
index 527c6ef12f..9ad87ac2e1 100644
--- a/src/backends/native/meta-kms-update.c
+++ b/src/backends/native/meta-kms-update.c
@@ -70,13 +70,14 @@ meta_kms_plane_feedback_new_take_error (MetaKmsPlane *plane,
 }
 
 MetaKmsFeedback *
-meta_kms_feedback_new_passed (void)
+meta_kms_feedback_new_passed (GList *failed_planes)
 {
   MetaKmsFeedback *feedback;
 
   feedback = g_new0 (MetaKmsFeedback, 1);
   *feedback = (MetaKmsFeedback) {
     .result = META_KMS_FEEDBACK_PASSED,
+    .failed_planes = failed_planes,
   };
 
   return feedback;
@@ -152,6 +153,9 @@ meta_kms_update_assign_plane (MetaKmsUpdate          *update,
   g_assert (!meta_kms_update_is_sealed (update));
   g_assert (meta_kms_crtc_get_device (crtc) == update->device);
   g_assert (meta_kms_plane_get_device (plane) == update->device);
+  g_assert (meta_kms_plane_get_plane_type (plane) !=
+            META_KMS_PLANE_TYPE_PRIMARY ||
+            !(flags & META_KMS_ASSIGN_PLANE_FLAG_ALLOW_FAIL));
 
   plane_assignment = g_new0 (MetaKmsPlaneAssignment, 1);
   *plane_assignment = (MetaKmsPlaneAssignment) {
diff --git a/src/backends/native/meta-kms-update.h b/src/backends/native/meta-kms-update.h
index afd82b3a0e..b5123265ea 100644
--- a/src/backends/native/meta-kms-update.h
+++ b/src/backends/native/meta-kms-update.h
@@ -40,6 +40,7 @@ typedef enum _MetaKmsAssignPlaneFlag
 {
   META_KMS_ASSIGN_PLANE_FLAG_NONE = 0,
   META_KMS_ASSIGN_PLANE_FLAG_FB_UNCHANGED = 1 << 0,
+  META_KMS_ASSIGN_PLANE_FLAG_ALLOW_FAIL = 1 << 1,
 } MetaKmsAssignPlaneFlag;
 
 struct _MetaKmsPageFlipFeedback


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