summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2021-03-12 01:27:19 -0500
committerMatthias Clasen <mclasen@redhat.com>2021-03-12 13:19:37 -0500
commit6a30c6b01c82edfbfd812bacd33a6ace8d363f75 (patch)
tree23166913cdd55df17c94c0d3fe4038beec51bfc3
parent06d5c8e72dee3d63391fc05ebf081c6f63ed3ce6 (diff)
downloadgtk+-6a30c6b01c82edfbfd812bacd33a6ace8d363f75.tar.gz
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.
-rw-r--r--gsk/ngl/gsknglrenderjob.c59
-rw-r--r--gsk/ngl/resources/coloring.glsl15
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);
}