[mutter] kms/update: Make explicit page flip just listeners



commit 5c7e2bfe221ef498969c0c23806d5aea559596b8
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Fri Oct 2 16:06:35 2020 +0200

    kms/update: Make explicit page flip just listeners
    
    Page flipping shouldn't necessarily be an actively requested action, but
    happen implicitly depending on the given state. Thus, change the "page
    flip" update into adding listeners for page flip feedback instead.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>

 src/backends/native/meta-kms-impl-device-simple.c | 116 ++++++++++++++++++----
 src/backends/native/meta-kms-page-flip-private.h  |  12 ++-
 src/backends/native/meta-kms-page-flip.c          |  78 +++++++++++----
 src/backends/native/meta-kms-types.h              |   2 +-
 src/backends/native/meta-kms-update-private.h     |   8 +-
 src/backends/native/meta-kms-update.c             |  28 +++---
 src/backends/native/meta-kms-update.h             |  10 +-
 src/backends/native/meta-renderer-native.c        |  11 +-
 8 files changed, 195 insertions(+), 70 deletions(-)
---
diff --git a/src/backends/native/meta-kms-impl-device-simple.c 
b/src/backends/native/meta-kms-impl-device-simple.c
index 0e386c479b..7a7b33a4ab 100644
--- a/src/backends/native/meta-kms-impl-device-simple.c
+++ b/src/backends/native/meta-kms-impl-device-simple.c
@@ -633,7 +633,6 @@ mode_set_fallback_feedback_idle (gpointer user_data)
 static gboolean
 mode_set_fallback (MetaKmsImplDeviceSimple  *impl_device_simple,
                    MetaKmsUpdate            *update,
-                   MetaKmsPageFlip          *page_flip,
                    MetaKmsPlaneAssignment   *plane_assignment,
                    MetaKmsPageFlipData      *page_flip_data,
                    GError                  **error)
