[mutter] Use signals instead of onscreen framebuffer frame callbacks



commit 28a898a22f82449cce524773bbdd24246e53bf9d
Author: Jonas Ådahl <jadahl gmail com>
Date:   Wed Jun 8 13:07:09 2016 +0800

    Use signals instead of onscreen framebuffer frame callbacks
    
    CoglFrameInfo is a frame info container associated with a single
    onscreen framebuffer. The clutter stage will eventually support drawing
    a stage frame with multiple onscreen framebuffers, thus needs its own
    frame info container.
    
    This patch introduces a new stage signal 'presented' and a accompaning
    ClutterFrameInfo and adapts the stage windows and past onscreen frame
    callbacks users to use the signal and new info container.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=768976

 clutter/clutter/clutter-mutter.h           |    5 --
 clutter/clutter/clutter-stage-private.h    |    4 ++
 clutter/clutter/clutter-stage-window.c     |   19 -------
 clutter/clutter/clutter-stage-window.h     |   12 -----
 clutter/clutter/clutter-stage.c            |   38 ++++++++++-----
 clutter/clutter/clutter-stage.h            |   10 ++++
 clutter/clutter/clutter-types.h            |    1 +
 clutter/clutter/cogl/clutter-stage-cogl.c  |   34 +++++---------
 clutter/clutter/cogl/clutter-stage-cogl.h  |    7 ++-
 clutter/clutter/x11/clutter-stage-x11.c    |   59 ++++++++++++-----------
 clutter/clutter/x11/clutter-stage-x11.h    |    2 +
 cogl/cogl/cogl-frame-info-private.h        |    2 +
 cogl/cogl/cogl-frame-info.c                |    6 ++
 cogl/cogl/cogl-frame-info.h                |    5 ++
 cogl/cogl/cogl-mutter.h                    |    1 +
 src/backends/native/meta-stage-native.c    |   71 +++++++++++++++------------
 src/compositor/compositor-private.h        |    1 -
 src/compositor/compositor.c                |   29 ++++++------
 src/compositor/meta-window-actor-private.h |    2 +-
 src/compositor/meta-window-actor.c         |   12 ++--
 20 files changed, 166 insertions(+), 154 deletions(-)
---
diff --git a/clutter/clutter/clutter-mutter.h b/clutter/clutter/clutter-mutter.h
index cdb6e4b..b820e6b 100644
--- a/clutter/clutter/clutter-mutter.h
+++ b/clutter/clutter/clutter-mutter.h
@@ -38,11 +38,6 @@ CLUTTER_AVAILABLE_IN_MUTTER
 gboolean        _clutter_get_sync_to_vblank     (void);
 
 CLUTTER_AVAILABLE_IN_MUTTER
-CoglFrameClosure *clutter_stage_add_frame_callback (ClutterStage     *stage,
-                                                    CoglFrameCallback callback,
-                                                    gpointer          user_data);
-
-CLUTTER_AVAILABLE_IN_MUTTER
 int64_t clutter_stage_get_frame_counter (ClutterStage *stage);
 
 #undef __CLUTTER_H_INSIDE__
diff --git a/clutter/clutter/clutter-stage-private.h b/clutter/clutter/clutter-stage-private.h
index 6e06cf1..517c9ad 100644
--- a/clutter/clutter/clutter-stage-private.h
+++ b/clutter/clutter/clutter-stage-private.h
@@ -125,6 +125,10 @@ gboolean                _clutter_stage_update_state     (ClutterStage      *stag
 void                    _clutter_stage_set_scale_factor (ClutterStage      *stage,
                                                          int                factor);
 
+void            _clutter_stage_presented                (ClutterStage      *stage,
+                                                         CoglFrameEvent     frame_event,
+                                                         ClutterFrameInfo  *frame_info);
+
 G_END_DECLS
 
 #endif /* __CLUTTER_STAGE_PRIVATE_H__ */
diff --git a/clutter/clutter/clutter-stage-window.c b/clutter/clutter/clutter-stage-window.c
index c6e7780..97eb5e4 100644
--- a/clutter/clutter/clutter-stage-window.c
+++ b/clutter/clutter/clutter-stage-window.c
@@ -338,25 +338,6 @@ _clutter_stage_window_get_views (ClutterStageWindow *window)
   return iface->get_views (window);
 }
 
