[cogl/wip/rib/frame-synchronization: 8/12] Add cogl_onscreen_add_swap_complete_callback() api
- From: Robert Bragg <rbragg src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [cogl/wip/rib/frame-synchronization: 8/12] Add cogl_onscreen_add_swap_complete_callback() api
- Date: Fri, 11 Jan 2013 16:43:23 +0000 (UTC)
commit de1925267cd4d890e8e3fa5d4c5b307e04b41627
Author: Robert Bragg <robert linux intel com>
Date: Tue Dec 4 16:29:51 2012 +0000
Add cogl_onscreen_add_swap_complete_callback() api
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;
- }
}
}
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]