[gtk/wip/chergert/glyphy: 1/3] gsk/gl: add stubs for Glyphy texture library




commit df983355c7f9b99db2105f160e14af8fa53d38e1
Author: Christian Hergert <chergert redhat com>
Date:   Mon Mar 14 16:22:52 2022 -0700

    gsk/gl: add stubs for Glyphy texture library
    
    This just gets some plumbing in place for us to have a texture library
    that can be used for storing Glyphy's SDF content. No glyphy integration
    is part of this commit, only preparation.

 gsk/gl/gskgldriver.c               |   2 +
 gsk/gl/gskgldriverprivate.h        |   1 +
 gsk/gl/gskglglyphylibrary.c        | 141 +++++++++++++++++++++++++++++++++++++
 gsk/gl/gskglglyphylibraryprivate.h |  93 ++++++++++++++++++++++++
 gsk/gl/gskgltypesprivate.h         |   1 +
 gsk/meson.build                    |   1 +
 6 files changed, 239 insertions(+)
---
diff --git a/gsk/gl/gskgldriver.c b/gsk/gl/gskgldriver.c
index 327dea93ff..712cc59ed0 100644
--- a/gsk/gl/gskgldriver.c
+++ b/gsk/gl/gskgldriver.c
@@ -32,6 +32,7 @@
 #include "gskglcommandqueueprivate.h"
 #include "gskglcompilerprivate.h"
 #include "gskglglyphlibraryprivate.h"
+#include "gskglglyphylibraryprivate.h"
 #include "gskgliconlibraryprivate.h"
 #include "gskglprogramprivate.h"
 #include "gskglshadowlibraryprivate.h"
@@ -457,6 +458,7 @@ gsk_gl_driver_new (GskGLCommandQueue  *command_queue,
     }
 
   self->glyphs = gsk_gl_glyph_library_new (self);
+  self->glyphy = gsk_gl_glyphy_library_new (self);
   self->icons = gsk_gl_icon_library_new (self);
   self->shadows = gsk_gl_shadow_library_new (self);
 
diff --git a/gsk/gl/gskgldriverprivate.h b/gsk/gl/gskgldriverprivate.h
index 4500962ed8..5878591396 100644
--- a/gsk/gl/gskgldriverprivate.h
+++ b/gsk/gl/gskgldriverprivate.h
@@ -101,6 +101,7 @@ struct _GskGLDriver
   GskGLCommandQueue *command_queue;
 
   GskGLGlyphLibrary *glyphs;
+  GskGLGlyphyLibrary *glyphy;
   GskGLIconLibrary *icons;
   GskGLShadowLibrary *shadows;
 
