[mutter/gnome-3-36] clutter/stage: Add API to get_next_presentation_time



commit 2c805524b49150793fe97908cb309d9b8c52f8ad
Author: Daniel van Vugt <daniel van vugt canonical com>
Date:   Tue Aug 13 17:33:19 2019 +0800

    clutter/stage: Add API to get_next_presentation_time
    
    https://gitlab.gnome.org/GNOME/mutter/merge_requests/724

 clutter/clutter/clutter-stage-private.h   |  1 +
 clutter/clutter/clutter-stage-window.c    | 16 ++++++++++++++++
 clutter/clutter/clutter-stage-window.h    |  4 ++++
 clutter/clutter/clutter-stage.c           | 15 +++++++++++++++
 clutter/clutter/cogl/clutter-stage-cogl.c | 32 ++++++++++++++++++++++++++++++-
 clutter/clutter/cogl/clutter-stage-cogl.h |  1 +
 6 files changed, 68 insertions(+), 1 deletion(-)
---
diff --git a/clutter/clutter/clutter-stage-private.h b/clutter/clutter/clutter-stage-private.h
index c8c1ef34a..a8abd0564 100644
--- a/clutter/clutter/clutter-stage-private.h
+++ b/clutter/clutter/clutter-stage-private.h
@@ -78,6 +78,7 @@ void     _clutter_stage_schedule_update                   (ClutterStage *stage);
 gint64    _clutter_stage_get_update_time                  (ClutterStage *stage);
 void     _clutter_stage_clear_update_time                 (ClutterStage *stage);
 gboolean _clutter_stage_has_full_redraw_queued            (ClutterStage *stage);
+int64_t  _clutter_stage_get_next_presentation_time        (ClutterStage *stage);
 
 void clutter_stage_log_pick (ClutterStage           *stage,
                              const graphene_point_t *vertices,
diff --git a/clutter/clutter/clutter-stage-window.c b/clutter/clutter/clutter-stage-window.c
index 3c80124a9..a3782a175 100644
--- a/clutter/clutter/clutter-stage-window.c
+++ b/clutter/clutter/clutter-stage-window.c
@@ -178,6 +178,22 @@ _clutter_stage_window_clear_update_time (ClutterStageWindow *window)
   iface->clear_update_time (window);
 }
 
+int64_t
+_clutter_stage_window_get_next_presentation_time (ClutterStageWindow *window)
+{
+  ClutterStageWindowInterface *iface;
+
+  g_return_val_if_fail (CLUTTER_IS_STAGE_WINDOW (window), 0);
+
+  iface = CLUTTER_STAGE_WINDOW_GET_IFACE (window);
+
+  /* If not implemented then just revert to the old behaviour... */
+  if (iface->get_next_presentation_time == NULL)
+    return _clutter_stage_window_get_update_time (window);
+
+  return iface->get_next_presentation_time (window);
+}
+
 void
 _clutter_stage_window_set_accept_focus (ClutterStageWindow *window,
                                         gboolean            accept_focus)
diff --git a/clutter/clutter/clutter-stage-window.h b/clutter/clutter/clutter-stage-window.h
index eb529416e..78d15b743 100644
--- a/clutter/clutter/clutter-stage-window.h
+++ b/clutter/clutter/clutter-stage-window.h
@@ -61,6 +61,8 @@ struct _ClutterStageWindowInterface
   GList            *(* get_views)               (ClutterStageWindow *stage_window);
   int64_t           (* get_frame_counter)       (ClutterStageWindow *stage_window);
   void              (* finish_frame)            (ClutterStageWindow *stage_window);
+
+  int64_t           (* get_next_presentation_time) (ClutterStageWindow *stage_window);
 };
 
 ClutterActor *    _clutter_stage_window_get_wrapper        (ClutterStageWindow *window);
@@ -101,6 +103,8 @@ void              _clutter_stage_window_finish_frame            (ClutterStageWin
 
 int64_t           _clutter_stage_window_get_frame_counter       (ClutterStageWindow *window);
 
+int64_t           _clutter_stage_window_get_next_presentation_time (ClutterStageWindow *window);
+
 G_END_DECLS
 
 #endif /* __CLUTTER_STAGE_WINDOW_H__ */
diff --git a/clutter/clutter/clutter-stage.c b/clutter/clutter/clutter-stage.c
index 07ba9dfae..fb73a027d 100644
--- a/clutter/clutter/clutter-stage.c
+++ b/clutter/clutter/clutter-stage.c
@@ -3751,6 +3751,21 @@ _clutter_stage_clear_update_time (ClutterStage *stage)
     _clutter_stage_window_clear_update_time (stage_window);
 }
 
