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
This commit is contained in:
parent
a5d3f7785a
commit
7fc2b33a0a
@ -240,39 +240,6 @@ rgba_from_clutter (GdkRGBA *rgba,
|
|||||||
rgba->alpha = color->alpha / 255.;
|
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. */
|
/* A private structure for keeping width and height. */
|
||||||
typedef struct {
|
typedef struct {
|
||||||
int width;
|
int width;
|
||||||
@ -525,13 +492,9 @@ load_pixbuf_thread (GSimpleAsyncResult *result,
|
|||||||
|
|
||||||
data = g_async_result_get_user_data (G_ASYNC_RESULT (result));
|
data = g_async_result_get_user_data (G_ASYNC_RESULT (result));
|
||||||
g_assert (data != NULL);
|
g_assert (data != NULL);
|
||||||
|
g_assert (data->uri != NULL);
|
||||||
|
|
||||||
if (data->uri)
|
|
||||||
pixbuf = impl_load_pixbuf_file (data->uri, data->width, data->height, &error);
|
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 ();
|
|
||||||
|
|
||||||
if (error != NULL)
|
if (error != NULL)
|
||||||
{
|
{
|
||||||
@ -632,30 +595,22 @@ pixbuf_to_cairo_surface (GdkPixbuf *pixbuf)
|
|||||||
}
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
on_pixbuf_loaded (GObject *source,
|
finish_texture_load (AsyncTextureLoadData *data,
|
||||||
GAsyncResult *result,
|
GdkPixbuf *pixbuf)
|
||||||
gpointer user_data)
|
|
||||||
{
|
{
|
||||||
GSList *iter;
|
GSList *iter;
|
||||||
StTextureCache *cache;
|
StTextureCache *cache;
|
||||||
AsyncTextureLoadData *data;
|
|
||||||
GdkPixbuf *pixbuf;
|
|
||||||
GError *error = NULL;
|
|
||||||
CoglHandle texdata = NULL;
|
CoglHandle texdata = NULL;
|
||||||
|
|
||||||
data = user_data;
|
cache = data->cache;
|
||||||
cache = ST_TEXTURE_CACHE (source);
|
|
||||||
|
|
||||||
g_hash_table_remove (cache->priv->outstanding_requests, data->key);
|
g_hash_table_remove (cache->priv->outstanding_requests, data->key);
|
||||||
|
|
||||||
pixbuf = load_pixbuf_async_finish (cache, result, &error);
|
|
||||||
if (pixbuf == NULL)
|
if (pixbuf == NULL)
|
||||||
goto out;
|
goto out;
|
||||||
|
|
||||||
texdata = pixbuf_to_cogl_handle (pixbuf, data->enforced_square);
|
texdata = pixbuf_to_cogl_handle (pixbuf, data->enforced_square);
|
||||||
|
|
||||||
g_object_unref (pixbuf);
|
|
||||||
|
|
||||||
if (data->policy != ST_TEXTURE_CACHE_POLICY_NONE)
|
if (data->policy != ST_TEXTURE_CACHE_POLICY_NONE)
|
||||||
{
|
{
|
||||||
gpointer orig_key, value;
|
gpointer orig_key, value;
|
||||||
@ -680,18 +635,79 @@ out:
|
|||||||
cogl_handle_unref (texdata);
|
cogl_handle_unref (texdata);
|
||||||
|
|
||||||
texture_load_data_free (data);
|
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
|
static void
|
||||||
load_texture_async (StTextureCache *cache,
|
load_texture_async (StTextureCache *cache,
|
||||||
AsyncTextureLoadData *data)
|
AsyncTextureLoadData *data)
|
||||||
{
|
{
|
||||||
|
if (data->uri)
|
||||||
|
{
|
||||||
GSimpleAsyncResult *result;
|
GSimpleAsyncResult *result;
|
||||||
result = g_simple_async_result_new (G_OBJECT (cache), on_pixbuf_loaded, data, load_texture_async);
|
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_simple_async_result_run_in_thread (result, load_pixbuf_thread, G_PRIORITY_DEFAULT, NULL);
|
||||||
g_object_unref (result);
|
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 {
|
typedef struct {
|
||||||
|
Loading…
Reference in New Issue
Block a user