[gtk/wip/chergert/glyphy] wip
- From: Christian Hergert <chergert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/chergert/glyphy] wip
- Date: Thu, 17 Mar 2022 08:48:07 +0000 (UTC)
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]