[Cogl] [PATCH] dispatch _COMPLETE instead of _PRESENTED frame events
Robert Bragg
robert at sixbynine.org
Thu Jan 24 12:25:52 PST 2013
From: Robert Bragg <robert at linux.intel.com>
As discussed, this removes the _PRESENTED event and adds a _COMPLETE event
instead that signifies the end of a frame.
regards,
- Robert
-- >8 --
Instead of dispatching a _PRESENTED frame event when we receive a SwapComplete
event we instead send a _COMPLETE event that signifies that a frame has
been completed and that it's a good opportunity for applications to
collect CoglFrameInfo statistics, including the _presentation_time().
---
cogl/cogl-context.h | 7 +++----
cogl/cogl-onscreen-private.h | 5 ++++-
cogl/cogl-onscreen.c | 31 ++++++++++++++++++++++++++-----
cogl/cogl-onscreen.h | 27 ++++++++++++++++-----------
cogl/winsys/cogl-winsys-egl-kms.c | 11 +++++++++--
cogl/winsys/cogl-winsys-glx.c | 12 ++++++++++--
6 files changed, 68 insertions(+), 25 deletions(-)
diff --git a/cogl/cogl-context.h b/cogl/cogl-context.h
index 840d76a..ae306d6 100644
--- a/cogl/cogl-context.h
+++ b/cogl/cogl-context.h
@@ -210,9 +210,8 @@ cogl_is_context (void *object);
* the depth buffer to a texture.
* @COGL_FEATURE_ID_FRAME_SYNC: Whether %COGL_FRAME_EVENT_SYNC events
* will be sent to registered #CoglFrameCallback functions.
- * @COGL_FEATURE_ID_PRESENTATION_EVENTS: Whether
- * %COGL_FRAME_EVENT_PRESENTED events will be sent to registered
- * #CoglFrameCallback functions.
+ * @COGL_FEATURE_ID_PRESENTATION_TIME: Whether frame presentation
+ * time stamps will be recorded in #CoglFrameInfo objects.
*
* All the capabilities that can vary between different GPUs supported
* by Cogl. Applications that depend on any of these features should explicitly
@@ -243,7 +242,7 @@ typedef enum _CoglFeatureID
COGL_FEATURE_ID_GLES2_CONTEXT,
COGL_FEATURE_ID_DEPTH_TEXTURE,
COGL_FEATURE_ID_FRAME_SYNC,
- COGL_FEATURE_ID_PRESENTATION_EVENTS,
+ COGL_FEATURE_ID_PRESENTATION_TIME,
/*< private >*/
_COGL_N_FEATURE_IDS /*< skip >*/
diff --git a/cogl/cogl-onscreen-private.h b/cogl/cogl-onscreen-private.h
index fd516c1..c712e72 100644
--- a/cogl/cogl-onscreen-private.h
+++ b/cogl/cogl-onscreen-private.h
@@ -97,7 +97,10 @@ _cogl_framebuffer_winsys_update_size (CoglFramebuffer *framebuffer,
int width, int height);
void
-_cogl_onscreen_notify_swap_buffers (CoglOnscreen *onscreen);
+_cogl_onscreen_notify_frame_sync (CoglOnscreen *onscreen, CoglFrameInfo *info);
+
+void
+_cogl_onscreen_notify_complete (CoglOnscreen *onscreen, CoglFrameInfo *info);
void
_cogl_onscreen_notify_resize (CoglOnscreen *onscreen);
diff --git a/cogl/cogl-onscreen.c b/cogl/cogl-onscreen.c
index 88118d0..64f8a40 100644
--- a/cogl/cogl-onscreen.c
+++ b/cogl/cogl-onscreen.c
@@ -343,7 +343,16 @@ shim_swap_buffers_callback (CoglOnscreen *onscreen,
{
SwapBufferCallbackState *state = user_data;
- if (event == COGL_FRAME_EVENT_PRESENTED)
+ /* XXX: Note that technically it is a change in semantics for this
+ * interface to forward _SYNC events here and also makes the api
+ * name somewhat missleading.
+ *
+ * In practice though this interface is currently used by
+ * applications for throttling, not because they are strictly
+ * interested in knowing when a frame has been presented and so
+ * forwarding _SYNC events should serve them better.
+ */
+ if (event == COGL_FRAME_EVENT_SYNC)
state->callback (COGL_FRAMEBUFFER (onscreen), state->user_data);
}
@@ -432,21 +441,33 @@ cogl_onscreen_hide (CoglOnscreen *onscreen)
}
void
-_cogl_onscreen_notify_swap_buffers (CoglOnscreen *onscreen)
+_cogl_onscreen_notify_frame_sync (CoglOnscreen *onscreen, CoglFrameInfo *info)
{
CoglFrameClosure *entry, *tmp;
- CoglFrameInfo *info = g_queue_pop_tail (&onscreen->pending_frame_infos);
COGL_TAILQ_FOREACH_SAFE (entry,
&onscreen->frame_closures,
list_node,
tmp)
{
- entry->callback (onscreen, COGL_FRAME_EVENT_PRESENTED, info,
+ entry->callback (onscreen, COGL_FRAME_EVENT_SYNC, info,
entry->user_data);
}
+}
+
+void
+_cogl_onscreen_notify_complete (CoglOnscreen *onscreen, CoglFrameInfo *info)
+{
+ CoglFrameClosure *entry, *tmp;
- cogl_object_unref (info);
+ COGL_TAILQ_FOREACH_SAFE (entry,
+ &onscreen->frame_closures,
+ list_node,
+ tmp)
+ {
+ entry->callback (onscreen, COGL_FRAME_EVENT_COMPLETE, info,
+ entry->user_data);
+ }
}
void
diff --git a/cogl/cogl-onscreen.h b/cogl/cogl-onscreen.h
index 5f664f4..9ce5cd2 100644
--- a/cogl/cogl-onscreen.h
+++ b/cogl/cogl-onscreen.h
@@ -341,11 +341,13 @@ cogl_onscreen_swap_region (CoglOnscreen *onscreen,
* new frame to be created. Only delivered
* if the %COGL_FEATURE_ID_FRAME_SYNC
* feature is supported.
- * @COGL_FRAME_EVENT_PRESENTED: Notifies that a frame has become
- * visible to the user. Only delivered
- * if the
- * %COGL_FEATURE_ID_PRESENTATION_EVENTS
- * feature is supported.
+ * @COGL_FRAME_EVENT_COMPLETE: Notifies that a frame has ended. This
+ * is a good time for applications to
+ * collect statistics about the frame
+ * since the #CoglFrameInfo should hold
+ * the most data at this point. No other
+ * events should be expected after a
+ * @COGL_FRAME_EVENT_COMPLETE event.
*
* Identifiers that are passed to #CoglFrameCallback functions
* (registered using cogl_onscreen_add_frame_callback()) that
@@ -353,11 +355,14 @@ cogl_onscreen_swap_region (CoglOnscreen *onscreen,
* means that new information will have been accumulated in the
* frame's corresponding #CoglFrameInfo object.
*
- * <note>Applications should not make assumptions about the relative
- * ordering of different types of frame events. A
- * %COGL_FRAME_EVENT_PRESENTED event can be received before a
- * %COGL_FRAME_EVENT_SYNC if the compositor is agressively throttling
- * your application.</note>
+ * The last event that will be sent for a frame will be a
+ * @COGL_FRAME_EVENT_COMPLETE event and so these are a good
+ * opportunity to collect statistics about a frame since the
+ * #CoglFrameInfo should hold the most data at this point.
+ *
+ * <note>A frame may not be completed before the next frame can start
+ * so applications should avoid needing to collect all statistics for
+ * a particular frame before they can start a new frame.</note>
*
* Since: 1.14
* Stability: unstable
@@ -365,7 +370,7 @@ cogl_onscreen_swap_region (CoglOnscreen *onscreen,
typedef enum _CoglFrameEvent
{
COGL_FRAME_EVENT_SYNC = 1,
- COGL_FRAME_EVENT_PRESENTED
+ COGL_FRAME_EVENT_COMPLETE
} CoglFrameEvent;
/**
diff --git a/cogl/winsys/cogl-winsys-egl-kms.c b/cogl/winsys/cogl-winsys-egl-kms.c
index f3e5e67..1c185c6 100644
--- a/cogl/winsys/cogl-winsys-egl-kms.c
+++ b/cogl/winsys/cogl-winsys-egl-kms.c
@@ -753,9 +753,11 @@ _cogl_winsys_egl_context_init (CoglContext *context,
CoglError **error)
{
COGL_FLAGS_SET (context->features,
+ COGL_FEATURE_ID_FRAME_SYNC, TRUE);
+ COGL_FLAGS_SET (context->features,
COGL_FEATURE_ID_SWAP_BUFFERS_EVENT, TRUE);
COGL_FLAGS_SET (context->features,
- COGL_FEATURE_ID_PRESENTATION_EVENTS, TRUE);
+ COGL_FEATURE_ID_PRESENTATION_TIME, TRUE);
COGL_FLAGS_SET (context->winsys_features,
COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT,
TRUE);
@@ -896,8 +898,13 @@ flush_pending_swap_notify_cb (void *data,
if (kms_onscreen->pending_swap_notify)
{
- _cogl_onscreen_notify_swap_buffers (onscreen);
+ CoglFrameInfo *info = g_queue_pop_tail (&onscreen->pending_frame_infos);
+
+ _cogl_onscreen_notify_frame_sync (onscreen, info);
+ _cogl_onscreen_notify_complete (onscreen, info);
kms_onscreen->pending_swap_notify = FALSE;
+
+ cogl_object_unref (info);
}
}
}
diff --git a/cogl/winsys/cogl-winsys-glx.c b/cogl/winsys/cogl-winsys-glx.c
index 1a56bb9..9e096fb 100644
--- a/cogl/winsys/cogl-winsys-glx.c
+++ b/cogl/winsys/cogl-winsys-glx.c
@@ -684,10 +684,13 @@ update_winsys_features (CoglContext *context, CoglError **error)
if (_cogl_winsys_has_feature (COGL_WINSYS_FEATURE_SWAP_BUFFERS_EVENT))
{
COGL_FLAGS_SET (context->features,
+ COGL_FEATURE_ID_FRAME_SYNC,
+ TRUE);
+ COGL_FLAGS_SET (context->features,
COGL_FEATURE_ID_SWAP_BUFFERS_EVENT,
TRUE);
COGL_FLAGS_SET (context->features,
- COGL_FEATURE_ID_PRESENTATION_EVENTS,
+ COGL_FEATURE_ID_PRESENTATION_TIME,
TRUE);
}
@@ -2424,8 +2427,13 @@ flush_pending_notifications_cb (void *data,
if (glx_onscreen->pending_swap_notify)
{
- _cogl_onscreen_notify_swap_buffers (onscreen);
+ CoglFrameInfo *info = g_queue_pop_tail (&onscreen->pending_frame_infos);
+
+ _cogl_onscreen_notify_frame_sync (onscreen, info);
+ _cogl_onscreen_notify_complete (onscreen, info);
glx_onscreen->pending_swap_notify = FALSE;
+
+ cogl_object_unref (info);
}
if (glx_onscreen->pending_resize_notify)
--
1.8.1.1
More information about the Cogl
mailing list