[Cogl] [PATCH] Add cogl_onscreen_add_swap_complete_callback() api

Owen Taylor otaylor at redhat.com
Thu Jan 24 11:11:52 PST 2013


At this point, I lose track of what's going on in

 wip/rib/frame-synchronization

This patch does a bunch of different things.

 * Reworks the callback structure - I think with the later patches
   on top in your branch the final API is fine,  but code is removed
   from the GLX code that I believe is necessary to dispatch the right
   event at the right time, and I don't see it added back later.

 * Removes a public frame history indexed by frame counter. 
   If you dislike it, I don't need it, could be added back later.

 * Removes begin_frame() and the idea that there is a current frame
   while drawing and any ability to access the FrameInfo until you
   get the first event. I disagree with these changes. It means that
   any history that an application keeps is going to have a strange
   structure where frames that have been drawn don't appear in the
   history until later.

 * Removes the frame time. Don't really care - I think it's a useful
   concept, but if you want COGL really to be minimal and imply nothing
   about the structure of the application, I can see where it could
   be considered an extraneous 

 * Replaces the refresh interval in the FrameInfo with the Output - with
   your later changes to add the refresh interval back in addition,
   this is OK.

My plan of attack here is to rebase your patches that I agree
with before this patch, and then rework this patch to go directly to
your final API and not pull in the changes that I disagree with, then we
can discuss those more separately :-)

- Owen

