[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