[cogl/wip/frame-synchronization: 222/223] Replace frame history with a queue



commit 41de98629a23f594715c703d26671d039085cf93
Author: Owen W. Taylor <otaylor fishsoup net>
Date:   Thu Jan 24 23:16:25 2013 -0500

    Replace frame history with a queue
    
    An arbitrary-length frame history seems hard to size, and can be implemented
    at the application level, so ditch it for a queue of frame info objects
    that are not yet complete.

 cogl/cogl-onscreen-private.h      |    6 +--
 cogl/cogl-onscreen.c              |   77 +++++++------------------------------
 cogl/cogl-onscreen.h              |   44 ---------------------
 cogl/winsys/cogl-winsys-egl-kms.c |    5 +-
 cogl/winsys/cogl-winsys-glx.c     |   22 +++++------
 5 files changed, 28 insertions(+), 126 deletions(-)
---
diff --git a/cogl/cogl-onscreen-private.h b/cogl/cogl-onscreen-private.h
index da36de0..c712e72 100644
--- a/cogl/cogl-onscreen-private.h
+++ b/cogl/cogl-onscreen-private.h
@@ -34,8 +34,6 @@
 #include <windows.h>
 #endif
 
-#define COGL_ONSCREEN_MAX_FRAME_INFOS 16
-
 COGL_TAILQ_HEAD (CoglFrameCallbackList, CoglFrameClosure);
 
 struct _CoglFrameClosure
@@ -86,9 +84,7 @@ struct _CoglOnscreen
   int64_t swap_frame_counter; /* frame counter at last all to
                                * cogl_onscreen_swap_region() or
                                * cogl_onscreen_swap_buffers() */
-  CoglFrameInfo *frame_info[COGL_ONSCREEN_MAX_FRAME_INFOS];
-  int current_frame_info;
-  int n_frame_infos;
+  GQueue pending_frame_infos;
 
   void *winsys;
 };
diff --git a/cogl/cogl-onscreen.c b/cogl/cogl-onscreen.c
index 19ddce0..64f8a40 100644
--- a/cogl/cogl-onscreen.c
+++ b/cogl/cogl-onscreen.c
@@ -36,8 +36,6 @@
 
 static void _cogl_onscreen_free (CoglOnscreen *onscreen);
 
-static void cogl_onscreen_before_swap (CoglOnscreen *onscreen);
-
 COGL_OBJECT_DEFINE_WITH_CODE (Onscreen, onscreen,
                               _cogl_onscreen_class.virt_unref =
                               _cogl_framebuffer_unref);
@@ -78,9 +76,6 @@ _cogl_onscreen_new (void)
 
   COGL_FRAMEBUFFER (onscreen)->allocated = TRUE;
 
-  onscreen->frame_counter = -1;
-  onscreen->current_frame_info = COGL_ONSCREEN_MAX_FRAME_INFOS - 1;
-
   /* XXX: Note we don't initialize onscreen->winsys in this case. */
 
   return _cogl_onscreen_object_new (onscreen);
@@ -122,7 +117,7 @@ _cogl_onscreen_free (CoglOnscreen *onscreen)
   const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
   CoglResizeNotifyEntry *resize_entry;
   CoglFrameClosure *frame_closure;
-  int i;
+  CoglFrameInfo *frame_info;
 
   while ((resize_entry = COGL_TAILQ_FIRST (&onscreen->resize_callbacks)))
     {
@@ -140,11 +135,9 @@ _cogl_onscreen_free (CoglOnscreen *onscreen)
       g_slice_free (CoglFrameClosure, frame_closure);
     }
 
-  for (i = 0; i < onscreen->n_frame_infos; i++)
-    {
-      cogl_object_unref (onscreen->frame_info[i]);
-      onscreen->frame_info[i] = NULL;
-    }
+  while ((frame_info = g_queue_pop_tail (&onscreen->pending_frame_infos)))
+    cogl_object_unref (frame_info);
+  g_queue_clear (&onscreen->pending_frame_infos);
 
   if (framebuffer->context->window_buffer == COGL_FRAMEBUFFER (onscreen))
     framebuffer->context->window_buffer = NULL;
@@ -163,10 +156,13 @@ cogl_onscreen_swap_buffers (CoglOnscreen *onscreen)
 {
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
   const CoglWinsysVtable *winsys;
+  CoglFrameInfo *info;
 
   _COGL_RETURN_IF_FAIL  (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN);
 
-  cogl_onscreen_before_swap (onscreen);
+  info = _cogl_frame_info_new ();
+  info->frame_counter = onscreen->frame_counter;
+  g_queue_push_tail (&onscreen->pending_frame_infos, info);
 
   /* FIXME: we shouldn't need to flush *all* journals here! */
   cogl_flush ();
@@ -176,6 +172,7 @@ cogl_onscreen_swap_buffers (CoglOnscreen *onscreen)
                                     COGL_BUFFER_BIT_COLOR |
                                     COGL_BUFFER_BIT_DEPTH |
                                     COGL_BUFFER_BIT_STENCIL);