On Tue, 2012-12-04 at 18:08 +0000, Robert Bragg wrote:
> From: Robert Bragg <robert at linux.intel.com>
> 
> Here's another patch to show what I was thinking about with regards to
> removing the history related apis and instead passing the information to
> applications via a modified swap-complete callback api.
> 
> -- >8--
> 
> This adds cogl_onscreen_add/remove_swap_complete_callback() functions to
> replace the cogl_onscreen_add/remove_swap_buffers_callback() functions
> where the new api passes a CoglSwapInfo pointer to the callback which
> provides meta data about the completed swap such as timing information.
> 
> This patch also removes the following public functions:
> cogl_onscreen_begin_frame
> cogl_onscreen_get_frame_history_start
> cogl_onscreen_get_swap_info
> cogl_onscreen_add_swap_info_callback
> cogl_onscreen_remove_swap_info_callback
> cogl_swap_info_get_complete
> cogl_swap_info_get_frame_time
> cogl_swap_info_get_refresh_interval
> 
> and adds cogl_swap_info_get_output
> 
> TODO: squash this back into owen's patch
> ---
>  cogl/cogl-context-private.h   |    2 +
>  cogl/cogl-onscreen-private.h  |   36 ++------
>  cogl/cogl-onscreen.c          |  214 ++++++++++++++++++-----------------------
>  cogl/cogl-onscreen.h          |  169 +++++++++++++--------------------
>  cogl/cogl-swap-info-private.h |    5 +-
>  cogl/cogl-swap-info.c         |   18 +---
>  cogl/cogl-swap-info.h         |   44 ++-------
>  cogl/winsys/cogl-winsys-glx.c |   81 ++++------------
>  8 files changed, 198 insertions(+), 371 deletions(-)
> 
> diff --git a/cogl/cogl-context-private.h b/cogl/cogl-context-private.h
> index 85d107c..da114ba 100644
> --- a/cogl/cogl-context-private.h
> +++ b/cogl/cogl-context-private.h
> @@ -184,6 +184,8 @@ struct _CoglContext
>    gboolean have_last_offscreen_allocate_flags;
>    CoglOffscreenAllocateFlags last_offscreen_allocate_flags;
>  
> +  int next_swap_complete_callback_id;
> +
>    CoglGLES2Context *current_gles2_context;
>    GQueue gles2_context_stack;
>  
> diff --git a/cogl/cogl-onscreen-private.h b/cogl/cogl-onscreen-private.h
> index 08fd5ec..a90ac43 100644
> --- a/cogl/cogl-onscreen-private.h
> +++ b/cogl/cogl-onscreen-private.h
> @@ -33,17 +33,15 @@
>  #include <windows.h>
>  #endif
>  
> -#define COGL_ONSCREEN_MAX_SWAP_INFOS 16
> +typedef struct _CoglSwapCompleteNotifyEntry CoglSwapCompleteNotifyEntry;
>  
> -typedef struct _CoglSwapBuffersNotifyEntry CoglSwapBuffersNotifyEntry;
> +COGL_TAILQ_HEAD (CoglSwapCompleteNotifyList, CoglSwapCompleteNotifyEntry);
>  
> -COGL_TAILQ_HEAD (CoglSwapBuffersNotifyList, CoglSwapBuffersNotifyEntry);
> -
> -struct _CoglSwapBuffersNotifyEntry
> +struct _CoglSwapCompleteNotifyEntry
>  {
> -  COGL_TAILQ_ENTRY (CoglSwapBuffersNotifyEntry) list_node;
> +  COGL_TAILQ_ENTRY (CoglSwapCompleteNotifyEntry) list_node;
>  
> -  CoglSwapBuffersNotify callback;
> +  CoglSwapCompleteNotify callback;
>    void *user_data;
>    unsigned int id;
>  };
> @@ -61,19 +59,6 @@ struct _CoglResizeNotifyEntry
>    unsigned int id;
>  };
>  
> -typedef struct _CoglSwapInfoCallbackEntry CoglSwapInfoCallbackEntry;
> -
> -COGL_TAILQ_HEAD (CoglSwapInfoCallbackList, CoglSwapInfoCallbackEntry);
> -
> -struct _CoglSwapInfoCallbackEntry
> -{
> -  COGL_TAILQ_ENTRY (CoglSwapInfoCallbackEntry) list_node;
> -
> -  CoglSwapInfoCallback callback;
> -  void *user_data;
> -  unsigned int id;
> -};
> -
>  struct _CoglOnscreen
>  {
>    CoglFramebuffer  _parent;
> @@ -90,20 +75,16 @@ struct _CoglOnscreen
>  
>    CoglBool swap_throttled;
>  
> -  CoglSwapBuffersNotifyList swap_callbacks;
> +  CoglSwapCompleteNotifyList swap_callbacks;
>  
>    CoglBool resizable;
>    CoglResizeNotifyList resize_callbacks;
>  
> -  CoglSwapInfoCallbackList swap_info_callbacks;
> -
>    int64_t frame_counter;
>    int64_t swap_frame_counter; /* frame counter at last all to
>                                 * cogl_onscreen_swap_region() or
>                                 * cogl_onscreen_swap_buffers() */
> -  CoglSwapInfo *swap_info[COGL_ONSCREEN_MAX_SWAP_INFOS];
> -  int current_swap_info;
> -  int n_swap_infos;
> +  GQueue pending_swap_infos;
>  
>    void *winsys;
>  };
> @@ -121,7 +102,4 @@ _cogl_onscreen_notify_swap_buffers (CoglOnscreen *onscreen);
>  void
>  _cogl_onscreen_notify_resize (CoglOnscreen *onscreen);
>  
> -void
> -_cogl_onscreen_notify_swap_info (CoglOnscreen *onscreen);
> -
>  #endif /* __COGL_ONSCREEN_PRIVATE_H */
> diff --git a/cogl/cogl-onscreen.c b/cogl/cogl-onscreen.c
> index 6df0583..374e0b9 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);
> @@ -50,7 +48,6 @@ _cogl_onscreen_init_from_template (CoglOnscreen *onscreen,
>  
>    COGL_TAILQ_INIT (&onscreen->swap_callbacks);
>    COGL_TAILQ_INIT (&onscreen->resize_callbacks);
> -  COGL_TAILQ_INIT (&onscreen->swap_info_callbacks);
>  
>    framebuffer->config = onscreen_template->config;
>    cogl_object_ref (framebuffer->config.swap_chain);
> @@ -79,9 +76,6 @@ _cogl_onscreen_new (void)
>  
>    COGL_FRAMEBUFFER (onscreen)->allocated = TRUE;
>  
> -  onscreen->frame_counter = -1;
> -  onscreen->current_swap_info = COGL_ONSCREEN_MAX_SWAP_INFOS - 1;
> -
>    /* XXX: Note we don't initialize onscreen->winsys in this case. */
>  
>    return _cogl_onscreen_object_new (onscreen);
> @@ -122,7 +116,8 @@ _cogl_onscreen_free (CoglOnscreen *onscreen)
>    CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
>    const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
>    CoglResizeNotifyEntry *resize_entry;
> -  CoglSwapBuffersNotifyEntry *swap_entry;
> +  CoglSwapCompleteNotifyEntry *swap_entry;
> +  CoglSwapInfo *swap_info;
>  
>    while ((resize_entry = COGL_TAILQ_FIRST (&onscreen->resize_callbacks)))
>      {
> @@ -133,9 +128,13 @@ _cogl_onscreen_free (CoglOnscreen *onscreen)
>    while ((swap_entry = COGL_TAILQ_FIRST (&onscreen->swap_callbacks)))
>      {
>        COGL_TAILQ_REMOVE (&onscreen->swap_callbacks, swap_entry, list_node);
> -      g_slice_free (CoglSwapBuffersNotifyEntry, swap_entry);
> +      g_slice_free (CoglSwapCompleteNotifyEntry, swap_entry);
>      }
>  
> +  while ((swap_info = g_queue_pop_tail (&onscreen->pending_swap_infos)))
> +    cogl_object_unref (swap_info);
> +  g_queue_clear (&onscreen->pending_swap_infos);
> +
>    if (framebuffer->context->window_buffer == COGL_FRAMEBUFFER (onscreen))
>      framebuffer->context->window_buffer = NULL;
>  
> @@ -153,10 +152,13 @@ cogl_onscreen_swap_buffers (CoglOnscreen *onscreen)
>  {
>    CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
>    const CoglWinsysVtable *winsys;
> +  CoglSwapInfo *info;
>  
>    _COGL_RETURN_IF_FAIL  (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN);
>  
> -  cogl_onscreen_before_swap (onscreen);
> +  info = _cogl_swap_info_new ();
> +  info->frame_counter = onscreen->frame_counter;
> +  g_queue_push_tail (&onscreen->pending_swap_infos, info);
>  
>    /* FIXME: we shouldn't need to flush *all* journals here! */
>    cogl_flush ();
> @@ -166,6 +168,7 @@ cogl_onscreen_swap_buffers (CoglOnscreen *onscreen)
>                                      COGL_BUFFER_BIT_COLOR |
>                                      COGL_BUFFER_BIT_DEPTH |
>                                      COGL_BUFFER_BIT_STENCIL);
> +  onscreen->frame_counter++;
>  }
>  
>  void
> @@ -175,10 +178,13 @@ cogl_onscreen_swap_region (CoglOnscreen *onscreen,
>  {
>    CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
>    const CoglWinsysVtable *winsys;
> +  CoglSwapInfo *info;
>  
>    _COGL_RETURN_IF_FAIL  (framebuffer->type == COGL_FRAMEBUFFER_TYPE_ONSCREEN);
>  
> -  cogl_onscreen_before_swap (onscreen);
> +  info = _cogl_swap_info_new ();
> +  info->frame_counter = onscreen->frame_counter;
> +  g_queue_push_tail (&onscreen->pending_swap_infos, info);
>  
>    /* FIXME: we shouldn't need to flush *all* journals here! */
>    cogl_flush ();
> @@ -197,6 +203,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
> @@ -282,37 +289,94 @@ cogl_win32_onscreen_get_window (CoglOnscreen *onscreen)
>  #endif /* COGL_HAS_WIN32_SUPPORT */
>  
>  unsigned int
> -cogl_onscreen_add_swap_buffers_callback (CoglOnscreen *onscreen,
> -                                         CoglSwapBuffersNotify callback,
> -                                         void *user_data)
> +cogl_onscreen_add_swap_complete_callback (CoglOnscreen *onscreen,
> +                                          CoglSwapCompleteNotify callback,
> +                                          void *user_data)
>  {
> -  CoglSwapBuffersNotifyEntry *entry = g_slice_new0 (CoglSwapBuffersNotifyEntry);
> -  static int next_swap_buffers_callback_id = 0;
> +  CoglSwapCompleteNotifyEntry *entry = g_slice_new0 (CoglSwapCompleteNotifyEntry);
> +  CoglContext *ctx = COGL_FRAMEBUFFER (onscreen)->context;
>  
>    entry->callback = callback;
>    entry->user_data = user_data;
> -  entry->id = next_swap_buffers_callback_id++;
> +  entry->id = ctx->next_swap_complete_callback_id++;
>  
>    COGL_TAILQ_INSERT_TAIL (&onscreen->swap_callbacks, entry, list_node);
>  
>    return entry->id;
>  }
>  
> -void
> -cogl_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen,
> -                                            unsigned int id)
> +static CoglSwapCompleteNotifyEntry *
> +remove_swap_complete_notify_entry (CoglOnscreen *onscreen,
> +                                   unsigned int id)
>  {
> -  CoglSwapBuffersNotifyEntry *entry;
> +  CoglSwapCompleteNotifyEntry *entry;
>  
>    COGL_TAILQ_FOREACH (entry, &onscreen->swap_callbacks, list_node)
>      {
>        if (entry->id == id)
>          {
>            COGL_TAILQ_REMOVE (&onscreen->swap_callbacks, entry, list_node);
> -          g_slice_free (CoglSwapBuffersNotifyEntry, entry);
> -          break;
> +          return entry;
>          }
>      }
> +
> +  return NULL;
> +}
> +
> +void
> +cogl_onscreen_remove_swap_complete_callback (CoglOnscreen *onscreen,
> +                                             unsigned int id)
> +{
> +  CoglSwapCompleteNotifyEntry *entry =
> +    remove_swap_complete_notify_entry (onscreen, id);
> +
> +  if (entry)
> +    g_slice_free (CoglSwapCompleteNotifyEntry, entry);
> +}
> +
> +typedef struct _SwapBufferCallbackState
> +{
> +  CoglSwapBuffersNotify callback;
> +  void *user_data;
> +} SwapBufferCallbackState;
> +
> +static void
> +shim_swap_buffers_callback (CoglOnscreen *onscreen,
> +                            CoglSwapInfo *info,
> +                            void *user_data)
> +{
> +  SwapBufferCallbackState *state = user_data;
> +
> +  state->callback (COGL_FRAMEBUFFER (onscreen), state->user_data);
> +}
> +
> +unsigned int
> +cogl_onscreen_add_swap_buffers_callback (CoglOnscreen *onscreen,
> +                                         CoglSwapBuffersNotify callback,
> +                                         void *user_data)
> +{
> +  SwapBufferCallbackState *state = g_slice_new (SwapBufferCallbackState);
> +
> +  state->callback = callback;
> +  state->user_data = user_data;
> +
> +  return cogl_onscreen_add_swap_complete_callback (onscreen,
> +                                                   shim_swap_buffers_callback,
> +                                                   state);
> +}
> +
> +void
> +cogl_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen,
> +                                            unsigned int id)
> +{
> +  CoglSwapCompleteNotifyEntry *entry =
> +    remove_swap_complete_notify_entry (onscreen, id);
> +
> +  if (entry)
> +    {
> +      g_slice_free (SwapBufferCallbackState, entry->user_data);
> +      g_slice_free (CoglSwapCompleteNotifyEntry, entry);
> +    }
>  }
>  
>  void
> @@ -363,13 +427,17 @@ cogl_onscreen_hide (CoglOnscreen *onscreen)
>  void
>  _cogl_onscreen_notify_swap_buffers (CoglOnscreen *onscreen)
>  {
> -  CoglSwapBuffersNotifyEntry *entry, *tmp;
> +  CoglSwapCompleteNotifyEntry *entry, *tmp;
>  
>    COGL_TAILQ_FOREACH_SAFE (entry,
>                             &onscreen->swap_callbacks,
>                             list_node,
>                             tmp)
> -    entry->callback (COGL_FRAMEBUFFER (onscreen), entry->user_data);
> +    {
> +      CoglSwapInfo *info = g_queue_pop_tail (&onscreen->pending_swap_infos);
> +
> +      entry->callback (onscreen, info, entry->user_data);
> +    }
>  }
>  
>  void
> @@ -478,101 +546,3 @@ cogl_onscreen_get_frame_counter (CoglOnscreen *onscreen)
>  {
>    return onscreen->frame_counter;
>  }
> -
> -void
> -cogl_onscreen_begin_frame (CoglOnscreen *onscreen,
> -                           int64_t frame_time)
> -{
> -  onscreen->frame_counter++;
> -  onscreen->current_swap_info = (onscreen->current_swap_info + 1) % COGL_ONSCREEN_MAX_SWAP_INFOS;
> -
> -  if (onscreen->n_swap_infos < COGL_ONSCREEN_MAX_SWAP_INFOS)
> -    onscreen->n_swap_infos++;
> -  else
> -    cogl_object_unref (onscreen->swap_info[onscreen->current_swap_info]);
> -
> -  onscreen->swap_info[onscreen->current_swap_info] = _cogl_swap_info_new ();
> -  onscreen->swap_info[onscreen->current_swap_info]->frame_counter = onscreen->frame_counter;
> -  onscreen->swap_info[onscreen->current_swap_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_swap_infos;
> -}
> -
> -CoglSwapInfo *
> -cogl_onscreen_get_swap_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_swap_infos)
> -    return NULL;
> -
> -  pos = ((onscreen->current_swap_info -
> -          (onscreen->frame_counter - frame_counter) + COGL_ONSCREEN_MAX_SWAP_INFOS)
> -         % COGL_ONSCREEN_MAX_SWAP_INFOS);
> -
> -  return onscreen->swap_info[pos];
> -}
> -
> -unsigned int
> -cogl_onscreen_add_swap_info_callback (CoglOnscreen *onscreen,
> -                                          CoglSwapInfoCallback callback,
> -                                          void *user_data)
> -{
> -  CoglSwapInfoCallbackEntry *entry = g_slice_new (CoglSwapInfoCallbackEntry);
> -  static int next_resize_callback_id = 0;
> -
> -  entry->callback = callback;
> -  entry->user_data = user_data;
> -  entry->id = next_resize_callback_id++;
> -
> -  COGL_TAILQ_INSERT_TAIL (&onscreen->swap_info_callbacks, entry, list_node);
> -
> -  return entry->id;
> -}
> -
> -void
> -cogl_onscreen_remove_swap_info_callback (CoglOnscreen *onscreen,
> -                                             unsigned int id)
> -{
> -  CoglSwapInfoCallbackEntry *entry;
> -
> -  COGL_TAILQ_FOREACH (entry, &onscreen->swap_info_callbacks, list_node)
> -    {
> -      if (entry->id == id)
> -        {
> -          COGL_TAILQ_REMOVE (&onscreen->swap_info_callbacks, entry, list_node);
> -          g_slice_free (CoglSwapInfoCallbackEntry, entry);
> -          break;
> -        }
> -    }
> -}
> -
> -void
> -_cogl_onscreen_notify_swap_info (CoglOnscreen *onscreen)
> -{
> -  CoglSwapInfoCallbackEntry *entry, *tmp;
> -
> -  COGL_TAILQ_FOREACH_SAFE (entry,
> -                           &onscreen->swap_info_callbacks,
> -                           list_node,
> -                           tmp)
> -    entry->callback (onscreen, entry->user_data);
> -}
> -
> diff --git a/cogl/cogl-onscreen.h b/cogl/cogl-onscreen.h
> index a82895b..d31aebc 100644
> --- a/cogl/cogl-onscreen.h
> +++ b/cogl/cogl-onscreen.h
> @@ -333,6 +333,70 @@ cogl_onscreen_swap_region (CoglOnscreen *onscreen,
>                             const int *rectangles,
>                             int n_rectangles);
>  
> +/**
> + * CoglSwapCompleteNotify:
> + * @onscreen: The onscreen framebuffer who's swap has completed
> + * @info: Meta information, such as timing information, about the
> + *        completed swap
> + * @user_data: The user pointer passed to
> + *             cogl_onscreen_add_swap_complete_callback()
> + *
> + * Is a callback that can be registered via
> + * cogl_onscreen_add_swap_complete_callback() to be notified when a
> + * swap buffers request made with cogl_onscreen_swap_buffers() has
> + * completed and to be able to receive meta information about the
> + * completed swap, such as timing information.
> + *
> + * Since: 1.14
> + * Stability: unstable
> + */
> +typedef void (*CoglSwapCompleteNotify) (CoglOnscreen *onscreen,
> +                                        CoglSwapInfo *info,
> +                                        void *user_data);
> +
> +/**
> + * cogl_onscreen_add_swap_complete_callback:
> + * @onscreen: A #CoglOnscreen framebuffer
> + * @callback: A callback function to call when a swap has completed
> + * @user_data: A private pointer to be passed to @callback
> + *
> + * Installs a @callback function that should be called whenever a swap buffers
> + * request (made using cogl_onscreen_swap_buffers()) for the given
> + * @onscreen completes.
> + *
> + * <note>Applications should check for the %COGL_FEATURE_ID_SWAP_BUFFERS_EVENT
> + * feature before using this API. It's currently undefined when and if
> + * registered callbacks will be called if this feature is not supported.</note>
> + *
> + * We recommend using this mechanism when available to manually throttle your
> + * applications (in conjunction with  cogl_onscreen_set_swap_throttled()) so
> + * your application will be able to avoid long blocks in the driver caused by
> + * throttling when you request to swap buffers too quickly.
> + *
> + * Return value: a unique identifier that can be used to remove to remove
> + *               the callback later.
> + * Since: 1.14
> + * Stability: unstable
> + */
> +unsigned int
> +cogl_onscreen_add_swap_complete_callback (CoglOnscreen *onscreen,
> +                                          CoglSwapCompleteNotify callback,
> +                                          void *user_data);
> +
> +/**
> + * cogl_onscreen_remove_swap_complete_callback:
> + * @onscreen: A #CoglOnscreen
> + * @id: An identifier returned from cogl_onscreen_add_swap_complete_callback()
> + *
> + * Removes a callback that was previously registered
> + * using cogl_onscreen_add_swap_complete_callback().
> + *
> + * Since: 1.14
> + * Stability: unstable
> + */
> +void
> +cogl_onscreen_remove_swap_complete_callback (CoglOnscreen *onscreen,
> +                                             unsigned int id);
>  
>  typedef void (*CoglSwapBuffersNotify) (CoglFramebuffer *framebuffer,
>                                         void *user_data);
> @@ -360,6 +424,7 @@ typedef void (*CoglSwapBuffersNotify) (CoglFramebuffer *framebuffer,
>   *               the callback later.
>   * Since: 1.10
>   * Stability: unstable
> + * Deprecated: 1.14: Use cogl_onscreen_add_swap_complete_callback
>   */
>  unsigned int
>  cogl_onscreen_add_swap_buffers_callback (CoglOnscreen *onscreen,
> @@ -376,6 +441,7 @@ cogl_onscreen_add_swap_buffers_callback (CoglOnscreen *onscreen,
>   *
>   * Since: 1.10
>   * Stability: unstable
> + * Deprecated: 1.14: Use cogl_onscreen_remove_swap_complete_callback
>   */
>  void
>  cogl_onscreen_remove_swap_buffers_callback (CoglOnscreen *onscreen,
> @@ -547,109 +613,6 @@ cogl_is_onscreen (void *object);
>  int64_t
>  cogl_onscreen_get_frame_counter (CoglOnscreen *onscreen);
>  
> -/**
> - * cogl_onscreen_begin_frame:
> - * @onscreen: a #CoglOnscreen framebuffer
> - * @frame_time: the time that should be used for creating
> - *   content for this frame.
> - *
> - * Marks the beginning of a frame. This increases the frame
> - * counter value and creates a new #CoglSwapInfo objeect.
> - *
> - * Since: 2.0
> - */
> -void
> -cogl_onscreen_begin_frame (CoglOnscreen *onscreen,
> -                           int64_t frame_time);
> -
> -/**
> - * cogl_onscreen_get_frame_history_start:
> - * @onscreen: a #CoglOnscreen framebuffer
> - *
> - * Gets the frame counter for the oldest #CoglSwapInfo that is
> - * being kept in the history. cogl_onscreen_get_swap_info() will
> - * always return %NULl for any frame counter before this.
> - *
> - * Return value: the frame counter for the oldest #CoglSwapInfo
> - *  in the history.
> - * Since: 2.0
> - */
> -int64_t
> -cogl_onscreen_get_frame_history_start (CoglOnscreen *onscreen);
> -
> -
> -/**
> - * cogl_onscreen_get_swap_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 #CoglSwapInfo object, or %NULL if swap info
> - *   information is not available for the given frame.
> - * Since: 2.0
> - */
> -CoglSwapInfo *
> -cogl_onscreen_get_swap_info (CoglOnscreen *onscreen,
> -                             int64_t frame_counter);
> -
> -/**
> - * CoglSwapInfoCallback:
> - * @onscreen: A #CoglOnscreen framebuffer that has updated timing information
> - * @user_data: The private passed to
> - *             cogl_onscreen_add_swap_info_callback()
> - *
> - * Is a callback type used with the
> - * cogl_onscreen_add_swap_info_callback() allowing applications to be
> - * notified whenever new frame timings information is available
> - * via cogl_onscreen_get_swap_info().
> - *
> - * <note>A frame timings callback will only ever be called while dispatching
> - * Cogl events from the system mainloop; so for example during
> - * cogl_poll_dispatch(). This is so that callbacks shouldn't occur
> - * while an application might have arbitrary locks held for
> - * example.</note>
> - *
> - * Since: 2.0
> - */
> -typedef void (*CoglSwapInfoCallback) (CoglOnscreen *onscreen,
> -                                      void *user_data);
> -
> -/**
> - * cogl_onscreen_add_swap_info_callback:
> - * @onscreen: A #CoglOnscreen framebuffer
> - * @callback: A callback function to call when new frame timings information is available
> - * @user_data: A private pointer to be passed to @callback
> - *
> - * Installs a @callback function that should be called whenever new data
> - * is available via cogl_onscreen_get_swap_info().
> - *
> - * Return value: a unique identifier that can be used to remove to remove
> - *               the callback later.
> - * Since: 2.0
> - * Stability: unstable
> - */
> -unsigned int
> -cogl_onscreen_add_swap_info_callback (CoglOnscreen *onscreen,
> -                                      CoglSwapInfoCallback callback,
> -                                      void *user_data);
> -
> -/**
> - * cogl_onscreen_remove_swap_info_callback:
> - * @onscreen: A #CoglOnscreen framebuffer
> - * @id: An identifier returned from cogl_onscreen_add_swap_info_callback()
> - *
> - * Removes a callback that was previously registered
> - * using cogl_onscreen_add_swap_info_callback().
> - *
> - * Since: 1.10
> - * Stability: unstable
> - */
> -void
> -cogl_onscreen_remove_swap_info_callback (CoglOnscreen *onscreen,
> -                                         unsigned int id);
> -
>  G_END_DECLS
>  
>  #endif /* __COGL_ONSCREEN_H */
> diff --git a/cogl/cogl-swap-info-private.h b/cogl/cogl-swap-info-private.h
> index 2697d53..61953fa 100644
> --- a/cogl/cogl-swap-info-private.h
> +++ b/cogl/cogl-swap-info-private.h
> @@ -26,17 +26,16 @@
>  
>  #include "cogl-swap-info.h"
>  #include "cogl-object-private.h"
> +#include "cogl-output.h"
>  
>  struct _CoglSwapInfo
>  {
>    CoglObject _parent;
>  
>    int64_t frame_counter;
> -  int64_t frame_time;
>    int64_t presentation_time;
> -  int64_t refresh_interval;
>  
> -  unsigned int complete : 1;
> +  CoglOutput *output;
>  };
>  
>  CoglSwapInfo *_cogl_swap_info_new (void);
> diff --git a/cogl/cogl-swap-info.c b/cogl/cogl-swap-info.c
> index b2dda13..e8f83bd 100644
> --- a/cogl/cogl-swap-info.c
> +++ b/cogl/cogl-swap-info.c
> @@ -47,12 +47,6 @@ _cogl_swap_info_free (CoglSwapInfo *info)
>    g_slice_free (CoglSwapInfo, info);
>  }
>  
> -CoglBool
> -cogl_swap_info_get_complete (CoglSwapInfo *info)
> -{
> -  return info->complete;
> -}
> -
>  int64_t
>  cogl_swap_info_get_frame_counter (CoglSwapInfo *info)
>  {
> @@ -60,19 +54,13 @@ cogl_swap_info_get_frame_counter (CoglSwapInfo *info)
>  }
>  
>  int64_t
> -cogl_swap_info_get_frame_time (CoglSwapInfo *info)
> -{
> -  return info->frame_time;
> -}
> -
> -int64_t
>  cogl_swap_info_get_presentation_time (CoglSwapInfo *info)
>  {
>    return info->presentation_time;
>  }
>  
> -int64_t
> -cogl_swap_info_get_refresh_interval (CoglSwapInfo *info)
> +CoglOutput *
> +cogl_swap_info_get_output (CoglSwapInfo *info)
>  {
> -  return info->refresh_interval;
> +  return info->output;
>  }
> diff --git a/cogl/cogl-swap-info.h b/cogl/cogl-swap-info.h
> index 710d005..62728b6 100644
> --- a/cogl/cogl-swap-info.h
> +++ b/cogl/cogl-swap-info.h
> @@ -32,6 +32,7 @@
>  #define __COGL_SWAP_INFO_H
>  
>  #include <cogl/cogl-types.h>
> +#include <cogl/cogl-output.h>
>  #include <glib.h>
>  
>  G_BEGIN_DECLS
> @@ -54,20 +55,6 @@ CoglBool
>  cogl_is_swap_info (void *object);
>  
>  /**
> - * cogl_swap_info_get_complete:
> - * @info: a #CoglSwapInfo object
> - *
> - * Gets whether all information that will potentially be provided for
> - * the frame has been provided. Once a swap info object is complete,
> - * no further changes will be made to it.
> - *
> - * Return value: whether the swap info object is complete.
> - * Since: 2.0
> - * Stability: unstable
> - */
> -CoglBool cogl_swap_info_get_complete (CoglSwapInfo *info);
> -
> -/**
>   * cogl_swap_info_get_frame_counter:
>   * @info: a #CoglSwapInfo object
>   *
> @@ -81,22 +68,6 @@ CoglBool cogl_swap_info_get_complete (CoglSwapInfo *info);
>  int64_t cogl_swap_info_get_frame_counter (CoglSwapInfo *info);
>  
>  /**
> - * cogl_swap_info_get_frame_time:
> - * @info: a #CoglSwapInfo object
> - *
> - * Gets the time used for creating content for the frame. This
> - * is determined by the time passed to cogl_onscreen_begin_frame(),
> - * and will typically be the current time when rendering started
> - * for the frame.
> - *
> - * Return value: the time used for coreating content for the frame,
> - *  in the timescale of g_get_monotonic_time().
> - * Since: 2.0
> - * Stability: unstable
> - */
> -int64_t cogl_swap_info_get_frame_time (CoglSwapInfo *info);
> -
> -/**
>   * cogl_swap_info_get_presentation_time:
>   * @info: a #CoglSwapInfo object
>   *
> @@ -111,19 +82,18 @@ int64_t cogl_swap_info_get_frame_time (CoglSwapInfo *info);
>  int64_t cogl_swap_info_get_presentation_time (CoglSwapInfo *info);
>  
>  /**
> - * cogl_swap_info_get_refresh_interval:
> + * cogl_swap_info_get_output:
>   * @info: a #CoglSwapInfo object
>   *
> - * Gets the refresh interval for the output that the frame was on at the
> - * time the frame was presented. This is the number of microseconds between
> - * refreshes of the screen, and is equal to 1000000 / refresh_rate.
> + * Gets the #CoglOutput that the swapped frame was presented to.
>   *
> - * Return value: the refresh interval, in microsecoonds.
> - *  .
> + * Return value: The #CoglOutput that the frame was presented to, or
> + *               %NULL if this could not be determined.
>   * Since: 2.0
>   * Stability: unstable
>   */
> -int64_t cogl_swap_info_get_refresh_interval (CoglSwapInfo *info);
> +CoglOutput *
> +cogl_swap_info_get_output (CoglSwapInfo *info);
>  
>  G_END_DECLS
>  
> diff --git a/cogl/winsys/cogl-winsys-glx.c b/cogl/winsys/cogl-winsys-glx.c
> index 5d1bda5..2917b6c 100644
> --- a/cogl/winsys/cogl-winsys-glx.c
> +++ b/cogl/winsys/cogl-winsys-glx.c
> @@ -273,29 +273,12 @@ ust_to_monotonic_time (CoglRenderer *renderer,
>  }
>  
>  static void
> -set_info_complete (CoglOnscreen *onscreen)
> -{
> -  CoglOnscreenGLX *glx_onscreen = onscreen->winsys;
> -  CoglContext *context = COGL_FRAMEBUFFER (onscreen)->context;
> -  CoglGLXDisplay *glx_display = context->display->winsys;
> -  int frame_counter = cogl_onscreen_get_frame_counter (onscreen);
> -  CoglSwapInfo *info = cogl_onscreen_get_swap_info (onscreen, frame_counter);
> -
> -  info->complete = TRUE;
> -
> -  glx_display->pending_swap_info_notify = TRUE;
> -  glx_onscreen->pending_swap_info_notify = TRUE;
> -}
> -
> -static void
>  notify_swap_buffers (CoglContext *context, GLXBufferSwapComplete *swap_event)
>  {
>    CoglOnscreen *onscreen = find_onscreen_for_xid (context, (uint32_t)swap_event->drawable);
>    CoglDisplay *display = context->display;
>    CoglGLXDisplay *glx_display = display->winsys;
>    CoglOnscreenGLX *glx_onscreen;
> -  int frame_counter;
> -  CoglSwapInfo *info;
>  
>    if (!onscreen)
>      return;
> @@ -307,14 +290,14 @@ notify_swap_buffers (CoglContext *context, GLXBufferSwapComplete *swap_event)
>    glx_display->pending_swap_notify = TRUE;
>    glx_onscreen->pending_swap_notify = TRUE;
>  
> -  frame_counter = cogl_onscreen_get_frame_counter (onscreen);
> -  info = cogl_onscreen_get_swap_info (onscreen, frame_counter);
>    if (swap_event->ust != 0)
> -    info->presentation_time = ust_to_monotonic_time (context->display->renderer,
> -                                                        glx_onscreen->glxwin,
> -                                                        swap_event->ust);
> -
> -  set_info_complete (onscreen);
> +    {
> +      CoglSwapInfo *info = g_queue_peek_tail (&onscreen->pending_swap_infos);
> +      info->presentation_time =
> +        ust_to_monotonic_time (context->display->renderer,
> +                               glx_onscreen->glxwin,
> +                               swap_event->ust);
> +    }
>  }
>  
>  static void
> @@ -1374,11 +1357,7 @@ _cogl_winsys_wait_for_vblank (CoglOnscreen *onscreen)
>    if (glx_renderer->pf_glXWaitForMsc ||
>        glx_renderer->pf_glXGetVideoSync)
>      {
> -      int frame_counter;
> -      CoglSwapInfo *info;
> -
> -      frame_counter = cogl_onscreen_get_frame_counter (onscreen);
> -      info = cogl_onscreen_get_swap_info (onscreen, frame_counter);
> +      CoglSwapInfo *info = g_queue_peek_tail (&onscreen->pending_swap_infos);
>  
>        if (glx_renderer->pf_glXWaitForMsc)
>          {
> @@ -1426,20 +1405,6 @@ _cogl_winsys_get_vsync_counter (void)
>  }
>  
>  static void
> -set_refresh_interval_from_output (CoglOnscreen *onscreen,
> -                                  CoglOutput   *output)
> -{
> -  float refresh_rate = cogl_output_get_refresh_rate (output);
> -  if (refresh_rate != 0.0)
> -    {
> -      int frame_counter = cogl_onscreen_get_frame_counter (onscreen);
> -      CoglSwapInfo *info = cogl_onscreen_get_swap_info (onscreen, frame_counter);
> -
> -      info->refresh_interval = (int)(0.5 + (1000000. / refresh_rate));
> -    }
> -}
> -
> -static void
>  _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
>                                     const int *user_rectangles,
>                                     int n_rectangles)
> @@ -1616,21 +1581,20 @@ _cogl_winsys_onscreen_swap_region (CoglOnscreen *onscreen,
>  
>    if (!xlib_onscreen->is_foreign_xwin)
>      {
> -      CoglOutput *output;
> +      CoglSwapInfo *info = g_queue_peek_tail (&onscreen->pending_swap_infos);
>  
>        x_min = CLAMP (x_min, 0, framebuffer_width);
>        x_max = CLAMP (x_max, 0, framebuffer_width);
>        y_min = CLAMP (y_min, 0, framebuffer_width);
>        y_max = CLAMP (y_max, 0, framebuffer_height);
>  
> -      output = _cogl_xlib_renderer_output_for_rectangle (context->display->renderer,
> -                                                         xlib_onscreen->x + x_min, xlib_onscreen->y + y_min,
> -                                                         x_max - x_min, y_max - y_min);
> -      if (output)
> -        set_refresh_interval_from_output (onscreen, output);
> +      info->output =
> +        _cogl_xlib_renderer_output_for_rectangle (context->display->renderer,
> +                                                  xlib_onscreen->x + x_min,
> +                                                  xlib_onscreen->y + y_min,
> +                                                  x_max - x_min,
> +                                                  y_max - y_min);
>      }
> -
> -  set_info_complete (onscreen);
>  }
>  
>  static void
> @@ -1711,11 +1675,10 @@ _cogl_winsys_onscreen_swap_buffers (CoglOnscreen *onscreen)
>      glx_onscreen->last_swap_vsync_counter = _cogl_winsys_get_vsync_counter ();
>  
>    if (xlib_onscreen->output)
> -    set_refresh_interval_from_output (onscreen, xlib_onscreen->output);
> -
> -  if (!(glx_renderer->pf_glXSwapInterval &&
> -        _cogl_winsys_has_feature (COGL_WINSYS_FEATURE_VBLANK_WAIT)))
> -    set_info_complete (onscreen);
> +    {
> +      CoglSwapInfo *info = g_queue_peek_tail (&onscreen->pending_swap_infos);
> +      info->output = xlib_onscreen->output;
> +    }
>  }
>  
>  static uint32_t
> @@ -2415,12 +2378,6 @@ flush_pending_notifications_cb (void *data,
>            _cogl_onscreen_notify_resize (onscreen);
>            glx_onscreen->pending_resize_notify = FALSE;
>          }
> -
> -      if (glx_onscreen->pending_swap_info_notify)
> -        {
> -          _cogl_onscreen_notify_swap_info (onscreen);
> -          glx_onscreen->pending_swap_info_notify = FALSE;
> -        }
>      }
>  }
>  




More information about the Cogl mailing list