forked from AuroraMiddleware/gtk
Two optimizations for icon cache lookups.
2007-12-03 Matthias Clasen <mclasen@redhat.com> Two optimizations for icon cache lookups. * gtk/gtkiconcache.[hc]: * gtk/gtkicontheme.c: Remember the directory index for subdirectories, instead of running over the directory list again and again. * gtk/gtkiconcache.c (find_image_offset): Remember the last chain and try it first; this helps with the the usage patterns in gtkicontheme.c, where the same icon is queried for a lot of subdirectories. svn path=/trunk/; revision=19099
This commit is contained in:
parent
f83588f87e
commit
f9e4618bda
14
ChangeLog
14
ChangeLog
@ -1,3 +1,17 @@
|
||||
2007-12-03 Matthias Clasen <mclasen@redhat.com>
|
||||
|
||||
Two optimizations for icon cache lookups.
|
||||
|
||||
* gtk/gtkiconcache.[hc]:
|
||||
* gtk/gtkicontheme.c: Remember the directory index for
|
||||
subdirectories, instead of running over the directory list
|
||||
again and again.
|
||||
|
||||
* gtk/gtkiconcache.c (find_image_offset): Remember the last
|
||||
chain and try it first; this helps with the the usage patterns
|
||||
in gtkicontheme.c, where the same icon is queried for a lot
|
||||
of subdirectories.
|
||||
|
||||
2007-12-03 15:18:17 Tim Janik <timj@imendio.com>
|
||||
|
||||
* gtk/Makefile.am (gtktypefuncs.c): use 'grep -o' to extract _get_type
|
||||
|
@ -49,11 +49,14 @@
|
||||
#define GET_UINT16(cache, offset) (GUINT16_FROM_BE (*(guint16 *)((cache) + (offset))))
|
||||
#define GET_UINT32(cache, offset) (GUINT32_FROM_BE (*(guint32 *)((cache) + (offset))))
|
||||
|
||||
|
||||
struct _GtkIconCache {
|
||||
gint ref_count;
|
||||
|
||||
GMappedFile *map;
|
||||
gchar *buffer;
|
||||
|
||||
guint32 last_chain_offset;
|
||||
};
|
||||
|
||||
GtkIconCache *
|
||||
@ -191,11 +194,11 @@ get_directory_index (GtkIconCache *cache,
|
||||
return -1;
|
||||
}
|
||||
|
||||
gboolean
|
||||
_gtk_icon_cache_has_directory (GtkIconCache *cache,
|
||||
const gchar *directory)
|
||||
gint
|
||||
_gtk_icon_cache_get_directory_index (GtkIconCache *cache,
|
||||
const gchar *directory)
|
||||
{
|
||||
return get_directory_index (cache, directory) != -1;
|
||||
return get_directory_index (cache, directory);
|
||||
}
|
||||
|
||||
static guint
|
||||
@ -214,19 +217,28 @@ icon_name_hash (gconstpointer key)
|
||||
static gint
|
||||
find_image_offset (GtkIconCache *cache,
|
||||
const gchar *icon_name,
|
||||
const gchar *directory)
|
||||
gint directory_index)
|
||||
{
|
||||
guint32 hash_offset;
|
||||
guint32 n_buckets;
|
||||
guint32 chain_offset;
|
||||
int hash, directory_index;
|
||||
int hash;
|
||||
guint32 image_list_offset, n_images;
|
||||
gboolean found = FALSE;
|
||||
int i;
|
||||
|
||||
|
||||
chain_offset = cache->last_chain_offset;
|
||||
if (chain_offset)
|
||||
{
|
||||
guint32 name_offset = GET_UINT32 (cache->buffer, chain_offset + 4);
|
||||
gchar *name = cache->buffer + name_offset;
|
||||
|
||||
if (strcmp (name, icon_name) == 0)
|
||||
goto find_dir;
|
||||
}
|
||||
|
||||
hash_offset = GET_UINT32 (cache->buffer, 4);
|
||||
n_buckets = GET_UINT32 (cache->buffer, hash_offset);
|
||||
|
||||
hash = icon_name_hash (icon_name) % n_buckets;
|
||||
|
||||
chain_offset = GET_UINT32 (cache->buffer, hash_offset + 4 + 4 * hash);
|
||||
@ -236,20 +248,19 @@ find_image_offset (GtkIconCache *cache,
|
||||
gchar *name = cache->buffer + name_offset;
|
||||
|
||||
if (strcmp (name, icon_name) == 0)
|
||||
{
|
||||
found = TRUE;
|
||||
break;
|
||||
{
|
||||
cache->last_chain_offset = chain_offset;
|
||||
goto find_dir;
|
||||
}
|
||||
|
||||
|
||||
chain_offset = GET_UINT32 (cache->buffer, chain_offset);
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
return 0;
|
||||
}
|
||||
cache->last_chain_offset = 0;
|
||||
return 0;
|
||||
|
||||
find_dir:
|
||||
/* We've found an icon list, now check if we have the right icon in it */
|
||||
directory_index = get_directory_index (cache, directory);
|
||||
image_list_offset = GET_UINT32 (cache->buffer, chain_offset + 8);
|
||||
n_images = GET_UINT32 (cache->buffer, image_list_offset);
|
||||
|
||||
@ -266,11 +277,11 @@ find_image_offset (GtkIconCache *cache,
|
||||
gint
|
||||
_gtk_icon_cache_get_icon_flags (GtkIconCache *cache,
|
||||
const gchar *icon_name,
|
||||
const gchar *directory)
|
||||
gint directory_index)
|
||||
{
|
||||
guint32 image_offset;
|
||||
|
||||
image_offset = find_image_offset (cache, icon_name, directory);
|
||||
image_offset = find_image_offset (cache, icon_name, directory_index);
|
||||
|
||||
if (!image_offset)
|
||||
return 0;
|
||||
@ -417,7 +428,7 @@ pixbuf_destroy_cb (guchar *pixels,
|
||||
GdkPixbuf *
|
||||
_gtk_icon_cache_get_icon (GtkIconCache *cache,
|
||||
const gchar *icon_name,
|
||||
const gchar *directory)
|
||||
gint directory_index)
|
||||
{
|
||||
guint32 offset, image_data_offset, pixel_data_offset;
|
||||
guint32 length, type;
|
||||
@ -425,7 +436,7 @@ _gtk_icon_cache_get_icon (GtkIconCache *cache,
|
||||
GdkPixdata pixdata;
|
||||
GError *error = NULL;
|
||||
|
||||
offset = find_image_offset (cache, icon_name, directory);
|
||||
offset = find_image_offset (cache, icon_name, directory_index);
|
||||
|
||||
image_data_offset = GET_UINT32 (cache->buffer, offset + 4);
|
||||
|
||||
@ -478,13 +489,13 @@ _gtk_icon_cache_get_icon (GtkIconCache *cache,
|
||||
GtkIconData *
|
||||
_gtk_icon_cache_get_icon_data (GtkIconCache *cache,
|
||||
const gchar *icon_name,
|
||||
const gchar *directory)
|
||||
gint directory_index)
|
||||
{
|
||||
guint32 offset, image_data_offset, meta_data_offset;
|
||||
GtkIconData *data;
|
||||
int i;
|
||||
|
||||
offset = find_image_offset (cache, icon_name, directory);
|
||||
offset = find_image_offset (cache, icon_name, directory_index);
|
||||
if (!offset)
|
||||
return NULL;
|
||||
|
||||
|
@ -38,8 +38,8 @@ struct _GtkIconData
|
||||
|
||||
GtkIconCache *_gtk_icon_cache_new (const gchar *data);
|
||||
GtkIconCache *_gtk_icon_cache_new_for_path (const gchar *path);
|
||||
gboolean _gtk_icon_cache_has_directory (GtkIconCache *cache,
|
||||
const gchar *directory);
|
||||
gint _gtk_icon_cache_get_directory_index (GtkIconCache *cache,
|
||||
const gchar *directory);
|
||||
gboolean _gtk_icon_cache_has_icon (GtkIconCache *cache,
|
||||
const gchar *icon_name);
|
||||
gboolean _gtk_icon_cache_has_icon_in_directory (GtkIconCache *cache,
|
||||
@ -51,13 +51,13 @@ void _gtk_icon_cache_add_icons (GtkIconCache *cache,
|
||||
|
||||
gint _gtk_icon_cache_get_icon_flags (GtkIconCache *cache,
|
||||
const gchar *icon_name,
|
||||
const gchar *directory);
|
||||
gint directory_index);
|
||||
GdkPixbuf *_gtk_icon_cache_get_icon (GtkIconCache *cache,
|
||||
const gchar *icon_name,
|
||||
const gchar *directory);
|
||||
gint directory_index);
|
||||
GtkIconData *_gtk_icon_cache_get_icon_data (GtkIconCache *cache,
|
||||
const gchar *icon_name,
|
||||
const gchar *directory);
|
||||
gint directory_index);
|
||||
|
||||
GtkIconCache *_gtk_icon_cache_ref (GtkIconCache *cache);
|
||||
void _gtk_icon_cache_unref (GtkIconCache *cache);
|
||||
|
@ -161,6 +161,7 @@ typedef struct
|
||||
|
||||
char *dir;
|
||||
char *subdir;
|
||||
int subdir_index;
|
||||
|
||||
GtkIconCache *cache;
|
||||
|
||||
@ -1149,11 +1150,11 @@ _gtk_icon_theme_ensure_builtin_cache (void)
|
||||
IconThemeDir *dir;
|
||||
static IconThemeDir dirs[5] =
|
||||
{
|
||||
{ ICON_THEME_DIR_THRESHOLD, 0, 16, 16, 16, 2, NULL, "16", NULL, NULL, NULL },
|
||||
{ ICON_THEME_DIR_THRESHOLD, 0, 20, 20, 20, 2, NULL, "20", NULL, NULL, NULL },
|
||||
{ ICON_THEME_DIR_THRESHOLD, 0, 24, 24, 24, 2, NULL, "24", NULL, NULL, NULL },
|
||||
{ ICON_THEME_DIR_THRESHOLD, 0, 32, 32, 32, 2, NULL, "32", NULL, NULL, NULL },
|
||||
{ ICON_THEME_DIR_THRESHOLD, 0, 48, 48, 48, 2, NULL, "48", NULL, NULL, NULL }
|
||||
{ ICON_THEME_DIR_THRESHOLD, 0, 16, 16, 16, 2, NULL, "16", -1, NULL, NULL, NULL },
|
||||
{ ICON_THEME_DIR_THRESHOLD, 0, 20, 20, 20, 2, NULL, "20", -1, NULL, NULL, NULL },
|
||||
{ ICON_THEME_DIR_THRESHOLD, 0, 24, 24, 24, 2, NULL, "24", -1, NULL, NULL, NULL },
|
||||
{ ICON_THEME_DIR_THRESHOLD, 0, 32, 32, 32, 2, NULL, "32", -1, NULL, NULL, NULL },
|
||||
{ ICON_THEME_DIR_THRESHOLD, 0, 48, 48, 48, 2, NULL, "48", -1, NULL, NULL, NULL }
|
||||
};
|
||||
gint i;
|
||||
|
||||
@ -1167,6 +1168,7 @@ _gtk_icon_theme_ensure_builtin_cache (void)
|
||||
{
|
||||
dir = &(dirs[i]);
|
||||
dir->cache = _gtk_icon_cache_ref (_builtin_cache);
|
||||
dir->subdir_index = _gtk_icon_cache_get_directory_index (dir->cache, dir->subdir);
|
||||
|
||||
builtin_dirs = g_list_append (builtin_dirs, dir);
|
||||
}
|
||||
@ -1612,6 +1614,9 @@ gtk_icon_theme_get_icon_sizes (GtkIconTheme *icon_theme,
|
||||
{
|
||||
IconThemeDir *dir = d->data;
|
||||
|
||||
if (dir->type != ICON_THEME_DIR_SCALABLE && g_hash_table_lookup_extended (sizes, GINT_TO_POINTER (dir->size), NULL, NULL))
|
||||
continue;
|
||||
|
||||
suffix = theme_dir_get_icon_suffix (dir, icon_name, NULL);
|
||||
if (suffix != ICON_SUFFIX_NONE)
|
||||
{
|
||||
@ -1627,6 +1632,9 @@ gtk_icon_theme_get_icon_sizes (GtkIconTheme *icon_theme,
|
||||
{
|
||||
IconThemeDir *dir = d->data;
|
||||
|
||||
if (dir->type != ICON_THEME_DIR_SCALABLE && g_hash_table_lookup_extended (sizes, GINT_TO_POINTER (dir->size), NULL, NULL))
|
||||
continue;
|
||||
|
||||
suffix = theme_dir_get_icon_suffix (dir, icon_name, NULL);
|
||||
if (suffix != ICON_SUFFIX_NONE)
|
||||
{
|
||||
@ -2019,7 +2027,7 @@ theme_dir_get_icon_suffix (IconThemeDir *dir,
|
||||
{
|
||||
suffix = (IconSuffix)_gtk_icon_cache_get_icon_flags (dir->cache,
|
||||
icon_name,
|
||||
dir->subdir);
|
||||
dir->subdir_index);
|
||||
|
||||
if (has_icon_file)
|
||||
*has_icon_file = suffix & HAS_ICON_FILE;
|
||||
@ -2058,7 +2066,7 @@ theme_lookup_icon (IconTheme *theme,
|
||||
/* Builtin icons are logically part of the default theme and
|
||||
* are searched before other subdirectories of the default theme.
|
||||
*/
|
||||
if (strcmp (theme->name, DEFAULT_THEME_NAME) == 0 && use_builtin)
|
||||
if (use_builtin && strcmp (theme->name, DEFAULT_THEME_NAME) == 0)
|
||||
{
|
||||
closest_builtin = find_builtin_icon (icon_name,
|
||||
size,
|
||||
@ -2078,7 +2086,7 @@ theme_lookup_icon (IconTheme *theme,
|
||||
{
|
||||
dir = l->data;
|
||||
|
||||
GTK_NOTE (ICONTHEME,
|
||||
GTK_NOTE (ICONTHEME,
|
||||
g_print ("theme_lookup_icon dir %s\n", dir->dir));
|
||||
suffix = theme_dir_get_icon_suffix (dir, icon_name, NULL);
|
||||
if (best_suffix (suffix, allow_svg) != ICON_SUFFIX_NONE)
|
||||
@ -2178,7 +2186,7 @@ theme_lookup_icon (IconTheme *theme,
|
||||
|
||||
if (icon_info->data == NULL && min_dir->cache != NULL)
|
||||
{
|
||||
icon_info->data = _gtk_icon_cache_get_icon_data (min_dir->cache, icon_name, min_dir->subdir);
|
||||
icon_info->data = _gtk_icon_cache_get_icon_data (min_dir->cache, icon_name, min_dir->subdir_index);
|
||||
if (icon_info->data)
|
||||
{
|
||||
if (min_dir->icon_data == NULL)
|
||||
@ -2212,7 +2220,7 @@ theme_lookup_icon (IconTheme *theme,
|
||||
if (min_dir->cache)
|
||||
{
|
||||
icon_info->cache_pixbuf = _gtk_icon_cache_get_icon (min_dir->cache, icon_name,
|
||||
min_dir->subdir);
|
||||
min_dir->subdir_index);
|
||||
}
|
||||
|
||||
icon_info->dir_type = min_dir->type;
|
||||
@ -2520,10 +2528,14 @@ theme_subdir_load (GtkIconTheme *icon_theme,
|
||||
dir->icon_data = NULL;
|
||||
dir->subdir = g_strdup (subdir);
|
||||
if (dir_mtime->cache != NULL)
|
||||
dir->cache = _gtk_icon_cache_ref (dir_mtime->cache);
|
||||
{
|
||||
dir->cache = _gtk_icon_cache_ref (dir_mtime->cache);
|
||||
dir->subdir_index = _gtk_icon_cache_get_directory_index (dir->cache, dir->subdir);
|
||||
}
|
||||
else
|
||||
{
|
||||
dir->cache = NULL;
|
||||
dir->subdir_index = -1;
|
||||
scan_directory (icon_theme->priv, dir, full_dir);
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user