[Cogl] [PATCH] onscreen: Make the resize callback work the same as the frame callback
Robert Bragg
robert at sixbynine.org
Fri Apr 5 03:18:31 PDT 2013
This looks good to land to me:
Reviewed-by: Robert Bragg <robert at linux.intel.com>
thanks,
- Robert
On Thu, Apr 4, 2013 at 8:41 PM, Neil Roberts <neil at linux.intel.com> wrote:
> When adding the frame callback API in 70040166 we decided on a common
> idiom for adding callbacks which would return an opaque pointer
> representing the closure for the callback. This pointer can then be
> used to later remove the callback. The closure can also contain an
> optional callback to invoke when the user data parameter is destroyed.
> The resize callback didn't work this way and instead had an integer
> handle to identify the closure. This patch changes it to work the same
> way as the frame callback.
> ---
> cogl/cogl-onscreen-private.h | 13 +++---
> cogl/cogl-onscreen.c | 77 +++++++++++++++-------------------
> cogl/cogl-onscreen.h | 52 +++++++++++++++--------
> doc/reference/cogl2/cogl2-sections.txt | 6 +++
> examples/cogl-x11-foreign.c | 2 +-
> 5 files changed, 81 insertions(+), 69 deletions(-)
>
> diff --git a/cogl/cogl-onscreen-private.h b/cogl/cogl-onscreen-private.h
> index 89efb0e..f40c515 100644
> --- a/cogl/cogl-onscreen-private.h
> +++ b/cogl/cogl-onscreen-private.h
> @@ -46,17 +46,16 @@ struct _CoglFrameClosure
> CoglUserDataDestroyCallback destroy;
> };
>
> -typedef struct _CoglResizeNotifyEntry CoglResizeNotifyEntry;
> +COGL_TAILQ_HEAD (CoglOnscreenResizeCallbackList, CoglOnscreenResizeClosure);
>
> -COGL_TAILQ_HEAD (CoglResizeNotifyList, CoglResizeNotifyEntry);
> -
> -struct _CoglResizeNotifyEntry
> +struct _CoglOnscreenResizeClosure
> {
> - COGL_TAILQ_ENTRY (CoglResizeNotifyEntry) list_node;
> + COGL_TAILQ_ENTRY (CoglOnscreenResizeClosure) list_node;
>
> CoglOnscreenResizeCallback callback;
> +
> void *user_data;
> - unsigned int id;
> + CoglUserDataDestroyCallback destroy;
> };
>
> typedef struct _CoglOnscreenEvent CoglOnscreenEvent;
> @@ -91,7 +90,7 @@ struct _CoglOnscreen
> CoglFrameCallbackList frame_closures;
>
> CoglBool resizable;
> - CoglResizeNotifyList resize_callbacks;
> + CoglOnscreenResizeCallbackList resize_closures;
>
> int64_t frame_counter;
> int64_t swap_frame_counter; /* frame counter at last all to
> diff --git a/cogl/cogl-onscreen.c b/cogl/cogl-onscreen.c
> index e79bf22..338f747 100644
> --- a/cogl/cogl-onscreen.c
> +++ b/cogl/cogl-onscreen.c
> @@ -46,7 +46,7 @@ _cogl_onscreen_init_from_template (CoglOnscreen *onscreen,
> CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
>
> COGL_TAILQ_INIT (&onscreen->frame_closures);
> - COGL_TAILQ_INIT (&onscreen->resize_callbacks);
> + COGL_TAILQ_INIT (&onscreen->resize_closures);
>
> framebuffer->config = onscreen_template->config;
> cogl_object_ref (framebuffer->config.swap_chain);
> @@ -86,24 +86,20 @@ _cogl_onscreen_free (CoglOnscreen *onscreen)
> {
> CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
> const CoglWinsysVtable *winsys = _cogl_framebuffer_get_winsys (framebuffer);
> - CoglResizeNotifyEntry *resize_entry;
> - CoglFrameClosure *frame_closure;
> CoglFrameInfo *frame_info;
>
> - while ((resize_entry = COGL_TAILQ_FIRST (&onscreen->resize_callbacks)))
> + while (!COGL_TAILQ_EMPTY (&onscreen->resize_closures))
> {
> - COGL_TAILQ_REMOVE (&onscreen->resize_callbacks, resize_entry, list_node);
> - g_slice_free (CoglResizeNotifyEntry, resize_entry);
> + CoglOnscreenResizeClosure *resize_closure =
> + COGL_TAILQ_FIRST (&onscreen->resize_closures);
> + cogl_onscreen_remove_resize_callback (onscreen, resize_closure);
> }
>
> - while ((frame_closure = COGL_TAILQ_FIRST (&onscreen->frame_closures)))
> + while (!COGL_TAILQ_EMPTY (&onscreen->frame_closures))
> {
> - COGL_TAILQ_REMOVE (&onscreen->frame_closures, frame_closure, list_node);
> -
> - if (frame_closure->destroy)
> - frame_closure->destroy (frame_closure->user_data);
> -
> - g_slice_free (CoglFrameClosure, frame_closure);
> + CoglFrameClosure *frame_closure =
> + COGL_TAILQ_FIRST (&onscreen->frame_closures);
> + cogl_onscreen_remove_frame_callback (onscreen, frame_closure);
> }
>
> while ((frame_info = g_queue_pop_tail (&onscreen->pending_frame_infos)))
> @@ -460,17 +456,17 @@ _cogl_onscreen_notify_complete (CoglOnscreen *onscreen, CoglFrameInfo *info)
> void
> _cogl_onscreen_notify_resize (CoglOnscreen *onscreen)
> {
> - CoglResizeNotifyEntry *entry, *tmp;
> + CoglOnscreenResizeClosure *closure, *tmp;
> CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
>
> - COGL_TAILQ_FOREACH_SAFE (entry,
> - &onscreen->resize_callbacks,
> + COGL_TAILQ_FOREACH_SAFE (closure,
> + &onscreen->resize_closures,
> list_node,
> tmp)
> - entry->callback (onscreen,
> - framebuffer->width,
> - framebuffer->height,
> - entry->user_data);
> + closure->callback (onscreen,
> + framebuffer->width,
> + framebuffer->height,
> + closure->user_data);
> }
>
> void
> @@ -514,38 +510,33 @@ cogl_onscreen_get_resizable (CoglOnscreen *onscreen)
> return onscreen->resizable;
> }
>
> -unsigned int
> -cogl_onscreen_add_resize_handler (CoglOnscreen *onscreen,
> - CoglOnscreenResizeCallback callback,
> - void *user_data)
> +CoglOnscreenResizeClosure *
> +cogl_onscreen_add_resize_callback (CoglOnscreen *onscreen,
> + CoglOnscreenResizeCallback callback,
> + void *user_data,
> + CoglUserDataDestroyCallback destroy)
> {
> - CoglResizeNotifyEntry *entry = g_slice_new (CoglResizeNotifyEntry);
> - static int next_resize_callback_id = 0;
> + CoglOnscreenResizeClosure *closure = g_slice_new (CoglOnscreenResizeClosure);
>
> - entry->callback = callback;
> - entry->user_data = user_data;
> - entry->id = next_resize_callback_id++;
> + closure->callback = callback;
> + closure->user_data = user_data;
> + closure->destroy = destroy;
>
> - COGL_TAILQ_INSERT_TAIL (&onscreen->resize_callbacks, entry, list_node);
> + COGL_TAILQ_INSERT_TAIL (&onscreen->resize_closures, closure, list_node);
>
> - return entry->id;
> + return closure;
> }
>
> void
> -cogl_onscreen_remove_resize_handler (CoglOnscreen *onscreen,
> - unsigned int id)
> +cogl_onscreen_remove_resize_callback (CoglOnscreen *onscreen,
> + CoglOnscreenResizeClosure *closure)
> {
> - CoglResizeNotifyEntry *entry;
> + if (closure->destroy)
> + closure->destroy (closure->user_data);
>
> - COGL_TAILQ_FOREACH (entry, &onscreen->resize_callbacks, list_node)
> - {
> - if (entry->id == id)
> - {
> - COGL_TAILQ_REMOVE (&onscreen->resize_callbacks, entry, list_node);
> - g_slice_free (CoglResizeNotifyEntry, entry);
> - break;
> - }
> - }
> + COGL_TAILQ_REMOVE (&onscreen->resize_closures, closure, list_node);
> +
> + g_slice_free (CoglOnscreenResizeClosure, closure);
> }
>
> int64_t
> diff --git a/cogl/cogl-onscreen.h b/cogl/cogl-onscreen.h
> index 13b51a1..ed4e25c 100644
> --- a/cogl/cogl-onscreen.h
> +++ b/cogl/cogl-onscreen.h
> @@ -567,7 +567,7 @@ cogl_onscreen_remove_frame_callback (CoglOnscreen *onscreen,
> * will be automatically updated to match the new size of the
> * framebuffer with an origin of (0,0). If your application needs more
> * specialized control of the viewport it will need to register a
> - * resize handler using cogl_onscreen_add_resize_handler() so that it
> + * resize handler using cogl_onscreen_add_resize_callback() so that it
> * can track when the viewport has been changed automatically.</note>
> *
> * Since: 2.0
> @@ -608,10 +608,10 @@ cogl_onscreen_get_resizable (CoglOnscreen *onscreen);
> * @width: The new width of @onscreen
> * @height: The new height of @onscreen
> * @user_data: The private passed to
> - * cogl_onscreen_add_resize_handler()
> + * cogl_onscreen_add_resize_callback()
> *
> * Is a callback type used with the
> - * cogl_onscreen_add_resize_handler() allowing applications to be
> + * cogl_onscreen_add_resize_callback() allowing applications to be
> * notified whenever an @onscreen framebuffer is resized.
> *
> * <note>Cogl automatically updates the viewport of an @onscreen
> @@ -632,18 +632,34 @@ typedef void (*CoglOnscreenResizeCallback) (CoglOnscreen *onscreen,
> void *user_data);
>
> /**
> - * cogl_onscreen_add_resize_handler:
> + * CoglOnscreenResizeClosure:
> + *
> + * An opaque type that tracks a #CoglOnscreenResizeCallback and
> + * associated user data. A #CoglOnscreenResizeClosure pointer will be
> + * returned from cogl_onscreen_add_resize_callback() and it allows you
> + * to remove a callback later using
> + * cogl_onscreen_remove_resize_callback().
> + *
> + * Since: 2.0
> + * Stability: unstable
> + */
> +typedef struct _CoglOnscreenResizeClosure CoglOnscreenResizeClosure;
> +
> +/**
> + * cogl_onscreen_add_resize_callback:
> * @onscreen: A #CoglOnscreen framebuffer
> * @callback: A #CoglOnscreenResizeCallback to call when the @onscreen
> * changes size.
> * @user_data: Private data to be passed to @callback.
> + * @destroy: An optional callback to destroy @user_data when the
> + * @callback is removed or @onscreen is freed.
> *
> * Registers a @callback with @onscreen that will be called whenever
> * the @onscreen framebuffer changes size.
> *
> * The @callback can be removed using
> - * cogl_onscreen_remove_resize_handler() passing the same @callback
> - * and @user_data pair.
> + * cogl_onscreen_remove_resize_callback() passing the returned closure
> + * pointer.
> *
> * <note>Since Cogl automatically updates the viewport of an @onscreen
> * framebuffer that is resized, a resize callback can also be used to
> @@ -657,29 +673,29 @@ typedef void (*CoglOnscreenResizeCallback) (CoglOnscreen *onscreen,
> * while an application might have arbitrary locks held for
> * example.</note>
> *
> - * Return value: a unique identifier that can be used to remove to remove
> - * the callback later.
> - *
> + * Return value: a #CoglOnscreenResizeClosure pointer that can be used to
> + * remove the callback and associated @user_data later.
> * Since: 2.0
> */
> -unsigned int
> -cogl_onscreen_add_resize_handler (CoglOnscreen *onscreen,
> - CoglOnscreenResizeCallback callback,
> - void *user_data);
> +CoglOnscreenResizeClosure *
> +cogl_onscreen_add_resize_callback (CoglOnscreen *onscreen,
> + CoglOnscreenResizeCallback callback,
> + void *user_data,
> + CoglUserDataDestroyCallback destroy);
>
> /**
> - * cogl_onscreen_remove_resize_handler:
> + * cogl_onscreen_remove_resize_callback:
> * @onscreen: A #CoglOnscreen framebuffer
> - * @id: An identifier returned from cogl_onscreen_add_resize_handler()
> + * @closure: An identifier returned from cogl_onscreen_add_resize_callback()
> *
> * Removes a resize @callback and @user_data pair that were previously
> - * associated with @onscreen via cogl_onscreen_add_resize_handler().
> + * associated with @onscreen via cogl_onscreen_add_resize_callback().
> *
> * Since: 2.0
> */
> void
> -cogl_onscreen_remove_resize_handler (CoglOnscreen *onscreen,
> - unsigned int id);
> +cogl_onscreen_remove_resize_callback (CoglOnscreen *onscreen,
> + CoglOnscreenResizeClosure *closure);
>
> /**
> * cogl_is_onscreen:
> diff --git a/doc/reference/cogl2/cogl2-sections.txt b/doc/reference/cogl2/cogl2-sections.txt
> index d75fa3f..e160a74 100644
> --- a/doc/reference/cogl2/cogl2-sections.txt
> +++ b/doc/reference/cogl2/cogl2-sections.txt
> @@ -554,6 +554,12 @@ cogl_onscreen_add_frame_callback
> cogl_onscreen_remove_frame_callback
>
> <SUBSECTION>
> +CoglOnscreenResizeCallback
> +CoglOnscreenResizeClosure
> +cogl_onscreen_add_resize_callback
> +cogl_onscreen_remove_resize_callback
> +
> +<SUBSECTION>
> cogl_onscreen_swap_buffers
> cogl_onscreen_swap_region
> cogl_onscreen_set_swap_throttled
> diff --git a/examples/cogl-x11-foreign.c b/examples/cogl-x11-foreign.c
> index ca9e3ed..849646c 100644
> --- a/examples/cogl-x11-foreign.c
> +++ b/examples/cogl-x11-foreign.c
> @@ -160,7 +160,7 @@ main (int argc, char **argv)
> fb = COGL_FRAMEBUFFER (onscreen);
>
> cogl_onscreen_set_resizable (onscreen, TRUE);
> - cogl_onscreen_add_resize_handler (onscreen, resize_handler, onscreen);
> + cogl_onscreen_add_resize_callback (onscreen, resize_handler, onscreen, NULL);
>
> triangle = cogl_primitive_new_p2c4 (ctx, COGL_VERTICES_MODE_TRIANGLES,
> 3, triangle_vertices);
> --
> 1.7.11.3.g3c3efa5
>
> _______________________________________________
> Cogl mailing list
> Cogl at lists.freedesktop.org
> http://lists.freedesktop.org/mailman/listinfo/cogl
More information about the Cogl
mailing list