[mutter] kms: Add symbolic page flips and cogl frame infos



commit 487ea0dd95f64ffc12a82fbd15724eda5e4ddb7f
Author: Jonas Ã…dahl <jadahl gmail com>
Date:   Sat Oct 10 00:52:11 2020 +0200

    kms: Add symbolic page flips and cogl frame infos
    
    This makes it possible to post a symbolic page flip and frame callback,
    meant to be used by immediate symbolic page flip reply when emulating
    cursor plane changes using legacy drmMode* functions.
    
    Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>

 clutter/clutter/cogl/clutter-stage-cogl.c         | 22 ++++++++----
 cogl/cogl/cogl-frame-info-private.h               |  8 +++++
 cogl/cogl/cogl-frame-info.c                       | 10 ++++++
 cogl/cogl/cogl-frame-info.h                       |  3 ++
 src/backends/native/meta-kms-impl-device-simple.c | 43 ++++++++++++++++++++++-
 src/backends/native/meta-kms-page-flip-private.h  |  2 ++
 src/backends/native/meta-kms-page-flip.c          | 26 +++++++++++---
 src/backends/native/meta-kms-update.h             |  3 ++
 src/backends/native/meta-renderer-native.c        | 19 ++++++++++
 9 files changed, 123 insertions(+), 13 deletions(-)
---
diff --git a/clutter/clutter/cogl/clutter-stage-cogl.c b/clutter/clutter/cogl/clutter-stage-cogl.c
index 646a0f8e71..90f428ec81 100644
--- a/clutter/clutter/cogl/clutter-stage-cogl.c
+++ b/clutter/clutter/cogl/clutter-stage-cogl.c
@@ -791,18 +791,26 @@ frame_cb (CoglOnscreen  *onscreen,
           void          *user_data)
 {
   ClutterStageView *view = user_data;
-  ClutterFrameInfo clutter_frame_info;
 
   if (frame_event == COGL_FRAME_EVENT_SYNC)
     return;
 
-  clutter_frame_info = (ClutterFrameInfo) {
-    .frame_counter = cogl_frame_info_get_global_frame_counter (frame_info),
-    .refresh_rate = cogl_frame_info_get_refresh_rate (frame_info),
-    .presentation_time = ns2us (cogl_frame_info_get_presentation_time (frame_info)),
-  };
+  if (cogl_frame_info_get_is_symbolic (frame_info))
+    {
+      clutter_stage_view_notify_ready (view);
+    }
+  else
+    {
+      ClutterFrameInfo clutter_frame_info;
 
-  clutter_stage_view_notify_presented (view, &clutter_frame_info);
+      clutter_frame_info = (ClutterFrameInfo) {
+        .frame_counter = cogl_frame_info_get_global_frame_counter (frame_info),
+        .refresh_rate = cogl_frame_info_get_refresh_rate (frame_info),
+        .presentation_time =
+          ns2us (cogl_frame_info_get_presentation_time (frame_info)),
+      };
+      clutter_stage_view_notify_presented (view, &clutter_frame_info);
+    }
 }
 
 static void
diff --git a/cogl/cogl/cogl-frame-info-private.h b/cogl/cogl/cogl-frame-info-private.h
index 13d8561750..1c8fdc5cff 100644
--- a/cogl/cogl/cogl-frame-info-private.h
+++ b/cogl/cogl/cogl-frame-info-private.h
@@ -34,6 +34,12 @@
 #include "cogl-frame-info.h"
 #include "cogl-object-private.h"
 
+typedef enum _CoglFrameInfoFlag
+{
+  COGL_FRAME_INFO_FLAG_NONE = 0,
+  COGL_FRAME_INFO_FLAG_SYMBOLIC = 1 << 0,
+} CoglFrameInfoFlag;
+
 struct _CoglFrameInfo
 {
   CoglObject _parent;
@@ -43,6 +49,8 @@ struct _CoglFrameInfo
   float refresh_rate;
 
   int64_t global_frame_counter;
+
+  CoglFrameInfoFlag flags;
 };
 
 COGL_EXPORT
diff --git a/cogl/cogl/cogl-frame-info.c b/cogl/cogl/cogl-frame-info.c
index b5da21110f..9d3420c029 100644
--- a/cogl/cogl/cogl-frame-info.c
+++ b/cogl/cogl/cogl-frame-info.c
@@ -64,12 +64,16 @@ cogl_frame_info_get_frame_counter (CoglFrameInfo *info)
 int64_t
 cogl_frame_info_get_presentation_time (CoglFrameInfo *info)
 {
+  g_warn_if_fail (!(info->flags & COGL_FRAME_INFO_FLAG_SYMBOLIC));
+
   return info->presentation_time;
 }
 
 float
 cogl_frame_info_get_refresh_rate (CoglFrameInfo *info)
 {
+  g_warn_if_fail (!(info->flags & COGL_FRAME_INFO_FLAG_SYMBOLIC));
+
   return info->refresh_rate;
 }
 