-CoglFrameClosure *
-_clutter_stage_window_set_frame_callback (ClutterStageWindow *window,
-                                          CoglFrameCallback   callback,
-                                          gpointer            user_data)
-{
-  ClutterStageWindowIface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
-
-  return iface->set_frame_callback (window, callback, user_data);
-}
-
-void
-_clutter_stage_window_remove_frame_callback (ClutterStageWindow *window,
-                                             CoglFrameClosure   *closure)
-{
-  ClutterStageWindowIface *iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
-
-  iface->remove_frame_callback (window, closure);
-}
-
 void
 _clutter_stage_window_finish_frame (ClutterStageWindow *window)
 {
diff --git a/clutter/clutter/clutter-stage-window.h b/clutter/clutter/clutter-stage-window.h
index 947eb87..452f9de 100644
--- a/clutter/clutter/clutter-stage-window.h
+++ b/clutter/clutter/clutter-stage-window.h
@@ -87,11 +87,6 @@ struct _ClutterStageWindowIface
                                                  int                 factor);
   int               (* get_scale_factor)        (ClutterStageWindow *stage_window);
   GList            *(* get_views)               (ClutterStageWindow *stage_window);
-  CoglFrameClosure *(* set_frame_callback)      (ClutterStageWindow *stage_window,
-                                                 CoglFrameCallback   callback,
-                                                 gpointer            user_data);
-  void              (* remove_frame_callback)   (ClutterStageWindow *stage_window,
-                                                 CoglFrameClosure   *closure);
   int64_t           (* get_frame_counter)       (ClutterStageWindow *stage_window);
   void              (* finish_frame)            (ClutterStageWindow *stage_window);
 };
@@ -151,13 +146,6 @@ int               _clutter_stage_window_get_scale_factor        (ClutterStageWin
 
 GList *           _clutter_stage_window_get_views               (ClutterStageWindow *window);
 
-CoglFrameClosure *_clutter_stage_window_set_frame_callback      (ClutterStageWindow *window,
-                                                                 CoglFrameCallback   callback,
-                                                                 gpointer            user_data);
-
-void              _clutter_stage_window_remove_frame_callback   (ClutterStageWindow *stage_winow,
-                                                                 CoglFrameClosure   *closure);
-
 void              _clutter_stage_window_finish_frame            (ClutterStageWindow *window);
 
 int64_t           _clutter_stage_window_get_frame_counter       (ClutterStageWindow *window);
diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c
index 6e53435..8041262 100644
--- a/clutter/clutter/clutter-stage.c
+++ b/clutter/clutter/clutter-stage.c
@@ -190,6 +190,7 @@ enum
   DEACTIVATE,
   DELETE_EVENT,
   AFTER_PAINT,
+  PRESENTED,
 
   LAST_SIGNAL
 };
@@ -2167,6 +2168,21 @@ clutter_stage_class_init (ClutterStageClass *klass)
                   NULL, NULL, NULL,
                   G_TYPE_NONE, 0);
 
+  /**
+   * ClutterStage::presented: (skip)
+   * @stage: the stage that received the event
+   * @frame_event: a #CoglFrameEvent
+   * @frame_info: a #ClutterFrameInfo
+   */
+  stage_signals[PRESENTED] =
+    g_signal_new (I_("presented"),
+                  G_TYPE_FROM_CLASS (gobject_class),
+                  G_SIGNAL_RUN_LAST,
+                  0,
+                  NULL, NULL, NULL,
+                  G_TYPE_NONE, 2,
+                  G_TYPE_INT, G_TYPE_POINTER);
+
   klass->fullscreen = clutter_stage_real_fullscreen;
   klass->activate = clutter_stage_real_activate;
   klass->deactivate = clutter_stage_real_deactivate;
@@ -4628,19 +4644,6 @@ _clutter_stage_set_scale_factor (ClutterStage *stage,
   clutter_actor_queue_redraw (CLUTTER_ACTOR (stage));
 }
 
