cogl: Use GHookList instead of CoglCallbackList

glib already has a data type to manage a list of callbacks called a
GHookList so we might as well use it instead of maintaining Cogl's own
type. The glib version may be slightly more efficient because it
avoids using a GList and instead encodes the prev and next pointers
directly in the GHook structure. It also has more features than
CoglCallbackList.
This commit is contained in:
Neil Roberts 2011-03-14 17:58:31 +00:00
parent 034d273030
commit f38b7a78fb
8 changed files with 65 additions and 208 deletions

View File

@ -273,8 +273,6 @@ cogl_sources_c = \
$(srcdir)/cogl-shader-boilerplate.h \ $(srcdir)/cogl-shader-boilerplate.h \
$(srcdir)/cogl-shader-private.h \ $(srcdir)/cogl-shader-private.h \
$(srcdir)/cogl-shader.c \ $(srcdir)/cogl-shader.c \
$(srcdir)/cogl-callback-list.h \
$(srcdir)/cogl-callback-list.c \
$(srcdir)/cogl-gtype-private.h \ $(srcdir)/cogl-gtype-private.h \
$(srcdir)/cogl-point-in-poly-private.h \ $(srcdir)/cogl-point-in-poly-private.h \
$(srcdir)/cogl-point-in-poly.c \ $(srcdir)/cogl-point-in-poly.c \

View File

