[gtk/ngl-vertex-attributes: 6/8] ngl: Make the coloring shader more versatile




commit 6a30c6b01c82edfbfd812bacd33a6ace8d363f75
Author: Matthias Clasen <mclasen redhat com>
Date:   Fri Mar 12 01:27:19 2021 -0500

    ngl: Make the coloring shader more versatile
    
    When the color passed is transparent black, use
    the color from the texture as source, instead of
    as mask. This lets use use the coloring program
    both for regular and color glyphs, avoiding
    program changes in text with Emoji.

 gsk/ngl/gsknglrenderjob.c       | 59 ++++++++++++++++++++++-------------------
 gsk/ngl/resources/coloring.glsl | 15 ++++++++++-
 2 files changed, 46 insertions(+), 28 deletions(-)
---
diff --git a/gsk/ngl/gsknglrenderjob.c b/gsk/ngl/gsknglrenderjob.c
index 14e3b3e42b..8f67575564 100644
--- a/gsk/ngl/gsknglrenderjob.c
+++ b/gsk/ngl/gsknglrenderjob.c
@@ -2703,15 +2703,20 @@ gsk_ngl_render_job_visit_text_node (GskNglRenderJob     *job,
   guint last_texture = 0;
   GskNglDrawVertex *vertices;
   guint used = 0;
+  GdkRGBA c;
 
   if (num_glyphs == 0)
     return;
 
-  /* If the font has color glyphs, we don't need to recolor anything */
+  program = CHOOSE_PROGRAM (job, coloring);
+
+  /* If the font has color glyphs, we don't need to recolor anything.
+   * We tell the shader by setting the color to vec4(-1).
+   */
   if (!force_color && gsk_text_node_has_color_glyphs (node))
-    program = CHOOSE_PROGRAM (job, blit);
+    c = (GdkRGBA) { -1.f, -1.f, -1.f, -1.f };
   else
-    program = CHOOSE_PROGRAM (job, coloring);
+    c = *color;
 
   lookup.font = (PangoFont *)font;
   lookup.scale = (guint) (text_scale * 1024);
@@ -2786,55 +2791,55 @@ gsk_ngl_render_job_visit_text_node (GskNglRenderJob     *job,
       vertices[base+0].position[1] = glyph_y;
       vertices[base+0].uv[0] = tx;
       vertices[base+0].uv[1] = ty;
-      vertices[base+0].color[0] = color->red;
-      vertices[base+0].color[1] = color->green;
-      vertices[base+0].color[2] = color->blue;
-      vertices[base+0].color[3] = color->alpha;
+      vertices[base+0].color[0] = c.red;
+      vertices[base+0].color[1] = c.green;
+      vertices[base+0].color[2] = c.blue;
+      vertices[base+0].color[3] = c.alpha;
 
       vertices[base+1].position[0] = glyph_x;
       vertices[base+1].position[1] = glyph_y2;
       vertices[base+1].uv[0] = tx;
       vertices[base+1].uv[1] = ty2;
-      vertices[base+1].color[0] = color->red;
-      vertices[base+1].color[1] = color->green;
-      vertices[base+1].color[2] = color->blue;
-      vertices[base+1].color[3] = color->alpha;
+      vertices[base+1].color[0] = c.red;
+      vertices[base+1].color[1] = c.green;
+      vertices[base+1].color[2] = c.blue;
+      vertices[base+1].color[3] = c.alpha;
 
       vertices[base+2].position[0] = glyph_x2;
       vertices[base+2].position[1] = glyph_y;
       vertices[base+2].uv[0] = tx2;
       vertices[base+2].uv[1] = ty;
-      vertices[base+2].color[0] = color->red;
-      vertices[base+2].color[1] = color->green;
-      vertices[base+2].color[2] = color->blue;
-      vertices[base+2].color[3] = color->alpha;
+      vertices[base+2].color[0] = c.red;
+      vertices[base+2].color[1] = c.green;
+      vertices[base+2].color[2] = c.blue;
+      vertices[base+2].color[3] = c.alpha;
 
       vertices[base+3].position[0] = glyph_x2;
       vertices[base+3].position[1] = glyph_y2;
       vertices[base+3].uv[0] = tx2;
       vertices[base+3].uv[1] = ty2;
-      vertices[base+3].color[0] = color->red;
-      vertices[base+3].color[1] = color->green;
-      vertices[base+3].color[2] = color->blue;
-      vertices[base+3].color[3] = color->alpha;
+      vertices[base+3].color[0] = c.red;
+      vertices[base+3].color[1] = c.green;
+      vertices[base+3].color[2] = c.blue;
+      vertices[base+3].color[3] = c.alpha;
 
       vertices[base+4].position[0] = glyph_x;
       vertices[base+4].position[1] = glyph_y2;
       vertices[base+4].uv[0] = tx;
       vertices[base+4].uv[1] = ty2;
-      vertices[base+4].color[0] = color->red;
-      vertices[base+4].color[1] = color->green;
-      vertices[base+4].color[2] = color->blue;
-      vertices[base+4].color[3] = color->alpha;
+      vertices[base+4].color[0] = c.red;
+      vertices[base+4].color[1] = c.green;
+      vertices[base+4].color[2] = c.blue;
+      vertices[base+4].color[3] = c.alpha;
 
       vertices[base+5].position[0] = glyph_x2;
       vertices[base+5].position[1] = glyph_y;
       vertices[base+5].uv[0] = tx2;
       vertices[base+5].uv[1] = ty;
-      vertices[base+5].color[0] = color->red;
-      vertices[base+5].color[1] = color->green;
-      vertices[base+5].color[2] = color->blue;
-      vertices[base+5].color[3] = color->alpha;
+      vertices[base+5].color[0] = c.red;
+      vertices[base+5].color[1] = c.green;
+      vertices[base+5].color[2] = c.blue;
+      vertices[base+5].color[3] = c.alpha;
 
       batch->draw.vbo_count += GSK_NGL_N_VERTICES;
       used++;
diff --git a/gsk/ngl/resources/coloring.glsl b/gsk/ngl/resources/coloring.glsl
index b6af0c1766..d7d2aed7d6 100644
--- a/gsk/ngl/resources/coloring.glsl
+++ b/gsk/ngl/resources/coloring.glsl
@@ -1,20 +1,33 @@
 // VERTEX_SHADER:
 _OUT_ vec4 final_color;
+flat _OUT_ int use_color;
 
 void main() {
   gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
 
   vUv = vec2(aUv.x, aUv.y);
 
+  // We use this shader for both plain glyphs (used as mask)
+  // and color glpyhs (used as source). The renderer sets
+  // aColor to vec4(-1) for color glyhs.
+  if (distance(aColor, vec4(-1)) < 0.001)
+    use_color = 0;
+  else
+    use_color = 1;
+
   final_color = gsk_premultiply(aColor) * u_alpha;
 }
 
 // FRAGMENT_SHADER:
 
 _IN_ vec4 final_color;
+flat _IN_ int use_color;
 
 void main() {
   vec4 diffuse = GskTexture(u_source, vUv);
 
-  gskSetOutputColor(final_color * diffuse.a);
+  if (use_color == 1)
+    gskSetOutputColor(final_color * diffuse.a);
+  else
+    gskSetOutputColor(diffuse * u_alpha);
 }


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