-CoglFrameClosure *
-clutter_stage_add_frame_callback (ClutterStage          *stage,
-                                  CoglFrameCallback      callback,
-                                  gpointer               user_data)
-{
-  ClutterStageWindow *stage_window;
-
-  stage_window = _clutter_stage_get_window (stage);
-  return _clutter_stage_window_set_frame_callback (stage_window,
-                                                   callback,
-                                                   user_data);
-}
-
 int64_t
 clutter_stage_get_frame_counter (ClutterStage          *stage)
 {
@@ -4649,3 +4652,12 @@ clutter_stage_get_frame_counter (ClutterStage          *stage)
   stage_window = _clutter_stage_get_window (stage);
   return _clutter_stage_window_get_frame_counter (stage_window);
 }
+
+void
+_clutter_stage_presented (ClutterStage     *stage,
+                          CoglFrameEvent    frame_event,
+                          ClutterFrameInfo *frame_info)
+{
+  g_signal_emit (stage, stage_signals[PRESENTED], 0,
+                 (int) frame_event, frame_info);
+}
diff --git a/clutter/clutter/clutter-stage.h b/clutter/clutter/clutter-stage.h
index 47cff93..e0911bc 100644
--- a/clutter/clutter/clutter-stage.h
+++ b/clutter/clutter/clutter-stage.h
@@ -135,6 +135,16 @@ struct _ClutterFog
   gfloat z_far;
 };
 
+/**
+ * ClutterFrameInfo: (skip)
+ */
+struct _ClutterFrameInfo
+{
+  int64_t frame_counter;
+  int64_t presentation_time;
+  float refresh_rate;
+};
+
 CLUTTER_AVAILABLE_IN_ALL
 GType clutter_perspective_get_type (void) G_GNUC_CONST;
 CLUTTER_DEPRECATED_IN_1_10
diff --git a/clutter/clutter/clutter-types.h b/clutter/clutter/clutter-types.h
index fd4c766..1e26105 100644
--- a/clutter/clutter/clutter-types.h
+++ b/clutter/clutter/clutter-types.h
@@ -51,6 +51,7 @@ G_BEGIN_DECLS
 typedef struct _ClutterActor                    ClutterActor;
 
 typedef struct _ClutterStage                    ClutterStage;
+typedef struct _ClutterFrameInfo                ClutterFrameInfo;
 typedef struct _ClutterContainer                ClutterContainer; /* dummy */
 typedef struct _ClutterChildMeta                ClutterChildMeta;
 typedef struct _ClutterLayoutMeta               ClutterLayoutMeta;
diff --git a/clutter/clutter/cogl/clutter-stage-cogl.c b/clutter/clutter/cogl/clutter-stage-cogl.c
index 07e10a2..d9c1c91 100644
--- a/clutter/clutter/cogl/clutter-stage-cogl.c
+++ b/clutter/clutter/cogl/clutter-stage-cogl.c
@@ -81,24 +81,15 @@ clutter_stage_cogl_unrealize (ClutterStageWindow *stage_window)
   ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
 
   CLUTTER_NOTE (BACKEND, "Unrealizing Cogl stage [%p]", stage_cogl);
-
-  if (stage_cogl->frame_closure != NULL)
-    {
-      _clutter_stage_window_remove_frame_callback (stage_window,
-                                                   stage_cogl->frame_closure);
-      stage_cogl->frame_closure = NULL;
-    }
 }
 