+  onscreen->frame_counter++;
 }
 
 void
@@ -185,10 +182,13 @@ cogl_onscreen_swap_region (CoglOnscreen *onscreen,
 {
   CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
   const CoglWinsysVtable *winsys;
+  CoglFrameInfo *info;
 
   _COGL_RETURN_IF_FAIL  (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN);
 
-  cogl_onscreen_before_swap (onscreen);
+  info = _cogl_frame_info_new ();
+  info->frame_counter = onscreen->frame_counter;
+  g_queue_push_tail (&onscreen->pending_frame_infos, info);
 
   /* FIXME: we shouldn't need to flush *all* journals here! */
   cogl_flush ();
@@ -207,6 +207,7 @@ cogl_onscreen_swap_region (CoglOnscreen *onscreen,
                                     COGL_BUFFER_BIT_COLOR |
                                     COGL_BUFFER_BIT_DEPTH |
                                     COGL_BUFFER_BIT_STENCIL);
+  onscreen->frame_counter++;
 }
 
 #ifdef COGL_HAS_X11_SUPPORT
@@ -565,53 +566,3 @@ cogl_onscreen_get_frame_counter (CoglOnscreen *onscreen)
 {
   return onscreen->frame_counter;
 }
-
-void
-cogl_onscreen_begin_frame (CoglOnscreen *onscreen)
-{
-  onscreen->frame_counter++;
-  onscreen->current_frame_info = (onscreen->current_frame_info + 1) % COGL_ONSCREEN_MAX_FRAME_INFOS;
-
-  if (onscreen->n_frame_infos < COGL_ONSCREEN_MAX_FRAME_INFOS)
-    onscreen->n_frame_infos++;
-  else
-    cogl_object_unref (onscreen->frame_info[onscreen->current_frame_info]);
-
-  onscreen->frame_info[onscreen->current_frame_info] = _cogl_frame_info_new ();
-  onscreen->frame_info[onscreen->current_frame_info]->frame_counter = onscreen->frame_counter;
-  onscreen->frame_info[onscreen->current_frame_info]->frame_time = frame_time;
-}
-
-static void
-cogl_onscreen_before_swap (CoglOnscreen *onscreen)
-{
-  if (onscreen->swap_frame_counter == onscreen->frame_counter)
-    cogl_onscreen_begin_frame (onscreen, 0);
-
-  onscreen->swap_frame_counter = onscreen->frame_counter;
-}
-
-int64_t
-cogl_onscreen_get_frame_history_start (CoglOnscreen *onscreen)
-{
-  return onscreen->frame_counter - onscreen->n_frame_infos;
-}
-
-CoglFrameInfo *
-cogl_onscreen_get_frame_info (CoglOnscreen *onscreen,
-                              int64_t       frame_counter)
-{
-  int pos;
-
-  if (frame_counter > onscreen->frame_counter)
-    return NULL;
-
-  if (frame_counter <= onscreen->frame_counter - onscreen->n_frame_infos)
-    return NULL;
-
-  pos = ((onscreen->current_frame_info -
-          (onscreen->frame_counter - frame_counter) + COGL_ONSCREEN_MAX_FRAME_INFOS)
-         % COGL_ONSCREEN_MAX_FRAME_INFOS);
-
-  return onscreen->frame_info[pos];
-}
diff --git a/cogl/cogl-onscreen.h b/cogl/cogl-onscreen.h
index 050e191..9ce5cd2 100644
--- a/cogl/cogl-onscreen.h
+++ b/cogl/cogl-onscreen.h
@@ -693,50 +693,6 @@ cogl_is_onscreen (void *object);
 int64_t
 cogl_onscreen_get_frame_counter (CoglOnscreen *onscreen);
 
-/**
- * cogl_onscreen_begin_frame:
- * @onscreen: a #CoglOnscreen framebuffer
- *
- * Marks the beginning of a frame. This increases the frame
- * counter value and creates a new #CoglFrameInfo objeect.
- *
- * Since: 2.0
- */
-void
-cogl_onscreen_begin_frame (CoglOnscreen *onscreen);
-
-/**
- * cogl_onscreen_get_frame_history_start:
- * @onscreen: a #CoglOnscreen framebuffer
- *
- * Gets the frame counter for the oldest #CoglFrameInfo that is
- * being kept in the history. cogl_onscreen_get_frame_info() will
- * always return %NULl for any frame counter before this.
- *
- * Return value: the frame counter for the oldest #CoglFrameInfo
- *  in the history.
- * Since: 2.0
- */
-int64_t
-cogl_onscreen_get_frame_history_start (CoglOnscreen *onscreen);
-
-
-/**
- * cogl_onscreen_get_frame_info:
- * @onscreen: A #CoglOnscreen framebuffer
- * @frame_counter: the value of cogl_onscreen_get_frame_counter()
- *       when the frame finished drawing.
- *
- * Gets frame timing information for a particular frame.
- *
- * Return value: a #CoglFrameInfo object, or %NULL if
- *   information is not available for the given frame.
- * Since: 2.0
- */
-CoglFrameInfo *
-cogl_onscreen_get_frame_info (CoglOnscreen *onscreen,
-                              int64_t frame_counter);
-
 COGL_END_DECLS
 
 #endif /* __COGL_ONSCREEN_H */
diff --git a/cogl/winsys/cogl-winsys-egl-kms.c b/cogl/winsys/cogl-winsys-egl-kms.c
index 498fb9d..b9d77db 100644
--- a/cogl/winsys/cogl-winsys-egl-kms.c
+++ b/cogl/winsys/cogl-winsys-egl-kms.c
@@ -896,14 +896,15 @@ flush_pending_swap_notify_cb (void *data,
 
       if (kms_onscreen->pending_swap_notify)
         {
-          int64_t frame_counter = cogl_onscreen_get_frame_counter (onscreen);
-          CoglFrameInfo *info = cogl_onscreen_get_frame_info (onscreen, frame_counter);
+          CoglFrameInfo *info = g_queue_pop_tail (&onscreen->pending_frame_infos);
 
           info->complete = TRUE;
 
           _cogl_onscreen_notify_frame_sync (onscreen, info);
           _cogl_onscreen_notify_complete (onscreen, info);
           kms_onscreen->pending_swap_notify = FALSE;
+
+          cogl_object_unref (info);
         }
     }
 }
