[gtk/ngl-coloring-underlines] ngl: Optimize underlines in text




commit de27150dbede602eb88e85c9f2d34b10500767ea
Author: Matthias Clasen <mclasen redhat com>
Date:   Thu Apr 8 23:11:06 2021 -0400

    ngl: Optimize underlines in text
    
    Opportunistically use the coloring program for
    drawing underlines instead of the color program.
    This avoids program changes in the middle of
    text.
    
    For the Emoji text scrolling benchmark, this reduces
    the program changes per frame from > 1000 to around 100.

 gsk/ngl/gsknglrenderjob.c | 47 ++++++++++++++++++++++++++++++++++++++++++-----
 1 file changed, 42 insertions(+), 5 deletions(-)
---
diff --git a/gsk/ngl/gsknglrenderjob.c b/gsk/ngl/gsknglrenderjob.c
index 3e823dedab..698c8c3b7a 100644
--- a/gsk/ngl/gsknglrenderjob.c
+++ b/gsk/ngl/gsknglrenderjob.c
@@ -1349,15 +1349,52 @@ blur_node (GskNglRenderJob       *job,
   *max_y = job->offset_y + node->bounds.origin.y + node->bounds.size.height + half_blur_extra;
 }
 
+#define ATLAS_SIZE 512
+
 static inline void
 gsk_ngl_render_job_visit_color_node (GskNglRenderJob     *job,
                                      const GskRenderNode *node)
 {
-  gsk_ngl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, color));
-  gsk_ngl_render_job_draw_rect_with_color (job,
-                                           &node->bounds,
-                                           gsk_color_node_get_color (node));
-  gsk_ngl_render_job_end_draw (job);
+  GskNglCommandBatch *batch;
+  GskNglProgram *program = CHOOSE_PROGRAM (job, coloring);
+
+  batch = gsk_ngl_command_queue_get_batch (job->command_queue);
+
+  /* Avoid switching away from the coloring program for
+   * rendering a solid color.
+   */
+  if (batch->any.kind == GSK_NGL_COMMAND_KIND_DRAW &&
+      batch->any.program == program->id)
+    {
+      GskNglRenderOffscreen offscreen = {0};
+
+      gsk_ngl_render_job_begin_draw (job, program);
+
+      /* The pixel at 1,1 in our atlases is always
+       * solid white, so we can use it here, without
+       * having to choose any particular atlas texture.
+       */
+      offscreen.was_offscreen = FALSE;
+      offscreen.area.x = 1.f / ATLAS_SIZE;
+      offscreen.area.y = 1.f / ATLAS_SIZE;
+      offscreen.area.x2 = 2.f / ATLAS_SIZE;
+      offscreen.area.y2 = 2.f / ATLAS_SIZE;
+
+      gsk_ngl_render_job_draw_offscreen_with_color (job,
+                                                    &node->bounds,
+                                                    &offscreen,
+                                                    gsk_color_node_get_color (node));
+
+      gsk_ngl_render_job_end_draw (job);
+    }
+  else
+    {
+      gsk_ngl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, color));
+      gsk_ngl_render_job_draw_rect_with_color (job,
+                                               &node->bounds,
+                                               gsk_color_node_get_color (node));
+      gsk_ngl_render_job_end_draw (job);
+    }
 }
 
 static inline void


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