Rework internals to be string based
Rather than having ShellTextureCache know about the type of each item it's caching, this lays the foundation for simply caching arbitrary string -> CoglHandle. https://bugzilla.gnome.org/show_bug.cgi?id=607500
This commit is contained in:
parent
5f8391314a
commit
394e01850b
@ -9,29 +9,21 @@
|
|||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <glib.h>
|
#include <glib.h>
|
||||||
|
|
||||||
typedef struct
|
#define CACHE_PREFIX_GICON "gicon:"
|
||||||
{
|
#define CACHE_PREFIX_URI "uri:"
|
||||||
StTextureCachePolicy policy;
|
#define CACHE_PREFIX_THUMBNAIL_URI "thumbnail-uri:"
|
||||||
|
#define CACHE_PREFIX_RAW_CHECKSUM "raw-checksum:"
|
||||||
/* These are exclusive */
|
#define CACHE_PREFIX_COMPRESSED_CHECKSUM "compressed-checksum:"
|
||||||
GIcon *icon;
|
|
||||||
gchar *uri;
|
|
||||||
gchar *thumbnail_uri;
|
|
||||||
gchar *checksum;
|
|
||||||
|
|
||||||
/* This one is common to all */
|
|
||||||
guint size;
|
|
||||||
} CacheKey;
|
|
||||||
|
|
||||||
struct _StTextureCachePrivate
|
struct _StTextureCachePrivate
|
||||||
{
|
{
|
||||||
/* Things that were loaded with a cache policy != NONE */
|
/* Things that were loaded with a cache policy != NONE */
|
||||||
GHashTable *keyed_cache; /* CacheKey -> CoglTexture* */
|
GHashTable *keyed_cache; /* char * -> CoglTexture* */
|
||||||
/* Presently this is used to de-duplicate requests for GIcons,
|
/* Presently this is used to de-duplicate requests for GIcons,
|
||||||
* it could in theory be extended to async URL loading and other
|
* it could in theory be extended to async URL loading and other
|
||||||
* cases too.
|
* cases too.
|
||||||
*/
|
*/
|
||||||
GHashTable *outstanding_requests; /* CacheKey -> AsyncTextureLoadData * */
|
GHashTable *outstanding_requests; /* char * -> AsyncTextureLoadData * */
|
||||||
GnomeDesktopThumbnailFactory *thumbnails;
|
GnomeDesktopThumbnailFactory *thumbnails;
|
||||||
};
|
};
|
||||||
|
|
||||||
@ -40,78 +32,6 @@ static void st_texture_cache_finalize (GObject *object);
|
|||||||
|
|
||||||
G_DEFINE_TYPE(StTextureCache, st_texture_cache, G_TYPE_OBJECT);
|
G_DEFINE_TYPE(StTextureCache, st_texture_cache, G_TYPE_OBJECT);
|
||||||
|
|
||||||
static guint
|
|
||||||
cache_key_hash (gconstpointer a)
|
|
||||||
{
|
|
||||||
CacheKey *akey = (CacheKey *)a;
|
|
||||||
guint base_hash;
|
|
||||||
|
|
||||||
if (akey->icon)
|
|
||||||
base_hash = g_icon_hash (akey->icon);
|
|
||||||
else if (akey->uri)
|
|
||||||
base_hash = g_str_hash (akey->uri);
|
|
||||||
else if (akey->thumbnail_uri)
|
|
||||||
base_hash = g_str_hash (akey->thumbnail_uri);
|
|
||||||
else if (akey->checksum)
|
|
||||||
base_hash = g_str_hash (akey->checksum);
|
|
||||||
else
|
|
||||||
g_assert_not_reached ();
|
|
||||||
return base_hash + 31*akey->size;
|
|
||||||
}
|
|
||||||
|
|
||||||
static gboolean
|
|
||||||
cache_key_equal (gconstpointer a,
|
|
||||||
gconstpointer b)
|
|
||||||
{
|
|
||||||
CacheKey *akey = (CacheKey*)a;
|
|
||||||
CacheKey *bkey = (CacheKey*)b;
|
|
||||||
|
|
||||||
/* We don't compare policy here, since we need
|
|
||||||
* a way to look up a cache key without respect to
|
|
||||||
* the policy. */
|
|
||||||
|
|
||||||
if (akey->size != bkey->size)
|
|
||||||
return FALSE;
|
|
||||||
|
|
||||||
if (akey->icon && bkey->icon)
|
|
||||||
return g_icon_equal (akey->icon, bkey->icon);
|
|
||||||
else if (akey->uri && bkey->uri)
|
|
||||||
return strcmp (akey->uri, bkey->uri) == 0;
|
|
||||||
else if (akey->thumbnail_uri && bkey->thumbnail_uri)
|
|
||||||
return strcmp (akey->thumbnail_uri, bkey->thumbnail_uri) == 0;
|
|
||||||
else if (akey->checksum && bkey->checksum)
|
|
||||||
return strcmp (akey->checksum, bkey->checksum) == 0;
|
|
||||||
|
|
||||||
return FALSE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static CacheKey *
|
|
||||||
cache_key_dup (CacheKey *key)
|
|
||||||
{
|
|
||||||
CacheKey *ret = g_new0 (CacheKey, 1);
|
|
||||||
ret->policy = key->policy;
|
|
||||||
if (key->icon)
|
|
||||||
ret->icon = g_object_ref (key->icon);
|
|
||||||
ret->uri = g_strdup (key->uri);
|
|
||||||
ret->thumbnail_uri = g_strdup (key->thumbnail_uri);
|
|
||||||
ret->checksum = g_strdup (key->checksum);
|
|
||||||
ret->size = key->size;
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void
|
|
||||||
cache_key_destroy (gpointer a)
|
|
||||||
{
|
|
||||||
CacheKey *akey = (CacheKey*)a;
|
|
||||||
if (akey->icon)
|
|
||||||
g_object_unref (akey->icon);
|
|
||||||
g_free (akey->uri);
|
|
||||||
g_free (akey->thumbnail_uri);
|
|
||||||
g_free (akey->checksum);
|
|
||||||
g_free (akey);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/* We want to preserve the aspect ratio by default, also the default
|
/* We want to preserve the aspect ratio by default, also the default
|
||||||
* material for an empty texture is full opacity white, which we
|
* material for an empty texture is full opacity white, which we
|
||||||
* definitely don't want. Skip that by setting 0 opacity.
|
* definitely don't want. Skip that by setting 0 opacity.
|
||||||
@ -145,10 +65,10 @@ static void
|
|||||||
st_texture_cache_init (StTextureCache *self)
|
st_texture_cache_init (StTextureCache *self)
|
||||||
{
|
{
|
||||||
self->priv = g_new0 (StTextureCachePrivate, 1);
|
self->priv = g_new0 (StTextureCachePrivate, 1);
|
||||||
self->priv->keyed_cache = g_hash_table_new_full (cache_key_hash, cache_key_equal,
|
self->priv->keyed_cache = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
cache_key_destroy, cogl_handle_unref);
|
g_free, cogl_handle_unref);
|
||||||
self->priv->outstanding_requests = g_hash_table_new_full (cache_key_hash, cache_key_equal,
|
self->priv->outstanding_requests = g_hash_table_new_full (g_str_hash, g_str_equal,
|
||||||
cache_key_destroy, NULL);
|
g_free, NULL);
|
||||||
self->priv->thumbnails = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL);
|
self->priv->thumbnails = gnome_desktop_thumbnail_factory_new (GNOME_DESKTOP_THUMBNAIL_SIZE_NORMAL);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,6 +81,10 @@ st_texture_cache_dispose (GObject *object)
|
|||||||
g_hash_table_destroy (self->priv->keyed_cache);
|
g_hash_table_destroy (self->priv->keyed_cache);
|
||||||
self->priv->keyed_cache = NULL;
|
self->priv->keyed_cache = NULL;
|
||||||
|
|
||||||
|
if (self->priv->outstanding_requests)
|
||||||
|
g_hash_table_destroy (self->priv->outstanding_requests);
|
||||||
|
self->priv->outstanding_requests = NULL;
|
||||||
|
|
||||||
if (self->priv->thumbnails)
|
if (self->priv->thumbnails)
|
||||||
g_object_unref (self->priv->thumbnails);
|
g_object_unref (self->priv->thumbnails);
|
||||||
self->priv->thumbnails = NULL;
|
self->priv->thumbnails = NULL;
|
||||||
@ -663,6 +587,7 @@ load_pixbuf_async_finish (StTextureCache *cache, GAsyncResult *result, GError **
|
|||||||
|
|
||||||
typedef struct {
|
typedef struct {
|
||||||
StTextureCachePolicy policy;
|
StTextureCachePolicy policy;
|
||||||
|
char *key;
|
||||||
char *uri;
|
char *uri;
|
||||||
gboolean thumbnail;
|
gboolean thumbnail;
|
||||||
char *mimetype;
|
char *mimetype;
|
||||||
@ -737,28 +662,15 @@ on_pixbuf_loaded (GObject *source,
|
|||||||
GdkPixbuf *pixbuf;
|
GdkPixbuf *pixbuf;
|
||||||
GError *error = NULL;
|
GError *error = NULL;
|
||||||
CoglHandle texdata = NULL;
|
CoglHandle texdata = NULL;
|
||||||
CacheKey key;
|
|
||||||
|
|
||||||
data = user_data;
|
data = user_data;
|
||||||
cache = ST_TEXTURE_CACHE (source);
|
cache = ST_TEXTURE_CACHE (source);
|
||||||
|
|
||||||
memset (&key, 0, sizeof(key));
|
g_hash_table_remove (cache->priv->outstanding_requests, data->key);
|
||||||
key.policy = data->policy;
|
|
||||||
if (data->icon)
|
|
||||||
key.icon = data->icon;
|
|
||||||
else if (data->recent_info && data->thumbnail)
|
|
||||||
key.thumbnail_uri = (char*)gtk_recent_info_get_uri (data->recent_info);
|
|
||||||
else if (data->thumbnail)
|
|
||||||
key.thumbnail_uri = (char*)data->uri;
|
|
||||||
else if (data->uri)
|
|
||||||
key.uri = data->uri;
|
|
||||||
key.size = data->width;
|
|
||||||
|
|
||||||
g_hash_table_remove (cache->priv->outstanding_requests, &key);
|
|
||||||
|
|
||||||
pixbuf = load_pixbuf_async_finish (cache, result, &error);
|
pixbuf = load_pixbuf_async_finish (cache, result, &error);
|
||||||
if (pixbuf == NULL)
|
if (pixbuf == NULL)
|
||||||
pixbuf = load_pixbuf_fallback(data);
|
pixbuf = load_pixbuf_fallback (data);
|
||||||
if (pixbuf == NULL)
|
if (pixbuf == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
@ -770,11 +682,11 @@ on_pixbuf_loaded (GObject *source,
|
|||||||
{
|
{
|
||||||
gpointer orig_key, value;
|
gpointer orig_key, value;
|
||||||
|
|
||||||
if (!g_hash_table_lookup_extended (cache->priv->keyed_cache, &key,
|
if (!g_hash_table_lookup_extended (cache->priv->keyed_cache, data->key,
|
||||||
&orig_key, &value))
|
&orig_key, &value))
|
||||||
{
|
{
|
||||||
cogl_handle_ref (texdata);
|
cogl_handle_ref (texdata);
|
||||||
g_hash_table_insert (cache->priv->keyed_cache, cache_key_dup (&key),
|
g_hash_table_insert (cache->priv->keyed_cache, g_strdup (data->key),
|
||||||
texdata);
|
texdata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -788,6 +700,8 @@ on_pixbuf_loaded (GObject *source,
|
|||||||
out:
|
out:
|
||||||
if (texdata)
|
if (texdata)
|
||||||
cogl_handle_unref (texdata);
|
cogl_handle_unref (texdata);
|
||||||
|
g_free (data->key);
|
||||||
|
|
||||||
if (data->icon)
|
if (data->icon)
|
||||||
{
|
{
|
||||||
gtk_icon_info_free (data->icon_info);
|
gtk_icon_info_free (data->icon_info);
|
||||||
@ -919,7 +833,8 @@ st_texture_cache_bind_pixbuf_property (StTextureCache *cache,
|
|||||||
/**
|
/**
|
||||||
* create_texture_and_ensure_request:
|
* create_texture_and_ensure_request:
|
||||||
* @cache:
|
* @cache:
|
||||||
* @key: A filled in #CacheKey
|
* @key: A cache key
|
||||||
|
* @size: Size in pixels
|
||||||
* @request: (out): If no request is outstanding, one will be created and returned here
|
* @request: (out): If no request is outstanding, one will be created and returned here
|
||||||
* @texture: (out): A new texture, also added to the request
|
* @texture: (out): A new texture, also added to the request
|
||||||
*
|
*
|
||||||
@ -931,7 +846,8 @@ st_texture_cache_bind_pixbuf_property (StTextureCache *cache,
|
|||||||
*/
|
*/
|
||||||
static gboolean
|
static gboolean
|
||||||
create_texture_and_ensure_request (StTextureCache *cache,
|
create_texture_and_ensure_request (StTextureCache *cache,
|
||||||
CacheKey *key,
|
const char *key,
|
||||||
|
guint size,
|
||||||
AsyncTextureLoadData **request,
|
AsyncTextureLoadData **request,
|
||||||
ClutterActor **texture)
|
ClutterActor **texture)
|
||||||
{
|
{
|
||||||
@ -940,7 +856,7 @@ create_texture_and_ensure_request (StTextureCache *cache,
|
|||||||
gboolean had_pending;
|
gboolean had_pending;
|
||||||
|
|
||||||
*texture = (ClutterActor *) create_default_texture (cache);
|
*texture = (ClutterActor *) create_default_texture (cache);
|
||||||
clutter_actor_set_size (*texture, key->size, key->size);
|
clutter_actor_set_size (*texture, size, size);
|
||||||
|
|
||||||
texdata = g_hash_table_lookup (cache->priv->keyed_cache, key);
|
texdata = g_hash_table_lookup (cache->priv->keyed_cache, key);
|
||||||
|
|
||||||
@ -958,7 +874,8 @@ create_texture_and_ensure_request (StTextureCache *cache,
|
|||||||
{
|
{
|
||||||
/* Not cached and no pending request, create it */
|
/* Not cached and no pending request, create it */
|
||||||
*request = g_new0 (AsyncTextureLoadData, 1);
|
*request = g_new0 (AsyncTextureLoadData, 1);
|
||||||
g_hash_table_insert (cache->priv->outstanding_requests, cache_key_dup (key), *request);
|
(*request)->key = g_strdup (key);
|
||||||
|
g_hash_table_insert (cache->priv->outstanding_requests, g_strdup (key), *request);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
*request = pending;
|
*request = pending;
|
||||||
@ -984,16 +901,20 @@ st_texture_cache_load_gicon (StTextureCache *cache,
|
|||||||
{
|
{
|
||||||
AsyncTextureLoadData *request;
|
AsyncTextureLoadData *request;
|
||||||
ClutterActor *texture;
|
ClutterActor *texture;
|
||||||
CacheKey key;
|
char *gicon_string;
|
||||||
|
char *key;
|
||||||
GtkIconTheme *theme;
|
GtkIconTheme *theme;
|
||||||
GtkIconInfo *info;
|
GtkIconInfo *info;
|
||||||
|
|
||||||
memset (&key, 0, sizeof(key));
|
gicon_string = g_icon_to_string (icon);
|
||||||
key.icon = icon;
|
key = g_strconcat (CACHE_PREFIX_GICON, gicon_string, NULL);
|
||||||
key.size = size;
|
g_free (gicon_string);
|
||||||
|
|
||||||
if (create_texture_and_ensure_request (cache, &key, &request, &texture))
|
if (create_texture_and_ensure_request (cache, key, size, &request, &texture))
|
||||||
|
{
|
||||||
|
g_free (key);
|
||||||
return texture;
|
return texture;
|
||||||
|
}
|
||||||
|
|
||||||
/* Do theme lookups in the main thread to avoid thread-unsafety */
|
/* Do theme lookups in the main thread to avoid thread-unsafety */
|
||||||
theme = gtk_icon_theme_get_default ();
|
theme = gtk_icon_theme_get_default ();
|
||||||
@ -1003,6 +924,7 @@ st_texture_cache_load_gicon (StTextureCache *cache,
|
|||||||
{
|
{
|
||||||
/* hardcoded here for now; we should actually blow this away on
|
/* hardcoded here for now; we should actually blow this away on
|
||||||
* icon theme changes probably */
|
* icon theme changes probably */
|
||||||
|
request->key = g_strdup (key);
|
||||||
request->policy = ST_TEXTURE_CACHE_POLICY_FOREVER;
|
request->policy = ST_TEXTURE_CACHE_POLICY_FOREVER;
|
||||||
request->icon = g_object_ref (icon);
|
request->icon = g_object_ref (icon);
|
||||||
request->icon_info = info;
|
request->icon_info = info;
|
||||||
@ -1018,9 +940,10 @@ st_texture_cache_load_gicon (StTextureCache *cache,
|
|||||||
g_slist_foreach (request->textures, (GFunc) g_object_unref, NULL);
|
g_slist_foreach (request->textures, (GFunc) g_object_unref, NULL);
|
||||||
g_slist_free (request->textures);
|
g_slist_free (request->textures);
|
||||||
g_free (request);
|
g_free (request);
|
||||||
g_hash_table_remove (cache->priv->outstanding_requests, &key);
|
g_hash_table_remove (cache->priv->outstanding_requests, key);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_free (key);
|
||||||
return CLUTTER_ACTOR (texture);
|
return CLUTTER_ACTOR (texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1075,6 +998,7 @@ st_texture_cache_load_uri_async (StTextureCache *cache,
|
|||||||
texture = create_default_texture (cache);
|
texture = create_default_texture (cache);
|
||||||
|
|
||||||
data = g_new0 (AsyncTextureLoadData, 1);
|
data = g_new0 (AsyncTextureLoadData, 1);
|
||||||
|
data->key = g_strconcat (CACHE_PREFIX_URI, uri, NULL);
|
||||||
data->policy = ST_TEXTURE_CACHE_POLICY_NONE;
|
data->policy = ST_TEXTURE_CACHE_POLICY_NONE;
|
||||||
data->uri = g_strdup (uri);
|
data->uri = g_strdup (uri);
|
||||||
data->width = available_width;
|
data->width = available_width;
|
||||||
@ -1095,22 +1019,17 @@ st_texture_cache_load_uri_sync_to_cogl_texture (StTextureCache *cache,
|
|||||||
{
|
{
|
||||||
CoglHandle texdata;
|
CoglHandle texdata;
|
||||||
GdkPixbuf *pixbuf;
|
GdkPixbuf *pixbuf;
|
||||||
CacheKey key;
|
char *key;
|
||||||
|
|
||||||
memset (&key, 0, sizeof (CacheKey));
|
key = g_strconcat (CACHE_PREFIX_URI, uri, NULL);
|
||||||
key.policy = policy;
|
|
||||||
key.uri = (char*)uri;
|
|
||||||
key.size = available_width;
|
|
||||||
|
|
||||||
texdata = g_hash_table_lookup (cache->priv->keyed_cache, &key);
|
texdata = g_hash_table_lookup (cache->priv->keyed_cache, key);
|
||||||
|
|
||||||
if (texdata == NULL)
|
if (texdata == NULL)
|
||||||
{
|
{
|
||||||
pixbuf = impl_load_pixbuf_file (uri, available_width, available_height, error);
|
pixbuf = impl_load_pixbuf_file (uri, available_width, available_height, error);
|
||||||
if (!pixbuf)
|
if (!pixbuf)
|
||||||
{
|
goto out;
|
||||||
return COGL_INVALID_HANDLE;
|
|
||||||
}
|
|
||||||
|
|
||||||
texdata = pixbuf_to_cogl_handle (pixbuf);
|
texdata = pixbuf_to_cogl_handle (pixbuf);
|
||||||
g_object_unref (pixbuf);
|
g_object_unref (pixbuf);
|
||||||
@ -1118,12 +1037,14 @@ st_texture_cache_load_uri_sync_to_cogl_texture (StTextureCache *cache,
|
|||||||
if (policy == ST_TEXTURE_CACHE_POLICY_FOREVER)
|
if (policy == ST_TEXTURE_CACHE_POLICY_FOREVER)
|
||||||
{
|
{
|
||||||
cogl_handle_ref (texdata);
|
cogl_handle_ref (texdata);
|
||||||
g_hash_table_insert (cache->priv->keyed_cache, cache_key_dup (&key), texdata);
|
g_hash_table_insert (cache->priv->keyed_cache, g_strdup (key), texdata);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
cogl_handle_ref (texdata);
|
cogl_handle_ref (texdata);
|
||||||
|
|
||||||
|
out:
|
||||||
|
g_free (key);
|
||||||
return texdata;
|
return texdata;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1262,25 +1183,24 @@ st_texture_cache_load_from_data (StTextureCache *cache,
|
|||||||
ClutterTexture *texture;
|
ClutterTexture *texture;
|
||||||
CoglHandle texdata;
|
CoglHandle texdata;
|
||||||
GdkPixbuf *pixbuf;
|
GdkPixbuf *pixbuf;
|
||||||
CacheKey key;
|
char *key;
|
||||||
gchar *checksum;
|
char *checksum;
|
||||||
|
|
||||||
texture = create_default_texture (cache);
|
texture = create_default_texture (cache);
|
||||||
clutter_actor_set_size (CLUTTER_ACTOR (texture), size, size);
|
clutter_actor_set_size (CLUTTER_ACTOR (texture), size, size);
|
||||||
|
|
||||||
checksum = g_compute_checksum_for_data (G_CHECKSUM_SHA1, data, len);
|
checksum = g_compute_checksum_for_data (G_CHECKSUM_SHA1, data, len);
|
||||||
|
key = g_strconcat (CACHE_PREFIX_COMPRESSED_CHECKSUM, checksum, NULL);
|
||||||
|
g_free (checksum);
|
||||||
|
|
||||||
memset (&key, 0, sizeof(key));
|
texdata = g_hash_table_lookup (cache->priv->keyed_cache, key);
|
||||||
key.size = size;
|
|
||||||
key.checksum = checksum;
|
|
||||||
|
|
||||||
texdata = g_hash_table_lookup (cache->priv->keyed_cache, &key);
|
|
||||||
if (texdata == NULL)
|
if (texdata == NULL)
|
||||||
{
|
{
|
||||||
pixbuf = impl_load_pixbuf_data (data, len, size, size, error);
|
pixbuf = impl_load_pixbuf_data (data, len, size, size, error);
|
||||||
if (!pixbuf)
|
if (!pixbuf)
|
||||||
{
|
{
|
||||||
g_object_unref (texture);
|
g_object_unref (texture);
|
||||||
|
g_free (key);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1289,10 +1209,10 @@ st_texture_cache_load_from_data (StTextureCache *cache,
|
|||||||
|
|
||||||
set_texture_cogl_texture (texture, texdata);
|
set_texture_cogl_texture (texture, texdata);
|
||||||
|
|
||||||
g_hash_table_insert (cache->priv->keyed_cache, cache_key_dup (&key), texdata);
|
g_hash_table_insert (cache->priv->keyed_cache, g_strdup (key), texdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (key.checksum);
|
g_free (key);
|
||||||
|
|
||||||
set_texture_cogl_texture (texture, texdata);
|
set_texture_cogl_texture (texture, texdata);
|
||||||
return CLUTTER_ACTOR (texture);
|
return CLUTTER_ACTOR (texture);
|
||||||
@ -1327,8 +1247,8 @@ st_texture_cache_load_from_raw (StTextureCache *cache,
|
|||||||
{
|
{
|
||||||
ClutterTexture *texture;
|
ClutterTexture *texture;
|
||||||
CoglHandle texdata;
|
CoglHandle texdata;
|
||||||
CacheKey key;
|
char *key;
|
||||||
gchar *checksum;
|
char *checksum;
|
||||||
|
|
||||||
texture = create_default_texture (cache);
|
texture = create_default_texture (cache);
|
||||||
clutter_actor_set_size (CLUTTER_ACTOR (texture), size, size);
|
clutter_actor_set_size (CLUTTER_ACTOR (texture), size, size);
|
||||||
@ -1337,22 +1257,20 @@ st_texture_cache_load_from_raw (StTextureCache *cache,
|
|||||||
* pixel data. We ignore that theory.
|
* pixel data. We ignore that theory.
|
||||||
*/
|
*/
|
||||||
checksum = g_compute_checksum_for_data (G_CHECKSUM_SHA1, data, len);
|
checksum = g_compute_checksum_for_data (G_CHECKSUM_SHA1, data, len);
|
||||||
|
key = g_strconcat (CACHE_PREFIX_RAW_CHECKSUM, checksum, NULL);
|
||||||
|
g_free (checksum);
|
||||||
|
|
||||||
memset (&key, 0, sizeof(key));
|
texdata = g_hash_table_lookup (cache->priv->keyed_cache, key);
|
||||||
key.size = size;
|
|
||||||
key.checksum = checksum;
|
|
||||||
|
|
||||||
texdata = g_hash_table_lookup (cache->priv->keyed_cache, &key);
|
|
||||||
if (texdata == NULL)
|
if (texdata == NULL)
|
||||||
{
|
{
|
||||||
texdata = cogl_texture_new_from_data (width, height, COGL_TEXTURE_NONE,
|
texdata = cogl_texture_new_from_data (width, height, COGL_TEXTURE_NONE,
|
||||||
has_alpha ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888,
|
has_alpha ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888,
|
||||||
COGL_PIXEL_FORMAT_ANY,
|
COGL_PIXEL_FORMAT_ANY,
|
||||||
rowstride, data);
|
rowstride, data);
|
||||||
g_hash_table_insert (cache->priv->keyed_cache, cache_key_dup (&key), texdata);
|
g_hash_table_insert (cache->priv->keyed_cache, g_strdup (key), texdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
g_free (key.checksum);
|
g_free (key);
|
||||||
|
|
||||||
set_texture_cogl_texture (texture, texdata);
|
set_texture_cogl_texture (texture, texdata);
|
||||||
return CLUTTER_ACTOR (texture);
|
return CLUTTER_ACTOR (texture);
|
||||||
@ -1382,7 +1300,7 @@ st_texture_cache_load_thumbnail (StTextureCache *cache,
|
|||||||
{
|
{
|
||||||
ClutterTexture *texture;
|
ClutterTexture *texture;
|
||||||
AsyncTextureLoadData *data;
|
AsyncTextureLoadData *data;
|
||||||
CacheKey key;
|
char *key;
|
||||||
CoglHandle texdata;
|
CoglHandle texdata;
|
||||||
|
|
||||||
/* Don't attempt to load thumbnails for non-local URIs */
|
/* Don't attempt to load thumbnails for non-local URIs */
|
||||||
@ -1395,14 +1313,13 @@ st_texture_cache_load_thumbnail (StTextureCache *cache,
|
|||||||
texture = create_default_texture (cache);
|
texture = create_default_texture (cache);
|
||||||
clutter_actor_set_size (CLUTTER_ACTOR (texture), size, size);
|
clutter_actor_set_size (CLUTTER_ACTOR (texture), size, size);
|
||||||
|
|
||||||
memset (&key, 0, sizeof(key));
|
key = g_strconcat (CACHE_PREFIX_THUMBNAIL_URI, uri, NULL);
|
||||||
key.size = size;
|
|
||||||
key.thumbnail_uri = (char*)uri;
|
|
||||||
|
|
||||||
texdata = g_hash_table_lookup (cache->priv->keyed_cache, &key);
|
texdata = g_hash_table_lookup (cache->priv->keyed_cache, key);
|
||||||
if (!texdata)
|
if (!texdata)
|
||||||
{
|
{
|
||||||
data = g_new0 (AsyncTextureLoadData, 1);
|
data = g_new0 (AsyncTextureLoadData, 1);
|
||||||
|
data->key = g_strdup (key);
|
||||||
data->policy = ST_TEXTURE_CACHE_POLICY_FOREVER;
|
data->policy = ST_TEXTURE_CACHE_POLICY_FOREVER;
|
||||||
data->uri = g_strdup (uri);
|
data->uri = g_strdup (uri);
|
||||||
data->mimetype = g_strdup (mimetype);
|
data->mimetype = g_strdup (mimetype);
|
||||||
@ -1417,6 +1334,7 @@ st_texture_cache_load_thumbnail (StTextureCache *cache,
|
|||||||
set_texture_cogl_texture (texture, texdata);
|
set_texture_cogl_texture (texture, texdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_free (key);
|
||||||
return CLUTTER_ACTOR (texture);
|
return CLUTTER_ACTOR (texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1456,7 +1374,7 @@ st_texture_cache_load_recent_thumbnail (StTextureCache *cache,
|
|||||||
{
|
{
|
||||||
ClutterTexture *texture;
|
ClutterTexture *texture;
|
||||||
AsyncTextureLoadData *data;
|
AsyncTextureLoadData *data;
|
||||||
CacheKey key;
|
char *key;
|
||||||
CoglHandle texdata;
|
CoglHandle texdata;
|
||||||
const char *uri;
|
const char *uri;
|
||||||
|
|
||||||
@ -1472,14 +1390,13 @@ st_texture_cache_load_recent_thumbnail (StTextureCache *cache,
|
|||||||
texture = CLUTTER_TEXTURE (clutter_texture_new ());
|
texture = CLUTTER_TEXTURE (clutter_texture_new ());
|
||||||
clutter_actor_set_size (CLUTTER_ACTOR (texture), size, size);
|
clutter_actor_set_size (CLUTTER_ACTOR (texture), size, size);
|
||||||
|
|
||||||
memset (&key, 0, sizeof(key));
|
key = g_strconcat (CACHE_PREFIX_THUMBNAIL_URI, uri, NULL);
|
||||||
key.size = size;
|
|
||||||
key.thumbnail_uri = (char*)gtk_recent_info_get_uri (info);
|
|
||||||
|
|
||||||
texdata = g_hash_table_lookup (cache->priv->keyed_cache, &key);
|
texdata = g_hash_table_lookup (cache->priv->keyed_cache, key);
|
||||||
if (!texdata)
|
if (!texdata)
|
||||||
{
|
{
|
||||||
data = g_new0 (AsyncTextureLoadData, 1);
|
data = g_new0 (AsyncTextureLoadData, 1);
|
||||||
|
data->key = g_strdup (key);
|
||||||
data->policy = ST_TEXTURE_CACHE_POLICY_FOREVER;
|
data->policy = ST_TEXTURE_CACHE_POLICY_FOREVER;
|
||||||
data->thumbnail = TRUE;
|
data->thumbnail = TRUE;
|
||||||
data->recent_info = gtk_recent_info_ref (info);
|
data->recent_info = gtk_recent_info_ref (info);
|
||||||
@ -1493,6 +1410,7 @@ st_texture_cache_load_recent_thumbnail (StTextureCache *cache,
|
|||||||
set_texture_cogl_texture (texture, texdata);
|
set_texture_cogl_texture (texture, texdata);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
g_free (key);
|
||||||
return CLUTTER_ACTOR (texture);
|
return CLUTTER_ACTOR (texture);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1508,20 +1426,11 @@ void
|
|||||||
st_texture_cache_evict_thumbnail (StTextureCache *cache,
|
st_texture_cache_evict_thumbnail (StTextureCache *cache,
|
||||||
const char *uri)
|
const char *uri)
|
||||||
{
|
{
|
||||||
GHashTableIter iter;
|
char *target_key;
|
||||||
gpointer key, value;
|
|
||||||
|
|
||||||
g_hash_table_iter_init (&iter, cache->priv->keyed_cache);
|
target_key = g_strconcat (CACHE_PREFIX_THUMBNAIL_URI, uri, NULL);
|
||||||
|
g_hash_table_remove (cache->priv->keyed_cache, target_key);
|
||||||
while (g_hash_table_iter_next (&iter, &key, &value))
|
g_free (target_key);
|
||||||
{
|
|
||||||
CacheKey *cachekey = key;
|
|
||||||
|
|
||||||
if (cachekey->thumbnail_uri == NULL || strcmp (cachekey->thumbnail_uri, uri) != 0)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
g_hash_table_iter_remove (&iter);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
Loading…
Reference in New Issue
Block a user