@@ -78,3 +82,9 @@ cogl_frame_info_get_global_frame_counter (CoglFrameInfo *info)
 {
   return info->global_frame_counter;
 }
+
+gboolean
+cogl_frame_info_get_is_symbolic (CoglFrameInfo *info)
+{
+  return !!(info->flags & COGL_FRAME_INFO_FLAG_SYMBOLIC);
+}
diff --git a/cogl/cogl/cogl-frame-info.h b/cogl/cogl/cogl-frame-info.h
index 2204bafdb0..e2f9ff3bdc 100644
--- a/cogl/cogl/cogl-frame-info.h
+++ b/cogl/cogl/cogl-frame-info.h
@@ -137,6 +137,9 @@ float cogl_frame_info_get_refresh_rate (CoglFrameInfo *info);
 COGL_EXPORT
 int64_t cogl_frame_info_get_global_frame_counter (CoglFrameInfo *info);
 
+COGL_EXPORT
+gboolean cogl_frame_info_get_is_symbolic (CoglFrameInfo *info);
+
 G_END_DECLS
 
 #endif /* __COGL_FRAME_INFO_H */
diff --git a/src/backends/native/meta-kms-impl-device-simple.c 
b/src/backends/native/meta-kms-impl-device-simple.c
index c9824539a0..a045f8df67 100644
--- a/src/backends/native/meta-kms-impl-device-simple.c
+++ b/src/backends/native/meta-kms-impl-device-simple.c
@@ -761,6 +761,27 @@ mode_set_fallback (MetaKmsImplDeviceSimple  *impl_device_simple,
   return TRUE;
 }
 
