[gtk/wip/otte/more-ram] Download more RAM!




commit e14fde3b71ce86761eb1df2c23e943d369c7d0c3
Author: Benjamin Otte <otte redhat com>
Date:   Tue Sep 14 14:53:10 2021 +0200

    Download more RAM!

 gdk/gdkcompressedtexture.c        | 176 ++++++++++++++++++++++++++++++++++++++
 gdk/gdkcompressedtextureprivate.h |  37 ++++++++
 gdk/gdkmemorytexture.c            |   1 +
 gdk/gdktexture.c                  |  45 +---------
 gdk/meson.build                   |   1 +
 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 ();


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]