+int64_t
+_clutter_stage_get_next_presentation_time (ClutterStage *stage)
+{
+  ClutterStageWindow *stage_window;
+
+  if (CLUTTER_ACTOR_IN_DESTRUCTION (stage))
+    return 0;
+
+  stage_window = _clutter_stage_get_window (stage);
+  if (stage_window == NULL)
+    return 0;
+
+  return _clutter_stage_window_get_next_presentation_time (stage_window);
+}
+
 ClutterPaintVolume *
 _clutter_stage_paint_volume_stack_allocate (ClutterStage *stage)
 {
diff --git a/clutter/clutter/cogl/clutter-stage-cogl.c b/clutter/clutter/cogl/clutter-stage-cogl.c
index d48e97641..28b33455f 100644
--- a/clutter/clutter/cogl/clutter-stage-cogl.c
+++ b/clutter/clutter/cogl/clutter-stage-cogl.c
@@ -235,7 +235,12 @@ clutter_stage_cogl_schedule_update (ClutterStageWindow *stage_window,
   stage_cogl->update_time = next_presentation_time - max_render_time_allowed;
 
   if (stage_cogl->update_time == stage_cogl->last_update_time)
-    stage_cogl->update_time = stage_cogl->last_update_time + refresh_interval;
+    {
+      stage_cogl->update_time += refresh_interval;
+      next_presentation_time += refresh_interval;
+    }
+
+  stage_cogl->next_presentation_time = next_presentation_time;
 }
 
 static gint64
@@ -256,6 +261,29 @@ clutter_stage_cogl_clear_update_time (ClutterStageWindow *stage_window)
 
   stage_cogl->last_update_time = stage_cogl->update_time;
   stage_cogl->update_time = -1;
+  stage_cogl->next_presentation_time = -1;
+}
+
+static int64_t
+clutter_stage_cogl_get_next_presentation_time (ClutterStageWindow *stage_window)
+{
+  ClutterStageCogl *stage_cogl = CLUTTER_STAGE_COGL (stage_window);
+  int64_t now = g_get_monotonic_time ();
+
+  if (stage_cogl->next_presentation_time > 0 &&
+      stage_cogl->next_presentation_time <= now)
+    {
+      CLUTTER_NOTE (BACKEND,
+                    "Missed some frames. Something blocked for over "
+                    "%" G_GINT64_FORMAT "ms.",
+                    (now - stage_cogl->next_presentation_time) / 1000);
+
+      stage_cogl->update_time = -1;
+      clutter_stage_cogl_schedule_update (stage_window,
+                                          stage_cogl->last_sync_delay);
+    }
+
+  return stage_cogl->next_presentation_time;
 }
 
 static ClutterActor *
@@ -1008,6 +1036,7 @@ clutter_stage_window_iface_init (ClutterStageWindowInterface *iface)
   iface->schedule_update = clutter_stage_cogl_schedule_update;
   iface->get_update_time = clutter_stage_cogl_get_update_time;
   iface->clear_update_time = clutter_stage_cogl_clear_update_time;
+  iface->get_next_presentation_time = clutter_stage_cogl_get_next_presentation_time;
   iface->redraw = clutter_stage_cogl_redraw;
 }
 
@@ -1053,6 +1082,7 @@ _clutter_stage_cogl_init (ClutterStageCogl *stage)
   stage->refresh_rate = 0.0;
 
   stage->update_time = -1;
+  stage->next_presentation_time = -1;
 }
 
 static void
diff --git a/clutter/clutter/cogl/clutter-stage-cogl.h b/clutter/clutter/cogl/clutter-stage-cogl.h
index 1eaa02e8f..634f856d4 100644
--- a/clutter/clutter/cogl/clutter-stage-cogl.h
+++ b/clutter/clutter/cogl/clutter-stage-cogl.h
@@ -48,6 +48,7 @@ struct _ClutterStageCogl
   gint64 last_presentation_time;
   gint64 update_time;
   int64_t last_update_time;
+  int64_t next_presentation_time;
 
   /* We only enable clipped redraws after 2 frames, since we've seen
    * a lot of drivers can struggle to get going and may output some


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