summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBenjamin Otte <otte@redhat.com>2021-09-14 14:53:10 +0200
committerBenjamin Otte <otte@redhat.com>2021-09-14 14:59:02 +0200
commite14fde3b71ce86761eb1df2c23e943d369c7d0c3 (patch)
treee05402e103ae69950b50db30132426ad093084ae
parent527084dd448e6be8881e34f41f5d0fa04279d1e0 (diff)
downloadgtk+-wip/otte/more-ram.tar.gz
Download more RAM!wip/otte/more-ram
-rw-r--r--gdk/gdkcompressedtexture.c176
-rw-r--r--gdk/gdkcompressedtextureprivate.h37
-rw-r--r--gdk/gdkmemorytexture.c1
-rw-r--r--gdk/gdktexture.c45
-rw-r--r--gdk/meson.build1
-rw-r--r--gtk/gdkpixbufutils.c3
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 ();