From 534e535a287059fd0acd53bd53a72c0f40264042 Mon Sep 17 00:00:00 2001 From: Neil Roberts Date: Sat, 8 Jun 2013 23:03:25 +0100 Subject: [PATCH] Use the Wayland embedded linked list implementation instead of BSD's MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit 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 (cherry picked from commit 13abf613b15f571ba1fcf6d2eb831ffc6fa31324) Conflicts: cogl/cogl-context-private.h cogl/cogl-context.c cogl/driver/gl/cogl-pipeline-fragend-glsl.c doc/reference/cogl-2.0-experimental/Makefile.am --- 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 | 48 +- .../cogl-2.0-experimental/Makefile.am | 1 - 28 files changed, 375 insertions(+), 823 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 4036ab26c..0183c1b23 100644 --- a/cogl/Makefile.am +++ b/cogl/Makefile.am @@ -409,7 +409,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 9aaa179e1..92ba0a1d0 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 60b26b444..dfb5bf398 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 c800b3f64..d5e52917f 100644 --- a/cogl/cogl-context-private.h +++ b/cogl/cogl-context-private.h @@ -197,8 +197,8 @@ struct _CoglContext GHashTable *swap_callback_closures; int next_swap_callback_id; - CoglOnscreenEventList onscreen_events_queue; - CoglOnscreenQueuedDirtyList onscreen_dirty_queue; + CoglList onscreen_events_queue; + CoglList onscreen_dirty_queue; CoglClosure *onscreen_dispatch_idle; CoglGLES2Context *current_gles2_context; @@ -311,7 +311,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 7365f9172..87041c6bc 100644 --- a/cogl/cogl-context.c +++ b/cogl/cogl-context.c @@ -315,8 +315,8 @@ cogl_context_new (CoglDisplay *display, context->swap_callback_closures = g_hash_table_new (g_direct_hash, g_direct_equal); - 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); @@ -481,7 +481,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 0817b7d7a..7a41c5173 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 2055ac46a..77469d7c4 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 5afb296fa..c9d4bcc75 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 c2b61fd59..ade857007 100644 --- a/cogl/cogl-gles2-context.c +++ b/cogl/cogl-gles2-context.c @@ -1439,7 +1439,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); } @@ -1517,10 +1517,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 */ @@ -1576,7 +1578,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); @@ -1698,9 +1700,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; @@ -1744,9 +1746,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 b73fbd1fc..63cbc2388 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 763b619e6..dc1cfa8ae 100644 --- a/cogl/cogl-journal.c +++ b/cogl/cogl-journal.c @@ -154,7 +154,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); } @@ -1272,11 +1272,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 000000000..3fbc675ae --- /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 +#include + +#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 000000000..7d716a893 --- /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 5f4547e88..2aefcc92d 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 #include -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 f1b505cec..ee2246c44 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 ab32e2886..88bf99172 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 5dcf96770..f60d6bc07 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 @@ -35,30 +35,22 @@ #include #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 ce533e711..52b4554cc 100644 --- a/cogl/cogl-onscreen.c +++ b/cogl/cogl-onscreen.c @@ -48,9 +48,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); @@ -154,23 +154,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; @@ -183,12 +180,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, @@ -226,7 +223,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); } @@ -258,7 +255,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 5ebf0e428..ec850c13e 100644 --- a/cogl/cogl-pipeline-layer.c +++ b/cogl/cogl-pipeline-layer.c @@ -347,7 +347,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; @@ -369,7 +369,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 3d8972143..5c875e3a8 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 dcf459aef..4ef83399b 100644 --- a/cogl/cogl-pipeline.c +++ b/cogl/cogl-pipeline.c @@ -459,7 +459,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)); @@ -1356,7 +1356,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 e29d9976c..c50d64816 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 7020ae076..000000000 --- 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 62aca7e3c..efc20a349 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 1e3471440..e3008db79 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 602cac043..324bfd83d 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 7b1098676..00e053b42 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 @@ -68,13 +69,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 @@ -83,7 +80,7 @@ struct _LayerData int previous_layer_index; CoglPipelineLayer *layer; -}; +} LayerData; typedef struct { @@ -99,8 +96,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; @@ -363,7 +359,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); @@ -764,7 +760,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; @@ -779,7 +775,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, @@ -896,13 +892,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; } @@ -1002,20 +1003,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/cogl-2.0-experimental/Makefile.am b/doc/reference/cogl-2.0-experimental/Makefile.am index 8839f1806..fd569c837 100644 --- a/doc/reference/cogl-2.0-experimental/Makefile.am +++ b/doc/reference/cogl-2.0-experimental/Makefile.am @@ -82,7 +82,6 @@ IGNORE_HFILES=\ cogl-glsl-shader-boilerplate.h \ cogl-deprecated.h \ cogl-profile.h \ - cogl-queue.h \ cogl-rectangle-map.h \ cogl-spans.h \ cogl-texture-driver.h \