-static void
-frame_cb (CoglOnscreen  *onscreen,
-          CoglFrameEvent event,
-          CoglFrameInfo *info,
-          void          *user_data)
+void
+_clutter_stage_cogl_presented (ClutterStageCogl *stage_cogl,
+                               CoglFrameEvent    frame_event,
+                               ClutterFrameInfo *frame_info)
 {
-  ClutterStageCogl *stage_cogl = user_data;
 
-  if (event == COGL_FRAME_EVENT_SYNC)
+  if (frame_event == COGL_FRAME_EVENT_SYNC)
     {
       /* Early versions of the swap_event implementation in Mesa
        * deliver BufferSwapComplete event when not selected for,
@@ -112,13 +103,14 @@ frame_cb (CoglOnscreen  *onscreen,
       if (stage_cogl->pending_swaps > 0)
         stage_cogl->pending_swaps--;
     }
-  else if (event == COGL_FRAME_EVENT_COMPLETE)
+  else if (frame_event == COGL_FRAME_EVENT_COMPLETE)
     {
-      gint64 presentation_time_cogl = cogl_frame_info_get_presentation_time (info);
+      gint64 presentation_time_cogl = frame_info->presentation_time;
 
       if (presentation_time_cogl != 0)
         {
-          CoglContext *context = cogl_framebuffer_get_context (COGL_FRAMEBUFFER (onscreen));
+          ClutterBackend *backend = stage_cogl->backend;
+          CoglContext *context = clutter_backend_get_cogl_context (backend);
           gint64 current_time_cogl = cogl_get_clock_time (context);
           gint64 now = g_get_monotonic_time ();
 
@@ -126,8 +118,10 @@ frame_cb (CoglOnscreen  *onscreen,
             now + (presentation_time_cogl - current_time_cogl) / 1000;
         }
 
-      stage_cogl->refresh_rate = cogl_frame_info_get_refresh_rate (info);
+      stage_cogl->refresh_rate = frame_info->refresh_rate;
     }
+
+  _clutter_stage_presented (stage_cogl->wrapper, frame_event, frame_info);
 }
 
 static gboolean
@@ -148,10 +142,6 @@ clutter_stage_cogl_realize (ClutterStageWindow *stage_window)
       return FALSE;
     }
 
-  stage_cogl->frame_closure =
-    _clutter_stage_window_set_frame_callback (stage_window,
-                                              frame_cb, stage_window);
-
   return TRUE;
 }
 
diff --git a/clutter/clutter/cogl/clutter-stage-cogl.h b/clutter/clutter/cogl/clutter-stage-cogl.h
index 6a4a773..6122f2b 100644
--- a/clutter/clutter/cogl/clutter-stage-cogl.h
+++ b/clutter/clutter/cogl/clutter-stage-cogl.h
@@ -51,8 +51,6 @@ struct _ClutterStageCogl
   float refresh_rate;
   int pending_swaps;
 
-  CoglFrameClosure *frame_closure;
-
   gint64 last_presentation_time;
   gint64 update_time;
 
@@ -78,6 +76,11 @@ struct _ClutterStageCoglClass
 CLUTTER_AVAILABLE_IN_MUTTER
 GType _clutter_stage_cogl_get_type (void) G_GNUC_CONST;
 
+CLUTTER_AVAILABLE_IN_MUTTER
+void _clutter_stage_cogl_presented (ClutterStageCogl *stage_cogl,
+                                    CoglFrameEvent    frame_event,
+                                    ClutterFrameInfo *frame_info);
+
 G_END_DECLS
 
 #endif /* __CLUTTER_STAGE_COGL_H__ */
diff --git a/clutter/clutter/x11/clutter-stage-x11.c b/clutter/clutter/x11/clutter-stage-x11.c
index 2838292..39ff031 100644
--- a/clutter/clutter/x11/clutter-stage-x11.c
+++ b/clutter/clutter/x11/clutter-stage-x11.c
@@ -443,6 +443,13 @@ clutter_stage_x11_unrealize (ClutterStageWindow *stage_window)
   if (cogl_get_draw_framebuffer () == COGL_FRAMEBUFFER (stage_x11->onscreen))
     _clutter_backend_reset_cogl_framebuffer (stage_cogl->backend);
 
+  if (stage_x11->frame_closure)
+    {
+      cogl_onscreen_remove_frame_callback (stage_x11->onscreen,
+                                           stage_x11->frame_closure);
+      stage_x11->frame_closure = NULL;
+    }
+
   clutter_stage_window_parent_iface->unrealize (stage_window);
 
   g_list_free (stage_x11->legacy_views);
@@ -604,6 +611,23 @@ stage_events_device_added (ClutterDeviceManager *device_manager,
                                                  stage_cogl->wrapper);
 }
 
+static void
+frame_cb (CoglOnscreen  *onscreen,
+          CoglFrameEvent frame_event,
+          CoglFrameInfo *frame_info,
+          void          *user_data)
+
+{
+  ClutterStageCogl *stage_cogl = user_data;
+  ClutterFrameInfo clutter_frame_info = {
+    .frame_counter = cogl_frame_info_get_frame_counter (frame_info),
+    .presentation_time = cogl_frame_info_get_presentation_time (frame_info),
+    .refresh_rate = cogl_frame_info_get_refresh_rate (frame_info)
+  };
+
+  _clutter_stage_cogl_presented (stage_cogl, frame_event, &clutter_frame_info);
+}
+
 static gboolean
 clutter_stage_x11_realize (ClutterStageWindow *stage_window)
 {
@@ -628,6 +652,14 @@ clutter_stage_x11_realize (ClutterStageWindow *stage_window)
 
   stage_x11->onscreen = cogl_onscreen_new (backend->cogl_context, width, height);
 
+  cogl_onscreen_set_swap_throttled (stage_x11->onscreen,
+                                    _clutter_get_sync_to_vblank ());
+  stage_x11->frame_closure =
+    cogl_onscreen_add_frame_callback (stage_x11->onscreen,
+                                      frame_cb,
+                                      stage_cogl,
+                                      NULL);
+
   if (stage_x11->legacy_view)
     g_object_set (G_OBJECT (stage_x11->legacy_view),
                   "framebuffer", stage_x11->onscreen,
@@ -929,31 +961,6 @@ clutter_stage_x11_get_views (ClutterStageWindow *stage_window)
   return stage_x11->legacy_views;
 }
 
-static CoglFrameClosure *
-clutter_stage_x11_set_frame_callback (ClutterStageWindow *stage_window,
-                                      CoglFrameCallback   callback,
-                                      gpointer            user_data)
-{
-  ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
-
-  cogl_onscreen_set_swap_throttled (stage_x11->onscreen,
-                                    _clutter_get_sync_to_vblank ());
-
-  return cogl_onscreen_add_frame_callback (stage_x11->onscreen,
-                                           callback,
-                                           user_data,
-                                           NULL);
-}
-
-static void
-clutter_stage_x11_remove_frame_callback (ClutterStageWindow *stage_window,
-                                         CoglFrameClosure   *closure)
-{
-  ClutterStageX11 *stage_x11 = CLUTTER_STAGE_X11 (stage_window);
-
-  cogl_onscreen_remove_frame_callback (stage_x11->onscreen, closure);
-}
-
 static int64_t
 clutter_stage_x11_get_frame_counter (ClutterStageWindow *stage_window)
 {
@@ -1037,8 +1044,6 @@ clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
   iface->set_scale_factor = clutter_stage_x11_set_scale_factor;
   iface->get_scale_factor = clutter_stage_x11_get_scale_factor;
   iface->get_views = clutter_stage_x11_get_views;
-  iface->set_frame_callback = clutter_stage_x11_set_frame_callback;
-  iface->remove_frame_callback = clutter_stage_x11_remove_frame_callback;
   iface->get_frame_counter = clutter_stage_x11_get_frame_counter;
 }
 
diff --git a/clutter/clutter/x11/clutter-stage-x11.h b/clutter/clutter/x11/clutter-stage-x11.h
index e1ee033..98ba53b 100644
--- a/clutter/clutter/x11/clutter-stage-x11.h
+++ b/clutter/clutter/x11/clutter-stage-x11.h
@@ -61,6 +61,8 @@ struct _ClutterStageX11
   ClutterStageView *legacy_view;
   GList *legacy_views;
 
+  CoglFrameClosure *frame_closure;
+
   gchar *title;
 
   guint clipped_redraws_cool_off;
diff --git a/cogl/cogl/cogl-frame-info-private.h b/cogl/cogl/cogl-frame-info-private.h
index 32f5ba8..16d393e 100644
--- a/cogl/cogl/cogl-frame-info-private.h
+++ b/cogl/cogl/cogl-frame-info-private.h
@@ -42,6 +42,8 @@ struct _CoglFrameInfo
   int64_t presentation_time;
   float refresh_rate;
 
+  int64_t global_frame_counter;
+
   CoglOutput *output;
 };
 
diff --git a/cogl/cogl/cogl-frame-info.c b/cogl/cogl/cogl-frame-info.c
index 0571960..4e7ac3a 100644
--- a/cogl/cogl/cogl-frame-info.c
+++ b/cogl/cogl/cogl-frame-info.c
@@ -79,3 +79,9 @@ cogl_frame_info_get_output (CoglFrameInfo *info)
 {
   return info->output;
 }
+
+int64_t
+cogl_frame_info_get_global_frame_counter (CoglFrameInfo *info)
+{
+  return info->global_frame_counter;
+}
diff --git a/cogl/cogl/cogl-frame-info.h b/cogl/cogl/cogl-frame-info.h
index 7304c53..3e44d74 100644
--- a/cogl/cogl/cogl-frame-info.h
+++ b/cogl/cogl/cogl-frame-info.h
@@ -143,6 +143,11 @@ float cogl_frame_info_get_refresh_rate (CoglFrameInfo *info);
 CoglOutput *
 cogl_frame_info_get_output (CoglFrameInfo *info);
 
+/**
+ * cogl_frame_info_get_global_frame_counter: (skip)
+ */
+int64_t cogl_frame_info_get_global_frame_counter (CoglFrameInfo *info);
+
 G_END_DECLS
 
 #endif /* __COGL_FRAME_INFO_H */
diff --git a/cogl/cogl/cogl-mutter.h b/cogl/cogl/cogl-mutter.h
index d490a9c..4bfac07 100644
--- a/cogl/cogl/cogl-mutter.h
+++ b/cogl/cogl/cogl-mutter.h
@@ -37,6 +37,7 @@
 #include <cogl/cogl-texture.h>
 #include <cogl/cogl-meta-texture.h>
 #include <cogl/cogl-error-private.h>
+#include <cogl/cogl-frame-info-private.h>
 #include <cogl/cogl-renderer-private.h>
 #include <cogl/winsys/cogl-winsys-egl-private.h>
 #include <cogl/winsys/cogl-winsys-private.h>
diff --git a/src/backends/native/meta-stage-native.c b/src/backends/native/meta-stage-native.c
index 1dd3c50..624c514 100644
--- a/src/backends/native/meta-stage-native.c
+++ b/src/backends/native/meta-stage-native.c
@@ -36,6 +36,7 @@ struct _MetaStageNative
   ClutterStageCogl parent;
 
   CoglOnscreen *pending_onscreen;
+  CoglClosure *frame_closure;
 };
 
 static ClutterStageWindowIface *clutter_stage_window_parent_iface = NULL;
