[gtk/wip/chergert/glyphy] wip



commit e341a9b0129111df34a6bd931c53573b4b372d3c
Author: Christian Hergert <chergert redhat com>
Date:   Thu Mar 17 01:47:54 2022 -0700

    wip

 gsk/gl/gskglcommandqueue.c         |   2 +-
 gsk/gl/gskglglyphylibrary.c        |  10 +--
 gsk/gl/gskglglyphylibraryprivate.h |   2 +
 gsk/gl/gskglprograms.defs          |   8 ++-
 gsk/gl/gskglrenderjob.c            | 143 +++++++++++++++++++++++++++++++++++--
 gsk/gl/gskgluniformstateprivate.h  |   2 +-
 gsk/gl/resources/glyphy.atlas.glsl |   5 +-
 gsk/gl/resources/glyphy.fs.glsl    |   8 +--
 gsk/gl/resources/glyphy.vs.glsl    |  13 ++--
 9 files changed, 165 insertions(+), 28 deletions(-)
---
diff --git a/gsk/gl/gskglcommandqueue.c b/gsk/gl/gskglcommandqueue.c
index b7640edf87..4d7ef4b3d3 100644
--- a/gsk/gl/gskglcommandqueue.c
+++ b/gsk/gl/gskglcommandqueue.c
@@ -282,7 +282,7 @@ snapshot_uniforms (GskGLUniformState    *state,
     {
       const GskGLUniformMapping *mapping = &program->mappings[i];
 
-      if (!mapping->info.initial && mapping->location > -1)
+      if (!mapping->info.initial && mapping->info.format && mapping->location > -1)
         {
           uniform[count].location = mapping->location;
           uniform[count].info = mapping->info;
diff --git a/gsk/gl/gskglglyphylibrary.c b/gsk/gl/gskglglyphylibrary.c
index b6e039060b..9305d7a935 100644
--- a/gsk/gl/gskglglyphylibrary.c
+++ b/gsk/gl/gskglglyphylibrary.c
@@ -32,8 +32,6 @@
 
 #define TOLERANCE (1/2048.)
 #define MIN_FONT_SIZE 10
-#define ITEM_W 64
-#define ITEM_H_QUANTUM 8
 
 G_DEFINE_TYPE (GskGLGlyphyLibrary, gsk_gl_glyphy_library, GSK_TYPE_GL_TEXTURE_LIBRARY)
 
@@ -136,6 +134,8 @@ gsk_gl_glyphy_library_init (GskGLGlyphyLibrary *self)
 
   self->acc = glyphy_arc_accumulator_create ();
   self->acc_endpoints = g_array_new (FALSE, FALSE, sizeof (glyphy_arc_endpoint_t));
+  self->item_w = 64;
+  self->item_h_q = 8;
 }
 
 static glyphy_bool_t
@@ -234,7 +234,7 @@ gsk_gl_glyphy_library_add (GskGLGlyphyLibrary      *self,
     return FALSE;
 
   /* Allocate space for list within atlas */
-  width = ITEM_W;
+  width = self->item_w;
   height = (output_len + width - 1) / width;
   value = gsk_gl_texture_library_pack (tl, key, sizeof *value,
                                        width, height, 0,
@@ -283,8 +283,8 @@ gsk_gl_glyphy_library_add (GskGLGlyphyLibrary      *self,
   value->extents = extents;
   value->nominal_w = nominal_w;
   value->nominal_h = nominal_h;
-  value->atlas_x = packed_x / ITEM_W;
-  value->atlas_y = packed_y / ITEM_H_QUANTUM;
+  value->atlas_x = packed_x / self->item_w;
+  value->atlas_y = packed_y / self->item_h_q;
 
   *out_value = value;
 
diff --git a/gsk/gl/gskglglyphylibraryprivate.h b/gsk/gl/gskglglyphylibraryprivate.h
index 800c1fb0d9..3d2a817768 100644
--- a/gsk/gl/gskglglyphylibraryprivate.h
+++ b/gsk/gl/gskglglyphylibraryprivate.h
@@ -55,6 +55,8 @@ struct _GskGLGlyphyLibrary
   GskGLTextureLibrary parent_instance;
   glyphy_arc_accumulator_t *acc;
   GArray *acc_endpoints;
+  guint item_w;
+  guint item_h_q;
   struct {
     GskGLGlyphyKey key;
     const GskGLGlyphyValue *value;
diff --git a/gsk/gl/gskglprograms.defs b/gsk/gl/gskglprograms.defs
index f0e3e84760..a0a1cc26d9 100644
--- a/gsk/gl/gskglprograms.defs
+++ b/gsk/gl/gskglprograms.defs
@@ -94,4 +94,10 @@ GSK_GL_DEFINE_PROGRAM (glyphy,
                                              GSK_GL_SHADER_STRING (glyphy_sdf_shader_source ()),
                                              GSK_GL_SHADER_RESOURCE ("glyphy.fs.glsl"),
                                              NULL),
-                       GSK_GL_NO_UNIFORMS)
+                       GSK_GL_ADD_UNIFORM (0, GLYPHY_CONTRAST, u_contrast)
+                       GSK_GL_ADD_UNIFORM (1, GLYPHY_GAMMA_ADJUST, u_gamma_adjust)
+                       GSK_GL_ADD_UNIFORM (2, GLYPHY_OUTLINE_THICKNESS, u_outline_thickness)
+                       GSK_GL_ADD_UNIFORM (3, GLYPHY_OUTLINE, u_outline)
+                       GSK_GL_ADD_UNIFORM (4, GLYPHY_BOLDNESS, u_boldness)
+                       GSK_GL_ADD_UNIFORM (5, GLYPHY_DEBUG, u_debug)
+                       GSK_GL_ADD_UNIFORM (6, GLYPHY_ATLAS_INFO, u_atlas_info))
diff --git a/gsk/gl/gskglrenderjob.c b/gsk/gl/gskglrenderjob.c
index cff4327f45..13168907f2 100644
--- a/gsk/gl/gskglrenderjob.c
+++ b/gsk/gl/gskglrenderjob.c
@@ -3123,6 +3123,61 @@ gsk_gl_render_job_visit_text_node_legacy (GskGLRenderJob      *job,
   gsk_gl_render_job_end_draw (job);
 }
 
+typedef struct
+{
+  float x;
+  float y;
+  float g16hi;
+  float g16lo;
+} EncodedGlyph;
+
+static unsigned int
+glyph_encode (guint atlas_x ,  /* 7 bits */
+              guint atlas_y,   /* 7 bits */
+              guint corner_x,  /* 1 bit */
+              guint corner_y,  /* 1 bit */
+              guint nominal_w, /* 6 bits */
+              guint nominal_h) /* 6 bits */
+{
+  guint x, y;
+
+  g_assert (0 == (atlas_x & ~0x7F));
+  g_assert (0 == (atlas_y & ~0x7F));
+  g_assert (0 == (corner_x & ~1));
+  g_assert (0 == (corner_y & ~1));
+  g_assert (0 == (nominal_w & ~0x3F));
+  g_assert (0 == (nominal_h & ~0x3F));
+
+  x = (((atlas_x << 6) | nominal_w) << 1) | corner_x;
+  y = (((atlas_y << 6) | nominal_h) << 1) | corner_y;
+
+  return (x << 16) | y;
+}
+
+static void
+encoded_glyph_init (EncodedGlyph           *eg,
+                    float                   x,
+                    float                   y,
+                    guint                   corner_x,
+                    guint                   corner_y,
+                    const GskGLGlyphyValue *gi)
+{
+  guint encoded = glyph_encode (gi->atlas_x, gi->atlas_y, corner_x, corner_y, gi->nominal_w, gi->nominal_h);
+
+  eg->x = x;
+  eg->y = y;
+  eg->g16hi = encoded >> 16;
+  eg->g16lo = encoded & 0xFFFF;
+}
+
+static inline void
+add_encoded_glyph (GskGLDrawVertex    *vertices,
+                   const EncodedGlyph *eg,
+                   const guint16       c[4])
+{
+  *vertices = (GskGLDrawVertex) { .position = { eg->x, eg->y}, .uv = { eg->g16hi, eg->g16lo}, .color = { 
c[0], c[1], c[2], c[3] } };
+}
+
 static inline void
 gsk_gl_render_job_visit_text_node_glyphy (GskGLRenderJob      *job,
                                           const GskRenderNode *node,
@@ -3136,19 +3191,26 @@ gsk_gl_render_job_visit_text_node_glyphy (GskGLRenderJob      *job,
   GskGLCommandBatch *batch;
   const PangoFont *font;
   GskGLDrawVertex *vertices;
+  const guint16 *c;
   GskGLGlyphyKey lookup;
+  guint16 nc[4] = { FP16_MINUS_ONE, FP16_MINUS_ONE, FP16_MINUS_ONE, FP16_MINUS_ONE };
+  guint16 cc[4];
   float x;
   float y;
   guint last_texture = 0;
   guint num_glyphs;
   guint used = 0;
   guint i;
+  int x_position = 0;
 
   g_assert (!gsk_text_node_has_color_glyphs (node));
 
   if (!(num_glyphs = gsk_text_node_get_num_glyphs (node)))
     return;
 
+  if (RGBA_IS_CLEAR (color))
+    return;
+
   font = gsk_text_node_get_font (node);
   glyphs = gsk_text_node_get_glyphs (node, NULL);
   library = job->driver->glyphy_library;
@@ -3156,7 +3218,14 @@ gsk_gl_render_job_visit_text_node_glyphy (GskGLRenderJob      *job,
   x = offset->x + job->offset_x;
   y = offset->y + job->offset_y;
 
-  gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, coloring));
+  rgba_to_half (color, cc);
+
+  if (!force_color)
+    c = nc;
+  else
+    c = cc;
+
+  gsk_gl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, glyphy));
 
   batch = gsk_gl_command_queue_get_batch (job->command_queue);
   vertices = gsk_gl_command_queue_add_n_vertices (job->command_queue, num_glyphs);
@@ -3166,18 +3235,80 @@ gsk_gl_render_job_visit_text_node_glyphy (GskGLRenderJob      *job,
   for (i = 0, gi = glyphs; i < num_glyphs; i++, gi++)
     {
       const GskGLGlyphyValue *glyph;
-      float glyph_x, glyph_y, glyph_x2, glyph_y2;
-      float tx, ty, tx2, ty2;
-      float cx;
-      float cy;
+      float cx = 0, cy = 0;
       guint texture_id;
 
       lookup.glyph = gi->glyph;
-
       texture_id = gsk_gl_glyphy_library_lookup_or_add (library, &lookup, &glyph);
       if G_UNLIKELY (texture_id == 0)
         continue;
 
+      if G_UNLIKELY (last_texture != texture_id || batch->draw.vbo_count + GSK_GL_N_VERTICES > 0xffff)
+        {
+          if G_LIKELY (last_texture != 0)
+            {
+              guint vbo_offset = batch->draw.vbo_offset + batch->draw.vbo_count;
+
+              /* Since we have batched added our VBO vertices to avoid repeated
+               * calls to the buffer, we need to manually tweak the vbo offset
+               * of the new batch as otherwise it will point at the end of our
+               * vbo array.
+               */
+              gsk_gl_render_job_split_draw (job);
+              batch = gsk_gl_command_queue_get_batch (job->command_queue);
+              batch->draw.vbo_offset = vbo_offset;
+            }
+
+          gsk_gl_program_set_uniform4i (job->current_program,
+                                        UNIFORM_GLYPHY_ATLAS_INFO, 0,
+                                        GSK_GL_TEXTURE_LIBRARY (library)->atlas_width,
+                                        GSK_GL_TEXTURE_LIBRARY (library)->atlas_height,
+                                        library->item_w,
+                                        library->item_h_q);
+          gsk_gl_program_set_uniform_texture (job->current_program,
+                                              UNIFORM_SHARED_SOURCE, 0,
+                                              GL_TEXTURE_2D,
+                                              GL_TEXTURE0,
+                                              texture_id);
+          gsk_gl_program_set_uniform1f (job->current_program,
+                                        UNIFORM_GLYPHY_GAMMA_ADJUST, 0,
+                                        1.0);
+          gsk_gl_program_set_uniform1f (job->current_program,
+                                        UNIFORM_GLYPHY_CONTRAST, 0,
+                                        1.0);
+
+          last_texture = texture_id;
+        }
+
+      cx = (float)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
+      if G_UNLIKELY (gi->geometry.y_offset != 0)
+        cy = (float)(gi->geometry.y_offset) / PANGO_SCALE;
+
+      x_position += gi->geometry.width;
+
+      EncodedGlyph encoded[4];
+#define ENCODE_CORNER(_cx, _cy) \
+  G_STMT_START { \
+    float _vx = x + cx + ((1-_cx) * glyph->extents.min_x + _cx * glyph->extents.max_x); \
+    float _vy = y + cy - ((1-_cy) * glyph->extents.min_y + _cy * glyph->extents.max_y); \
+    encoded_glyph_init (&encoded[_cx * 2 + _cy], _vx, _vy, _cx, _cy, glyph); \
+  } G_STMT_END
+      ENCODE_CORNER (0, 0);
+      ENCODE_CORNER (0, 1);
+      ENCODE_CORNER (1, 0);
+      ENCODE_CORNER (1, 1);
+#undef ENCODE_CORNER
+
+      add_encoded_glyph (vertices++, &encoded[0], c);
+      add_encoded_glyph (vertices++, &encoded[1], c);
+      add_encoded_glyph (vertices++, &encoded[2], c);
+
+      add_encoded_glyph (vertices++, &encoded[1], c);
+      add_encoded_glyph (vertices++, &encoded[2], c);
+      add_encoded_glyph (vertices++, &encoded[3], c);
+
+      batch->draw.vbo_count += GSK_GL_N_VERTICES;
+      used++;
     }
 
   if (used != num_glyphs)
diff --git a/gsk/gl/gskgluniformstateprivate.h b/gsk/gl/gskgluniformstateprivate.h
index af5c82ab07..a823c439f8 100644
--- a/gsk/gl/gskgluniformstateprivate.h
+++ b/gsk/gl/gskgluniformstateprivate.h
@@ -244,7 +244,7 @@ gsk_gl_uniform_state_set1f (GskGLUniformState   *state,
     {
       if (info->info.initial || u->v0 != value0)
         {
-          GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform1f , 1);
+          GSK_GL_UNIFORM_STATE_REPLACE (info, u, Uniform1f, 1);
           u->v0 = value0;
           gsk_gl_uniform_info_changed (info, stamp);
         }
diff --git a/gsk/gl/resources/glyphy.atlas.glsl b/gsk/gl/resources/glyphy.atlas.glsl
index ec6bc1af7b..af5910e46c 100644
--- a/gsk/gl/resources/glyphy.atlas.glsl
+++ b/gsk/gl/resources/glyphy.atlas.glsl
@@ -1,9 +1,8 @@
-uniform sampler2D u_atlas_tex;
 uniform ivec4 u_atlas_info;
 
 #define GLYPHY_TEXTURE1D_EXTRA_DECLS , sampler2D _tex, ivec4 _atlas_info, ivec2 _atlas_pos
 #define GLYPHY_TEXTURE1D_EXTRA_ARGS , _tex, _atlas_info, _atlas_pos
-#define GLYPHY_DEMO_EXTRA_ARGS , u_atlas_tex, u_atlas_info, gi.atlas_pos
+#define GLYPHY_DEMO_EXTRA_ARGS , u_source, u_atlas_info, gi.atlas_pos
 
 vec4
 glyphy_texture1D_func (int offset GLYPHY_TEXTURE1D_EXTRA_DECLS)
@@ -12,5 +11,5 @@ glyphy_texture1D_func (int offset GLYPHY_TEXTURE1D_EXTRA_DECLS)
   vec2 pos = (vec2 (_atlas_pos.xy * item_geom +
                   ivec2 (mod (float (offset), float (item_geom.x)), offset / item_geom.x)) +
              + vec2 (.5, .5)) / vec2(_atlas_info.xy);
-  return texture2D (_tex, pos);
+  return GskTexture (_tex, pos);
 }
diff --git a/gsk/gl/resources/glyphy.fs.glsl b/gsk/gl/resources/glyphy.fs.glsl
index 0ea4cdf495..9ceb999ee9 100644
--- a/gsk/gl/resources/glyphy.fs.glsl
+++ b/gsk/gl/resources/glyphy.fs.glsl
@@ -8,8 +8,8 @@ uniform bool  u_outline;
 uniform float u_boldness;
 uniform bool  u_debug;
 
-varying vec4 v_glyph;
-
+_IN_ vec4 v_glyph;
+_IN_ vec4 final_color;
 
 #define SQRT2_2 0.70710678118654757 /* 1 / sqrt(2.) */
 #define SQRT2   1.4142135623730951
@@ -46,7 +46,7 @@ main()
   vec2 dpdy = dFdy (p);
   float m = length (vec2 (length (dpdx), length (dpdy))) * SQRT2_2;
 
-  vec4 color = vec4 (0,0,0,1);
+  vec4 color = vec4(0,0,0,1);
 
   float gsdist = glyphy_sdf (p, gi.nominal_size GLYPHY_DEMO_EXTRA_ARGS);
   float sdist = gsdist / m * u_contrast;
@@ -84,5 +84,5 @@ main()
     color += vec4 (0,0,1,.1) * float(arc_list.num_endpoints) * 32./255.;
   }
 
-  gl_FragColor = color;
+  gskSetOutputColor(color);
 }
diff --git a/gsk/gl/resources/glyphy.vs.glsl b/gsk/gl/resources/glyphy.vs.glsl
index 38521b3b47..c99d61c647 100644
--- a/gsk/gl/resources/glyphy.vs.glsl
+++ b/gsk/gl/resources/glyphy.vs.glsl
@@ -1,11 +1,8 @@
 // VERTEX_SHADER:
 // glyphy.vs.glsl
 
-uniform mat4 u_matViewProjection;
-
-attribute vec4 a_glyph_vertex;
-
-varying vec4 v_glyph;
+_OUT_ vec4 v_glyph;
+_OUT_ vec4 final_color;
 
 vec4
 glyph_vertex_transcode (vec2 v)
@@ -20,6 +17,8 @@ glyph_vertex_transcode (vec2 v)
 void
 main()
 {
-  gl_Position = u_matViewProjection * vec4 (a_glyph_vertex.xy, 0, 1);
-  v_glyph = glyph_vertex_transcode (a_glyph_vertex.zw);
+  v_glyph = glyph_vertex_transcode(aUv);
+  vUv = v_glyph.xy;
+  gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+  final_color = gsk_scaled_premultiply(aColor, u_alpha);
 }


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