+static gboolean
+symbolic_page_flip_idle (gpointer user_data)
+{
+  MetaKmsPageFlipData *page_flip_data = user_data;
+  MetaKmsImplDevice *impl_device;
+  MetaKmsCrtc *crtc;
+
+  impl_device = meta_kms_page_flip_data_get_impl_device (page_flip_data);
+  crtc = meta_kms_page_flip_data_get_crtc (page_flip_data);
+
+  meta_topic (META_DEBUG_KMS,
+              "[simple] Handling symbolic page flip callback from %s, data: %p, CRTC: %u",
+              meta_kms_impl_device_get_path (impl_device),
+              page_flip_data,
+              meta_kms_crtc_get_id (crtc));
+
+  meta_kms_impl_device_handle_page_flip_callback (impl_device, page_flip_data);
+
+  return G_SOURCE_REMOVE;
+}
+
 static gboolean
 dispatch_page_flip (MetaKmsImplDevice    *impl_device,
                     MetaKmsUpdate        *update,
@@ -780,10 +801,30 @@ dispatch_page_flip (MetaKmsImplDevice    *impl_device,
   plane_assignment = meta_kms_update_get_primary_plane_assignment (update,
                                                                    crtc);
 
-  fd = meta_kms_impl_device_get_fd (impl_device);
   meta_kms_update_get_custom_page_flip_func (update,
                                              &custom_page_flip_func,
                                              &custom_page_flip_user_data);
+
+  if (!plane_assignment && !custom_page_flip_func)
+    {
+      MetaKmsDevice *device = meta_kms_impl_device_get_device (impl_device);
+      MetaKms *kms = meta_kms_device_get_kms (device);
+      GSource *source;
+
+      meta_kms_page_flip_data_make_symbolic (page_flip_data);
+
+      source = meta_kms_add_source_in_impl (kms,
+                                            symbolic_page_flip_idle,
+                                            page_flip_data,
+                                            NULL);
+
+      g_source_set_ready_time (source, 0);
+      g_source_unref (source);
+
+      return TRUE;
+    }
+
+  fd = meta_kms_impl_device_get_fd (impl_device);
   if (custom_page_flip_func)
     {
       meta_topic (META_DEBUG_KMS,
diff --git a/src/backends/native/meta-kms-page-flip-private.h 
b/src/backends/native/meta-kms-page-flip-private.h
index 50c95ae1c8..1aed388f8b 100644
--- a/src/backends/native/meta-kms-page-flip-private.h
+++ b/src/backends/native/meta-kms-page-flip-private.h
@@ -58,4 +58,6 @@ void meta_kms_page_flip_data_discard_in_impl (MetaKmsPageFlipData *page_flip_dat
 void meta_kms_page_flip_data_take_error (MetaKmsPageFlipData *page_flip_data,
                                          GError              *error);
 
+void meta_kms_page_flip_data_make_symbolic (MetaKmsPageFlipData *page_flip_data);
+
 #endif /* META_KMS_PAGE_FLIP_H */
diff --git a/src/backends/native/meta-kms-page-flip.c b/src/backends/native/meta-kms-page-flip.c
index eaf6db51bd..9f9f95ec21 100644
--- a/src/backends/native/meta-kms-page-flip.c
+++ b/src/backends/native/meta-kms-page-flip.c
@@ -44,6 +44,8 @@ struct _MetaKmsPageFlipData
   unsigned int sec;
   unsigned int usec;
 
+  gboolean is_symbolic;
+
   GError *error;
 };
 
@@ -125,11 +127,19 @@ meta_kms_page_flip_data_flipped (MetaKms  *kms,
     {
       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);
+      if (page_flip_data->is_symbolic)
+        {
+          closure->vtable->ready (page_flip_data->crtc,
+                                  closure->user_data);
+        }
+      else
+        {
+          closure->vtable->flipped (page_flip_data->crtc,
+                                    page_flip_data->sequence,
+                                    page_flip_data->sec,
+                                    page_flip_data->usec,
+                                    closure->user_data);
+        }
     }
 }
 
@@ -156,6 +166,12 @@ meta_kms_page_flip_data_set_timings_in_impl (MetaKmsPageFlipData *page_flip_data
   page_flip_data->usec = usec;
 }
 
+void
+meta_kms_page_flip_data_make_symbolic (MetaKmsPageFlipData *page_flip_data)
+{
+  page_flip_data->is_symbolic = TRUE;
+}
+
 void
 meta_kms_page_flip_data_flipped_in_impl (MetaKmsPageFlipData *page_flip_data)
 {
diff --git a/src/backends/native/meta-kms-update.h b/src/backends/native/meta-kms-update.h
index aa3cbb11dc..2274b37917 100644
--- a/src/backends/native/meta-kms-update.h
+++ b/src/backends/native/meta-kms-update.h
@@ -51,6 +51,9 @@ struct _MetaKmsPageFlipListenerVtable
                     unsigned int  tv_usec,
                     gpointer      user_data);
 
+  void (* ready) (MetaKmsCrtc *crtc,
+                  gpointer     user_data);
+
   void (* mode_set_fallback) (MetaKmsCrtc *crtc,
                               gpointer     user_data);
 
diff --git a/src/backends/native/meta-renderer-native.c b/src/backends/native/meta-renderer-native.c
index a14749f568..9efee2c1fe 100644
--- a/src/backends/native/meta-renderer-native.c
+++ b/src/backends/native/meta-renderer-native.c
@@ -1110,6 +1110,24 @@ page_flip_feedback_flipped (MetaKmsCrtc  *kms_crtc,
   g_object_unref (view);
 }
 
+static void
+page_flip_feedback_ready (MetaKmsCrtc *kms_crtc,
+                          gpointer     user_data)
+{
+  MetaRendererView *view = user_data;
+  CoglFramebuffer *framebuffer =
+    clutter_stage_view_get_onscreen (CLUTTER_STAGE_VIEW (view));
+  CoglOnscreen *onscreen = COGL_ONSCREEN (framebuffer);
+  CoglFrameInfo *frame_info;
+
+  frame_info = g_queue_peek_tail (&onscreen->pending_frame_infos);
+  frame_info->flags |= COGL_FRAME_INFO_FLAG_SYMBOLIC;
+
+  meta_onscreen_native_notify_frame_complete (onscreen);
+
+  g_object_unref (view);
+}
+
 static void
 page_flip_feedback_mode_set_fallback (MetaKmsCrtc *kms_crtc,
                                       gpointer     user_data)
@@ -1162,6 +1180,7 @@ page_flip_feedback_discarded (MetaKmsCrtc  *kms_crtc,
 
 static const MetaKmsPageFlipListenerVtable page_flip_listener_vtable = {
   .flipped = page_flip_feedback_flipped,
+  .ready = page_flip_feedback_ready,
   .mode_set_fallback = page_flip_feedback_mode_set_fallback,
   .discarded = page_flip_feedback_discarded,
 };


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