[gtk/wip/chergert/glproto] implement basics for icon library
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/chergert/glproto] implement basics for icon library
- Date: Wed, 20 Jan 2021 01:13:55 +0000 (UTC)
commit ccae8c7fc26a4d78c60bf51c2904329570d46501
Author: Christian Hergert <chergert redhat com>
Date: Tue Jan 19 17:13:46 2021 -0800
implement basics for icon library
gsk/next/gskgliconlibrary.c | 149 ++++++++++++++++++++++++++++++++++++-
gsk/next/gskgliconlibraryprivate.h | 24 +++++-
2 files changed, 171 insertions(+), 2 deletions(-)
---
diff --git a/gsk/next/gskgliconlibrary.c b/gsk/next/gskgliconlibrary.c
index 207ff04ea5..b7b3c54a6c 100644
--- a/gsk/next/gskgliconlibrary.c
+++ b/gsk/next/gskgliconlibrary.c
@@ -20,6 +20,10 @@
#include "config.h"
+#include <gdk/gdkglcontextprivate.h>
+#include <gdk/gdkmemorytextureprivate.h>
+#include <gdk/gdktextureprivate.h>
+
#include "gskgldriverprivate.h"
#include "gskgliconlibraryprivate.h"
@@ -40,6 +44,15 @@ gsk_gl_icon_library_new (GskNextDriver *driver)
NULL);
}
+static void
+gsk_gl_icon_data_free (gpointer data)
+{
+ GskGLIconData *icon_data = data;
+
+ g_clear_object (&icon_data->source_texture);
+ g_slice_free (GskGLIconData, icon_data);
+}
+
static void
gsk_gl_icon_library_class_init (GskGLIconLibraryClass *klass)
{
@@ -49,5 +62,139 @@ static void
gsk_gl_icon_library_init (GskGLIconLibrary *self)
{
gsk_gl_texture_library_set_funcs (GSK_GL_TEXTURE_LIBRARY (self),
- NULL, NULL, NULL, NULL);
+ NULL, NULL, NULL,
+ gsk_gl_icon_data_free);
+}
+
+void
+gsk_gl_icon_library_add (GskGLIconLibrary *self,
+ GdkTexture *key,
+ const GskGLIconData **out_value)
+{
+ cairo_surface_t *surface;
+ GskGLIconData *icon_data;
+ guint8 *pixel_data;
+ guint8 *surface_data;
+ guint8 *free_data = NULL;
+ guint gl_format;
+ guint gl_type;
+ int packed_x = 0;
+ int packed_y = 0;
+ int width;
+ int height;
+ guint texture_id;
+
+ g_return_if_fail (GSK_IS_GL_ICON_LIBRARY (self));
+ g_return_if_fail (GDK_IS_TEXTURE (key));
+ g_return_if_fail (out_value != NULL);
+
+ width = key->width;
+ height = key->height;
+
+ icon_data = gsk_gl_texture_library_pack (GSK_GL_TEXTURE_LIBRARY (self),
+ key,
+ sizeof (GskGLIconData),
+ width + 2,
+ height + 2);
+ icon_data->source_texture = g_object_ref (key);
+
+ /* actually upload the texture */
+ surface = gdk_texture_download_surface (key);
+ surface_data = cairo_image_surface_get_data (surface);
+ gdk_gl_context_push_debug_group_printf (gdk_gl_context_get_current (),
+ "Uploading texture");
+
+ if (gdk_gl_context_get_use_es (gdk_gl_context_get_current ()))
+ {
+ pixel_data = free_data = g_malloc (width * height * 4);
+ gdk_memory_convert (pixel_data, width * 4,
+ GDK_MEMORY_R8G8B8A8_PREMULTIPLIED,
+ surface_data, cairo_image_surface_get_stride (surface),
+ GDK_MEMORY_DEFAULT, width, height);
+ gl_format = GL_RGBA;
+ gl_type = GL_UNSIGNED_BYTE;
+ }
+ else
+ {
+ pixel_data = surface_data;
+ gl_format = GL_BGRA;
+ gl_type = GL_UNSIGNED_INT_8_8_8_8_REV;
+ }
+
+ texture_id = GSK_GL_TEXTURE_ATLAS_ENTRY_TEXTURE (icon_data);
+
+ glBindTexture (GL_TEXTURE_2D, texture_id);
+
+ glTexSubImage2D (GL_TEXTURE_2D, 0,
+ packed_x + 1, packed_y + 1,
+ width, height,
+ gl_format, gl_type,
+ pixel_data);
+ /* Padding top */
+ glTexSubImage2D (GL_TEXTURE_2D, 0,
+ packed_x + 1, packed_y,
+ width, 1,
+ gl_format, gl_type,
+ pixel_data);
+ /* Padding left */
+ glTexSubImage2D (GL_TEXTURE_2D, 0,
+ packed_x, packed_y + 1,
+ 1, height,
+ gl_format, gl_type,
+ pixel_data);
+ /* Padding top left */
+ glTexSubImage2D (GL_TEXTURE_2D, 0,
+ packed_x, packed_y,
+ 1, 1,
+ gl_format, gl_type,
+ pixel_data);
+
+ /* Padding right */
+ glPixelStorei (GL_UNPACK_ROW_LENGTH, width);
+ glPixelStorei (GL_UNPACK_SKIP_PIXELS, width - 1);
+ glTexSubImage2D (GL_TEXTURE_2D, 0,
+ packed_x + width + 1, packed_y + 1,
+ 1, height,
+ gl_format, gl_type,
+ pixel_data);
+ /* Padding top right */
+ glTexSubImage2D (GL_TEXTURE_2D, 0,
+ packed_x + width + 1, packed_y,
+ 1, 1,
+ gl_format, gl_type,
+ pixel_data);
+ /* Padding bottom */
+ glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei (GL_UNPACK_SKIP_ROWS, height - 1);
+ glTexSubImage2D (GL_TEXTURE_2D, 0,
+ packed_x + 1, packed_y + 1 + height,
+ width, 1,
+ gl_format, gl_type,
+ pixel_data);
+ /* Padding bottom left */
+ glTexSubImage2D (GL_TEXTURE_2D, 0,
+ packed_x, packed_y + 1 + height,
+ 1, 1,
+ gl_format, gl_type,
+ pixel_data);
+ /* Padding bottom right */
+ glPixelStorei (GL_UNPACK_ROW_LENGTH, width);
+ glPixelStorei (GL_UNPACK_SKIP_PIXELS, width - 1);
+ glTexSubImage2D (GL_TEXTURE_2D, 0,
+ packed_x + 1 + width, packed_y + 1 + height,
+ 1, 1,
+ gl_format, gl_type,
+ pixel_data);
+ /* Reset this */
+ glPixelStorei (GL_UNPACK_SKIP_PIXELS, 0);
+ glPixelStorei (GL_UNPACK_ROW_LENGTH, 0);
+ glPixelStorei (GL_UNPACK_SKIP_ROWS, 0);
+
+ gdk_gl_context_pop_debug_group (gdk_gl_context_get_current ());
+
+ *out_value = icon_data;
+
+ cairo_surface_destroy (surface);
+ g_free (free_data);
}
diff --git a/gsk/next/gskgliconlibraryprivate.h b/gsk/next/gskgliconlibraryprivate.h
index 37812cc554..130c49d2bb 100644
--- a/gsk/next/gskgliconlibraryprivate.h
+++ b/gsk/next/gskgliconlibraryprivate.h
@@ -29,9 +29,31 @@ G_BEGIN_DECLS
#define GSK_TYPE_GL_ICON_LIBRARY (gsk_gl_icon_library_get_type())
+typedef struct _GskGLIconData
+{
+ GskGLTextureAtlasEntry entry;
+ GdkTexture *source_texture;
+} GskGLIconData;
+
G_DECLARE_FINAL_TYPE (GskGLIconLibrary, gsk_gl_icon_library, GSK, GL_ICON_LIBRARY, GskGLTextureLibrary)
-GskGLIconLibrary *gsk_gl_icon_library_new (GskNextDriver *driver);
+GskGLIconLibrary *gsk_gl_icon_library_new (GskNextDriver *driver);
+void gsk_gl_icon_library_add (GskGLIconLibrary *self,
+ GdkTexture *key,
+ const GskGLIconData **out_value);
+
+static inline void
+gsk_gl_icon_library_lookup_or_add (GskGLIconLibrary *self,
+ GdkTexture *key,
+ const GskGLIconData **out_value)
+{
+ GskGLTextureAtlasEntry *entry;
+
+ if G_LIKELY (gsk_gl_texture_library_lookup ((GskGLTextureLibrary *)self, key, &entry))
+ *out_value = (GskGLIconData *)entry;
+ else
+ gsk_gl_icon_library_add (self, key, out_value);
+}
G_END_DECLS
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]