@@ -136,6 +137,16 @@ meta_stage_native_unrealize (ClutterStageWindow *stage_window)
 
   clutter_stage_window_parent_iface->unrealize (stage_window);
 
+  if (stage_native->frame_closure)
+    {
+      CoglOnscreen *onscreen;
+
+      onscreen = get_legacy_onscreen (stage_native);
+      cogl_onscreen_remove_frame_callback (onscreen,
+                                           stage_native->frame_closure);
+      stage_native->frame_closure = NULL;
+    }
+
   g_clear_pointer (&stage_native->pending_onscreen, cogl_object_unref);
 }
 
@@ -169,6 +180,23 @@ meta_stage_native_get_geometry (ClutterStageWindow    *stage_window,
 }
 
 static void
+frame_cb (CoglOnscreen  *onscreen,
+          CoglFrameEvent frame_event,
+          CoglFrameInfo *frame_info,
+          void          *user_data)
+{
+  MetaStageNative *stage_native = user_data;
+  ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_native);
+  ClutterFrameInfo clutter_frame_info = {
+    .frame_counter = cogl_frame_info_get_frame_counter (frame_info),
+    .refresh_rate = cogl_frame_info_get_refresh_rate (frame_info),
+    .presentation_time = cogl_frame_info_get_presentation_time (frame_info)
+  };
+
+  _clutter_stage_cogl_presented (stage_cogl, frame_event, &clutter_frame_info);
+}
+
+static void
 ensure_legacy_view (ClutterStageWindow *stage_window)
 {
   MetaStageNative *stage_native = META_STAGE_NATIVE (stage_window);
@@ -179,6 +207,7 @@ ensure_legacy_view (ClutterStageWindow *stage_window)
   MetaRendererView *legacy_view;
   cairo_rectangle_int_t view_layout = { 0 };
   CoglFramebuffer *framebuffer;
+  CoglOnscreen *onscreen;
 
   legacy_view = get_legacy_view (renderer);
   if (legacy_view)
@@ -196,6 +225,16 @@ ensure_legacy_view (ClutterStageWindow *stage_window)
                               "framebuffer", framebuffer,
                               NULL);
   meta_renderer_set_legacy_view (renderer, legacy_view);
