[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