summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiří Techet <techet@gmail.com>2013-08-06 15:40:54 +0200
committerJiří Techet <techet@gmail.com>2013-08-07 13:37:07 +0200
commit8a3398cf983760a42cb0e8b1cc1f0a35bde7acab (patch)
treeb8f74dd017488987d0d2aea622cb61c293f4260c
parent4ca95de2a62495b93a9e4fdd74f9b8e4c0a12f7b (diff)
downloadlibchamplain-8a3398cf983760a42cb0e8b1cc1f0a35bde7acab.tar.gz
Load tile bitmaps asynchronously
-rw-r--r--champlain/champlain-image-renderer.c88
1 files changed, 52 insertions, 36 deletions
diff --git a/champlain/champlain-image-renderer.c b/champlain/champlain-image-renderer.c
index 02917cb..e5484a1 100644
--- a/champlain/champlain-image-renderer.c
+++ b/champlain/champlain-image-renderer.c
@@ -39,6 +39,16 @@ struct _ChamplainImageRendererPrivate
guint size;
};
+typedef struct _RendererData RendererData;
+
+struct _RendererData
+{
+ ChamplainRenderer *renderer;
+ ChamplainTile *tile;
+ gchar *data;
+ guint size;
+};
+
static void set_data (ChamplainRenderer *renderer,
const gchar *data,
guint size);
@@ -120,51 +130,25 @@ set_data (ChamplainRenderer *renderer, const gchar *data, guint size)
}
-static void
-render (ChamplainRenderer *renderer, ChamplainTile *tile)
+static void
+image_rendered_cb (GInputStream *stream, GAsyncResult *res, RendererData *data)
{
- ChamplainImageRendererPrivate *priv = GET_PRIVATE (renderer);
+ ChamplainTile *tile = data->tile;
gboolean error = TRUE;
- GdkPixbufLoader *loader = NULL;
GError *gerror = NULL;
ClutterActor *actor = NULL;
GdkPixbuf *pixbuf;
ClutterContent *content;
gfloat width, height;
-
- if (!priv->data || priv->size == 0)
- goto finish;
-
- loader = gdk_pixbuf_loader_new ();
- if (!gdk_pixbuf_loader_write (loader,
- (const guchar *) priv->data,
- priv->size,
- &gerror))
- {
- if (gerror)
- {
- g_warning ("Unable to load the pixbuf: %s", gerror->message);
- g_error_free (gerror);
- }
- goto finish;
- }
-
- gdk_pixbuf_loader_close (loader, &gerror);
- if (gerror)
- {
- g_warning ("Unable to close the pixbuf loader: %s", gerror->message);
- g_error_free (gerror);
- goto finish;
- }
-
- /* Load the image into clutter */
- pixbuf = gdk_pixbuf_loader_get_pixbuf (loader);
+
+ pixbuf = gdk_pixbuf_new_from_stream_finish (res, NULL);
if (!pixbuf)
{
g_warning ("NULL pixbuf");
goto finish;
}
+ /* Load the image into clutter */
content = clutter_image_new ();
if (!clutter_image_set_data (CLUTTER_IMAGE (content),
gdk_pixbuf_get_pixels (pixbuf),
@@ -190,7 +174,6 @@ render (ChamplainRenderer *renderer, ChamplainTile *tile)
actor = clutter_actor_new ();
clutter_actor_set_size (actor, width, height);
clutter_actor_set_content (actor, content);
- clutter_content_invalidate (content);
g_object_unref (content);
/* has to be set for proper opacity */
clutter_actor_set_offscreen_redirect (actor, CLUTTER_OFFSCREEN_REDIRECT_AUTOMATIC_FOR_OPACITY);
@@ -202,8 +185,41 @@ finish:
if (actor)
champlain_tile_set_content (tile, actor);
- g_signal_emit_by_name (tile, "render-complete", priv->data, priv->size, error);
+ g_signal_emit_by_name (tile, "render-complete", data->data, data->size, error);
+
+ if (pixbuf)
+ g_object_unref (pixbuf);
+
+ g_object_unref (data->renderer);
+ g_object_unref (tile);
+ g_object_unref (stream);
+ g_free (data->data);
+ g_slice_free (RendererData, data);
+}
+
- if (loader)
- g_object_unref (loader);
+
+static void
+render (ChamplainRenderer *renderer, ChamplainTile *tile)
+{
+ ChamplainImageRendererPrivate *priv = GET_PRIVATE (renderer);
+ GInputStream *stream;
+
+ if (!priv->data || priv->size == 0)
+ {
+ g_signal_emit_by_name (tile, "render-complete", priv->data, priv->size, TRUE);
+ return;
+ }
+
+ RendererData *data;
+
+ data = g_slice_new (RendererData);
+ data->tile = g_object_ref (tile);
+ data->renderer = g_object_ref (renderer);
+ data->data = priv->data;
+ data->size = priv->size;
+
+ stream = g_memory_input_stream_new_from_data (priv->data, priv->size, NULL);
+ gdk_pixbuf_new_from_stream_async (stream, NULL, (GAsyncReadyCallback)image_rendered_cb, data);
+ priv->data = NULL;
}