+
+  onscreen = COGL_ONSCREEN (framebuffer);
+  cogl_onscreen_set_swap_throttled (onscreen,
+                                    _clutter_get_sync_to_vblank ());
+
+  stage_native->frame_closure =
+    cogl_onscreen_add_frame_callback (onscreen,
+                                      frame_cb,
+                                      stage_native,
+                                      NULL);
 }
 
 static GList *
@@ -208,36 +247,6 @@ meta_stage_native_get_views (ClutterStageWindow *stage_window)
   return meta_renderer_get_views (renderer);
 }
 
-static CoglClosure *
-meta_stage_native_set_frame_callback (ClutterStageWindow *stage_window,
-                                      CoglFrameCallback   callback,
-                                      gpointer            user_data)
-{
-  MetaStageNative *stage_native = META_STAGE_NATIVE (stage_window);
-  CoglOnscreen *legacy_onscreen;
-
-  legacy_onscreen = get_legacy_onscreen (stage_native);
-  cogl_onscreen_set_swap_throttled (legacy_onscreen,
-                                    _clutter_get_sync_to_vblank ());
-
-  return cogl_onscreen_add_frame_callback (legacy_onscreen,
-                                           callback,
-                                           user_data,
-                                           NULL);
-}
-
-static void
-meta_stage_native_remove_frame_callback (ClutterStageWindow *stage_window,
-                                         CoglFrameClosure   *closure)
-{
-  MetaStageNative *stage_native = META_STAGE_NATIVE (stage_window);
-  CoglOnscreen *legacy_onscreen;
-
-  legacy_onscreen = get_legacy_onscreen (stage_native);
-
-  cogl_onscreen_remove_frame_callback (legacy_onscreen, closure);
-}
-
 static int64_t
 meta_stage_native_get_frame_counter (ClutterStageWindow *stage_window)
 {
@@ -269,7 +278,5 @@ clutter_stage_window_iface_init (ClutterStageWindowIface *iface)
   iface->can_clip_redraws = meta_stage_native_can_clip_redraws;
   iface->get_geometry = meta_stage_native_get_geometry;
   iface->get_views = meta_stage_native_get_views;
-  iface->set_frame_callback = meta_stage_native_set_frame_callback;
-  iface->remove_frame_callback = meta_stage_native_remove_frame_callback;
   iface->get_frame_counter = meta_stage_native_get_frame_counter;
 }