@ -58,8 +58,8 @@ _cogl_atlas_new (CoglPixelFormat texture_format,
atlas->texture = NULL; atlas->texture = NULL;
atlas->flags = flags; atlas->flags = flags;
atlas->texture_format = texture_format; atlas->texture_format = texture_format;
_cogl_callback_list_init (&atlas->pre_reorganize_callbacks); g_hook_list_init (&atlas->pre_reorganize_callbacks, sizeof (GHook));
_cogl_callback_list_init (&atlas->post_reorganize_callbacks); g_hook_list_init (&atlas->post_reorganize_callbacks, sizeof (GHook));
return _cogl_atlas_object_new (atlas); return _cogl_atlas_object_new (atlas);
} }
@ -74,8 +74,8 @@ _cogl_atlas_free (CoglAtlas *atlas)
if (atlas->map) if (atlas->map)
_cogl_rectangle_map_free (atlas->map); _cogl_rectangle_map_free (atlas->map);
_cogl_callback_list_destroy (&atlas->pre_reorganize_callbacks); g_hook_list_clear (&atlas->pre_reorganize_callbacks);
_cogl_callback_list_destroy (&atlas->post_reorganize_callbacks); g_hook_list_clear (&atlas->post_reorganize_callbacks);
g_free (atlas); g_free (atlas);
} }
@ -312,13 +312,13 @@ _cogl_atlas_compare_size_cb (const void *a,
static void static void
_cogl_atlas_notify_pre_reorganize (CoglAtlas *atlas) _cogl_atlas_notify_pre_reorganize (CoglAtlas *atlas)
{ {
_cogl_callback_list_invoke (&atlas->pre_reorganize_callbacks); g_hook_list_invoke (&atlas->pre_reorganize_callbacks, FALSE);
} }
static void static void
_cogl_atlas_notify_post_reorganize (CoglAtlas *atlas) _cogl_atlas_notify_post_reorganize (CoglAtlas *atlas)
{ {
_cogl_callback_list_invoke (&atlas->post_reorganize_callbacks); g_hook_list_invoke (&atlas->post_reorganize_callbacks, FALSE);
} }
gboolean gboolean
@ -542,30 +542,48 @@ _cogl_atlas_copy_rectangle (CoglAtlas *atlas,
void void
_cogl_atlas_add_reorganize_callback (CoglAtlas *atlas, _cogl_atlas_add_reorganize_callback (CoglAtlas *atlas,
CoglCallbackListFunc pre_callback, GHookFunc pre_callback,
CoglCallbackListFunc post_callback, GHookFunc post_callback,
void *user_data) void *user_data)
{ {
if (pre_callback) if (pre_callback)
_cogl_callback_list_add (&atlas->pre_reorganize_callbacks, {
pre_callback, GHook *hook = g_hook_alloc (&atlas->post_reorganize_callbacks);
user_data); hook->func = pre_callback;
hook->data = user_data;
g_hook_prepend (&atlas->pre_reorganize_callbacks, hook);
}
if (post_callback) if (post_callback)
_cogl_callback_list_add (&atlas->post_reorganize_callbacks, {
post_callback, GHook *hook = g_hook_alloc (&atlas->pre_reorganize_callbacks);
user_data); hook->func = post_callback;
hook->data = user_data;
g_hook_prepend (&atlas->post_reorganize_callbacks, hook);
}
} }
void void
_cogl_atlas_remove_reorganize_callback (CoglAtlas *atlas, _cogl_atlas_remove_reorganize_callback (CoglAtlas *atlas,
CoglCallbackListFunc pre_callback, GHookFunc pre_callback,
CoglCallbackListFunc post_callback, GHookFunc post_callback,
void *user_data) void *user_data)
{ {
if (pre_callback) if (pre_callback)
_cogl_callback_list_remove (&atlas->pre_reorganize_callbacks, {
pre_callback, user_data); GHook *hook = g_hook_find_func_data (&atlas->pre_reorganize_callbacks,
FALSE,
pre_callback,
user_data);
if (hook)
g_hook_destroy_link (&atlas->pre_reorganize_callbacks, hook);
}
if (post_callback) if (post_callback)
_cogl_callback_list_remove (&atlas->post_reorganize_callbacks, {
post_callback, user_data); GHook *hook = g_hook_find_func_data (&atlas->post_reorganize_callbacks,
FALSE,
post_callback,
user_data);
if (hook)
g_hook_destroy_link (&atlas->post_reorganize_callbacks, hook);
}
} }

View File

@ -25,7 +25,6 @@
#define __COGL_ATLAS_H #define __COGL_ATLAS_H
#include "cogl-rectangle-map.h" #include "cogl-rectangle-map.h"
#include "cogl-callback-list.h"
#include "cogl-object-private.h" #include "cogl-object-private.h"
typedef void typedef void
@ -55,8 +54,8 @@ struct _CoglAtlas
CoglAtlasUpdatePositionCallback update_position_cb; CoglAtlasUpdatePositionCallback update_position_cb;
CoglCallbackList pre_reorganize_callbacks; GHookList pre_reorganize_callbacks;
CoglCallbackList post_reorganize_callbacks; GHookList post_reorganize_callbacks;
}; };
CoglAtlas * CoglAtlas *
@ -85,14 +84,14 @@ _cogl_atlas_copy_rectangle (CoglAtlas *atlas,
void void
_cogl_atlas_add_reorganize_callback (CoglAtlas *atlas, _cogl_atlas_add_reorganize_callback (CoglAtlas *atlas,
CoglCallbackListFunc pre_callback, GHookFunc pre_callback,
CoglCallbackListFunc post_callback, GHookFunc post_callback,
void *user_data); void *user_data);
void void
_cogl_atlas_remove_reorganize_callback (CoglAtlas *atlas, _cogl_atlas_remove_reorganize_callback (CoglAtlas *atlas,
CoglCallbackListFunc pre_callback, GHookFunc pre_callback,
CoglCallbackListFunc post_callback, GHookFunc post_callback,
void *user_data); void *user_data);
#endif /* __COGL_ATLAS_H */ #endif /* __COGL_ATLAS_H */

View File

@ -1,107 +0,0 @@
/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the
* Free Software Foundation, Inc., 59 Temple Place - Suite 330,
* Boston, MA 02111-1307, USA.
*
* Authors:
* Neil Roberts <neil@linux.intel.com>
*/
#ifdef HAVE_CONFIG_H
#include "config.h"
#endif
#include "cogl.h"
#include "cogl-callback-list.h"
typedef struct _CoglCallbackListClosure
{
CoglCallbackListFunc func;
void *user_data;
} CoglCallbackListClosure;
void
_cogl_callback_list_init (CoglCallbackList *list)
{
list->funcs = NULL;
}
void
_cogl_callback_list_destroy (CoglCallbackList *list)
{
while (list->funcs)
{
CoglCallbackListClosure *closure = list->funcs->data;
_cogl_callback_list_remove (list, closure->func, closure->user_data);
}
}
void
_cogl_callback_list_add (CoglCallbackList *list,
CoglCallbackListFunc func,
void *user_data)
{
CoglCallbackListClosure *closure = g_slice_new (CoglCallbackListClosure);
closure->func = func;
closure->user_data = user_data;
list->funcs = g_slist_prepend (list->funcs, closure);
}
void
_cogl_callback_list_remove (CoglCallbackList *list,
CoglCallbackListFunc func,
void *user_data)
{
GSList *prev = NULL, *l;
for (l = list->funcs; l; l = l->next)
{
CoglCallbackListClosure *closure = l->data;
if (closure->func == func && closure->user_data == user_data)
{
g_slice_free (CoglCallbackListClosure, closure);
if (prev)
prev->next = g_slist_delete_link (prev->next, l);
else
list->funcs = g_slist_delete_link (list->funcs, l);
break;
}
prev = l;
}
}
void
_cogl_callback_list_invoke (CoglCallbackList *list)
{
GSList *l;
for (l = list->funcs; l; l = l->next)
{
CoglCallbackListClosure *closure = l->data;
closure->func (closure->user_data);
}
}

View File

@ -1,58 +0,0 @@
/*
* Cogl
*
* An object oriented GL/GLES Abstraction/Utility Layer
*
* Copyright (C) 2010 Intel Corporation.
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this library. If not, see <http://www.gnu.org/licenses/>.
*
*/
#ifndef __COGL_CALLBACK_LIST_H__
#define __COGL_CALLBACK_LIST_H__
#include <glib.h>
G_BEGIN_DECLS
typedef void (* CoglCallbackListFunc) (void *user_data);
typedef struct _CoglCallbackList
{
GSList *funcs;
} CoglCallbackList;
void
_cogl_callback_list_init (CoglCallbackList *list);
void
_cogl_callback_list_add (CoglCallbackList *list,
CoglCallbackListFunc func,
void *user_data);
void
_cogl_callback_list_remove (CoglCallbackList *list,
CoglCallbackListFunc func,
void *user_data);
void
_cogl_callback_list_invoke (CoglCallbackList *list);
void
_cogl_callback_list_destroy (CoglCallbackList *list);
G_END_DECLS
#endif /* __COGL_CALLBACK_LIST_H__ */

View File

@ -30,7 +30,6 @@
#include "cogl-pango-glyph-cache.h" #include "cogl-pango-glyph-cache.h"
#include "cogl-pango-private.h" #include "cogl-pango-private.h"
#include "cogl/cogl-atlas.h" #include "cogl/cogl-atlas.h"
#include "cogl/cogl-callback-list.h"
typedef struct _CoglPangoGlyphCacheKey CoglPangoGlyphCacheKey; typedef struct _CoglPangoGlyphCacheKey CoglPangoGlyphCacheKey;
@ -44,7 +43,7 @@ struct _CoglPangoGlyphCache
GSList *atlases; GSList *atlases;
/* List of callbacks to invoke when an atlas is reorganized */ /* List of callbacks to invoke when an atlas is reorganized */
CoglCallbackList reorganize_callbacks; GHookList reorganize_callbacks;
/* True if some of the glyphs are dirty. This is used as an /* True if some of the glyphs are dirty. This is used as an
optimization in _cogl_pango_glyph_cache_set_dirty_glyphs to avoid optimization in _cogl_pango_glyph_cache_set_dirty_glyphs to avoid
@ -115,7 +114,7 @@ cogl_pango_glyph_cache_new (void)
(GDestroyNotify) cogl_pango_glyph_cache_value_free); (GDestroyNotify) cogl_pango_glyph_cache_value_free);
cache->atlases = NULL; cache->atlases = NULL;
_cogl_callback_list_init (&cache->reorganize_callbacks); g_hook_list_init (&cache->reorganize_callbacks, sizeof (GHook));
cache->has_dirty_glyphs = FALSE; cache->has_dirty_glyphs = FALSE;
@ -140,7 +139,7 @@ cogl_pango_glyph_cache_free (CoglPangoGlyphCache *cache)
g_hash_table_unref (cache->hash_table); g_hash_table_unref (cache->hash_table);
_cogl_callback_list_destroy (&cache->reorganize_callbacks); g_hook_list_clear (&cache->reorganize_callbacks);
g_free (cache); g_free (cache);
} }
@ -177,7 +176,7 @@ cogl_pango_glyph_cache_reorganize_cb (void *user_data)
{ {
CoglPangoGlyphCache *cache = user_data; CoglPangoGlyphCache *cache = user_data;
_cogl_callback_list_invoke (&cache->reorganize_callbacks); g_hook_list_invoke (&cache->reorganize_callbacks, FALSE);
} }
CoglPangoGlyphCacheValue * CoglPangoGlyphCacheValue *
@ -293,16 +292,25 @@ _cogl_pango_glyph_cache_set_dirty_glyphs (CoglPangoGlyphCache *cache,
void void
_cogl_pango_glyph_cache_add_reorganize_callback (CoglPangoGlyphCache *cache, _cogl_pango_glyph_cache_add_reorganize_callback (CoglPangoGlyphCache *cache,
CoglCallbackListFunc func, GHookFunc func,
void *user_data) void *user_data)
{ {
_cogl_callback_list_add (&cache->reorganize_callbacks, func, user_data); GHook *hook = g_hook_alloc (&cache->reorganize_callbacks);
hook->func = func;
hook->data = user_data;
g_hook_prepend (&cache->reorganize_callbacks, hook);
} }
void void
_cogl_pango_glyph_cache_remove_reorganize_callback (CoglPangoGlyphCache *cache, _cogl_pango_glyph_cache_remove_reorganize_callback (CoglPangoGlyphCache *cache,
CoglCallbackListFunc func, GHookFunc func,
void *user_data) void *user_data)
{ {
_cogl_callback_list_remove (&cache->reorganize_callbacks, func, user_data); GHook *hook = g_hook_find_func_data (&cache->reorganize_callbacks,
FALSE,
func,
user_data);
if (hook)
g_hook_destroy_link (&cache->reorganize_callbacks, hook);
} }

View File

@ -26,7 +26,6 @@
#include <glib.h> #include <glib.h>
#include <cogl/cogl.h> #include <cogl/cogl.h>
#include <cogl/cogl-callback-list.h>
#include <pango/pango-font.h> #include <pango/pango-font.h>
G_BEGIN_DECLS G_BEGIN_DECLS
@ -77,12 +76,12 @@ cogl_pango_glyph_cache_clear (CoglPangoGlyphCache *cache);
void void
_cogl_pango_glyph_cache_add_reorganize_callback (CoglPangoGlyphCache *cache, _cogl_pango_glyph_cache_add_reorganize_callback (CoglPangoGlyphCache *cache,
CoglCallbackListFunc func, GHookFunc func,
void *user_data); void *user_data);
void void
_cogl_pango_glyph_cache_remove_reorganize_callback (CoglPangoGlyphCache *cache, _cogl_pango_glyph_cache_remove_reorganize_callback (CoglPangoGlyphCache *cache,
CoglCallbackListFunc func, GHookFunc func,
void *user_data); void *user_data);
void void

View File

@ -212,7 +212,7 @@ cogl_pango_render_qdata_forget_display_list (CoglPangoRendererQdata *qdata)
{ {
_cogl_pango_glyph_cache_remove_reorganize_callback _cogl_pango_glyph_cache_remove_reorganize_callback
(qdata->renderer->glyph_cache, (qdata->renderer->glyph_cache,
(CoglCallbackListFunc) cogl_pango_render_qdata_forget_display_list, (GHookFunc) cogl_pango_render_qdata_forget_display_list,
qdata); qdata);
_cogl_pango_display_list_free (qdata->display_list); _cogl_pango_display_list_free (qdata->display_list);
@ -289,7 +289,7 @@ cogl_pango_render_layout_subpixel (PangoLayout *layout,
we can rebuild the display list */ we can rebuild the display list */
_cogl_pango_glyph_cache_add_reorganize_callback _cogl_pango_glyph_cache_add_reorganize_callback
(priv->glyph_cache, (priv->glyph_cache,
(CoglCallbackListFunc) cogl_pango_render_qdata_forget_display_list, (GHookFunc) cogl_pango_render_qdata_forget_display_list,
qdata); qdata);
priv->display_list = qdata->display_list; priv->display_list = qdata->display_list;