diff options
author | Benjamin Otte <otte@redhat.com> | 2013-02-02 01:42:04 +0100 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2013-02-02 01:44:17 +0100 |
commit | e6b3cbe7d2c8ad23284bcf4a17f350043e3afb54 (patch) | |
tree | 49ed28930fbe0a5efaffab78754422abe6f8461c /gtk/gtkcssimageurl.c | |
parent | b2e1b1124f4b5a5fcf83474aa3eed8fda547c66a (diff) | |
download | gtk+-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.c | 86 |
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; } |