diff --git a/src/compositor/compositor-private.h b/src/compositor/compositor-private.h
index 72dffe5..4629fa5 100644
--- a/src/compositor/compositor-private.h
+++ b/src/compositor/compositor-private.h
@@ -29,7 +29,6 @@ struct _MetaCompositor
   GList                 *windows;
   Window                 output;
 
-  CoglFrameClosure      *frame_closure;
   CoglContext           *context;
 
   /* Used for unredirecting fullscreen windows */
diff --git a/src/compositor/compositor.c b/src/compositor/compositor.c
index 0efb09b..59ad7f7 100644
--- a/src/compositor/compositor.c
+++ b/src/compositor/compositor.c
@@ -83,6 +83,12 @@
 #include "wayland/meta-wayland-private.h"
 #endif
 
+static void
+on_presented (ClutterStage     *stage,
+              CoglFrameEvent    event,
+              ClutterFrameInfo *frame_info,
+              MetaCompositor   *compositor);
+
 static gboolean
 is_modal (MetaDisplay *display)
 {
@@ -475,6 +481,10 @@ meta_compositor_manage (MetaCompositor *compositor)
 
   compositor->stage = meta_backend_get_stage (backend);
 
+  g_signal_connect (compositor->stage, "presented",
+                    G_CALLBACK (on_presented),
+                    compositor);
+
   /* We use connect_after() here to accomodate code in GNOME Shell that,
    * when benchmarking drawing performance, connects to ::after-paint
    * and calls glFinish(). The timing information from that will be
@@ -998,17 +1008,16 @@ meta_compositor_sync_window_geometry (MetaCompositor *compositor,
 }
 
 static void
-frame_callback (CoglOnscreen  *onscreen,
-                CoglFrameEvent event,
-                CoglFrameInfo *frame_info,
-                void          *user_data)
+on_presented (ClutterStage     *stage,
+              CoglFrameEvent    event,
+              ClutterFrameInfo *frame_info,
+              MetaCompositor   *compositor)
 {
-  MetaCompositor *compositor = user_data;
   GList *l;
 
   if (event == COGL_FRAME_EVENT_COMPLETE)
     {
-      gint64 presentation_time_cogl = cogl_frame_info_get_presentation_time (frame_info);
+      gint64 presentation_time_cogl = frame_info->presentation_time;
       gint64 presentation_time;
 
       if (presentation_time_cogl != 0)
@@ -1045,14 +1054,6 @@ meta_pre_paint_func (gpointer data)
   MetaWindowActor *top_window;
   MetaCompositor *compositor = data;
 
-  if (!compositor->frame_closure)
-    {
-      compositor->frame_closure =
-        clutter_stage_add_frame_callback (CLUTTER_STAGE (compositor->stage),
-                                          frame_callback,
-                                          compositor);
-    }
-
   if (compositor->windows == NULL)
     return TRUE;
 
diff --git a/src/compositor/meta-window-actor-private.h b/src/compositor/meta-window-actor-private.h
index 1f7947b..ef21674 100644
--- a/src/compositor/meta-window-actor-private.h
+++ b/src/compositor/meta-window-actor-private.h
@@ -30,7 +30,7 @@ void meta_window_actor_process_x11_damage (MetaWindowActor    *self,
 void meta_window_actor_pre_paint      (MetaWindowActor    *self);
 void meta_window_actor_post_paint     (MetaWindowActor    *self);
 void meta_window_actor_frame_complete (MetaWindowActor    *self,
-                                       CoglFrameInfo      *frame_info,
+                                       ClutterFrameInfo   *frame_info,
                                        gint64              presentation_time);
 
 void meta_window_actor_invalidate_shadow (MetaWindowActor *self);
diff --git a/src/compositor/meta-window-actor.c b/src/compositor/meta-window-actor.c
index 197a193..25a8f11 100644
--- a/src/compositor/meta-window-actor.c
+++ b/src/compositor/meta-window-actor.c
@@ -2029,13 +2029,13 @@ do_send_frame_timings (MetaWindowActor  *self,
 static void
 send_frame_timings (MetaWindowActor  *self,
                     FrameData        *frame,
-                    CoglFrameInfo    *frame_info,
+                    ClutterFrameInfo *frame_info,
                     gint64            presentation_time)
 {
   float refresh_rate;
   int refresh_interval;
 
-  refresh_rate = cogl_frame_info_get_refresh_rate (frame_info);
+  refresh_rate = frame_info->refresh_rate;
   /* 0.0 is a flag for not known, but sanity-check against other odd numbers */
   if (refresh_rate >= 1.0)
     refresh_interval = (int) (0.5 + 1000000 / refresh_rate);
@@ -2046,9 +2046,9 @@ send_frame_timings (MetaWindowActor  *self,
 }
 
 void
-meta_window_actor_frame_complete (MetaWindowActor *self,
-                                  CoglFrameInfo   *frame_info,
-                                  gint64           presentation_time)
+meta_window_actor_frame_complete (MetaWindowActor  *self,
+                                  ClutterFrameInfo *frame_info,
+                                  gint64            presentation_time)
 {
   MetaWindowActorPrivate *priv = self->priv;
   GList *l;
@@ -2060,7 +2060,7 @@ meta_window_actor_frame_complete (MetaWindowActor *self,
     {
       GList *l_next = l->next;
       FrameData *frame = l->data;
-      gint64 frame_counter = cogl_frame_info_get_frame_counter (frame_info);
+      gint64 frame_counter = frame_info->frame_counter;
 
       if (frame->frame_counter != -1 && frame->frame_counter <= frame_counter)
         {


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