diff --git a/cogl/winsys/cogl-winsys-glx.c b/cogl/winsys/cogl-winsys-glx.c
index 03a2e64..ca51476 100644
--- a/cogl/winsys/cogl-winsys-glx.c
+++ b/cogl/winsys/cogl-winsys-glx.c
@@ -287,8 +287,7 @@ set_info_complete (CoglOnscreen *onscreen)
   CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
   CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
   CoglGLXDisplay *glx_display = context->display->winsys;
-  int64_t frame_counter = cogl_onscreen_get_frame_counter (onscreen);
-  CoglFrameInfo *info = cogl_onscreen_get_frame_info (onscreen, frame_counter);
+  CoglFrameInfo *info = g_queue_peek_tail (&onscreen->pending_frame_infos);
 
   info->complete = TRUE;
 
@@ -316,8 +315,7 @@ notify_swap_buffers (CoglContext *context, GLXBufferSwapComplete *swap_event)
 
   if (swap_event->ust != 0)
     {
-      int64_t frame_counter = cogl_onscreen_get_frame_counter (onscreen);
-      CoglFrameInfo *info = cogl_onscreen_get_frame_info (onscreen, frame_counter);
+      CoglFrameInfo *info = g_queue_peek_tail (&onscreen->pending_frame_infos);
 
       info->presentation_time =
         ust_to_nanoseconds (context->display->renderer,
@@ -1422,8 +1420,7 @@ _cogl_winsys_wait_for_vblank (CoglOnscreen *onscreen)
   if (glx_renderer->glXWaitForMsc ||
       glx_renderer->glXGetVideoSync)
     {
-      int64_t frame_counter = cogl_onscreen_get_frame_counter (onscreen);
-      CoglFrameInfo *info = cogl_onscreen_get_frame_info (onscreen, frame_counter);
+      CoglFrameInfo *info = g_queue_peek_tail (&onscreen->pending_frame_infos);
 
       if (glx_renderer->glXWaitForMsc)
         {
@@ -1476,8 +1473,7 @@ static void
 set_frame_info_output (CoglOnscreen *onscreen,
                        CoglOutput *output)
 {
-  int64_t frame_counter = cogl_onscreen_get_frame_counter (onscreen);
-  CoglFrameInfo *info = cogl_onscreen_get_frame_info (onscreen, frame_counter);
+  CoglFrameInfo *info = g_queue_peek_tail (&onscreen->pending_frame_infos);
 
   info->output = output;
 
@@ -2459,18 +2455,20 @@ flush_pending_notifications_cb (void *data,
 
       if (glx_onscreen->pending_sync_notify)
         {
-          int64_t frame_counter = cogl_onscreen_get_frame_counter (onscreen);
-          CoglFrameInfo *info = cogl_onscreen_get_frame_info (onscreen, frame_counter);
+          CoglFrameInfo *info = g_queue_peek_tail (&onscreen->pending_frame_infos);
+
           _cogl_onscreen_notify_frame_sync (onscreen, info);
           glx_onscreen->pending_sync_notify = FALSE;
         }
 
       if (glx_onscreen->pending_complete_notify)
         {
-          int64_t frame_counter = cogl_onscreen_get_frame_counter (onscreen);
-          CoglFrameInfo *info = cogl_onscreen_get_frame_info (onscreen, frame_counter);
+          CoglFrameInfo *info = g_queue_pop_tail (&onscreen->pending_frame_infos);
+
           _cogl_onscreen_notify_complete (onscreen, info);
           glx_onscreen->pending_complete_notify = FALSE;
+
+          cogl_object_unref (info);
         }
 
       if (glx_onscreen->pending_resize_notify)



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