[cogl] Use the Wayland embedded linked list implementation instead of BSD's



commit 13abf613b15f571ba1fcf6d2eb831ffc6fa31324
Author: Neil Roberts <neil linux intel com>
Date:   Sat Jun 8 23:03:25 2013 +0100

    Use the Wayland embedded linked list implementation instead of BSD's
    
    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.
    
    Reviewed-by: Robert Bragg <robert linux intel com>

 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(-)
---
diff --git a/cogl/Makefile.am b/cogl/Makefile.am
index b3fbd8c..5c30102 100644
--- a/cogl/Makefile.am
+++ b/cogl/Makefile.am
@@ -336,7 +336,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 7243379..c2ad0a2 100644
--- a/cogl/cogl-context.c
+++ b/cogl/cogl-context.c
@@ -293,8 +293,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);
 
@@ -432,7 +432,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-renderer-private.h b/cogl/cogl-renderer-private.h
index bcf0b9a..1816588 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 252ba29..c5a2940 100644
--- a/cogl/cogl-renderer.c
+++ b/cogl/cogl-renderer.c
@@ -278,7 +278,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 d610285..6274212 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                   \



[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]