[Cogl] [PATCH 2/2] Use the Wayland embedded linked list implementation instead of BSD's

Robert Bragg robert at sixbynine.org
Wed Jun 12 03:38:56 PDT 2013


This is a really good patch, thanks for looking at this. We talked a
bit more about the CoglPipeline pointers offline and I think it would
be good if we can at least keep in mind re-visiting this later to try
and reduce the size, but we shouldn't block landing this.

This looks good to land to me:

Reviewed-by: Robert Bragg <robert at linux.intel.com>

thanks,
- Robert

On Mon, Jun 10, 2013 at 2:15 PM, Neil Roberts <neil at linux.intel.com> wrote:
> This removes cogl-queue.h and adds a copy of Wayland's embedded list
> implementation. The advantage of the Wayland model is that it is much
> simpler and so it is easier to follow. It also doesn't require
> defining a typedef for every list type.
>
> The downside is that there is only one list type which is a
> doubly-linked list where the head has a pointer to both the beginning
> and the end. The BSD implementation has many more combinations some of
> which we were taking advantage of to reduce the size of critical
> structs where we didn't need a pointer to the end of the list.
>
> The corresponding changes to uses of cogl-queue.h are:
>
> • COGL_STAILQ_* was used for onscreen the list of events and dirty
>   notifications. This makes the size of the CoglContext grow by one
>   pointer.
>
> • COGL_TAILQ_* was used for fences.
>
> • COGL_LIST_* for CoglClosures. In this case the list head now has an
>   extra pointer which means CoglOnscreen will grow by the size of
>   three pointers, but this doesn't seem like a particularly important
>   struct to optimise for size anyway.
>
> • COGL_LIST_* was used for the list of foreign GLES2 offscreens.
>
> • COGL_TAILQ_* was used for the list of sub stacks in a
>   CoglMemoryStack.
>
> • COGL_LIST_* was used to track the list of layers that haven't had
>   code generated yet while generating a fragment shader for a
>   pipeline.
>
> • COGL_LIST_* was used to track the pipeline hierarchy in CoglNode.
>
> The last part is a bit more controversial because it increases the
> size of CoglPipeline and CoglPipelineLayer by one pointer in order to
> have the redundant tail pointer for the list head. Normally we try to
> be very careful about the size of the CoglPipeline struct. Because
> CoglPipeline is slice-allocated, this effectively ends up adding two
> pointers to the size because GSlice rounds up to the size of two
> pointers.
> ---
>  cogl/Makefile.am                            |   3 +-
>  cogl/cogl-closure-list-private.h            |  52 ++-
>  cogl/cogl-closure-list.c                    |  10 +-
>  cogl/cogl-context-private.h                 |   6 +-
>  cogl/cogl-context.c                         |   6 +-
>  cogl/cogl-fence-private.h                   |   6 +-
>  cogl/cogl-fence.c                           |  25 +-
>  cogl/cogl-gles2-context-private.h           |  14 +-
>  cogl/cogl-gles2-context.c                   |  21 +-
>  cogl/cogl-journal-private.h                 |   2 +-
>  cogl/cogl-journal.c                         |   8 +-
>  cogl/cogl-list.c                            |  94 ++++
>  cogl/cogl-list.h                            | 123 ++++++
>  cogl/cogl-memory-stack.c                    |  39 +-
>  cogl/cogl-node-private.h                    |   8 +-
>  cogl/cogl-node.c                            |  10 +-
>  cogl/cogl-onscreen-private.h                |  28 +-
>  cogl/cogl-onscreen.c                        |  29 +-
>  cogl/cogl-pipeline-layer.c                  |   4 +-
>  cogl/cogl-pipeline-private.h                |   2 +-
>  cogl/cogl-pipeline.c                        |   4 +-
>  cogl/cogl-poll.c                            |   2 +-
>  cogl/cogl-queue.h                           | 647 ----------------------------
>  cogl/cogl-renderer-private.h                |   2 +-
>  cogl/cogl-renderer.c                        |   2 +-
>  cogl/cogl-sdl.c                             |   2 +-
>  cogl/driver/gl/cogl-pipeline-fragend-glsl.c |  47 +-
>  doc/reference/cogl2/Makefile.am             |   1 -
>  28 files changed, 375 insertions(+), 822 deletions(-)
>  create mode 100644 cogl/cogl-list.c
>  create mode 100644 cogl/cogl-list.h
>  delete mode 100644 cogl/cogl-queue.h
>
> diff --git a/cogl/Makefile.am b/cogl/Makefile.am
> index 323239d..0c470f0 100644
> --- a/cogl/Makefile.am
> +++ b/cogl/Makefile.am
> @@ -375,7 +375,8 @@ cogl_sources_c = \
>         $(srcdir)/cogl-point-in-poly-private.h          \
>         $(srcdir)/cogl-point-in-poly.c                  \
>         $(srcdir)/cogl-clutter.c                        \
> -       $(srcdir)/cogl-queue.h                          \
> +       $(srcdir)/cogl-list.c                           \
> +       $(srcdir)/cogl-list.h                           \
>         $(srcdir)/winsys/cogl-winsys-stub-private.h     \
>         $(srcdir)/winsys/cogl-winsys-stub.c             \
>         $(srcdir)/cogl-config-private.h                 \
> diff --git a/cogl/cogl-closure-list-private.h b/cogl/cogl-closure-list-private.h
> index 9aaa179..92ba0a1 100644
> --- a/cogl/cogl-closure-list-private.h
> +++ b/cogl/cogl-closure-list-private.h
> @@ -25,7 +25,7 @@
>  #define _COGL_CLOSURE_LIST_PRIVATE_H_
>
>  #include "cogl-object.h"
> -#include "cogl-queue.h"
> +#include "cogl-list.h"
>
>  /*
>   * This implements a list of callbacks that can be used a bit like
> @@ -43,18 +43,14 @@
>   * point.
>   */
>
> -typedef struct _CoglClosure CoglClosure;
> -
> -COGL_LIST_HEAD (CoglClosureList, CoglClosure);
> -
> -struct _CoglClosure
> +typedef struct _CoglClosure
>  {
> -  COGL_LIST_ENTRY (CoglClosure) list_node;
> +  CoglList link;
>
>    void *function;
>    void *user_data;
>    CoglUserDataDestroyCallback destroy_cb;
> -};
> +} CoglClosure;
>
>  /*
>   * _cogl_closure_disconnect:
> @@ -67,10 +63,10 @@ void
>  _cogl_closure_disconnect (CoglClosure *closure);
>
>  void
> -_cogl_closure_list_disconnect_all (CoglClosureList *list);
> +_cogl_closure_list_disconnect_all (CoglList *list);
>
>  CoglClosure *
> -_cogl_closure_list_add (CoglClosureList *list,
> +_cogl_closure_list_add (CoglList *list,
>                          void *function,
>                          void *user_data,
>                          CoglUserDataDestroyCallback destroy_cb);
> @@ -91,26 +87,26 @@ _cogl_closure_list_add (CoglClosureList *list,
>   * callbacks. If you want to handle the return value you should
>   * manually iterate the list and invoke the callbacks yourself.
>   */
> -#define _cogl_closure_list_invoke(list, cb_type, ...)            \
> -  G_STMT_START {                                                \
> -    CoglClosure *_c, *_tmp;                                     \
> -                                                                \
> -    COGL_LIST_FOREACH_SAFE (_c, (list), list_node, _tmp)        \
> -      {                                                         \
> -        cb_type _cb = _c->function;                             \
> -        _cb (__VA_ARGS__, _c->user_data);                       \
> -      }                                                         \
> +#define _cogl_closure_list_invoke(list, cb_type, ...)   \
> +  G_STMT_START {                                        \
> +    CoglClosure *_c, *_tmp;                             \
> +                                                        \
> +    _cogl_list_for_each_safe (_c, _tmp, (list), link)   \
> +      {                                                 \
> +        cb_type _cb = _c->function;                     \
> +        _cb (__VA_ARGS__, _c->user_data);               \
> +      }                                                 \
>    } G_STMT_END
>
> -#define _cogl_closure_list_invoke_no_args(list)                 \
> -  G_STMT_START {                                                \
> -    CoglClosure *_c, *_tmp;                                     \
> -                                                                \
> -    COGL_LIST_FOREACH_SAFE (_c, (list), list_node, _tmp)        \
> -      {                                                         \
> -        void (*_cb)(void *) = _c->function;                     \
> -        _cb (_c->user_data);                                    \
> -      }                                                         \
> +#define _cogl_closure_list_invoke_no_args(list)         \
> +  G_STMT_START {                                        \
> +    CoglClosure *_c, *_tmp;                             \
> +                                                        \
> +    _cogl_list_for_each_safe (_c, _tmp, (list), link)   \
> +      {                                                 \
> +        void (*_cb)(void *) = _c->function;             \
> +        _cb (_c->user_data);                            \
> +      }                                                 \
>    } G_STMT_END
>
>  #endif /* _COGL_CLOSURE_LIST_PRIVATE_H_ */
> diff --git a/cogl/cogl-closure-list.c b/cogl/cogl-closure-list.c
> index 60b26b4..dfb5bf3 100644
> --- a/cogl/cogl-closure-list.c
> +++ b/cogl/cogl-closure-list.c
> @@ -30,7 +30,7 @@
>  void
>  _cogl_closure_disconnect (CoglClosure *closure)
>  {
> -  COGL_LIST_REMOVE (closure, list_node);
> +  _cogl_list_remove (&closure->link);
>
>    if (closure->destroy_cb)
>      closure->destroy_cb (closure->user_data);
> @@ -39,16 +39,16 @@ _cogl_closure_disconnect (CoglClosure *closure)
>  }
>
>  void
> -_cogl_closure_list_disconnect_all (CoglClosureList *list)
> +_cogl_closure_list_disconnect_all (CoglList *list)
>  {
>    CoglClosure *closure, *next;
>
> -  COGL_LIST_FOREACH_SAFE (closure, list, list_node, next)
> +  _cogl_list_for_each_safe (closure, next, list, link)
>      _cogl_closure_disconnect (closure);
>  }
>
>  CoglClosure *
> -_cogl_closure_list_add (CoglClosureList *list,
> +_cogl_closure_list_add (CoglList *list,
>                          void *function,
>                          void *user_data,
>                          CoglUserDataDestroyCallback destroy_cb)
> @@ -59,7 +59,7 @@ _cogl_closure_list_add (CoglClosureList *list,
>    closure->user_data = user_data;
>    closure->destroy_cb = destroy_cb;
>
> -  COGL_LIST_INSERT_HEAD (list, closure, list_node);
> +  _cogl_list_insert (list, &closure->link);
>
>    return closure;
>  }
> diff --git a/cogl/cogl-context-private.h b/cogl/cogl-context-private.h
> index 7978232..c5f215d 100644
> --- a/cogl/cogl-context-private.h
> +++ b/cogl/cogl-context-private.h
> @@ -176,8 +176,8 @@ struct _CoglContext
>    gboolean have_last_offscreen_allocate_flags;
>    CoglOffscreenAllocateFlags last_offscreen_allocate_flags;
>
> -  CoglOnscreenEventList onscreen_events_queue;
> -  CoglOnscreenQueuedDirtyList onscreen_dirty_queue;
> +  CoglList onscreen_events_queue;
> +  CoglList onscreen_dirty_queue;
>    CoglClosure *onscreen_dispatch_idle;
>
>    CoglGLES2Context *current_gles2_context;
> @@ -274,7 +274,7 @@ struct _CoglContext
>    int n_uniform_names;
>
>    CoglPollSource *fences_poll_source;
> -  CoglFenceList fences;
> +  CoglList fences;
>
>    /* This defines a list of function pointers that Cogl uses from
>       either GL or GLES. All functions are accessed indirectly through
> diff --git a/cogl/cogl-context.c b/cogl/cogl-context.c
> index 39901b1..26fe85c 100644
> --- a/cogl/cogl-context.c
> +++ b/cogl/cogl-context.c
> @@ -292,8 +292,8 @@ cogl_context_new (CoglDisplay *display,
>    context->current_draw_buffer_state_flushed = 0;
>    context->current_draw_buffer_changes = COGL_FRAMEBUFFER_STATE_ALL;
>
> -  COGL_TAILQ_INIT (&context->onscreen_events_queue);
> -  COGL_TAILQ_INIT (&context->onscreen_dirty_queue);
> +  _cogl_list_init (&context->onscreen_events_queue);
> +  _cogl_list_init (&context->onscreen_dirty_queue);
>
>    g_queue_init (&context->gles2_context_stack);
>
> @@ -431,7 +431,7 @@ cogl_context_new (CoglDisplay *display,
>        cogl_has_feature (context, COGL_FEATURE_ID_POINT_SPRITE))
>      GE (context, glEnable (GL_POINT_SPRITE));
>
> -  COGL_TAILQ_INIT (&context->fences);
> +  _cogl_list_init (&context->fences);
>
>    return context;
>  }
> diff --git a/cogl/cogl-fence-private.h b/cogl/cogl-fence-private.h
> index 0817b7d..7a41c51 100644
> --- a/cogl/cogl-fence-private.h
> +++ b/cogl/cogl-fence-private.h
> @@ -25,11 +25,9 @@
>  #define __COGL_FENCE_PRIVATE_H__
>
>  #include "cogl-fence.h"
> -#include "cogl-queue.h"
> +#include "cogl-list.h"
>  #include "cogl-winsys-private.h"
>
> -COGL_TAILQ_HEAD (CoglFenceList, CoglFenceClosure);
> -
>  typedef enum
>  {
>    FENCE_TYPE_PENDING,
> @@ -42,7 +40,7 @@ typedef enum
>
>  struct _CoglFenceClosure
>  {
> -  COGL_TAILQ_ENTRY (CoglFenceClosure) list;
> +  CoglList link;
>    CoglFramebuffer *framebuffer;
>
>    CoglFenceType type;
> diff --git a/cogl/cogl-fence.c b/cogl/cogl-fence.c
> index 2055ac4..77469d7 100644
> --- a/cogl/cogl-fence.c
> +++ b/cogl/cogl-fence.c
> @@ -73,9 +73,9 @@ static void
>  _cogl_fence_poll_dispatch (void *source, int revents)
>  {
>    CoglContext *context = source;
> -  CoglFenceClosure *fence, *next;
> +  CoglFenceClosure *fence, *tmp;
>
> -  COGL_TAILQ_FOREACH_SAFE (fence, &context->fences, list, next)
> +  _cogl_list_for_each_safe (fence, tmp, &context->fences, link)
>      _cogl_fence_check (fence);
>  }
>
> @@ -92,11 +92,11 @@ _cogl_fence_poll_prepare (void *source)
>      {
>        CoglFramebuffer *fb = l->data;
>
> -      if (!COGL_TAILQ_EMPTY (&fb->journal->pending_fences))
> +      if (!_cogl_list_empty (&fb->journal->pending_fences))
>          _cogl_framebuffer_flush_journal (fb);
>      }
>
> -  if (!COGL_TAILQ_EMPTY (&context->fences))
> +  if (!_cogl_list_empty (&context->fences))
>      return FENCE_CHECK_TIMEOUT;
>    else
>      return -1;
> @@ -134,7 +134,7 @@ _cogl_fence_submit (CoglFenceClosure *fence)
>  #endif
>
>   done:
> -  COGL_TAILQ_INSERT_TAIL (&context->fences, fence, list);
> +  _cogl_list_insert (context->fences.prev, &fence->link);
>
>    if (!context->fences_poll_source)
>      {
> @@ -166,7 +166,7 @@ cogl_framebuffer_add_fence_callback (CoglFramebuffer *framebuffer,
>
>    if (journal->entries->len)
>      {
> -      COGL_TAILQ_INSERT_TAIL (&journal->pending_fences, fence, list);
> +      _cogl_list_insert (journal->pending_fences.prev, &fence->link);
>        fence->type = FENCE_TYPE_PENDING;
>      }
>    else
> @@ -179,16 +179,15 @@ void
>  cogl_framebuffer_cancel_fence_callback (CoglFramebuffer *framebuffer,
>                                          CoglFenceClosure *fence)
>  {
> -  CoglJournal *journal = framebuffer->journal;
>    CoglContext *context = framebuffer->context;
>
>    if (fence->type == FENCE_TYPE_PENDING)
>      {
> -      COGL_TAILQ_REMOVE (&journal->pending_fences, fence, list);
> +      _cogl_list_remove (&fence->link);
>      }
>    else
>      {
> -      COGL_TAILQ_REMOVE (&context->fences, fence, list);
> +      _cogl_list_remove (&fence->link);
>
>        if (fence->type == FENCE_TYPE_WINSYS)
>          {
> @@ -212,15 +211,15 @@ _cogl_fence_cancel_fences_for_framebuffer (CoglFramebuffer *framebuffer)
>  {
>    CoglJournal *journal = framebuffer->journal;
>    CoglContext *context = framebuffer->context;
> -  CoglFenceClosure *fence, *next;
> +  CoglFenceClosure *fence, *tmp;
>
> -  while (!COGL_TAILQ_EMPTY (&journal->pending_fences))
> +  while (!_cogl_list_empty (&journal->pending_fences))
>      {
> -      fence = COGL_TAILQ_FIRST (&journal->pending_fences);
> +      fence = _cogl_container_of (journal->pending_fences.next, fence, link);
>        cogl_framebuffer_cancel_fence_callback (framebuffer, fence);
>      }
>
> -  COGL_TAILQ_FOREACH_SAFE (fence, &context->fences, list, next)
> +  _cogl_list_for_each_safe (fence, tmp, &context->fences, link)
>      {
>        if (fence->framebuffer == framebuffer)
>          cogl_framebuffer_cancel_fence_callback (framebuffer, fence);
> diff --git a/cogl/cogl-gles2-context-private.h b/cogl/cogl-gles2-context-private.h
> index 5afb296..c9d4bcc 100644
> --- a/cogl/cogl-gles2-context-private.h
> +++ b/cogl/cogl-gles2-context-private.h
> @@ -33,18 +33,14 @@
>
>  #include "cogl-object-private.h"
>  #include "cogl-framebuffer-private.h"
> -#include "cogl-queue.h"
> +#include "cogl-list.h"
>
> -typedef struct _CoglGLES2Offscreen CoglGLES2Offscreen;
> -
> -COGL_LIST_HEAD (CoglGLES2OffscreenList, CoglGLES2Offscreen);
> -
> -struct _CoglGLES2Offscreen
> +typedef struct _CoglGLES2Offscreen
>  {
> -  COGL_LIST_ENTRY (CoglGLES2Offscreen) list_node;
> +  CoglList link;
>    CoglOffscreen *original_offscreen;
>    CoglGLFramebuffer gl_framebuffer;
> -};
> +} CoglGLES2Offscreen;
>
>  typedef struct
>  {
> @@ -143,7 +139,7 @@ struct _CoglGLES2Context
>
>    GLuint current_fbo_handle;
>
> -  CoglGLES2OffscreenList foreign_offscreens;
> +  CoglList foreign_offscreens;
>
>    CoglGLES2Vtable *vtable;
>
> diff --git a/cogl/cogl-gles2-context.c b/cogl/cogl-gles2-context.c
> index 2d0ab52..4063fdc 100644
> --- a/cogl/cogl-gles2-context.c
> +++ b/cogl/cogl-gles2-context.c
> @@ -1435,7 +1435,7 @@ gl_tex_image_2d_wrapper (GLenum target,
>  static void
>  _cogl_gles2_offscreen_free (CoglGLES2Offscreen *gles2_offscreen)
>  {
> -  COGL_LIST_REMOVE (gles2_offscreen, list_node);
> +  _cogl_list_remove (&gles2_offscreen->link);
>    g_slice_free (CoglGLES2Offscreen, gles2_offscreen);
>  }
>
> @@ -1513,10 +1513,12 @@ _cogl_gles2_context_free (CoglGLES2Context *gles2_context)
>    winsys = ctx->display->renderer->winsys_vtable;
>    winsys->destroy_gles2_context (gles2_context);
>
> -  while (gles2_context->foreign_offscreens.lh_first)
> +  while (!_cogl_list_empty (&gles2_context->foreign_offscreens))
>      {
>        CoglGLES2Offscreen *gles2_offscreen =
> -        gles2_context->foreign_offscreens.lh_first;
> +        _cogl_container_of (gles2_context->foreign_offscreens.next,
> +                            gles2_offscreen,
> +                            link);
>
>        /* Note: this will also indirectly free the gles2_offscreen by
>         * calling the destroy notify for the _user_data */
> @@ -1572,7 +1574,7 @@ cogl_gles2_context_new (CoglContext *ctx, CoglError **error)
>
>    gles2_ctx->context = ctx;
>
> -  COGL_LIST_INIT (&gles2_ctx->foreign_offscreens);
> +  _cogl_list_init (&gles2_ctx->foreign_offscreens);
>
>    winsys = ctx->display->renderer->winsys_vtable;
>    gles2_ctx->winsys = winsys->context_create_gles2_context (ctx, error);
> @@ -1694,9 +1696,9 @@ _cogl_gles2_offscreen_allocate (CoglOffscreen *offscreen,
>        return NULL;
>      }
>
> -  for (gles2_offscreen = gles2_context->foreign_offscreens.lh_first;
> -       gles2_offscreen;
> -       gles2_offscreen = gles2_offscreen->list_node.le_next)
> +  _cogl_list_for_each (gles2_offscreen,
> +                       &gles2_context->foreign_offscreens,
> +                       link)
>      {
>        if (gles2_offscreen->original_offscreen == offscreen)
>          return gles2_offscreen;
> @@ -1740,9 +1742,8 @@ _cogl_gles2_offscreen_allocate (CoglOffscreen *offscreen,
>
>    gles2_offscreen->original_offscreen = offscreen;
>
> -  COGL_LIST_INSERT_HEAD (&gles2_context->foreign_offscreens,
> -                         gles2_offscreen,
> -                         list_node);
> +  _cogl_list_insert (&gles2_context->foreign_offscreens,
> +                     &gles2_offscreen->link);
>
>    /* So we avoid building up an ever growing collection of ancillary
>     * buffers for wrapped framebuffers, we make sure that the wrappers
> diff --git a/cogl/cogl-journal-private.h b/cogl/cogl-journal-private.h
> index b73fbd1..63cbc23 100644
> --- a/cogl/cogl-journal-private.h
> +++ b/cogl/cogl-journal-private.h
> @@ -59,7 +59,7 @@ typedef struct _CoglJournal
>
>    int fast_read_pixel_count;
>
> -  CoglFenceList pending_fences;
> +  CoglList pending_fences;
>
>  } CoglJournal;
>
> diff --git a/cogl/cogl-journal.c b/cogl/cogl-journal.c
> index 518a797..703f162 100644
> --- a/cogl/cogl-journal.c
> +++ b/cogl/cogl-journal.c
> @@ -153,7 +153,7 @@ _cogl_journal_new (CoglFramebuffer *framebuffer)
>    journal->entries = g_array_new (FALSE, FALSE, sizeof (CoglJournalEntry));
>    journal->vertices = g_array_new (FALSE, FALSE, sizeof (float));
>
> -  COGL_TAILQ_INIT (&journal->pending_fences);
> +  _cogl_list_init (&journal->pending_fences);
>
>    return _cogl_journal_object_new (journal);
>  }
> @@ -1262,11 +1262,11 @@ _cogl_journal_all_entries_within_bounds (CoglJournal *journal,
>  static void
>  post_fences (CoglJournal *journal)
>  {
> -  CoglFenceClosure *fence, *next;
> +  CoglFenceClosure *fence, *tmp;
>
> -  COGL_TAILQ_FOREACH_SAFE (fence, &journal->pending_fences, list, next)
> +  _cogl_list_for_each_safe (fence, tmp, &journal->pending_fences, link)
>      {
> -      COGL_TAILQ_REMOVE (&journal->pending_fences, fence, list);
> +      _cogl_list_remove (&fence->link);
>        _cogl_fence_submit (fence);
>      }
>  }
> diff --git a/cogl/cogl-list.c b/cogl/cogl-list.c
> new file mode 100644
> index 0000000..3fbc675
> --- /dev/null
> +++ b/cogl/cogl-list.c
> @@ -0,0 +1,94 @@
> +/*
> + * Copyright © 2008-2011 Kristian Høgsberg
> + * Copyright © 2011, 2012 Intel Corporation
> + *
> + * Permission to use, copy, modify, distribute, and sell this software and its
> + * documentation for any purpose is hereby granted without fee, provided that
> + * the above copyright notice appear in all copies and that both that copyright
> + * notice and this permission notice appear in supporting documentation, and
> + * that the name of the copyright holders not be used in advertising or
> + * publicity pertaining to distribution of the software without specific,
> + * written prior permission.  The copyright holders make no representations
> + * about the suitability of this software for any purpose.  It is provided "as
> + * is" without express or implied warranty.
> + *
> + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
> + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
> + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
> + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
> + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
> + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
> + * OF THIS SOFTWARE.
> + */
> +
> +/* This list implementation is based on the Wayland source code */
> +
> +#ifdef HAVE_CONFIG_H
> +#include "config.h"
> +#endif
> +
> +#include <stdlib.h>
> +#include <string.h>
> +
> +#include "cogl-list.h"
> +
> +void
> +_cogl_list_init (CoglList *list)
> +{
> +  list->prev = list;
> +  list->next = list;
> +}
> +
> +void
> +_cogl_list_insert (CoglList *list, CoglList *elm)
> +{
> +  elm->prev = list;
> +  elm->next = list->next;
> +  list->next = elm;
> +  elm->next->prev = elm;
> +}
> +
> +void
> +_cogl_list_remove (CoglList *elm)
> +{
> +  elm->prev->next = elm->next;
> +  elm->next->prev = elm->prev;
> +  elm->next = NULL;
> +  elm->prev = NULL;
> +}
> +
> +int
> +_cogl_list_length (CoglList *list)
> +{
> +  CoglList *e;
> +  int count;
> +
> +  count = 0;
> +  e = list->next;
> +  while (e != list)
> +    {
> +      e = e->next;
> +      count++;
> +    }
> +
> +  return count;
> +}
> +
> +int
> +_cogl_list_empty (CoglList *list)
> +{
> +  return list->next == list;
> +}
> +
> +void
> +_cogl_list_insert_list (CoglList *list,
> +                        CoglList *other)
> +{
> +  if (_cogl_list_empty (other))
> +    return;
> +
> +  other->next->prev = list;
> +  other->prev->next = list->next;
> +  list->next->prev = other->prev;
> +  list->next = other->next;
> +}
> diff --git a/cogl/cogl-list.h b/cogl/cogl-list.h
> new file mode 100644
> index 0000000..7d716a8
> --- /dev/null
> +++ b/cogl/cogl-list.h
> @@ -0,0 +1,123 @@
> +/*
> + * Copyright © 2008 Kristian Høgsberg
> + * Copyright © 2012, 2013 Intel Corporation
> + *
> + * Permission to use, copy, modify, distribute, and sell this software and its
> + * documentation for any purpose is hereby granted without fee, provided that
> + * the above copyright notice appear in all copies and that both that copyright
> + * notice and this permission notice appear in supporting documentation, and
> + * that the name of the copyright holders not be used in advertising or
> + * publicity pertaining to distribution of the software without specific,
> + * written prior permission.  The copyright holders make no representations
> + * about the suitability of this software for any purpose.  It is provided "as
> + * is" without express or implied warranty.
> + *
> + * THE COPYRIGHT HOLDERS DISCLAIM ALL WARRANTIES WITH REGARD TO THIS SOFTWARE,
> + * INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS, IN NO
> + * EVENT SHALL THE COPYRIGHT HOLDERS BE LIABLE FOR ANY SPECIAL, INDIRECT OR
> + * CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM LOSS OF USE,
> + * DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE OR OTHER
> + * TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR PERFORMANCE
> + * OF THIS SOFTWARE.
> + */
> +
> +/* This list implementation is based on the Wayland source code */
> +
> +#ifndef COGL_LIST_H
> +#define COGL_LIST_H
> +
> +/**
> + * CoglList - linked list
> + *
> + * The list head is of "CoglList" type, and must be initialized
> + * using cogl_list_init().  All entries in the list must be of the same
> + * type.  The item type must have a "CoglList" member. This
> + * member will be initialized by cogl_list_insert(). There is no need to
> + * call cogl_list_init() on the individual item. To query if the list is
> + * empty in O(1), use cogl_list_empty().
> + *
> + * Let's call the list reference "CoglList foo_list", the item type as
> + * "item_t", and the item member as "CoglList link". The following code
> + *
> + * The following code will initialize a list:
> + *
> + *      cogl_list_init (foo_list);
> + *      cogl_list_insert (foo_list, item1);      Pushes item1 at the head
> + *      cogl_list_insert (foo_list, item2);      Pushes item2 at the head
> + *      cogl_list_insert (item2, item3);         Pushes item3 after item2
> + *
> + * The list now looks like [item2, item3, item1]
> + *
> + * Will iterate the list in ascending order:
> + *
> + *      item_t *item;
> + *      cogl_list_for_each(item, foo_list, link) {
> + *              Do_something_with_item(item);
> + *      }
> + */
> +
> +typedef struct _CoglList CoglList;
> +
> +struct _CoglList
> +{
> +  CoglList *prev;
> +  CoglList *next;
> +};
> +
> +void
> +_cogl_list_init (CoglList *list);
> +
> +void
> +_cogl_list_insert (CoglList *list,
> +                   CoglList *elm);
> +
> +void
> +_cogl_list_remove (CoglList *elm);
> +
> +int
> +_cogl_list_length (CoglList *list);
> +
> +int
> +_cogl_list_empty (CoglList *list);
> +
> +void
> +_cogl_list_insert_list (CoglList *list,
> +                        CoglList *other);
> +
> +#ifdef __GNUC__
> +#define _cogl_container_of(ptr, sample, member)                         \
> +  (__typeof__(sample))((char *)(ptr)    -                               \
> +                       ((char *)&(sample)->member - (char *)(sample)))
> +#else
> +#define _cogl_container_of(ptr, sample, member)                 \
> +  (void *)((char *)(ptr)        -                               \
> +           ((char *)&(sample)->member - (char *)(sample)))
> +#endif
> +
> +#define _cogl_list_for_each(pos, head, member)                          \
> +  for (pos = 0, pos = _cogl_container_of((head)->next, pos, member);    \
> +       &pos->member != (head);                                          \
> +       pos = _cogl_container_of(pos->member.next, pos, member))
> +
> +#define _cogl_list_for_each_safe(pos, tmp, head, member)                \
> +  for (pos = 0, tmp = 0,                                                \
> +         pos = _cogl_container_of((head)->next, pos, member),           \
> +         tmp = _cogl_container_of((pos)->member.next, tmp, member);     \
> +       &pos->member != (head);                                          \
> +       pos = tmp,                                                       \
> +         tmp = _cogl_container_of(pos->member.next, tmp, member))
> +
> +#define _cogl_list_for_each_reverse(pos, head, member)                  \
> +  for (pos = 0, pos = _cogl_container_of((head)->prev, pos, member);    \
> +       &pos->member != (head);                                          \
> +       pos = _cogl_container_of(pos->member.prev, pos, member))
> +
> +#define _cogl_list_for_each_reverse_safe(pos, tmp, head, member)        \
> +  for (pos = 0, tmp = 0,                                                \
> +         pos = _cogl_container_of((head)->prev, pos, member),           \
> +         tmp = _cogl_container_of((pos)->member.prev, tmp, member);     \
> +       &pos->member != (head);                                          \
> +       pos = tmp,                                                       \
> +         tmp = _cogl_container_of(pos->member.prev, tmp, member))
> +
> +#endif /* COGL_LIST_H */
> diff --git a/cogl/cogl-memory-stack.c b/cogl/cogl-memory-stack.c
> index 5f4547e..2aefcc9 100644
> --- a/cogl/cogl-memory-stack.c
> +++ b/cogl/cogl-memory-stack.c
> @@ -53,26 +53,22 @@
>  #endif
>
>  #include "cogl-memory-stack-private.h"
> -#include "cogl-queue.h"
> +#include "cogl-list.h"
>
>  #include <stdint.h>
>
>  #include <glib.h>
>
> -typedef struct _CoglMemorySubStack CoglMemorySubStack;
> -
> -COGL_TAILQ_HEAD (CoglMemorySubStackList, CoglMemorySubStack);
> -
> -struct _CoglMemorySubStack
> +typedef struct _CoglMemorySubStack
>  {
> -  COGL_TAILQ_ENTRY (CoglMemorySubStack) list_node;
> +  CoglList link;
>    size_t bytes;
>    uint8_t *data;
> -};
> +} CoglMemorySubStack;
>
>  struct _CoglMemoryStack
>  {
> -  CoglMemorySubStackList sub_stacks;
> +  CoglList sub_stacks;
>
>    CoglMemorySubStack *sub_stack;
>    size_t sub_stack_offset;
> @@ -93,7 +89,7 @@ _cogl_memory_stack_add_sub_stack (CoglMemoryStack *stack,
>  {
>    CoglMemorySubStack *sub_stack =
>      _cogl_memory_sub_stack_alloc (sub_stack_bytes);
> -  COGL_TAILQ_INSERT_TAIL (&stack->sub_stacks, sub_stack, list_node);
> +  _cogl_list_insert (stack->sub_stacks.prev, &sub_stack->link);
>    stack->sub_stack = sub_stack;
>    stack->sub_stack_offset = 0;
>  }
> @@ -103,7 +99,7 @@ _cogl_memory_stack_new (size_t initial_size_bytes)
>  {
>    CoglMemoryStack *stack = g_slice_new0 (CoglMemoryStack);
>
> -  COGL_TAILQ_INIT (&stack->sub_stacks);
> +  _cogl_list_init (&stack->sub_stacks);
>
>    _cogl_memory_stack_add_sub_stack (stack, initial_size_bytes);
>
> @@ -128,9 +124,9 @@ _cogl_memory_stack_alloc (CoglMemoryStack *stack, size_t bytes)
>     * is made then we may need to skip over one or more of the
>     * sub-stacks that are too small for the requested allocation
>     * size... */
> -  for (sub_stack = sub_stack->list_node.tqe_next;
> -       sub_stack;
> -       sub_stack = sub_stack->list_node.tqe_next)
> +  for (sub_stack = _cogl_container_of (sub_stack->link.next, sub_stack, link);
> +       &sub_stack->link != &stack->sub_stacks;
> +       sub_stack = _cogl_container_of (sub_stack->link.next, sub_stack, link))
>      {
>        if (sub_stack->bytes >= bytes)
>          {
> @@ -147,11 +143,11 @@ _cogl_memory_stack_alloc (CoglMemoryStack *stack, size_t bytes)
>     * requested allocation if that's bigger.
>     */
>
> -  sub_stack = COGL_TAILQ_LAST (&stack->sub_stacks, CoglMemorySubStackList);
> +  sub_stack = _cogl_container_of (stack->sub_stacks.prev, sub_stack, link);
>
>    _cogl_memory_stack_add_sub_stack (stack, MAX (sub_stack->bytes, bytes) * 2);
>
> -  sub_stack = COGL_TAILQ_LAST (&stack->sub_stacks, CoglMemorySubStackList);
> +  sub_stack = _cogl_container_of (stack->sub_stacks.prev, sub_stack, link);
>
>    stack->sub_stack_offset += bytes;
>
> @@ -161,7 +157,9 @@ _cogl_memory_stack_alloc (CoglMemoryStack *stack, size_t bytes)
>  void
>  _cogl_memory_stack_rewind (CoglMemoryStack *stack)
>  {
> -  stack->sub_stack = COGL_TAILQ_FIRST (&stack->sub_stacks);
> +  stack->sub_stack = _cogl_container_of (stack->sub_stacks.next,
> +                                         stack->sub_stack,
> +                                         link);
>    stack->sub_stack_offset = 0;
>  }
>
> @@ -175,11 +173,12 @@ _cogl_memory_sub_stack_free (CoglMemorySubStack *sub_stack)
>  void
>  _cogl_memory_stack_free (CoglMemoryStack *stack)
>  {
> -  CoglMemorySubStack *sub_stack;
>
> -  while ((sub_stack = COGL_TAILQ_FIRST (&stack->sub_stacks)))
> +  while (!_cogl_list_empty (&stack->sub_stacks))
>      {
> -      COGL_TAILQ_REMOVE (&stack->sub_stacks, sub_stack, list_node);
> +      CoglMemorySubStack *sub_stack =
> +        _cogl_container_of (stack->sub_stacks.next, sub_stack, link);
> +      _cogl_list_remove (&sub_stack->link);
>        _cogl_memory_sub_stack_free (sub_stack);
>      }
>
> diff --git a/cogl/cogl-node-private.h b/cogl/cogl-node-private.h
> index f1b505c..ee2246c 100644
> --- a/cogl/cogl-node-private.h
> +++ b/cogl/cogl-node-private.h
> @@ -29,12 +29,10 @@
>  #define __COGL_NODE_PRIVATE_H
>
>  #include "cogl-object-private.h"
> -#include "cogl-queue.h"
> +#include "cogl-list.h"
>
>  typedef struct _CoglNode CoglNode;
>
> -COGL_LIST_HEAD (CoglNodeList, CoglNode);
> -
>  /* Pipelines and layers represent their state in a tree structure where
>   * some of the state relating to a given pipeline or layer may actually
>   * be owned by one if is ancestors in the tree. We have a common data
> @@ -49,10 +47,10 @@ struct _CoglNode
>    CoglNode *parent;
>
>    /* The list entry here contains pointers to the node's siblings */
> -  COGL_LIST_ENTRY (CoglNode) list_node;
> +  CoglList link;
>
>    /* List of children */
> -  CoglNodeList children;
> +  CoglList children;
>
>    /* TRUE if the node took a strong reference on its parent. Weak
>     * pipelines for instance don't take a reference on their parent. */
> diff --git a/cogl/cogl-node.c b/cogl/cogl-node.c
> index ab32e28..88bf991 100644
> --- a/cogl/cogl-node.c
> +++ b/cogl/cogl-node.c
> @@ -36,7 +36,7 @@ void
>  _cogl_pipeline_node_init (CoglNode *node)
>  {
>    node->parent = NULL;
> -  COGL_LIST_INIT (&node->children);
> +  _cogl_list_init (&node->children);
>  }
>
>  void
> @@ -59,7 +59,7 @@ _cogl_pipeline_node_set_parent_real (CoglNode *node,
>    if (node->parent)
>      unparent (node);
>
> -  COGL_LIST_INSERT_HEAD (&parent->children, node, list_node);
> +  _cogl_list_insert (&parent->children, &node->link);
>
>    node->parent = parent;
>    node->has_parent_reference = take_strong_reference;
> @@ -80,9 +80,9 @@ _cogl_pipeline_node_unparent_real (CoglNode *node)
>    if (parent == NULL)
>      return;
>
> -  _COGL_RETURN_IF_FAIL (!COGL_LIST_EMPTY (&parent->children));
> +  _COGL_RETURN_IF_FAIL (!_cogl_list_empty (&parent->children));
>
> -  COGL_LIST_REMOVE (node, list_node);
> +  _cogl_list_remove (&node->link);
>
>    if (node->has_parent_reference)
>      cogl_object_unref (parent);
> @@ -97,7 +97,7 @@ _cogl_pipeline_node_foreach_child (CoglNode *node,
>  {
>    CoglNode *child, *next;
>
> -  COGL_LIST_FOREACH_SAFE (child, &node->children, list_node, next)
> +  _cogl_list_for_each_safe (child, next, &node->children, link)
>      callback (child, user_data);
>  }
>
> diff --git a/cogl/cogl-onscreen-private.h b/cogl/cogl-onscreen-private.h
> index e960dc3..1fd62ea 100644
> --- a/cogl/cogl-onscreen-private.h
> +++ b/cogl/cogl-onscreen-private.h
> @@ -26,8 +26,8 @@
>
>  #include "cogl-onscreen.h"
>  #include "cogl-framebuffer-private.h"
> -#include "cogl-queue.h"
>  #include "cogl-closure-list-private.h"
> +#include "cogl-list.h"
>
>  #include <glib.h>
>
> @@ -35,30 +35,22 @@
>  #include <windows.h>
>  #endif
>
> -typedef struct _CoglOnscreenEvent CoglOnscreenEvent;
> -
> -COGL_TAILQ_HEAD (CoglOnscreenEventList, CoglOnscreenEvent);
> -
> -struct _CoglOnscreenEvent
> +typedef struct _CoglOnscreenEvent
>  {
> -  COGL_TAILQ_ENTRY (CoglOnscreenEvent) list_node;
> +  CoglList link;
>
>    CoglOnscreen *onscreen;
>    CoglFrameInfo *info;
>    CoglFrameEvent type;
> -};
> +} CoglOnscreenEvent;
>
> -typedef struct _CoglOnscreenQueuedDirty CoglOnscreenQueuedDirty;
> -
> -COGL_TAILQ_HEAD (CoglOnscreenQueuedDirtyList, CoglOnscreenQueuedDirty);
> -
> -struct _CoglOnscreenQueuedDirty
> +typedef struct _CoglOnscreenQueuedDirty
>  {
> -  COGL_TAILQ_ENTRY (CoglOnscreenQueuedDirty) list_node;
> +  CoglList link;
>
>    CoglOnscreen *onscreen;
>    CoglOnscreenDirtyInfo info;
> -};
> +} CoglOnscreenQueuedDirty;
>
>  struct _CoglOnscreen
>  {
> @@ -80,12 +72,12 @@ struct _CoglOnscreen
>
>    CoglBool swap_throttled;
>
> -  CoglClosureList frame_closures;
> +  CoglList frame_closures;
>
>    CoglBool resizable;
> -  CoglClosureList resize_closures;
> +  CoglList resize_closures;
>
> -  CoglClosureList dirty_closures;
> +  CoglList dirty_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 f686b14..c115a6e 100644
> --- a/cogl/cogl-onscreen.c
> +++ b/cogl/cogl-onscreen.c
> @@ -47,9 +47,9 @@ _cogl_onscreen_init_from_template (CoglOnscreen *onscreen,
>  {
>    CoglFramebuffer *framebuffer = COGL_FRAMEBUFFER (onscreen);
>
> -  COGL_LIST_INIT (&onscreen->frame_closures);
> -  COGL_LIST_INIT (&onscreen->resize_closures);
> -  COGL_LIST_INIT (&onscreen->dirty_closures);
> +  _cogl_list_init (&onscreen->frame_closures);
> +  _cogl_list_init (&onscreen->resize_closures);
> +  _cogl_list_init (&onscreen->dirty_closures);
>
>    framebuffer->config = onscreen_template->config;
>    cogl_object_ref (framebuffer->config.swap_chain);
> @@ -122,23 +122,20 @@ static void
>  _cogl_dispatch_onscreen_cb (CoglContext *context)
>  {
>    CoglOnscreenEvent *event, *tmp;
> -  CoglOnscreenEventList queue;
> +  CoglList queue;
>
>    /* Dispatching the event callback may cause another frame to be
>     * drawn which in may cause another event to be queued immediately.
>     * To make sure this loop will only dispatch one set of events we'll
>     * steal the queue and iterate that separately */
> -  COGL_TAILQ_INIT (&queue);
> -  COGL_TAILQ_CONCAT (&queue, &context->onscreen_events_queue, list_node);
> -  COGL_TAILQ_INIT (&context->onscreen_events_queue);
> +  _cogl_list_init (&queue);
> +  _cogl_list_insert_list (&queue, &context->onscreen_events_queue);
> +  _cogl_list_init (&context->onscreen_events_queue);
>
>    _cogl_closure_disconnect (context->onscreen_dispatch_idle);
>    context->onscreen_dispatch_idle = NULL;
>
> -  COGL_TAILQ_FOREACH_SAFE (event,
> -                           &queue,
> -                           list_node,
> -                           tmp)
> +  _cogl_list_for_each_safe (event, tmp, &queue, link)
>      {
>        CoglOnscreen *onscreen = event->onscreen;
>        CoglFrameInfo *info = event->info;
> @@ -151,12 +148,12 @@ _cogl_dispatch_onscreen_cb (CoglContext *context)
>        g_slice_free (CoglOnscreenEvent, event);
>      }
>
> -  while (!COGL_TAILQ_EMPTY (&context->onscreen_dirty_queue))
> +  while (!_cogl_list_empty (&context->onscreen_dirty_queue))
>      {
>        CoglOnscreenQueuedDirty *qe =
> -        COGL_TAILQ_FIRST (&context->onscreen_dirty_queue);
> +        _cogl_container_of (context->onscreen_dirty_queue.next, qe, link);
>
> -      COGL_TAILQ_REMOVE (&context->onscreen_dirty_queue, qe, list_node);
> +      _cogl_list_remove (&qe->link);
>
>        _cogl_closure_list_invoke (&qe->onscreen->dirty_closures,
>                                   CoglOnscreenDirtyCallback,
> @@ -194,7 +191,7 @@ _cogl_onscreen_queue_dirty (CoglOnscreen *onscreen,
>
>    qe->onscreen = cogl_object_ref (onscreen);
>    qe->info = *info;
> -  COGL_TAILQ_INSERT_TAIL (&ctx->onscreen_dirty_queue, qe, list_node);
> +  _cogl_list_insert (ctx->onscreen_dirty_queue.prev, &qe->link);
>
>    _cogl_onscreen_queue_dispatch_idle (onscreen);
>  }
> @@ -226,7 +223,7 @@ _cogl_onscreen_queue_event (CoglOnscreen *onscreen,
>    event->info = cogl_object_ref (info);
>    event->type = type;
>
> -  COGL_TAILQ_INSERT_TAIL (&ctx->onscreen_events_queue, event, list_node);
> +  _cogl_list_insert (ctx->onscreen_events_queue.prev, &event->link);
>
>    _cogl_onscreen_queue_dispatch_idle (onscreen);
>  }
> diff --git a/cogl/cogl-pipeline-layer.c b/cogl/cogl-pipeline-layer.c
> index bb77f6b..a401773 100644
> --- a/cogl/cogl-pipeline-layer.c
> +++ b/cogl/cogl-pipeline-layer.c
> @@ -346,7 +346,7 @@ _cogl_pipeline_layer_pre_change_notify (CoglPipeline *required_owner,
>
>    /* Identify the case where the layer is new with no owner or
>     * dependants and so we don't need to do anything. */
> -  if (COGL_LIST_EMPTY (&COGL_NODE (layer)->children) &&
> +  if (_cogl_list_empty (&COGL_NODE (layer)->children) &&
>        layer->owner == NULL)
>      goto init_layer_state;
>
> @@ -368,7 +368,7 @@ _cogl_pipeline_layer_pre_change_notify (CoglPipeline *required_owner,
>     * they have dependants - either direct children, or another
>     * pipeline as an owner.
>     */
> -  if (!COGL_LIST_EMPTY (&COGL_NODE (layer)->children) ||
> +  if (!_cogl_list_empty (&COGL_NODE (layer)->children) ||
>        layer->owner != required_owner)
>      {
>        CoglPipelineLayer *new = _cogl_pipeline_layer_copy (layer);
> diff --git a/cogl/cogl-pipeline-private.h b/cogl/cogl-pipeline-private.h
> index a185b3c..72917de 100644
> --- a/cogl/cogl-pipeline-private.h
> +++ b/cogl/cogl-pipeline-private.h
> @@ -34,7 +34,7 @@
>  #include "cogl-matrix.h"
>  #include "cogl-object-private.h"
>  #include "cogl-profile.h"
> -#include "cogl-queue.h"
> +#include "cogl-list.h"
>  #include "cogl-boxed-value.h"
>  #include "cogl-pipeline-snippet-private.h"
>  #include "cogl-pipeline-state.h"
> diff --git a/cogl/cogl-pipeline.c b/cogl/cogl-pipeline.c
> index b9264ed..19a8a19 100644
> --- a/cogl/cogl-pipeline.c
> +++ b/cogl/cogl-pipeline.c
> @@ -431,7 +431,7 @@ _cogl_pipeline_free (CoglPipeline *pipeline)
>                                       destroy_weak_children_cb,
>                                       NULL);
>
> -  g_assert (COGL_LIST_EMPTY (&COGL_NODE (pipeline)->children));
> +  g_assert (_cogl_list_empty (&COGL_NODE (pipeline)->children));
>
>    _cogl_pipeline_unparent (COGL_NODE (pipeline));
>
> @@ -1212,7 +1212,7 @@ _cogl_pipeline_pre_change_notify (CoglPipeline     *pipeline,
>    /* If there are still children remaining though we'll need to
>     * perform a copy-on-write and reparent the dependants as children
>     * of the copy. */
> -  if (!COGL_LIST_EMPTY (&COGL_NODE (pipeline)->children))
> +  if (!_cogl_list_empty (&COGL_NODE (pipeline)->children))
>      {
>        CoglPipeline *new_authority;
>
> diff --git a/cogl/cogl-poll.c b/cogl/cogl-poll.c
> index e29d997..c50d648 100644
> --- a/cogl/cogl-poll.c
> +++ b/cogl/cogl-poll.c
> @@ -57,7 +57,7 @@ cogl_poll_renderer_get_info (CoglRenderer *renderer,
>    *n_poll_fds = renderer->poll_fds->len;
>    *timeout = -1;
>
> -  if (!COGL_LIST_EMPTY (&renderer->idle_closures))
> +  if (!_cogl_list_empty (&renderer->idle_closures))
>      {
>        *timeout = 0;
>        return renderer->poll_fds_age;
> diff --git a/cogl/cogl-queue.h b/cogl/cogl-queue.h
> deleted file mode 100644
> index 7020ae0..0000000
> --- a/cogl/cogl-queue.h
> +++ /dev/null
> @@ -1,647 +0,0 @@
> -/*-
> - * Copyright (c) 1991, 1993
> - *      The Regents of the University of California.  All rights reserved.
> - *
> - * Copyright (C) 2011 Intel Corporation.
> - *
> - * Redistribution and use in source and binary forms, with or without
> - * modification, are permitted provided that the following conditions
> - * are met:
> - * 1. Redistributions of source code must retain the above copyright
> - *    notice, this list of conditions and the following disclaimer.
> - * 2. Redistributions in binary form must reproduce the above copyright
> - *    notice, this list of conditions and the following disclaimer in the
> - *    documentation and/or other materials provided with the distribution.
> - * 4. Neither the name of the University nor the names of its contributors
> - *    may be used to endorse or promote products derived from this software
> - *    without specific prior written permission.
> - *
> - * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
> - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
> - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
> - * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
> - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
> - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
> - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
> - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
> - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
> - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
> - * SUCH DAMAGE.
> - *
> - *      @(#)queue.h     8.5 (Berkeley) 8/20/94
> - * $FreeBSD$
> - */
> -
> -#ifndef _COGL_QUEUE_H_
> -#define _COGL_QUEUE_H_
> -
> -/*
> - * This file defines four types of data structures: singly-linked lists,
> - * singly-linked tail queues, lists and tail queues.
> - *
> - * A singly-linked list is headed by a single forward pointer. The elements
> - * are singly linked for minimum space and pointer manipulation overhead at
> - * the expense of O(n) removal for arbitrary elements. New elements can be
> - * added to the list after an existing element or at the head of the list.
> - * Elements being removed from the head of the list should use the explicit
> - * macro for this purpose for optimum efficiency. A singly-linked list may
> - * only be traversed in the forward direction.  Singly-linked lists are ideal
> - * for applications with large datasets and few or no removals or for
> - * implementing a LIFO queue.
> - *
> - * A singly-linked tail queue is headed by a pair of pointers, one to the
> - * head of the list and the other to the tail of the list. The elements are
> - * singly linked for minimum space and pointer manipulation overhead at the
> - * expense of O(n) removal for arbitrary elements. New elements can be added
> - * to the list after an existing element, at the head of the list, or at the
> - * end of the list. Elements being removed from the head of the tail queue
> - * should use the explicit macro for this purpose for optimum efficiency.
> - * A singly-linked tail queue may only be traversed in the forward direction.
> - * Singly-linked tail queues are ideal for applications with large datasets
> - * and few or no removals or for implementing a FIFO queue.
> - *
> - * A list is headed by a single forward pointer (or an array of forward
> - * pointers for a hash table header). The elements are doubly linked
> - * so that an arbitrary element can be removed without a need to
> - * traverse the list. New elements can be added to the list before
> - * or after an existing element or at the head of the list. A list
> - * may only be traversed in the forward direction.
> - *
> - * A tail queue is headed by a pair of pointers, one to the head of the
> - * list and the other to the tail of the list. The elements are doubly
> - * linked so that an arbitrary element can be removed without a need to
> - * traverse the list. New elements can be added to the list before or
> - * after an existing element, at the head of the list, or at the end of
> - * the list. A tail queue may be traversed in either direction.
> - *
> - * For details on the use of these macros, see the queue(3) manual page.
> - *
> - *
> - *                              SLIST   LIST    STAILQ  TAILQ
> - * _HEAD                        +       +       +       +
> - * _HEAD_INITIALIZER            +       +       +       +
> - * _ENTRY                       +       +       +       +
> - * _INIT                        +       +       +       +
> - * _EMPTY                       +       +       +       +
> - * _FIRST                       +       +       +       +
> - * _NEXT                        +       +       +       +
> - * _PREV                        -       -       -       +
> - * _LAST                        -       -       +       +
> - * _FOREACH                     +       +       +       +
> - * _FOREACH_SAFE                +       +       +       +
> - * _FOREACH_REVERSE             -       -       -       +
> - * _FOREACH_REVERSE_SAFE        -       -       -       +
> - * _INSERT_HEAD                 +       +       +       +
> - * _INSERT_BEFORE               -       +       -       +
> - * _INSERT_AFTER                +       +       +       +
> - * _INSERT_TAIL                 -       -       +       +
> - * _CONCAT                      -       -       +       +
> - * _REMOVE_AFTER                +       -       +       -
> - * _REMOVE_HEAD                 +       -       +       -
> - * _REMOVE                      +       +       +       +
> - * _SWAP                        +       +       +       +
> - *
> - */
> -#ifdef COGL_QUEUE_MACRO_DEBUG
> -/* Store the last 2 places the queue element or head was altered */
> -struct cogl_qm_trace {
> -        char * lastfile;
> -        int lastline;
> -        char * prevfile;
> -        int prevline;
> -};
> -
> -#define COGL_TRACEBUF struct cogl_qm_trace trace;
> -#define COGL_TRASHIT(x) do {(x) = (void *)-1;} while (0)
> -#define COGL_QMD_SAVELINK(name, link) void **name = (void *)&(link)
> -
> -#define COGL_QMD_TRACE_HEAD(head) do {                                  \
> -        (head)->trace.prevline = (head)->trace.lastline;                \
> -        (head)->trace.prevfile = (head)->trace.lastfile;                \
> -        (head)->trace.lastline = __LINE__;                              \
> -        (head)->trace.lastfile = __FILE__;                              \
> -} while (0)
> -
> -#define COGL_QMD_TRACE_ELEM(elem) do {                                  \
> -        (elem)->trace.prevline = (elem)->trace.lastline;                \
> -        (elem)->trace.prevfile = (elem)->trace.lastfile;                \
> -        (elem)->trace.lastline = __LINE__;                              \
> -        (elem)->trace.lastfile = __FILE__;                              \
> -} while (0)
> -
> -#else
> -#define COGL_QMD_TRACE_ELEM(elem)
> -#define COGL_QMD_TRACE_HEAD(head)
> -#define COGL_QMD_SAVELINK(name, link)
> -#define COGL_TRACEBUF
> -#define COGL_TRASHIT(x)
> -#endif  /* COGL_QUEUE_MACRO_DEBUG */
> -
> -/*
> - * Singly-linked List declarations.
> - */
> -#define COGL_SLIST_HEAD(name, type)                                     \
> -typedef struct _ ## name {                                              \
> -  type *slh_first; /* first element */                                  \
> -} name
> -
> -#define COGL_SLIST_HEAD_INITIALIZER(head)                               \
> -        { NULL }
> -
> -#define COGL_SLIST_ENTRY(type)                                          \
> -struct {                                                                \
> -  type *sle_next;  /* next element */                                   \
> -}
> -
> -/*
> - * Singly-linked List functions.
> - */
> -#define COGL_SLIST_EMPTY(head)  ((head)->slh_first == NULL)
> -
> -#define COGL_SLIST_FIRST(head)  ((head)->slh_first)
> -
> -#define COGL_SLIST_FOREACH(var, head, field)                            \
> -        for ((var) = COGL_SLIST_FIRST((head));                          \
> -            (var);                                                      \
> -            (var) = COGL_SLIST_NEXT((var), field))
> -
> -#define COGL_SLIST_FOREACH_SAFE(var, head, field, tvar)                 \
> -        for ((var) = COGL_SLIST_FIRST((head));                          \
> -            (var) && ((tvar) = COGL_SLIST_NEXT((var), field), 1);       \
> -            (var) = (tvar))
> -
> -#define COGL_SLIST_FOREACH_PREVPTR(var, varp, head, field)              \
> -        for ((varp) = &COGL_SLIST_FIRST((head));                        \
> -            ((var) = *(varp)) != NULL;                                  \
> -            (varp) = &COGL_SLIST_NEXT((var), field))
> -
> -#define COGL_SLIST_INIT(head) do {                                      \
> -        COGL_SLIST_FIRST((head)) = NULL;                                \
> -} while (0)
> -
> -#define COGL_SLIST_INSERT_AFTER(slistelm, elm, field) do {              \
> -        COGL_SLIST_NEXT((elm), field) = COGL_SLIST_NEXT((slistelm), field);  \
> -        COGL_SLIST_NEXT((slistelm), field) = (elm);                     \
> -} while (0)
> -
> -#define COGL_SLIST_INSERT_HEAD(head, elm, field) do {                   \
> -        COGL_SLIST_NEXT((elm), field) = COGL_SLIST_FIRST((head));       \
> -        COGL_SLIST_FIRST((head)) = (elm);                               \
> -} while (0)
> -
> -#define COGL_SLIST_NEXT(elm, field)  ((elm)->field.sle_next)
> -
> -#define COGL_SLIST_REMOVE(head, elm, type, field) do {                  \
> -        COGL_QMD_SAVELINK(oldnext, (elm)->field.sle_next);              \
> -        if (COGL_SLIST_FIRST((head)) == (elm)) {                        \
> -                COGL_SLIST_REMOVE_HEAD((head), field);                  \
> -        }                                                               \
> -        else {                                                          \
> -                type *curelm = COGL_SLIST_FIRST((head));                \
> -                while (COGL_SLIST_NEXT(curelm, field) != (elm))         \
> -                        curelm = COGL_SLIST_NEXT(curelm, field);        \
> -                COGL_SLIST_REMOVE_AFTER(curelm, field);                 \
> -        }                                                               \
> -        COGL_TRASHIT(*oldnext);                                         \
> -} while (0)
> -
> -#define COGL_SLIST_REMOVE_AFTER(elm, field) do {                        \
> -        COGL_SLIST_NEXT(elm, field) =                                   \
> -            COGL_SLIST_NEXT(COGL_SLIST_NEXT(elm, field), field);        \
> -} while (0)
> -
> -#define COGL_SLIST_REMOVE_HEAD(head, field) do {                        \
> -    COGL_SLIST_FIRST((head)) =                                          \
> -      COGL_SLIST_NEXT(COGL_SLIST_FIRST((head)), field);                 \
> -} while (0)
> -
> -#define COGL_SLIST_SWAP(head1, head2, type) do {                        \
> -        type *swap_first = COGL_SLIST_FIRST(head1);                     \
> -        COGL_SLIST_FIRST(head1) = COGL_SLIST_FIRST(head2);              \
> -        COGL_SLIST_FIRST(head2) = swap_first;                           \
> -} while (0)
> -
> -/*
> - * Singly-linked Tail queue declarations.
> - */
> -#define COGL_STAILQ_HEAD(name, type)                                    \
> -typedef struct _ ## name {                                              \
> -        type *stqh_first;/* first element */                            \
> -        type **stqh_last;/* addr of last next element */                \
> -} name
> -
> -#define COGL_STAILQ_HEAD_INITIALIZER(head)                              \
> -        { NULL, &(head).stqh_first }
> -
> -#define COGL_STAILQ_ENTRY(type)                                         \
> -struct {                                                                \
> -        type *stqe_next; /* next element */                             \
> -}
> -
> -/*
> - * Singly-linked Tail queue functions.
> - */
> -#define COGL_STAILQ_CONCAT(head1, head2) do {                           \
> -        if (!COGL_STAILQ_EMPTY((head2))) {                              \
> -                *(head1)->stqh_last = (head2)->stqh_first;              \
> -                (head1)->stqh_last = (head2)->stqh_last;                \
> -                COGL_STAILQ_INIT((head2));                              \
> -        }                                                               \
> -} while (0)
> -
> -#define COGL_STAILQ_EMPTY(head) ((head)->stqh_first == NULL)
> -
> -#define COGL_STAILQ_FIRST(head) ((head)->stqh_first)
> -
> -#define COGL_STAILQ_FOREACH(var, head, field)                           \
> -        for((var) = COGL_STAILQ_FIRST((head));                          \
> -           (var);                                                       \
> -           (var) = COGL_STAILQ_NEXT((var), field))
> -
> -
> -#define COGL_STAILQ_FOREACH_SAFE(var, head, field, tvar)                \
> -        for ((var) = COGL_STAILQ_FIRST((head));                         \
> -            (var) && ((tvar) = COGL_STAILQ_NEXT((var), field), 1);      \
> -            (var) = (tvar))
> -
> -#define COGL_STAILQ_INIT(head) do {                                     \
> -        COGL_STAILQ_FIRST((head)) = NULL;                               \
> -        (head)->stqh_last = &COGL_STAILQ_FIRST((head));                 \
> -} while (0)
> -
> -#define COGL_STAILQ_INSERT_AFTER(head, tqelm, elm, field) do {          \
> -    if ((COGL_STAILQ_NEXT((elm), field) =                               \
> -         COGL_STAILQ_NEXT((tqelm), field)) == NULL)                     \
> -      (head)->stqh_last = &COGL_STAILQ_NEXT((elm), field);              \
> -    COGL_STAILQ_NEXT((tqelm), field) = (elm);                           \
> -} while (0)
> -
> -#define COGL_STAILQ_INSERT_HEAD(head, elm, field) do {                  \
> -    if ((COGL_STAILQ_NEXT((elm), field) =                               \
> -         COGL_STAILQ_FIRST((head))) == NULL)                            \
> -      (head)->stqh_last = &COGL_STAILQ_NEXT((elm), field);              \
> -    COGL_STAILQ_FIRST((head)) = (elm);                                  \
> -  } while (0)
> -
> -#define COGL_STAILQ_INSERT_TAIL(head, elm, field) do {                  \
> -        COGL_STAILQ_NEXT((elm), field) = NULL;                          \
> -        *(head)->stqh_last = (elm);                                     \
> -        (head)->stqh_last = &COGL_STAILQ_NEXT((elm), field);            \
> -} while (0)
> -
> -#define COGL_STAILQ_LAST(head, type, field)                             \
> -        (COGL_STAILQ_EMPTY((head)) ?                                    \
> -                NULL :                                                  \
> -                ((type *)(void *)                                       \
> -                 ((char *)((head)->stqh_last) -                         \
> -                  __offsetof(struct type, field))))
> -
> -#define COGL_STAILQ_NEXT(elm, field) ((elm)->field.stqe_next)
> -
> -#define COGL_STAILQ_REMOVE(head, elm, type, field) do {                 \
> -        COGL_QMD_SAVELINK(oldnext, (elm)->field.stqe_next);             \
> -        if (COGL_STAILQ_FIRST((head)) == (elm)) {                       \
> -                COGL_STAILQ_REMOVE_HEAD((head), field);                 \
> -        }                                                               \
> -        else {                                                          \
> -                type *curelm = COGL_STAILQ_FIRST((head));               \
> -                while (COGL_STAILQ_NEXT(curelm, field) != (elm))        \
> -                        curelm = COGL_STAILQ_NEXT(curelm, field);       \
> -                COGL_STAILQ_REMOVE_AFTER(head, curelm, field);          \
> -        }                                                               \
> -        COGL_TRASHIT(*oldnext);                                         \
> -} while (0)
> -
> -#define COGL_STAILQ_REMOVE_AFTER(head, elm, field) do {                 \
> -        if ((COGL_STAILQ_NEXT(elm, field) =                             \
> -             COGL_STAILQ_NEXT(COGL_STAILQ_NEXT(elm, field),             \
> -                              field)) == NULL)                          \
> -                (head)->stqh_last = &COGL_STAILQ_NEXT((elm), field);    \
> -} while (0)
> -
> -#define COGL_STAILQ_REMOVE_HEAD(head, field) do {                       \
> -        if ((COGL_STAILQ_FIRST((head)) =                                \
> -             COGL_STAILQ_NEXT(COGL_STAILQ_FIRST((head)), field)) == NULL) \
> -                (head)->stqh_last = &COGL_STAILQ_FIRST((head));         \
> -} while (0)
> -
> -#define COGL_STAILQ_SWAP(head1, head2, type) do {                       \
> -        type *swap_first = COGL_STAILQ_FIRST(head1);                    \
> -        type **swap_last = (head1)->stqh_last;                          \
> -        COGL_STAILQ_FIRST(head1) = COGL_STAILQ_FIRST(head2);            \
> -        (head1)->stqh_last = (head2)->stqh_last;                        \
> -        COGL_STAILQ_FIRST(head2) = swap_first;                          \
> -        (head2)->stqh_last = swap_last;                                 \
> -        if (COGL_STAILQ_EMPTY(head1))                                   \
> -                (head1)->stqh_last = &COGL_STAILQ_FIRST(head1);         \
> -        if (COGL_STAILQ_EMPTY(head2))                                   \
> -                (head2)->stqh_last = &COGL_STAILQ_FIRST(head2);         \
> -} while (0)
> -
> -
> -/*
> - * List declarations.
> - */
> -#define COGL_LIST_HEAD(name, type)                                      \
> -typedef struct _ ## name {                                              \
> -        type *lh_first;  /* first element */                            \
> -} name
> -
> -#define COGL_LIST_HEAD_INITIALIZER(head)                                \
> -        { NULL }
> -
> -#define COGL_LIST_ENTRY(type)                                           \
> -struct {                                                                \
> -        type *le_next;   /* next element */                             \
> -        type **le_prev;  /* address of previous next element */         \
> -}
> -
> -/*
> - * List functions.
> - */
> -
> -#if (defined(_KERNEL) && defined(INVARIANTS))
> -#define COGL_QMD_LIST_CHECK_HEAD(head, field) do {                      \
> -        if (COGL_LIST_FIRST((head)) != NULL &&                          \
> -            COGL_LIST_FIRST((head))->field.le_prev !=                   \
> -             &COGL_LIST_FIRST((head)))                                  \
> -                panic("Bad list head %p first->prev != head", (head));  \
> -} while (0)
> -
> -#define COGL_QMD_LIST_CHECK_NEXT(elm, field) do {                       \
> -        if (COGL_LIST_NEXT((elm), field) != NULL &&                     \
> -            COGL_LIST_NEXT((elm), field)->field.le_prev !=              \
> -             &((elm)->field.le_next))                                   \
> -                panic("Bad link elm %p next->prev != elm", (elm));      \
> -} while (0)
> -
> -#define COGL_QMD_LIST_CHECK_PREV(elm, field) do {                       \
> -        if (*(elm)->field.le_prev != (elm))                             \
> -                panic("Bad link elm %p prev->next != elm", (elm));      \
> -} while (0)
> -#else
> -#define COGL_QMD_LIST_CHECK_HEAD(head, field)
> -#define COGL_QMD_LIST_CHECK_NEXT(elm, field)
> -#define COGL_QMD_LIST_CHECK_PREV(elm, field)
> -#endif /* (_KERNEL && INVARIANTS) */
> -
> -#define COGL_LIST_EMPTY(head)   ((head)->lh_first == NULL)
> -
> -#define COGL_LIST_FIRST(head)   ((head)->lh_first)
> -
> -#define COGL_LIST_FOREACH(var, head, field)                             \
> -        for ((var) = COGL_LIST_FIRST((head));                           \
> -            (var);                                                      \
> -            (var) = COGL_LIST_NEXT((var), field))
> -
> -#define COGL_LIST_FOREACH_SAFE(var, head, field, tvar)                  \
> -        for ((var) = COGL_LIST_FIRST((head));                           \
> -            (var) && ((tvar) = COGL_LIST_NEXT((var), field), 1);        \
> -            (var) = (tvar))
> -
> -#define COGL_LIST_INIT(head) do {                                       \
> -        COGL_LIST_FIRST((head)) = NULL;                                 \
> -} while (0)
> -
> -#define COGL_LIST_INSERT_AFTER(listelm, elm, field) do {                \
> -        COGL_QMD_LIST_CHECK_NEXT(listelm, field);                       \
> -        if ((COGL_LIST_NEXT((elm), field) =                             \
> -             COGL_LIST_NEXT((listelm), field)) != NULL)                 \
> -                COGL_LIST_NEXT((listelm), field)->field.le_prev =       \
> -                    &COGL_LIST_NEXT((elm), field);                      \
> -        COGL_LIST_NEXT((listelm), field) = (elm);                       \
> -        (elm)->field.le_prev = &COGL_LIST_NEXT((listelm), field);       \
> -} while (0)
> -
> -#define COGL_LIST_INSERT_BEFORE(listelm, elm, field) do {               \
> -        COGL_QMD_LIST_CHECK_PREV(listelm, field);                       \
> -        (elm)->field.le_prev = (listelm)->field.le_prev;                \
> -        COGL_LIST_NEXT((elm), field) = (listelm);                       \
> -        *(listelm)->field.le_prev = (elm);                              \
> -        (listelm)->field.le_prev = &COGL_LIST_NEXT((elm), field);       \
> -} while (0)
> -
> -#define COGL_LIST_INSERT_HEAD(head, elm, field) do {                    \
> -        COGL_QMD_LIST_CHECK_HEAD((head), field);                        \
> -        if ((COGL_LIST_NEXT((elm), field) =                             \
> -             COGL_LIST_FIRST((head))) != NULL)                          \
> -          COGL_LIST_FIRST((head))->field.le_prev =                      \
> -            &COGL_LIST_NEXT((elm), field);                              \
> -        COGL_LIST_FIRST((head)) = (elm);                                \
> -        (elm)->field.le_prev = &COGL_LIST_FIRST((head));                \
> -} while (0)
> -
> -#define COGL_LIST_NEXT(elm, field)   ((elm)->field.le_next)
> -
> -#define COGL_LIST_REMOVE(elm, field) do {                               \
> -        COGL_QMD_SAVELINK(oldnext, (elm)->field.le_next);               \
> -        COGL_QMD_SAVELINK(oldprev, (elm)->field.le_prev);               \
> -        COGL_QMD_LIST_CHECK_NEXT(elm, field);                           \
> -        COGL_QMD_LIST_CHECK_PREV(elm, field);                           \
> -        if (COGL_LIST_NEXT((elm), field) != NULL)                       \
> -                COGL_LIST_NEXT((elm), field)->field.le_prev =           \
> -                    (elm)->field.le_prev;                               \
> -        *(elm)->field.le_prev = COGL_LIST_NEXT((elm), field);           \
> -        COGL_TRASHIT(*oldnext);                                         \
> -        COGL_TRASHIT(*oldprev);                                         \
> -} while (0)
> -
> -#define COGL_LIST_SWAP(head1, head2, type, field) do {                  \
> -        type *swap_tmp = COGL_LIST_FIRST((head1));                      \
> -        COGL_LIST_FIRST((head1)) = COGL_LIST_FIRST((head2));            \
> -        COGL_LIST_FIRST((head2)) = swap_tmp;                            \
> -        if ((swap_tmp = COGL_LIST_FIRST((head1))) != NULL)              \
> -                swap_tmp->field.le_prev = &COGL_LIST_FIRST((head1));    \
> -        if ((swap_tmp = COGL_LIST_FIRST((head2))) != NULL)              \
> -                swap_tmp->field.le_prev = &COGL_LIST_FIRST((head2));    \
> -} while (0)
> -
> -/*
> - * Tail queue declarations.
> - */
> -#define COGL_TAILQ_HEAD(name, type)                                     \
> -typedef struct _ ## name {                                              \
> -        type *tqh_first; /* first element */                            \
> -        type **tqh_last; /* addr of last next element */                \
> -        COGL_TRACEBUF                                                   \
> -} name
> -
> -#define COGL_TAILQ_HEAD_INITIALIZER(head)                               \
> -        { NULL, &(head).tqh_first }
> -
> -#define COGL_TAILQ_ENTRY(type)                                          \
> -struct {                                                                \
> -        type *tqe_next;  /* next element */                             \
> -        type **tqe_prev; /* address of previous next element */         \
> -        COGL_TRACEBUF                                                   \
> -}
> -
> -/*
> - * Tail queue functions.
> - */
> -#if (defined(_KERNEL) && defined(INVARIANTS))
> -#define COGL_QMD_TAILQ_CHECK_HEAD(head, field) do {                     \
> -        if (!COGL_TAILQ_EMPTY(head) &&                                  \
> -            COGL_TAILQ_FIRST((head))->field.tqe_prev !=                 \
> -             &COGL_TAILQ_FIRST((head)))                                 \
> -                panic("Bad tailq head %p first->prev != head", (head)); \
> -} while (0)
> -
> -#define COGL_QMD_TAILQ_CHECK_TAIL(head, field) do {                     \
> -        if (*(head)->tqh_last != NULL)                                  \
> -                panic("Bad tailq NEXT(%p->tqh_last) != NULL", (head));  \
> -} while (0)
> -
> -#define COGL_QMD_TAILQ_CHECK_NEXT(elm, field) do {                      \
> -        if (COGL_TAILQ_NEXT((elm), field) != NULL &&                    \
> -            COGL_TAILQ_NEXT((elm), field)->field.tqe_prev !=            \
> -             &((elm)->field.tqe_next))                                  \
> -                panic("Bad link elm %p next->prev != elm", (elm));      \
> -} while (0)
> -
> -#define COGL_QMD_TAILQ_CHECK_PREV(elm, field) do {                      \
> -        if (*(elm)->field.tqe_prev != (elm))                            \
> -                panic("Bad link elm %p prev->next != elm", (elm));      \
> -} while (0)
> -#else
> -#define COGL_QMD_TAILQ_CHECK_HEAD(head, field)
> -#define COGL_QMD_TAILQ_CHECK_TAIL(head, headname)
> -#define COGL_QMD_TAILQ_CHECK_NEXT(elm, field)
> -#define COGL_QMD_TAILQ_CHECK_PREV(elm, field)
> -#endif /* (_KERNEL && INVARIANTS) */
> -
> -#define COGL_TAILQ_CONCAT(head1, head2, field) do {                     \
> -        if (!COGL_TAILQ_EMPTY(head2)) {                                 \
> -                *(head1)->tqh_last = (head2)->tqh_first;                \
> -                (head2)->tqh_first->field.tqe_prev = (head1)->tqh_last; \
> -                (head1)->tqh_last = (head2)->tqh_last;                  \
> -                COGL_TAILQ_INIT((head2));                               \
> -                COGL_QMD_TRACE_HEAD(head1);                             \
> -                COGL_QMD_TRACE_HEAD(head2);                             \
> -        }                                                               \
> -} while (0)
> -
> -#define COGL_TAILQ_EMPTY(head)  ((head)->tqh_first == NULL)
> -
> -#define COGL_TAILQ_FIRST(head)  ((head)->tqh_first)
> -
> -#define COGL_TAILQ_FOREACH(var, head, field)                            \
> -        for ((var) = COGL_TAILQ_FIRST((head));                          \
> -            (var);                                                      \
> -            (var) = COGL_TAILQ_NEXT((var), field))
> -
> -#define COGL_TAILQ_FOREACH_SAFE(var, head, field, tvar)                 \
> -        for ((var) = COGL_TAILQ_FIRST((head));                          \
> -            (var) && ((tvar) = COGL_TAILQ_NEXT((var), field), 1);       \
> -            (var) = (tvar))
> -
> -#define COGL_TAILQ_FOREACH_REVERSE(var, head, headname, field)          \
> -        for ((var) = COGL_TAILQ_LAST((head), headname);                 \
> -            (var);                                                      \
> -            (var) = COGL_TAILQ_PREV((var), headname, field))
> -
> -#define COGL_TAILQ_FOREACH_REVERSE_SAFE(var, head, headname, field, tvar) \
> -        for ((var) = COGL_TAILQ_LAST((head), headname);                 \
> -            (var) && ((tvar) = COGL_TAILQ_PREV((var), headname, field), 1); \
> -            (var) = (tvar))
> -
> -#define COGL_TAILQ_INIT(head) do {                                      \
> -        COGL_TAILQ_FIRST((head)) = NULL;                                \
> -        (head)->tqh_last = &COGL_TAILQ_FIRST((head));                   \
> -        COGL_QMD_TRACE_HEAD(head);                                      \
> -} while (0)
> -
> -#define COGL_TAILQ_INSERT_AFTER(head, listelm, elm, field) do {         \
> -        COGL_QMD_TAILQ_CHECK_NEXT(listelm, field);                      \
> -        if ((COGL_TAILQ_NEXT((elm), field) =                            \
> -             COGL_TAILQ_NEXT((listelm), field)) != NULL)                \
> -                COGL_TAILQ_NEXT((elm), field)->field.tqe_prev =         \
> -                    &COGL_TAILQ_NEXT((elm), field);                     \
> -        else {                                                          \
> -                (head)->tqh_last = &COGL_TAILQ_NEXT((elm), field);      \
> -                COGL_QMD_TRACE_HEAD(head);                              \
> -        }                                                               \
> -        COGL_TAILQ_NEXT((listelm), field) = (elm);                      \
> -        (elm)->field.tqe_prev = &COGL_TAILQ_NEXT((listelm), field);     \
> -        COGL_QMD_TRACE_ELEM(&(elm)->field);                             \
> -        COGL_QMD_TRACE_ELEM(&listelm->field);                           \
> -} while (0)
> -
> -#define COGL_TAILQ_INSERT_BEFORE(listelm, elm, field) do {              \
> -        COGL_QMD_TAILQ_CHECK_PREV(listelm, field);                      \
> -        (elm)->field.tqe_prev = (listelm)->field.tqe_prev;              \
> -        COGL_TAILQ_NEXT((elm), field) = (listelm);                      \
> -        *(listelm)->field.tqe_prev = (elm);                             \
> -        (listelm)->field.tqe_prev = &COGL_TAILQ_NEXT((elm), field);     \
> -        COGL_QMD_TRACE_ELEM(&(elm)->field);                             \
> -        COGL_QMD_TRACE_ELEM(&listelm->field);                           \
> -} while (0)
> -
> -#define COGL_TAILQ_INSERT_HEAD(head, elm, field) do {                   \
> -        COGL_QMD_TAILQ_CHECK_HEAD(head, field);                         \
> -        if ((COGL_TAILQ_NEXT((elm), field) =                            \
> -             COGL_TAILQ_FIRST((head))) != NULL)                         \
> -                COGL_TAILQ_FIRST((head))->field.tqe_prev =              \
> -                    &COGL_TAILQ_NEXT((elm), field);                     \
> -        else                                                            \
> -                (head)->tqh_last = &COGL_TAILQ_NEXT((elm), field);      \
> -        COGL_TAILQ_FIRST((head)) = (elm);                               \
> -        (elm)->field.tqe_prev = &COGL_TAILQ_FIRST((head));              \
> -        COGL_QMD_TRACE_HEAD(head);                                      \
> -        COGL_QMD_TRACE_ELEM(&(elm)->field);                             \
> -} while (0)
> -
> -#define COGL_TAILQ_INSERT_TAIL(head, elm, field) do {                   \
> -        COGL_QMD_TAILQ_CHECK_TAIL(head, field);                         \
> -        COGL_TAILQ_NEXT((elm), field) = NULL;                           \
> -        (elm)->field.tqe_prev = (head)->tqh_last;                       \
> -        *(head)->tqh_last = (elm);                                      \
> -        (head)->tqh_last = &COGL_TAILQ_NEXT((elm), field);              \
> -        COGL_QMD_TRACE_HEAD(head);                                      \
> -        COGL_QMD_TRACE_ELEM(&(elm)->field);                             \
> -} while (0)
> -
> -#define COGL_TAILQ_LAST(head, headname)                                 \
> -        (*(((headname *)((head)->tqh_last))->tqh_last))
> -
> -#define COGL_TAILQ_NEXT(elm, field) ((elm)->field.tqe_next)
> -
> -#define COGL_TAILQ_PREV(elm, headname, field)                           \
> -        (*(((headname *)((elm)->field.tqe_prev))->tqh_last))
> -
> -#define COGL_TAILQ_REMOVE(head, elm, field) do {                        \
> -        COGL_QMD_SAVELINK(oldnext, (elm)->field.tqe_next);              \
> -        COGL_QMD_SAVELINK(oldprev, (elm)->field.tqe_prev);              \
> -        COGL_QMD_TAILQ_CHECK_NEXT(elm, field);                          \
> -        COGL_QMD_TAILQ_CHECK_PREV(elm, field);                          \
> -        if ((COGL_TAILQ_NEXT((elm), field)) != NULL)                    \
> -                COGL_TAILQ_NEXT((elm), field)->field.tqe_prev =         \
> -                    (elm)->field.tqe_prev;                              \
> -        else {                                                          \
> -                (head)->tqh_last = (elm)->field.tqe_prev;               \
> -                COGL_QMD_TRACE_HEAD(head);                              \
> -        }                                                               \
> -        *(elm)->field.tqe_prev = COGL_TAILQ_NEXT((elm), field);         \
> -        COGL_TRASHIT(*oldnext);                                         \
> -        COGL_TRASHIT(*oldprev);                                         \
> -        COGL_QMD_TRACE_ELEM(&(elm)->field);                             \
> -} while (0)
> -
> -#define COGL_TAILQ_SWAP(head1, head2, type, field) do {                 \
> -        type *swap_first = (head1)->tqh_first;                          \
> -        type **swap_last = (head1)->tqh_last;                           \
> -        (head1)->tqh_first = (head2)->tqh_first;                        \
> -        (head1)->tqh_last = (head2)->tqh_last;                          \
> -        (head2)->tqh_first = swap_first;                                \
> -        (head2)->tqh_last = swap_last;                                  \
> -        if ((swap_first = (head1)->tqh_first) != NULL)                  \
> -                swap_first->field.tqe_prev = &(head1)->tqh_first;       \
> -        else                                                            \
> -                (head1)->tqh_last = &(head1)->tqh_first;                \
> -        if ((swap_first = (head2)->tqh_first) != NULL)                  \
> -                swap_first->field.tqe_prev = &(head2)->tqh_first;       \
> -        else                                                            \
> -                (head2)->tqh_last = &(head2)->tqh_first;                \
> -} while (0)
> -
> -#endif /* !_COGL_QUEUE_H_ */
> diff --git a/cogl/cogl-renderer-private.h b/cogl/cogl-renderer-private.h
> index 62aca7e..efc20a3 100644
> --- a/cogl/cogl-renderer-private.h
> +++ b/cogl/cogl-renderer-private.h
> @@ -56,7 +56,7 @@ struct _CoglRenderer
>    int poll_fds_age;
>    GList *poll_sources;
>
> -  CoglClosureList idle_closures;
> +  CoglList idle_closures;
>
>    GList *outputs;
>
> diff --git a/cogl/cogl-renderer.c b/cogl/cogl-renderer.c
> index bfd91cd..6f978c6 100644
> --- a/cogl/cogl-renderer.c
> +++ b/cogl/cogl-renderer.c
> @@ -187,7 +187,7 @@ cogl_renderer_new (void)
>
>    renderer->poll_fds = g_array_new (FALSE, TRUE, sizeof (CoglPollFD));
>
> -  COGL_LIST_INIT (&renderer->idle_closures);
> +  _cogl_list_init (&renderer->idle_closures);
>
>  #ifdef COGL_HAS_XLIB_SUPPORT
>    renderer->xlib_enable_event_retrieval = TRUE;
> diff --git a/cogl/cogl-sdl.c b/cogl/cogl-sdl.c
> index 602cac0..324bfd8 100644
> --- a/cogl/cogl-sdl.c
> +++ b/cogl/cogl-sdl.c
> @@ -100,6 +100,6 @@ cogl_sdl_idle (CoglContext *context)
>     * to make sure the blocking returns immediately. We'll post our
>     * dummy event to make sure that happens
>     */
> -  if (!COGL_LIST_EMPTY (&renderer->idle_closures))
> +  if (!_cogl_list_empty (&renderer->idle_closures))
>      _cogl_sdl_push_wakeup_event (context);
>  }
> diff --git a/cogl/driver/gl/cogl-pipeline-fragend-glsl.c b/cogl/driver/gl/cogl-pipeline-fragend-glsl.c
> index 0b06dd4..9fa9cbf 100644
> --- a/cogl/driver/gl/cogl-pipeline-fragend-glsl.c
> +++ b/cogl/driver/gl/cogl-pipeline-fragend-glsl.c
> @@ -38,6 +38,7 @@
>  #include "cogl-pipeline-layer-private.h"
>  #include "cogl-blend-string.h"
>  #include "cogl-snippet-private.h"
> +#include "cogl-list.h"
>
>  #ifdef COGL_PIPELINE_FRAGEND_GLSL
>
> @@ -66,13 +67,9 @@ typedef struct _UnitState
>    unsigned int combine_constant_used:1;
>  } UnitState;
>
> -typedef struct _LayerData LayerData;
> -
> -COGL_LIST_HEAD (LayerDataList, LayerData);
> -
> -struct _LayerData
> +typedef struct _LayerData
>  {
> -  COGL_LIST_ENTRY (LayerData) list_node;
> +  CoglList link;
>
>    /* Layer index for the for the previous layer. This isn't
>       necessarily the same as this layer's index - 1 because the
> @@ -81,7 +78,7 @@ struct _LayerData
>    int previous_layer_index;
>
>    CoglPipelineLayer *layer;
> -};
> +} LayerData;
>
>  typedef struct
>  {
> @@ -97,7 +94,7 @@ typedef struct
>       in reverse order. As soon as we're about to generate code for
>       layer we'll remove it from the list so we don't generate it
>       again */
> -  LayerDataList layers;
> +  CoglList layers;
>  } CoglPipelineShaderState;
>
>  static CoglUserDataKey shader_state_key;
> @@ -349,7 +346,7 @@ _cogl_pipeline_fragend_glsl_start (CoglPipeline *pipeline,
>    g_string_set_size (ctx->codegen_source_buffer, 0);
>    shader_state->header = ctx->codegen_header_buffer;
>    shader_state->source = ctx->codegen_source_buffer;
> -  COGL_LIST_INIT (&shader_state->layers);
> +  _cogl_list_init (&shader_state->layers);
>
>    add_layer_declarations (pipeline, shader_state);
>    add_global_declarations (pipeline, shader_state);
> @@ -750,7 +747,7 @@ ensure_layer_generated (CoglPipeline *pipeline,
>    LayerData *layer_data;
>
>    /* Find the layer that corresponds to this layer_num */
> -  COGL_LIST_FOREACH (layer_data, &shader_state->layers, list_node)
> +  _cogl_list_for_each (layer_data, &shader_state->layers, link)
>      {
>        layer = layer_data->layer;
>
> @@ -765,7 +762,7 @@ ensure_layer_generated (CoglPipeline *pipeline,
>   found:
>
>    /* Remove the layer from the list so we don't generate it again */
> -  COGL_LIST_REMOVE (layer_data, list_node);
> +  _cogl_list_remove (&layer_data->link);
>
>    combine_authority =
>      _cogl_pipeline_layer_get_authority (layer,
> @@ -882,13 +879,18 @@ _cogl_pipeline_fragend_glsl_add_layer (CoglPipeline *pipeline,
>    layer_data = g_slice_new (LayerData);
>    layer_data->layer = layer;
>
> -  if (COGL_LIST_EMPTY (&shader_state->layers))
> -    layer_data->previous_layer_index = -1;
> +  if (_cogl_list_empty (&shader_state->layers))
> +    {
> +      layer_data->previous_layer_index = -1;
> +    }
>    else
> -    layer_data->previous_layer_index
> -      = COGL_LIST_FIRST (&shader_state->layers)->layer->index;
> +    {
> +      LayerData *first =
> +        _cogl_container_of (shader_state->layers.next, first, link);
> +      layer_data->previous_layer_index = first->layer->index;
> +    }
>
> -  COGL_LIST_INSERT_HEAD (&shader_state->layers, layer_data, list_node);
> +  _cogl_list_insert (&shader_state->layers, &layer_data->link);
>
>    return TRUE;
>  }
> @@ -988,20 +990,25 @@ _cogl_pipeline_fragend_glsl_end (CoglPipeline *pipeline,
>           for the last layer. If the value of this layer depends on any
>           previous layers then it will recursively generate the code
>           for those layers */
> -      if (!COGL_LIST_EMPTY (&shader_state->layers))
> +      if (!_cogl_list_empty (&shader_state->layers))
>          {
>            CoglPipelineLayer *last_layer;
>            LayerData *layer_data, *tmp;
>
> -          last_layer = COGL_LIST_FIRST (&shader_state->layers)->layer;
> +          layer_data = _cogl_container_of (shader_state->layers.next,
> +                                           layer_data,
> +                                           link);
> +          last_layer = layer_data->layer;
>
>            ensure_layer_generated (pipeline, last_layer->index);
>            g_string_append_printf (shader_state->source,
>                                    "  cogl_color_out = cogl_layer%i;\n",
>                                    last_layer->index);
>
> -          COGL_LIST_FOREACH_SAFE (layer_data, &shader_state->layers,
> -                                  list_node, tmp)
> +          _cogl_list_for_each_safe (layer_data,
> +                                    tmp,
> +                                    &shader_state->layers,
> +                                    link)
>              g_slice_free (LayerData, layer_data);
>          }
>        else
> diff --git a/doc/reference/cogl2/Makefile.am b/doc/reference/cogl2/Makefile.am
> index e4556c3..9424c51 100644
> --- a/doc/reference/cogl2/Makefile.am
> +++ b/doc/reference/cogl2/Makefile.am
> @@ -78,7 +78,6 @@ IGNORE_HFILES=\
>         cogl-gl-header.h                        \
>         cogl-glsl-shader-boilerplate.h          \
>         cogl-profile.h                          \
> -       cogl-queue.h                            \
>         cogl-rectangle-map.h                    \
>         cogl-spans.h                            \
>         cogl-texture-driver.h                   \
> --
> 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