[gtk/ngl-text-tweaks: 12/15] ngl: Speed up glyph loop




commit 6de17b4b65bfbc2ffbe419acc4053bd84faa0856
Author: Matthias Clasen <mclasen redhat com>
Date:   Sun Mar 28 20:20:50 2021 -0400

    ngl: Speed up glyph loop
    
    Move some work out of the loop in visit_text_node.
    This takes advantage of the fact that the yoffset
    of most glyphs is zero, so yphase generally does
    not change in a line of text.

 gsk/ngl/gsknglglyphlibraryprivate.h | 21 ++-------------
 gsk/ngl/gsknglrenderjob.c           | 54 ++++++++++++++++++++++++++++++-------
 2 files changed, 47 insertions(+), 28 deletions(-)
---
diff --git a/gsk/ngl/gsknglglyphlibraryprivate.h b/gsk/ngl/gsknglglyphlibraryprivate.h
index 5bf240e5e1..780054eb63 100644
--- a/gsk/ngl/gsknglglyphlibraryprivate.h
+++ b/gsk/ngl/gsknglglyphlibraryprivate.h
@@ -68,24 +68,7 @@ gboolean            gsk_ngl_glyph_library_add (GskNglGlyphLibrary      *self,
                                                GskNglGlyphKey          *key,
                                                const GskNglGlyphValue **out_value);
 
-static inline int
-gsk_ngl_glyph_key_phase (float value)
-{
-  return floorf (4 * (value + 0.125)) - 4 * floorf (value + 0.125);
-}
-
-static inline void
-gsk_ngl_glyph_key_set_glyph_and_shift (GskNglGlyphKey *key,
-                                       PangoGlyph      glyph,
-                                       float           x,
-                                       float           y)
-{
-  key->glyph = glyph;
-  key->xshift = gsk_ngl_glyph_key_phase (x);
-  key->yshift = gsk_ngl_glyph_key_phase (y);
-}
-
-static inline gboolean
+static inline guint
 gsk_ngl_glyph_library_lookup_or_add (GskNglGlyphLibrary      *self,
                                      const GskNglGlyphKey    *key,
                                      const GskNglGlyphValue **out_value)
@@ -112,7 +95,7 @@ gsk_ngl_glyph_library_lookup_or_add (GskNglGlyphLibrary      *self,
       self->front[front_index].value = *out_value;
     }
 
-  return GSK_NGL_TEXTURE_ATLAS_ENTRY_TEXTURE (*out_value) != 0;
+  return GSK_NGL_TEXTURE_ATLAS_ENTRY_TEXTURE (*out_value);
 }
 
 G_END_DECLS
diff --git a/gsk/ngl/gsknglrenderjob.c b/gsk/ngl/gsknglrenderjob.c
index 324b3d29f4..b45f33b7a8 100644
--- a/gsk/ngl/gsknglrenderjob.c
+++ b/gsk/ngl/gsknglrenderjob.c
@@ -2639,6 +2639,30 @@ gsk_ngl_render_job_visit_opacity_node (GskNglRenderJob     *job,
     }
 }
 
+static inline int
+compute_phase_and_pos (float value, float *pos)
+{
+  float v;
+
+  *pos = floorf (value);
+
+  v = value - *pos;
+
+  if (v < 0.125)
+    return 0;
+  else if (v < 0.375)
+    return 1;
+  else if (v < 0.625)
+    return 2;
+  else if (v < 0.875)
+    return 3;
+  else
+    {
+      *pos += 1;
+      return 0;
+    }
+}
+
 static inline void
 gsk_ngl_render_job_visit_text_node (GskNglRenderJob     *job,
                                     const GskRenderNode *node,
@@ -2662,6 +2686,8 @@ gsk_ngl_render_job_visit_text_node (GskNglRenderJob     *job,
   GdkRGBA c;
   const PangoGlyphInfo *gi;
   guint i;
+  int yshift;
+  float ypos;
 
   if (num_glyphs == 0)
     return;
@@ -2677,6 +2703,8 @@ gsk_ngl_render_job_visit_text_node (GskNglRenderJob     *job,
   lookup.font = (PangoFont *)font;
   lookup.scale = (guint) (text_scale * 1024);
 
+  yshift = compute_phase_and_pos (y, &ypos);
+
   gsk_ngl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, coloring));
 
   batch = gsk_ngl_command_queue_get_batch (job->command_queue);
@@ -2695,20 +2723,28 @@ gsk_ngl_render_job_visit_text_node (GskNglRenderJob     *job,
       if G_UNLIKELY (gi->glyph == PANGO_GLYPH_EMPTY)
         continue;
 
+      lookup.glyph = gi->glyph;
+
       cx = (float)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
-      cy = (float)(gi->geometry.y_offset) / PANGO_SCALE;
+      lookup.xshift = compute_phase_and_pos (x + cx, &cx);
 
-      gsk_ngl_glyph_key_set_glyph_and_shift (&lookup, gi->glyph, x + cx, y + cy);
+      if G_UNLIKELY (gi->geometry.y_offset != 0)
+        {
+          cy = (float)(gi->geometry.y_offset) / PANGO_SCALE;
+          lookup.yshift = compute_phase_and_pos (y + cy, &cy);
+        }
+      else
+        {
+          lookup.yshift = yshift;
+          cy = ypos;
+        }
 
-      if G_UNLIKELY (!gsk_ngl_glyph_library_lookup_or_add (library, &lookup, &glyph))
+      texture_id = gsk_ngl_glyph_library_lookup_or_add (library, &lookup, &glyph);
+      if G_UNLIKELY (texture_id == 0)
         goto next;
 
-      texture_id = GSK_NGL_TEXTURE_ATLAS_ENTRY_TEXTURE (glyph);
-
       if G_UNLIKELY (last_texture != texture_id)
         {
-          g_assert (texture_id > 0);
-
           if G_LIKELY (last_texture != 0)
             {
               guint vbo_offset = batch->draw.vbo_offset + batch->draw.vbo_count;
@@ -2736,8 +2772,8 @@ gsk_ngl_render_job_visit_text_node (GskNglRenderJob     *job,
       tx2 = glyph->entry.area.x2;
       ty2 = glyph->entry.area.y2;
 
-      glyph_x = floorf (x + cx + 0.125) + glyph->ink_rect.x;
-      glyph_y = floorf (y + cy + 0.125) + glyph->ink_rect.y;
+      glyph_x = cx + glyph->ink_rect.x;
+      glyph_y = cy + glyph->ink_rect.y;
       glyph_x2 = glyph_x + glyph->ink_rect.width;
       glyph_y2 = glyph_y + glyph->ink_rect.height;
 


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