[gnome-shell] st-texture-cache: Use async variants of the icon loading API
- From: Jasper St. Pierre <jstpierre src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gnome-shell] st-texture-cache: Use async variants of the icon loading API
- Date: Thu, 14 Feb 2013 21:41:14 +0000 (UTC)
commit 7fc2b33a0a16c9f821d8bea5190001efb1a41aa7
Author: Jasper St. Pierre <jstpierre mecheye net>
Date: Thu Feb 14 15:30:46 2013 -0500
st-texture-cache: Use async variants of the icon loading API
While we were relying on gtk_icon_info_load_icon and friends being
thread-safe, there was no such guarantee, and recent caching that
was added to GTK+ made it non-threadsafe. To replace it, _async()
variants of the icon loading code were added that are thread-safe.
Use those instead of using our own worker threads.
https://bugzilla.gnome.org/show_bug.cgi?id=692845
src/st/st-texture-cache.c | 126 +++++++++++++++++++++++++--------------------
1 files changed, 71 insertions(+), 55 deletions(-)
---
diff --git a/src/st/st-texture-cache.c b/src/st/st-texture-cache.c
index 3b2b8a9..52f77df 100644
--- a/src/st/st-texture-cache.c
+++ b/src/st/st-texture-cache.c
@@ -240,39 +240,6 @@ rgba_from_clutter (GdkRGBA *rgba,
rgba->alpha = color->alpha / 255.;
}
-static GdkPixbuf *
-impl_load_pixbuf_gicon (GtkIconInfo *info,
- int size,
- StIconColors *colors,
- GError **error)
-{
- GdkPixbuf *pixbuf;
-
- if (colors)
- {
- GdkRGBA foreground_color;
- GdkRGBA success_color;
- GdkRGBA warning_color;
- GdkRGBA error_color;
-
- rgba_from_clutter (&foreground_color, &colors->foreground);
- rgba_from_clutter (&success_color, &colors->success);
- rgba_from_clutter (&warning_color, &colors->warning);
- rgba_from_clutter (&error_color, &colors->error);
-
- pixbuf = gtk_icon_info_load_symbolic (info,
- &foreground_color, &success_color,
- &warning_color, &error_color,
- NULL, error);
- }
- else
- {
- pixbuf = gtk_icon_info_load_icon (info, error);
- }
-
- return pixbuf;
-}
-
/* A private structure for keeping width and height. */
typedef struct {
int width;
@@ -525,13 +492,9 @@ load_pixbuf_thread (GSimpleAsyncResult *result,
data = g_async_result_get_user_data (G_ASYNC_RESULT (result));
g_assert (data != NULL);
+ g_assert (data->uri != NULL);
- if (data->uri)
- pixbuf = impl_load_pixbuf_file (data->uri, data->width, data->height, &error);
- else if (data->icon_info)
- pixbuf = impl_load_pixbuf_gicon (data->icon_info, data->width, data->colors, &error);
- else
- g_assert_not_reached ();
+ pixbuf = impl_load_pixbuf_file (data->uri, data->width, data->height, &error);
if (error != NULL)
{
@@ -632,30 +595,22 @@ pixbuf_to_cairo_surface (GdkPixbuf *pixbuf)
}
static void
-on_pixbuf_loaded (GObject *source,
- GAsyncResult *result,
- gpointer user_data)
+finish_texture_load (AsyncTextureLoadData *data,
+ GdkPixbuf *pixbuf)
{
GSList *iter;
StTextureCache *cache;
- AsyncTextureLoadData *data;
- GdkPixbuf *pixbuf;
- GError *error = NULL;
CoglHandle texdata = NULL;
- data = user_data;
- cache = ST_TEXTURE_CACHE (source);
+ cache = data->cache;
g_hash_table_remove (cache->priv->outstanding_requests, data->key);
- pixbuf = load_pixbuf_async_finish (cache, result, &error);
if (pixbuf == NULL)
goto out;
texdata = pixbuf_to_cogl_handle (pixbuf, data->enforced_square);
- g_object_unref (pixbuf);
-
if (data->policy != ST_TEXTURE_CACHE_POLICY_NONE)
{
gpointer orig_key, value;
@@ -680,18 +635,79 @@ out:
cogl_handle_unref (texdata);
texture_load_data_free (data);
+}
- g_clear_error (&error);
+static void
+on_symbolic_icon_loaded (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GdkPixbuf *pixbuf;
+ pixbuf = gtk_icon_info_load_symbolic_finish (GTK_ICON_INFO (source), result, NULL, NULL);
+ finish_texture_load (user_data, pixbuf);
+ g_clear_object (&pixbuf);
+}
+
+static void
+on_icon_loaded (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GdkPixbuf *pixbuf;
+ pixbuf = gtk_icon_info_load_icon_finish (GTK_ICON_INFO (source), result, NULL);
+ finish_texture_load (user_data, pixbuf);
+ g_clear_object (&pixbuf);
+}
+
+static void
+on_pixbuf_loaded (GObject *source,
+ GAsyncResult *result,
+ gpointer user_data)
+{
+ GdkPixbuf *pixbuf;
+ pixbuf = load_pixbuf_async_finish (ST_TEXTURE_CACHE (source), result, NULL);
+ finish_texture_load (user_data, pixbuf);
+ g_clear_object (&pixbuf);
}
static void
load_texture_async (StTextureCache *cache,
AsyncTextureLoadData *data)
{
- GSimpleAsyncResult *result;
- result = g_simple_async_result_new (G_OBJECT (cache), on_pixbuf_loaded, data, load_texture_async);
- g_simple_async_result_run_in_thread (result, load_pixbuf_thread, G_PRIORITY_DEFAULT, NULL);
- g_object_unref (result);
+ if (data->uri)
+ {
+ GSimpleAsyncResult *result;
+ result = g_simple_async_result_new (G_OBJECT (cache), on_pixbuf_loaded, data, load_texture_async);
+ g_simple_async_result_run_in_thread (result, load_pixbuf_thread, G_PRIORITY_DEFAULT, NULL);
+ g_object_unref (result);
+ }
+ else if (data->icon_info)
+ {
+ StIconColors *colors = data->colors;
+ if (colors)
+ {
+ GdkRGBA foreground_color;
+ GdkRGBA success_color;
+ GdkRGBA warning_color;
+ GdkRGBA error_color;
+
+ rgba_from_clutter (&foreground_color, &colors->foreground);
+ rgba_from_clutter (&success_color, &colors->success);
+ rgba_from_clutter (&warning_color, &colors->warning);
+ rgba_from_clutter (&error_color, &colors->error);
+
+ gtk_icon_info_load_symbolic_async (data->icon_info,
+ &foreground_color, &success_color,
+ &warning_color, &error_color,
+ NULL, on_symbolic_icon_loaded, data);
+ }
+ else
+ {
+ gtk_icon_info_load_icon_async (data->icon_info, NULL, on_icon_loaded, data);
+ }
+ }
+ else
+ g_assert_not_reached ();
}
typedef struct {
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]