diff --git a/gsk/gl/gskglglyphylibrary.c b/gsk/gl/gskglglyphylibrary.c
new file mode 100644
index 0000000000..fba0bcfe2f
--- /dev/null
+++ b/gsk/gl/gskglglyphylibrary.c
@@ -0,0 +1,141 @@
+/* gskglglyphylibrary.c
+ *
+ * Copyright 2020 Christian Hergert <chergert redhat com>
+ *
+ * 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 program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#include "config.h"
+
+#include <gdk/gdkglcontextprivate.h>
+#include <gdk/gdkmemoryformatprivate.h>
+#include <gdk/gdkprofilerprivate.h>
+
+#include "gskglcommandqueueprivate.h"
+#include "gskgldriverprivate.h"
+#include "gskglglyphylibraryprivate.h"
+
+#define MAX_GLYPH_SIZE 128
+
+G_DEFINE_TYPE (GskGLGlyphyLibrary, gsk_gl_glyphy_library, GSK_TYPE_GL_TEXTURE_LIBRARY)
+
+GskGLGlyphyLibrary *
+gsk_gl_glyphy_library_new (GskGLDriver *driver)
+{
+  g_return_val_if_fail (GSK_IS_GL_DRIVER (driver), NULL);
+
+  return g_object_new (GSK_TYPE_GL_GLYPHY_LIBRARY,
+                       "driver", driver,
+                       NULL);
+}
+
+static guint
+gsk_gl_glyphy_key_hash (gconstpointer data)
+{
+  const GskGLGlyphyKey *key = data;
+
+  /* malloc()'d pointers already guarantee 3 bits from the LSB on 64-bit and
+   * 2 bits from the LSB on 32-bit. Shift by enough to give us 256 entries
+   * in our front cache for the glyph since languages will naturally cluster
+   * for us.
+   */
+
+#if GLIB_SIZEOF_VOID_P == 4
+  return (guint)(GPOINTER_TO_SIZE (key->font) << 6) ^ key->glyph;
+#else
+  return (guint)(GPOINTER_TO_SIZE (key->font) << 5) ^ key->glyph;
+#endif
+}
+
+static gboolean
+gsk_gl_glyphy_key_equal (gconstpointer v1,
+                         gconstpointer v2)
+{
+  return memcmp (v1, v2, sizeof (GskGLGlyphyKey)) == 0;
+}
+
+static void
+gsk_gl_glyphy_key_free (gpointer data)
+{
+  GskGLGlyphyKey *key = data;
+
+  g_clear_object (&key->font);
+  g_slice_free (GskGLGlyphyKey, key);
+}
+
+static void
+gsk_gl_glyphy_value_free (gpointer data)
+{
+  g_slice_free (GskGLGlyphyValue, data);
+}
+
+static void
+gsk_gl_glyphy_library_begin_frame (GskGLTextureLibrary *library,
+                                  gint64               frame_id,
+                                  GPtrArray           *removed_atlases)
+{
+  GskGLGlyphyLibrary *self = (GskGLGlyphyLibrary *)library;
+
+  memset (self->front, 0, sizeof self->front);
+}
+
+static void
+gsk_gl_glyphy_library_finalize (GObject *object)
+{
+#if 0
+  GskGLGlyphyLibrary *self = (GskGLGlyphyLibrary *)object;
+#endif
+
+  G_OBJECT_CLASS (gsk_gl_glyphy_library_parent_class)->finalize (object);
+}
+
+static void
+gsk_gl_glyphy_library_class_init (GskGLGlyphyLibraryClass *klass)
+{
+  GObjectClass *object_class = G_OBJECT_CLASS (klass);
+  GskGLTextureLibraryClass *library_class = GSK_GL_TEXTURE_LIBRARY_CLASS (klass);
+
+  object_class->finalize = gsk_gl_glyphy_library_finalize;
+
+  library_class->begin_frame = gsk_gl_glyphy_library_begin_frame;
+}
+
+static void
+gsk_gl_glyphy_library_init (GskGLGlyphyLibrary *self)
+{
+  GskGLTextureLibrary *tl = (GskGLTextureLibrary *)self;
+
+  tl->max_entry_size = MAX_GLYPH_SIZE;
+  gsk_gl_texture_library_set_funcs (tl,
+                                    gsk_gl_glyphy_key_hash,
+                                    gsk_gl_glyphy_key_equal,
+                                    gsk_gl_glyphy_key_free,
+                                    gsk_gl_glyphy_value_free);
+}
+
+gboolean
+gsk_gl_glyphy_library_add (GskGLGlyphyLibrary      *self,
+                           GskGLGlyphyKey          *key,
+                           const GskGLGlyphyValue **out_value)
+{
+  g_assert (GSK_IS_GL_GLYPHY_LIBRARY (self));
+  g_assert (key != NULL);
+  g_assert (out_value != NULL);
+
+  *out_value = NULL;
+
+  return FALSE;
+}
diff --git a/gsk/gl/gskglglyphylibraryprivate.h b/gsk/gl/gskglglyphylibraryprivate.h
new file mode 100644
index 0000000000..c8456d8788
--- /dev/null
+++ b/gsk/gl/gskglglyphylibraryprivate.h
@@ -0,0 +1,93 @@
+/* gskglglyphylibraryprivate.h
+ *
+ * Copyright 2020-2022 Christian Hergert <chergert redhat com>
+ *
+ * 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 program.  If not, see <http://www.gnu.org/licenses/>.
+ *
+ * SPDX-License-Identifier: LGPL-2.1-or-later
+ */
+
+#ifndef __GSK_GL_GLYPHY_LIBRARY_PRIVATE_H__
+#define __GSK_GL_GLYPHY_LIBRARY_PRIVATE_H__
+
+#include <pango/pango.h>
+
+#include "gskgltexturelibraryprivate.h"
+
+G_BEGIN_DECLS
+
+#define GSK_TYPE_GL_GLYPHY_LIBRARY (gsk_gl_glyphy_library_get_type())
+
+typedef struct _GskGLGlyphyKey
+{
+  PangoFont *font;
+  PangoGlyph glyph;
+} GskGLGlyphyKey;
+
+typedef struct _GskGLGlyphyValue
+{
+  GskGLTextureAtlasEntry entry;
+} GskGLGlyphyValue;
+
+G_DECLARE_FINAL_TYPE (GskGLGlyphyLibrary, gsk_gl_glyphy_library, GSK, GL_GLYPHY_LIBRARY, GskGLTextureLibrary)
+
+struct _GskGLGlyphyLibrary
+{
+  GskGLTextureLibrary parent_instance;
+  guint8 *surface_data;
+  gsize surface_data_len;
+  struct {
+    GskGLGlyphyKey key;
+    const GskGLGlyphyValue *value;
+  } front[256];
+};
+
+GskGLGlyphyLibrary *gsk_gl_glyphy_library_new (GskGLDriver             *driver);
+gboolean            gsk_gl_glyphy_library_add (GskGLGlyphyLibrary      *self,
+                                               GskGLGlyphyKey          *key,
+                                               const GskGLGlyphyValue **out_value);
+
+static inline guint
+gsk_gl_glyphy_library_lookup_or_add (GskGLGlyphyLibrary      *self,
+                                     const GskGLGlyphyKey    *key,
+                                     const GskGLGlyphyValue **out_value)
+{
+  GskGLTextureAtlasEntry *entry;
+  guint front_index = key->glyph & 0xFF;
+
+  if (memcmp (key, &self->front[front_index], sizeof *key) == 0)
+    {
+      *out_value = self->front[front_index].value;
+    }
+  else if (gsk_gl_texture_library_lookup ((GskGLTextureLibrary *)self, key, &entry))
+    {
+      *out_value = (GskGLGlyphyValue *)entry;
+      self->front[front_index].key = *key;
+      self->front[front_index].value = *out_value;
+    }
+  else
+    {
+      GskGLGlyphyKey *k = g_slice_copy (sizeof *key, key);
+      g_object_ref (k->font);
+      gsk_gl_glyphy_library_add (self, k, out_value);
+      self->front[front_index].key = *key;
+      self->front[front_index].value = *out_value;
+    }
+
+  return GSK_GL_TEXTURE_ATLAS_ENTRY_TEXTURE (*out_value);
+}
+
+G_END_DECLS
+
+#endif /* __GSK_GL_GLYPHY_LIBRARY_PRIVATE_H__ */
diff --git a/gsk/gl/gskgltypesprivate.h b/gsk/gl/gskgltypesprivate.h
index 1250756fb7..57364fcf4e 100644
--- a/gsk/gl/gskgltypesprivate.h
+++ b/gsk/gl/gskgltypesprivate.h
@@ -37,6 +37,7 @@ typedef struct _GskGLCompiler GskGLCompiler;
 typedef struct _GskGLDrawVertex GskGLDrawVertex;
 typedef struct _GskGLRenderTarget GskGLRenderTarget;
 typedef struct _GskGLGlyphLibrary GskGLGlyphLibrary;
+typedef struct _GskGLGlyphyLibrary GskGLGlyphyLibrary;
 typedef struct _GskGLIconLibrary GskGLIconLibrary;
 typedef struct _GskGLProgram GskGLProgram;
 typedef struct _GskGLRenderJob GskGLRenderJob;
diff --git a/gsk/meson.build b/gsk/meson.build
index 1c3cae4a63..99020f48fd 100644
--- a/gsk/meson.build
+++ b/gsk/meson.build
@@ -45,6 +45,7 @@ gsk_private_sources = files([
   'gl/gskglcompiler.c',
   'gl/gskgldriver.c',
   'gl/gskglglyphlibrary.c',
+  'gl/gskglglyphylibrary.c',
   'gl/gskgliconlibrary.c',
   'gl/gskglprogram.c',
   'gl/gskglrenderjob.c',


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