diff options
author | Jiří Techet <techet@gmail.com> | 2013-08-06 15:40:54 +0200 |
---|---|---|
committer | Jiří Techet <techet@gmail.com> | 2013-08-07 13:37:07 +0200 |
commit | 8a3398cf983760a42cb0e8b1cc1f0a35bde7acab (patch) | |
tree | b8f74dd017488987d0d2aea622cb61c293f4260c | |
parent | 4ca95de2a62495b93a9e4fdd74f9b8e4c0a12f7b (diff) | |
download | libchamplain-8a3398cf983760a42cb0e8b1cc1f0a35bde7acab.tar.gz |
Load tile bitmaps asynchronously
-rw-r--r-- | champlain/champlain-image-renderer.c | 88 |
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; } |