diff options
author | Benjamin Otte <otte@redhat.com> | 2021-09-14 14:53:10 +0200 |
---|---|---|
committer | Benjamin Otte <otte@redhat.com> | 2021-09-14 14:59:02 +0200 |
commit | e14fde3b71ce86761eb1df2c23e943d369c7d0c3 (patch) | |
tree | e05402e103ae69950b50db30132426ad093084ae | |
parent | 527084dd448e6be8881e34f41f5d0fa04279d1e0 (diff) | |
download | gtk+-wip/otte/more-ram.tar.gz |
Download more RAM!wip/otte/more-ram
-rw-r--r-- | gdk/gdkcompressedtexture.c | 176 | ||||
-rw-r--r-- | gdk/gdkcompressedtextureprivate.h | 37 | ||||
-rw-r--r-- | gdk/gdkmemorytexture.c | 1 | ||||
-rw-r--r-- | gdk/gdktexture.c | 45 | ||||
-rw-r--r-- | gdk/meson.build | 1 | ||||
-rw-r--r-- | gtk/gdkpixbufutils.c | 3 |
6 files changed, 220 insertions, 43 deletions
diff --git a/gdk/gdkcompressedtexture.c b/gdk/gdkcompressedtexture.c new file mode 100644 index 0000000000..0c0ecb3793 --- /dev/null +++ b/gdk/gdkcompressedtexture.c @@ -0,0 +1,176 @@ +/* + * Copyright © 2021 Benjamin Otte + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Authors: Benjamin Otte <otte@gnome.org> + */ + +#include "config.h" + +#include "gdkcompressedtextureprivate.h" + +#include "loaders/gdkpngprivate.h" +#include "loaders/gdktiffprivate.h" +#include "loaders/gdkjpegprivate.h" + +struct _GdkCompressedTexture +{ + GdkTexture parent_instance; + + GBytes *bytes; + GdkTexture *texture; + guint remove_id; +}; + +struct _GdkCompressedTextureClass +{ + GdkTextureClass parent_class; +}; + +G_DEFINE_TYPE (GdkCompressedTexture, gdk_compressed_texture, GDK_TYPE_TEXTURE) + +static gboolean +gdk_compressed_texture_clear (gpointer data) +{ + GdkCompressedTexture *self = data; + + g_print ("CLEAR %zu %u\n", g_bytes_get_size (self->bytes), self->texture ? G_OBJECT (self->texture)->ref_count : 0); + g_clear_object (&self->texture); + g_clear_handle_id (&self->remove_id, g_source_remove); + + return FALSE; +} + +static GdkTexture * +gdk_compresed_texture_load (GBytes *bytes, + GError **error) +{ + const char *data; + gsize size; + + data = g_bytes_get_data (bytes, &size); + + if (size > strlen (PNG_SIGNATURE) && + memcmp (data, PNG_SIGNATURE, strlen (PNG_SIGNATURE)) == 0) + { + return gdk_load_png (bytes, error); + } + else if ((size > strlen (TIFF_SIGNATURE1) && + memcmp (data, TIFF_SIGNATURE1, strlen (TIFF_SIGNATURE1)) == 0) || + (size > strlen (TIFF_SIGNATURE2) && + memcmp (data, TIFF_SIGNATURE2, strlen (TIFF_SIGNATURE2)) == 0)) + { + return gdk_load_tiff (bytes, error); + } + else if (size > strlen (JPEG_SIGNATURE) && + memcmp (data, JPEG_SIGNATURE, strlen (JPEG_SIGNATURE)) == 0) + { + return gdk_load_jpeg (bytes, error); + } + else + { + GInputStream *stream; + GdkPixbuf *pixbuf; + GdkTexture *texture; + + stream = g_memory_input_stream_new_from_bytes (bytes); + pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, error); + g_object_unref (stream); + if (pixbuf == NULL) + return NULL; + + texture = gdk_texture_new_for_pixbuf (pixbuf); + g_object_unref (pixbuf); + return texture; + } +} + +static void +gdk_compressed_texture_ensure_texture (GdkCompressedTexture *self) +{ + g_print ("%9zu %p Ensuring texture\n", g_bytes_get_size (self->bytes), self); + if (self->texture == NULL) + { + self->texture = gdk_compresed_texture_load (self->bytes, NULL); + g_assert (self->texture); + } + else + { + g_clear_handle_id (&self->remove_id, g_source_remove); + } + + self->remove_id = g_timeout_add_seconds (10, gdk_compressed_texture_clear, self); +} + +static void +gdk_compressed_texture_dispose (GObject *object) +{ + GdkCompressedTexture *self = GDK_COMPRESSED_TEXTURE (object); + + gdk_compressed_texture_clear (self); + g_clear_pointer (&self->bytes, g_bytes_unref); + + G_OBJECT_CLASS (gdk_compressed_texture_parent_class)->dispose (object); +} + +static GdkTexture * +gdk_compressed_texture_download_texture (GdkTexture *texture) +{ + GdkCompressedTexture *self = GDK_COMPRESSED_TEXTURE (texture); + + gdk_compressed_texture_ensure_texture (self); + + return g_object_ref (self->texture); +} + +static void +gdk_compressed_texture_class_init (GdkCompressedTextureClass *klass) +{ + GdkTextureClass *texture_class = GDK_TEXTURE_CLASS (klass); + GObjectClass *gobject_class = G_OBJECT_CLASS (klass); + + texture_class->download_texture = gdk_compressed_texture_download_texture; + gobject_class->dispose = gdk_compressed_texture_dispose; +} + +static void +gdk_compressed_texture_init (GdkCompressedTexture *self) +{ +} + +GdkTexture * +gdk_compressed_texture_new_from_bytes (GBytes *bytes, + GError **error) +{ + GdkCompressedTexture *self; + GdkTexture *texture; + + texture = gdk_compresed_texture_load (bytes, error); + if (texture == NULL) + return NULL; + + self = g_object_new (GDK_TYPE_COMPRESSED_TEXTURE, + "width", gdk_texture_get_width (texture), + "height", gdk_texture_get_height (texture), + NULL); + + self->bytes = g_bytes_ref (bytes); + self->texture = texture; + /* install the removal handler */ + gdk_compressed_texture_ensure_texture (self); + + return GDK_TEXTURE (self); +} + diff --git a/gdk/gdkcompressedtextureprivate.h b/gdk/gdkcompressedtextureprivate.h new file mode 100644 index 0000000000..094e2b7ac3 --- /dev/null +++ b/gdk/gdkcompressedtextureprivate.h @@ -0,0 +1,37 @@ +/* + * Copyright © 2021 Benjamin Otte + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library. If not, see <http://www.gnu.org/licenses/>. + * + * Authors: Benjamin Otte <otte@gnome.org> + */ + +#ifndef __GDK_COMPRESSED_TEXTURE_PRIVATE_H__ +#define __GDK_COMPRESSED_TEXTURE_PRIVATE_H__ + +#include "gdktextureprivate.h" + +G_BEGIN_DECLS + +#define GDK_TYPE_COMPRESSED_TEXTURE (gdk_compressed_texture_get_type ()) + +G_DECLARE_FINAL_TYPE (GdkCompressedTexture, gdk_compressed_texture, GDK, COMPRESSED_TEXTURE, GdkTexture) + +GdkTexture * gdk_compressed_texture_new_from_bytes (GBytes *bytes, + GError **error); + + +G_END_DECLS + +#endif /* __GDK_COMPRESSED_TEXTURE_PRIVATE_H__ */ diff --git a/gdk/gdkmemorytexture.c b/gdk/gdkmemorytexture.c index 631357bcc8..32740fb103 100644 --- a/gdk/gdkmemorytexture.c +++ b/gdk/gdkmemorytexture.c @@ -124,6 +124,7 @@ gdk_memory_texture_dispose (GObject *object) { GdkMemoryTexture *self = GDK_MEMORY_TEXTURE (object); + g_print ("freeing %zu bytes\n", g_bytes_get_size (self->bytes)); g_clear_pointer (&self->bytes, g_bytes_unref); G_OBJECT_CLASS (gdk_memory_texture_parent_class)->dispose (object); diff --git a/gdk/gdktexture.c b/gdk/gdktexture.c index aca0a415b4..ca9b3310ff 100644 --- a/gdk/gdktexture.c +++ b/gdk/gdktexture.c @@ -41,6 +41,7 @@ #include "gdktextureprivate.h" #include "gdkinternals.h" +#include "gdkcompressedtextureprivate.h" #include "gdkmemorytextureprivate.h" #include "gdkpaintable.h" #include "gdksnapshot.h" @@ -431,52 +432,10 @@ GdkTexture * gdk_texture_new_from_bytes (GBytes *bytes, GError **error) { - const char *data; - gsize size; - g_return_val_if_fail (bytes != NULL, NULL); g_return_val_if_fail (error == NULL || *error == NULL, NULL); - data = g_bytes_get_data (bytes, &size); - - if (size > strlen (PNG_SIGNATURE) && - memcmp (data, PNG_SIGNATURE, strlen (PNG_SIGNATURE)) == 0) - { - return gdk_load_png (bytes, error); - } - else if ((size > strlen (TIFF_SIGNATURE1) && - memcmp (data, TIFF_SIGNATURE1, strlen (TIFF_SIGNATURE1)) == 0) || - (size > strlen (TIFF_SIGNATURE2) && - memcmp (data, TIFF_SIGNATURE2, strlen (TIFF_SIGNATURE2)) == 0)) - { - return gdk_load_tiff (bytes, error); - } - else if (size > strlen (JPEG_SIGNATURE) && - memcmp (data, JPEG_SIGNATURE, strlen (JPEG_SIGNATURE)) == 0) - { - return gdk_load_jpeg (bytes, error); - } - else - { - GInputStream *stream; - GdkPixbuf *pixbuf; - - stream = g_memory_input_stream_new_from_bytes (bytes); - pixbuf = gdk_pixbuf_new_from_stream (stream, NULL, error); - g_object_unref (stream); - - if (pixbuf) - { - GdkTexture *texture; - - texture = gdk_texture_new_for_pixbuf (pixbuf); - g_object_unref (pixbuf); - - return texture; - } - } - - return NULL; + return gdk_compressed_texture_new_from_bytes (bytes, error); } /** diff --git a/gdk/meson.build b/gdk/meson.build index 06905233f8..20044b9057 100644 --- a/gdk/meson.build +++ b/gdk/meson.build @@ -4,6 +4,7 @@ gdk_public_sources = files([ 'gdkcairo.c', 'gdkcairocontext.c', 'gdkclipboard.c', + 'gdkcompressedtexture.c', 'gdkcontentdeserializer.c', 'gdkcontentformats.c', 'gdkcontentprovider.c', diff --git a/gtk/gdkpixbufutils.c b/gtk/gdkpixbufutils.c index d1b6693918..dba8b3c624 100644 --- a/gtk/gdkpixbufutils.c +++ b/gtk/gdkpixbufutils.c @@ -610,6 +610,9 @@ gdk_paintable_new_from_bytes_scaled (GBytes *bytes, GdkTexture *texture; GdkPaintable *paintable; + if (scale_factor == 1) + return GDK_PAINTABLE (gdk_texture_new_from_bytes (bytes, NULL)); + loader_data.scale_factor = scale_factor; loader = gdk_pixbuf_loader_new (); |