@@ -641,7 +640,7 @@ mode_set_fallback (MetaKmsImplDeviceSimple  *impl_device_simple,
   MetaKmsImplDevice *impl_device = META_KMS_IMPL_DEVICE (impl_device_simple);
   MetaKmsDevice *device = meta_kms_impl_device_get_device (impl_device);
   MetaKms *kms = meta_kms_device_get_kms (device);
-  MetaKmsCrtc *crtc = page_flip->crtc;
+  MetaKmsCrtc *crtc = meta_kms_page_flip_data_get_crtc (page_flip_data);
   CachedModeSet *cached_mode_set;
   g_autofree uint32_t *connectors = NULL;
   int n_connectors;
@@ -704,31 +703,24 @@ mode_set_fallback (MetaKmsImplDeviceSimple  *impl_device_simple,
 }
 
 static gboolean
-process_page_flip (MetaKmsImplDevice  *impl_device,
-                   MetaKmsUpdate      *update,
-                   gpointer            update_entry,
-                   GError            **error)
+dispatch_page_flip (MetaKmsImplDevice    *impl_device,
+                    MetaKmsUpdate        *update,
+                    MetaKmsPageFlipData  *page_flip_data,
+                    GError              **error)
 {
   MetaKmsImplDeviceSimple *impl_device_simple =
     META_KMS_IMPL_DEVICE_SIMPLE (impl_device);
-  MetaKmsPageFlip *page_flip = update_entry;
   MetaKmsCrtc *crtc;
   MetaKmsPlaneAssignment *plane_assignment;
-  MetaKmsPageFlipData *page_flip_data;
   MetaKmsCustomPageFlipFunc custom_page_flip_func;
   gpointer custom_page_flip_user_data;
   int fd;
   int ret;
 
-  crtc = page_flip->crtc;
+  crtc = meta_kms_page_flip_data_get_crtc (page_flip_data);
   plane_assignment = meta_kms_update_get_primary_plane_assignment (update,
                                                                    crtc);
 
-  page_flip_data = meta_kms_page_flip_data_new (impl_device,
-                                                crtc,
-                                                page_flip->feedback,
-                                                page_flip->user_data);
-
   fd = meta_kms_impl_device_get_fd (impl_device);
   meta_kms_update_get_custom_page_flip_func (update,
                                              &custom_page_flip_func,
@@ -791,7 +783,6 @@ process_page_flip (MetaKmsImplDevice  *impl_device,
     {
       if (!mode_set_fallback (impl_device_simple,
                               update,
-                              page_flip,
                               plane_assignment,
                               page_flip_data,
                               error))
@@ -814,6 +805,95 @@ process_page_flip (MetaKmsImplDevice  *impl_device,
   return TRUE;
 }
 
+static GList *
+generate_page_flip_datas (MetaKmsImplDevice  *impl_device,
+                          MetaKmsUpdate      *update)
+{
+  GList *listeners;
+  GList *page_flip_datas = NULL;
+
+  listeners = g_list_copy (meta_kms_update_get_page_flip_listeners (update));
+
+  while (listeners)
+    {
+      MetaKmsPageFlipListener *listener = listeners->data;
+      MetaKmsCrtc *crtc = listener->crtc;
+      MetaKmsPageFlipData *page_flip_data;
+      GList *l;
+
+      page_flip_data = meta_kms_page_flip_data_new (impl_device, crtc);
+      page_flip_datas = g_list_append (page_flip_datas, page_flip_data);
+
+      meta_kms_page_flip_data_add_listener (page_flip_data,
+                                            listener->vtable,
+                                            listener->user_data);
+
+      listeners = g_list_delete_link (listeners, listeners);
+
+      l = listeners;
+      while (l)
+        {
+          MetaKmsPageFlipListener *other_listener = l->data;
+          GList *l_next = l->next;
+
+          if (other_listener->crtc == crtc)
+            {
+              meta_kms_page_flip_data_add_listener (page_flip_data,
+                                                    other_listener->vtable,
+                                                    other_listener->user_data);
+              listeners = g_list_delete_link (listeners, l);
+            }
+
+          l = l_next;
+        }
+    }
+
+  return page_flip_datas;
+}
+
+static gboolean
+maybe_dispatch_page_flips (MetaKmsImplDevice  *impl_device,
+                           MetaKmsUpdate      *update,
+                           GList             **failed_planes,
+                           GError            **error)
+{
+  g_autoptr (GList) page_flip_datas = NULL;
+  GList *l;
+
+  page_flip_datas = generate_page_flip_datas (impl_device, update);
+
+  for (l = page_flip_datas; l; l = l->next)
+    {
+      MetaKmsPageFlipData *page_flip_data = l->data;
+
+      if (!dispatch_page_flip (impl_device, update, page_flip_data, error))
+        {
+          if (!g_error_matches (*error,
+                                G_IO_ERROR,
+                                G_IO_ERROR_PERMISSION_DENIED))
+            {
+              MetaKmsCrtc *crtc =
+                meta_kms_page_flip_data_get_crtc (page_flip_data);
+              MetaKmsPlaneAssignment *plane_assignment;
+              MetaKmsPlaneFeedback *plane_feedback;
+
+              plane_assignment =
+                meta_kms_update_get_primary_plane_assignment (update, crtc);
+
+              plane_feedback =
+                meta_kms_plane_feedback_new_take_error (plane_assignment->plane,
+                                                        plane_assignment->crtc,
+                                                        g_error_copy (*error));
+              *failed_planes = g_list_prepend (*failed_planes, plane_feedback);
+            }
+
+          return FALSE;
+        }
+    }
+
+  return TRUE;
+}
+
 static gboolean
 process_entries (MetaKmsImplDevice  *impl_device,
                  MetaKmsUpdate      *update,
@@ -1023,11 +1103,7 @@ meta_kms_impl_device_simple_process_update (MetaKmsImplDevice *impl_device,
   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))
+  if (!maybe_dispatch_page_flips (impl_device, update, &failed_planes, &error))
     goto err;
 
   return meta_kms_feedback_new_passed (failed_planes);
diff --git a/src/backends/native/meta-kms-page-flip-private.h 
b/src/backends/native/meta-kms-page-flip-private.h
index 2bb6e8b509..50c95ae1c8 100644
--- a/src/backends/native/meta-kms-page-flip-private.h
+++ b/src/backends/native/meta-kms-page-flip-private.h
@@ -28,17 +28,21 @@ typedef struct _MetaKmsPageFlipData MetaKmsPageFlipData;
 
 typedef void (* MetaPageFlipDataFeedbackFunc) (MetaKmsPageFlipData *page_flip_data);
 
-MetaKmsPageFlipData * meta_kms_page_flip_data_new (MetaKmsImplDevice             *impl_device,
-                                                   MetaKmsCrtc                   *crtc,
-                                                   const MetaKmsPageFlipFeedback *feedback,
-                                                   gpointer                       user_data);
+MetaKmsPageFlipData * meta_kms_page_flip_data_new (MetaKmsImplDevice *impl_device,
+                                                   MetaKmsCrtc       *crtc);
 
 MetaKmsPageFlipData * meta_kms_page_flip_data_ref (MetaKmsPageFlipData *page_flip_data);
 
 void meta_kms_page_flip_data_unref (MetaKmsPageFlipData *page_flip_data);
 
+void meta_kms_page_flip_data_add_listener (MetaKmsPageFlipData                 *page_flip_data,
+                                           const MetaKmsPageFlipListenerVtable *vtable,
+                                           gpointer                             user_data);
+
 MetaKmsImplDevice * meta_kms_page_flip_data_get_impl_device (MetaKmsPageFlipData *page_flip_data);
 
+MetaKmsCrtc * meta_kms_page_flip_data_get_crtc (MetaKmsPageFlipData *page_flip_data);
+
 void meta_kms_page_flip_data_set_timings_in_impl (MetaKmsPageFlipData *page_flip_data,
                                                   unsigned int         sequence,
                                                   unsigned int         sec,
diff --git a/src/backends/native/meta-kms-page-flip.c b/src/backends/native/meta-kms-page-flip.c
index 45222892c6..eaf6db51bd 100644
--- a/src/backends/native/meta-kms-page-flip.c
+++ b/src/backends/native/meta-kms-page-flip.c
@@ -25,6 +25,12 @@
 #include "backends/native/meta-kms-private.h"
 #include "backends/native/meta-kms-update.h"
 
+typedef struct _MetaKmsPageFlipClosure
+{
+  const MetaKmsPageFlipListenerVtable *vtable;
+  gpointer user_data;
+} MetaKmsPageFlipClosure;
+
 struct _MetaKmsPageFlipData
 {
   int ref_count;
@@ -32,8 +38,7 @@ struct _MetaKmsPageFlipData
   MetaKmsImplDevice *impl_device;
   MetaKmsCrtc *crtc;
 
-  const MetaKmsPageFlipFeedback *feedback;
-  gpointer user_data;
+  GList *closures;
 
   unsigned int sequence;
   unsigned int sec;
@@ -43,10 +48,8 @@ struct _MetaKmsPageFlipData
 };
 
 MetaKmsPageFlipData *
-meta_kms_page_flip_data_new (MetaKmsImplDevice             *impl_device,
-                             MetaKmsCrtc                   *crtc,
-                             const MetaKmsPageFlipFeedback *feedback,
-                             gpointer                       user_data)
+meta_kms_page_flip_data_new (MetaKmsImplDevice *impl_device,
+                             MetaKmsCrtc       *crtc)
 {
   MetaKmsPageFlipData *page_flip_data;
 
@@ -55,8 +58,6 @@ meta_kms_page_flip_data_new (MetaKmsImplDevice             *impl_device,
     .ref_count = 1,
     .impl_device = impl_device,
     .crtc = crtc,
-    .feedback = feedback,
-    .user_data = user_data,
   };
 
   return page_flip_data;
@@ -77,30 +78,59 @@ meta_kms_page_flip_data_unref (MetaKmsPageFlipData *page_flip_data)
 
   if (page_flip_data->ref_count == 0)
     {
+      g_list_free_full (page_flip_data->closures, g_free);
       g_clear_error (&page_flip_data->error);
       g_free (page_flip_data);
     }
 }
 
+void
+meta_kms_page_flip_data_add_listener (MetaKmsPageFlipData                 *page_flip_data,
+                                      const MetaKmsPageFlipListenerVtable *vtable,
+                                      gpointer                             user_data)
+{
+  MetaKmsPageFlipClosure *closure;
+
+  closure = g_new0 (MetaKmsPageFlipClosure, 1);
+  *closure = (MetaKmsPageFlipClosure) {
+    .vtable = vtable,
+    .user_data = user_data,
+  };
+
+  page_flip_data->closures = g_list_append (page_flip_data->closures, closure);
+}
+
 MetaKmsImplDevice *
 meta_kms_page_flip_data_get_impl_device (MetaKmsPageFlipData *page_flip_data)
 {
   return page_flip_data->impl_device;
 }
 
+MetaKmsCrtc *
+meta_kms_page_flip_data_get_crtc (MetaKmsPageFlipData *page_flip_data)
+{
+  return page_flip_data->crtc;
+}
+
 static void
 meta_kms_page_flip_data_flipped (MetaKms  *kms,
                                  gpointer  user_data)
 {
   MetaKmsPageFlipData *page_flip_data = user_data;
+  GList *l;
 
   meta_assert_not_in_kms_impl (kms);
 
-  page_flip_data->feedback->flipped (page_flip_data->crtc,
-                                     page_flip_data->sequence,
-                                     page_flip_data->sec,
-                                     page_flip_data->usec,
-                                     page_flip_data->user_data);
+  for (l = page_flip_data->closures; l; l = l->next)
+    {
+      MetaKmsPageFlipClosure *closure = l->data;
+
+      closure->vtable->flipped (page_flip_data->crtc,
+                                page_flip_data->sequence,
+                                page_flip_data->sec,
+                                page_flip_data->usec,
+                                closure->user_data);
+    }
 }
 
 static MetaKms *
@@ -144,11 +174,17 @@ meta_kms_page_flip_data_mode_set_fallback (MetaKms  *kms,
                                            gpointer  user_data)
 {
   MetaKmsPageFlipData *page_flip_data = user_data;
+  GList *l;
 
   meta_assert_not_in_kms_impl (kms);
 
-  page_flip_data->feedback->mode_set_fallback (page_flip_data->crtc,
-                                               page_flip_data->user_data);
+  for (l = page_flip_data->closures; l; l = l->next)
+    {
+      MetaKmsPageFlipClosure *closure = l->data;
+
+      closure->vtable->mode_set_fallback (page_flip_data->crtc,
+                                          closure->user_data);
+    }
 }
 
 void
@@ -169,12 +205,18 @@ meta_kms_page_flip_data_discard (MetaKms  *kms,
                                  gpointer  user_data)
 {
   MetaKmsPageFlipData *page_flip_data = user_data;
+  GList *l;
 
   meta_assert_not_in_kms_impl (kms);
 
-  page_flip_data->feedback->discarded (page_flip_data->crtc,
-                                       page_flip_data->user_data,
-                                       page_flip_data->error);
+  for (l = page_flip_data->closures; l; l = l->next)
+    {
+      MetaKmsPageFlipClosure *closure = l->data;
+
+      closure->vtable->discarded (page_flip_data->crtc,
+                                  closure->user_data,
+                                  page_flip_data->error);
+    }
 }
 
 void
diff --git a/src/backends/native/meta-kms-types.h b/src/backends/native/meta-kms-types.h
index 4d3950a2bf..7cfd79ad9d 100644
--- a/src/backends/native/meta-kms-types.h
+++ b/src/backends/native/meta-kms-types.h
@@ -37,7 +37,7 @@ typedef struct _MetaKmsMode MetaKmsMode;
 
 typedef struct _MetaKmsFeedback MetaKmsFeedback;
 
-typedef struct _MetaKmsPageFlipFeedback MetaKmsPageFlipFeedback;
+typedef struct _MetaKmsPageFlipListenerVtable MetaKmsPageFlipListenerVtable;
 
 typedef struct _MetaKmsImpl MetaKmsImpl;
 typedef struct _MetaKmsImplDevice MetaKmsImplDevice;
diff --git a/src/backends/native/meta-kms-update-private.h b/src/backends/native/meta-kms-update-private.h
index aa1f28ea58..0cf1e85a43 100644
--- a/src/backends/native/meta-kms-update-private.h
+++ b/src/backends/native/meta-kms-update-private.h
@@ -86,12 +86,12 @@ typedef struct _MetaKmsCrtcGamma
   uint16_t *blue;
 } MetaKmsCrtcGamma;
 
-typedef struct _MetaKmsPageFlip
+typedef struct _MetaKmsPageFlipListener
 {
   MetaKmsCrtc *crtc;
-  const MetaKmsPageFlipFeedback *feedback;
+  const MetaKmsPageFlipListenerVtable *vtable;
   gpointer user_data;
-} MetaKmsPageFlip;
+} MetaKmsPageFlipListener;
 
 void meta_kms_plane_feedback_free (MetaKmsPlaneFeedback *plane_feedback);
 
@@ -120,7 +120,7 @@ GList * meta_kms_update_get_plane_assignments (MetaKmsUpdate *update);
 
 GList * meta_kms_update_get_mode_sets (MetaKmsUpdate *update);
 
-GList * meta_kms_update_get_page_flips (MetaKmsUpdate *update);
+GList * meta_kms_update_get_page_flip_listeners (MetaKmsUpdate *update);
 
 GList * meta_kms_update_get_connector_updates (MetaKmsUpdate *update);
 
diff --git a/src/backends/native/meta-kms-update.c b/src/backends/native/meta-kms-update.c
index 39b99585a7..00d8ec6bda 100644
--- a/src/backends/native/meta-kms-update.c
+++ b/src/backends/native/meta-kms-update.c
@@ -37,12 +37,13 @@ struct _MetaKmsUpdate
   MetaPowerSave power_save;
   GList *mode_sets;
   GList *plane_assignments;
-  GList *page_flips;
   GList *connector_updates;
   GList *crtc_gammas;
 
   MetaKmsCustomPageFlipFunc custom_page_flip_func;
   gpointer custom_page_flip_user_data;
+
+  GList *page_flip_listeners;
 };
 
 void
@@ -326,24 +327,25 @@ meta_kms_update_set_crtc_gamma (MetaKmsUpdate  *update,
 }
 
 void
-meta_kms_update_page_flip (MetaKmsUpdate                 *update,
-                           MetaKmsCrtc                   *crtc,
-                           const MetaKmsPageFlipFeedback *feedback,
-                           gpointer                       user_data)
+meta_kms_update_add_page_flip_listener (MetaKmsUpdate                       *update,
+                                        MetaKmsCrtc                         *crtc,
+                                        const MetaKmsPageFlipListenerVtable *vtable,
+                                        gpointer                             user_data)
 {
-  MetaKmsPageFlip *page_flip;
+  MetaKmsPageFlipListener *listener;
 
   g_assert (!meta_kms_update_is_sealed (update));
   g_assert (meta_kms_crtc_get_device (crtc) == update->device);
 
-  page_flip = g_new0 (MetaKmsPageFlip, 1);
-  *page_flip = (MetaKmsPageFlip) {
+  listener = g_new0 (MetaKmsPageFlipListener, 1);
+  *listener = (MetaKmsPageFlipListener) {
     .crtc = crtc,
-    .feedback = feedback,
+    .vtable = vtable,
     .user_data = user_data,
   };
 
-  update->page_flips = g_list_prepend (update->page_flips, page_flip);
+  update->page_flip_listeners = g_list_prepend (update->page_flip_listeners,
+                                                listener);
 }
 
 void
@@ -407,9 +409,9 @@ meta_kms_update_get_mode_sets (MetaKmsUpdate *update)
 }
 
 GList *
-meta_kms_update_get_page_flips (MetaKmsUpdate *update)
+meta_kms_update_get_page_flip_listeners (MetaKmsUpdate *update)
 {
-  return update->page_flips;
+  return update->page_flip_listeners;
 }
 
 GList *
@@ -469,7 +471,7 @@ meta_kms_update_free (MetaKmsUpdate *update)
                     (GDestroyNotify) meta_kms_plane_assignment_free);
   g_list_free_full (update->mode_sets,
                     (GDestroyNotify) meta_kms_mode_set_free);
-  g_list_free_full (update->page_flips, g_free);
+  g_list_free_full (update->page_flip_listeners, g_free);
   g_list_free_full (update->connector_updates, g_free);
   g_list_free_full (update->crtc_gammas, (GDestroyNotify) meta_kms_crtc_gamma_free);
 
diff --git a/src/backends/native/meta-kms-update.h b/src/backends/native/meta-kms-update.h
index 82a0d96c77..9e69c53346 100644
--- a/src/backends/native/meta-kms-update.h
+++ b/src/backends/native/meta-kms-update.h
@@ -43,7 +43,7 @@ typedef enum _MetaKmsAssignPlaneFlag
   META_KMS_ASSIGN_PLANE_FLAG_ALLOW_FAIL = 1 << 1,
 } MetaKmsAssignPlaneFlag;
 
-struct _MetaKmsPageFlipFeedback
+struct _MetaKmsPageFlipListenerVtable
 {
   void (* flipped) (MetaKmsCrtc  *crtc,
                     unsigned int  sequence,
@@ -117,10 +117,10 @@ MetaKmsPlaneAssignment * meta_kms_update_unassign_plane (MetaKmsUpdate *update,
                                                          MetaKmsCrtc   *crtc,
                                                          MetaKmsPlane  *plane);
 
-void meta_kms_update_page_flip (MetaKmsUpdate                 *update,
-                                MetaKmsCrtc                   *crtc,
-                                const MetaKmsPageFlipFeedback *feedback,
-                                gpointer                       user_data);
+void meta_kms_update_add_page_flip_listener (MetaKmsUpdate                       *update,
+                                             MetaKmsCrtc                         *crtc,
+                                             const MetaKmsPageFlipListenerVtable *vtable,
+                                             gpointer                             user_data);
 
 void meta_kms_update_set_custom_page_flip (MetaKmsUpdate             *update,
                                            MetaKmsCustomPageFlipFunc  func,
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index 6b6c59f623..2cb3126c83 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -1160,7 +1160,7 @@ page_flip_feedback_discarded (MetaKmsCrtc  *kms_crtc,
   g_object_unref (view);
 }
 
-static const MetaKmsPageFlipFeedback page_flip_feedback = {
+static const MetaKmsPageFlipListenerVtable page_flip_listener_vtable = {
   .flipped = page_flip_feedback_flipped,
   .mode_set_fallback = page_flip_feedback_mode_set_fallback,
   .discarded = page_flip_feedback_discarded,
@@ -1259,6 +1259,7 @@ meta_onscreen_native_flip_crtc (CoglOnscreen     *onscreen,
   MetaRendererNative *renderer_native = onscreen_native->renderer_native;
   MetaGpuKms *render_gpu = onscreen_native->render_gpu;
   MetaCrtcKms *crtc_kms = META_CRTC_KMS (crtc);
+  MetaKmsCrtc *kms_crtc = meta_crtc_kms_get_kms_crtc (crtc_kms);
   MetaRendererNativeGpuData *renderer_gpu_data;
   MetaGpuKms *gpu_kms;
   MetaKmsDevice *kms_device;
@@ -1301,10 +1302,10 @@ meta_onscreen_native_flip_crtc (CoglOnscreen     *onscreen,
 #endif
     }
 
-  meta_kms_update_page_flip (kms_update,
-                             meta_crtc_kms_get_kms_crtc (crtc_kms),
-                             &page_flip_feedback,
-                             g_object_ref (view));
+  meta_kms_update_add_page_flip_listener (kms_update,
+                                          kms_crtc,
+                                          &page_flip_listener_vtable,
+                                          g_object_ref (view));
 }
 
 static void


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