summaryrefslogtreecommitdiff
path: root/gtk/gtkcssimageurl.c
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2013-02-02 01:42:04 +0100
committerBenjamin Otte <otte@redhat.com>2013-02-02 01:44:17 +0100
commite6b3cbe7d2c8ad23284bcf4a17f350043e3afb54 (patch)
tree49ed28930fbe0a5efaffab78754422abe6f8461c /gtk/gtkcssimageurl.c
parentb2e1b1124f4b5a5fcf83474aa3eed8fda547c66a (diff)
downloadgtk+-e6b3cbe7d2c8ad23284bcf4a17f350043e3afb54.tar.gz
cssimage: Only load image data when needed
Saves ~6MB of memory per application in the Adwaita I am using - at least until the app starts using all the images in the theme, because the code doesn't discard images yet once they were loaded. https://bugzilla.gnome.org/show_bug.cgi?id=692934
Diffstat (limited to 'gtk/gtkcssimageurl.c')
-rw-r--r--gtk/gtkcssimageurl.c86
1 files changed, 49 insertions, 37 deletions
diff --git a/gtk/gtkcssimageurl.c b/gtk/gtkcssimageurl.c
index eb5d92b23c..0a7c4f3eef 100644
--- a/gtk/gtkcssimageurl.c
+++ b/gtk/gtkcssimageurl.c
@@ -29,6 +29,55 @@ G_DEFINE_TYPE (GtkCssImageUrl, _gtk_css_image_url, GTK_TYPE_CSS_IMAGE)
static GtkCssImage *
gtk_css_image_url_load_image (GtkCssImageUrl *url)
{
+ GdkPixbuf *pixbuf;
+ GError *error = NULL;
+ GFileInputStream *input;
+
+ if (url->loaded_image)
+ return url->loaded_image;
+
+ /* We special case resources here so we can use
+ gdk_pixbuf_new_from_resource, which in turn has some special casing
+ for GdkPixdata files to avoid duplicating the memory for the pixbufs */
+ if (g_file_has_uri_scheme (url->file, "resource"))
+ {
+ char *uri = g_file_get_uri (url->file);
+ char *resource_path = g_uri_unescape_string (uri + strlen ("resource://"), NULL);
+
+ pixbuf = gdk_pixbuf_new_from_resource (resource_path, &error);
+ g_free (resource_path);
+ g_free (uri);
+ }
+ else
+ {
+ input = g_file_read (url->file, NULL, &error);
+ if (input != NULL)
+ {
+ pixbuf = gdk_pixbuf_new_from_stream (G_INPUT_STREAM (input), NULL, &error);
+ g_object_unref (input);
+ }
+ else
+ {
+ pixbuf = NULL;
+ }
+ }
+
+ if (pixbuf == NULL)
+ {
+ cairo_surface_t *empty = cairo_image_surface_create (CAIRO_FORMAT_ARGB32, 0, 0);
+
+ /* XXX: Can we get the error somehow sent to the CssProvider?
+ * I don't like just dumping it to stderr or losing it completely. */
+ g_warning ("Error loading image: %s", error->message);
+ g_error_free (error);
+ url->loaded_image = _gtk_css_image_surface_new (empty);
+ cairo_surface_destroy (empty);
+ return url->loaded_image;
+ }
+
+ url->loaded_image = _gtk_css_image_surface_new_for_pixbuf (pixbuf);
+ g_object_unref (pixbuf);
+
return url->loaded_image;
}
@@ -85,48 +134,11 @@ gtk_css_image_url_parse (GtkCssImage *image,
GtkCssParser *parser)
{
GtkCssImageUrl *url = GTK_CSS_IMAGE_URL (image);
- GdkPixbuf *pixbuf;
- GError *error = NULL;
- GFileInputStream *input;
url->file = _gtk_css_parser_read_url (parser);
if (url->file == NULL)
return FALSE;
- /* We special case resources here so we can use
- gdk_pixbuf_new_from_resource, which in turn has some special casing
- for GdkPixdata files to avoid duplicating the memory for the pixbufs */
- if (g_file_has_uri_scheme (url->file, "resource"))
- {
- char *uri = g_file_get_uri (url->file);
- char *resource_path = g_uri_unescape_string (uri + strlen ("resource://"), NULL);
-
- pixbuf = gdk_pixbuf_new_from_resource (resource_path, &error);
- g_free (resource_path);
- g_free (uri);
- }
- else
- {
- input = g_file_read (url->file, NULL, &error);
- if (input == NULL)
- {
- _gtk_css_parser_take_error (parser, error);
- return FALSE;
- }
-
- pixbuf = gdk_pixbuf_new_from_stream (G_INPUT_STREAM (input), NULL, &error);
- g_object_unref (input);
- }
-
- if (pixbuf == NULL)
- {
- _gtk_css_parser_take_error (parser, error);
- return FALSE;
- }
-
- url->loaded_image = _gtk_css_image_surface_new_for_pixbuf (pixbuf);
- g_object_unref (pixbuf);
-
return TRUE;
}