[mutter] kms/update: Add way to receive result from later posted update



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

    kms/update: Add way to receive result from later posted update
    
    Something might want to affect the next update that is going to be
    posted, but without posting it immediately. For example, changing the
    cursor might need to wait for mode setting. Make it possible to get
    feedback from posting the update, in order to gracefully handle any
    errors.
    
    Note, the API for notifiying about results take out the result listener
    from the update, and notifies them in an open coded for loop. The reason
    for this is that in the next commit we'll sometimes reuse updates, and
    we only want notify about the results once.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>

 src/backends/native/meta-kms-update-private.h | 13 +++++++++
 src/backends/native/meta-kms-update.c         | 39 +++++++++++++++++++++++++++
 src/backends/native/meta-kms-update.h         |  7 +++++
 src/backends/native/meta-kms.c                | 13 +++++++++
 4 files changed, 72 insertions(+)
---
diff --git a/src/backends/native/meta-kms-update-private.h b/src/backends/native/meta-kms-update-private.h
index 0cf1e85a43..a022e28645 100644
--- a/src/backends/native/meta-kms-update-private.h
+++ b/src/backends/native/meta-kms-update-private.h
@@ -93,6 +93,12 @@ typedef struct _MetaKmsPageFlipListener
   gpointer user_data;
 } MetaKmsPageFlipListener;
 
+typedef struct _MetaKmsResultListener
+{
+  MetaKmsResultListenerFunc func;
+  gpointer user_data;
+} MetaKmsResultListener;
+
 void meta_kms_plane_feedback_free (MetaKmsPlaneFeedback *plane_feedback);
 
 MetaKmsPlaneFeedback * meta_kms_plane_feedback_new_take_error (MetaKmsPlane *plane,
@@ -130,6 +136,13 @@ void meta_kms_update_get_custom_page_flip_func (MetaKmsUpdate             *updat
                                                 MetaKmsCustomPageFlipFunc *custom_page_flip_func,
                                                 gpointer                  *custom_page_flip_user_data);
 
+GList * meta_kms_update_take_result_listeners (MetaKmsUpdate *update);
+
+void meta_kms_result_listener_notify (MetaKmsResultListener *listener,
+                                      const MetaKmsFeedback *feedback);
+
+void meta_kms_result_listener_free (MetaKmsResultListener *listener);
+
 G_DEFINE_AUTOPTR_CLEANUP_FUNC (MetaKmsPlaneFeedback,
                                meta_kms_plane_feedback_free)
 
diff --git a/src/backends/native/meta-kms-update.c b/src/backends/native/meta-kms-update.c
index 00d8ec6bda..06bfc27c8f 100644
--- a/src/backends/native/meta-kms-update.c
+++ b/src/backends/native/meta-kms-update.c
@@ -44,6 +44,7 @@ struct _MetaKmsUpdate
   gpointer custom_page_flip_user_data;
 
   GList *page_flip_listeners;
+  GList *result_listeners;
 };
 
 void
@@ -379,6 +380,42 @@ meta_kms_plane_assignment_set_cursor_hotspot (MetaKmsPlaneAssignment *plane_assi
   plane_assignment->cursor_hotspot.y = y;
 }
 
+void
+meta_kms_update_add_result_listener (MetaKmsUpdate             *update,
+                                     MetaKmsResultListenerFunc  func,
+                                     gpointer                   user_data)
+{
+  MetaKmsResultListener *listener;
+
+  listener = g_new0 (MetaKmsResultListener, 1);
+  *listener = (MetaKmsResultListener) {
+    .func = func,
+    .user_data = user_data,
+  };
+
+  update->result_listeners = g_list_append (update->result_listeners,
+                                            listener);
+}
+
+GList *
+meta_kms_update_take_result_listeners (MetaKmsUpdate *update)
+{
+  return g_steal_pointer (&update->result_listeners);
+}
+
+void
+meta_kms_result_listener_notify (MetaKmsResultListener *listener,
+                                 const MetaKmsFeedback *feedback)
+{
+  listener->func (feedback, listener->user_data);
+}
+
+void
+meta_kms_result_listener_free (MetaKmsResultListener *listener)
+{
+  g_free (listener);
+}
+
 MetaKmsPlaneAssignment *
 meta_kms_update_get_primary_plane_assignment (MetaKmsUpdate *update,
                                               MetaKmsCrtc   *crtc)
@@ -467,6 +504,8 @@ meta_kms_update_new (MetaKmsDevice *device)
 void
 meta_kms_update_free (MetaKmsUpdate *update)
 {
+  g_list_free_full (update->result_listeners,
+                    (GDestroyNotify) meta_kms_result_listener_free);
   g_list_free_full (update->plane_assignments,
                     (GDestroyNotify) meta_kms_plane_assignment_free);
   g_list_free_full (update->mode_sets,
diff --git a/src/backends/native/meta-kms-update.h b/src/backends/native/meta-kms-update.h
index 9e69c53346..aa3cbb11dc 100644
--- a/src/backends/native/meta-kms-update.h
+++ b/src/backends/native/meta-kms-update.h
@@ -69,6 +69,9 @@ typedef struct _MetaKmsPlaneFeedback
   GError *error;
 } MetaKmsPlaneFeedback;
 
+typedef void (* MetaKmsResultListenerFunc) (const MetaKmsFeedback *feedback,
+                                            gpointer               user_data);
+
 void meta_kms_feedback_free (MetaKmsFeedback *feedback);
 
 MetaKmsFeedbackResult meta_kms_feedback_get_result (const MetaKmsFeedback *feedback);
@@ -130,6 +133,10 @@ void meta_kms_plane_assignment_set_cursor_hotspot (MetaKmsPlaneAssignment *plane
                                                    int                     x,
                                                    int                     y);
 
+void meta_kms_update_add_result_listener (MetaKmsUpdate             *update,
+                                          MetaKmsResultListenerFunc  func,
+                                          gpointer                   user_data);
+
 static inline MetaFixed16
 meta_fixed_16_from_int (int16_t d)
 {
diff --git a/src/backends/native/meta-kms.c b/src/backends/native/meta-kms.c
index f4c2b6848b..bcbf4ed7ca 100644
--- a/src/backends/native/meta-kms.c
+++ b/src/backends/native/meta-kms.c
@@ -251,6 +251,8 @@ meta_kms_post_pending_update_sync (MetaKms       *kms,
 {
   MetaKmsUpdate *update;
   MetaKmsFeedback *feedback;
+  GList *result_listeners;
+  GList *l;
 
   COGL_TRACE_BEGIN_SCOPED (MetaKmsPostUpdateSync,
                            "KMS (post update)");
@@ -266,6 +268,17 @@ meta_kms_post_pending_update_sync (MetaKms       *kms,
                                           update,
                                           NULL);
 
+  result_listeners = meta_kms_update_take_result_listeners (update);
+
+  for (l = result_listeners; l; l = l->next)
+    {
+      MetaKmsResultListener *listener = l->data;
+
+      meta_kms_result_listener_notify (listener, feedback);
+      meta_kms_result_listener_free (listener);
+    }
+  g_list_free (result_listeners);
+
   meta_kms_update_free (update);
 
   return feedback;


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