[gtk+/wip/baedert/gl: 48/111] gl renderer: Optimize text drawing
- From: Timm Bäder <baedert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk+/wip/baedert/gl: 48/111] gl renderer: Optimize text drawing
- Date: Thu, 21 Dec 2017 17:33:11 +0000 (UTC)
commit c9d79f9bc3ef6579f23b821ddb23f21a6bc52f7e
Author: Timm Bäder <mail baedert org>
Date: Thu Nov 23 19:49:41 2017 +0100
gl renderer: Optimize text drawing
Text nodes will almost always end up using the exact same texture and
the same program. So, in that case we can simply add vertex data for all
the characters we need to draw and use just one draw call.
gsk/gl/gskglrenderer.c | 40 +++++++++++++++++++---------------
gsk/gl/gskglrenderops.c | 46 ++++++++++++++++++++++++++++++++-------
gsk/gl/gskglrenderopsprivate.h | 5 +++-
3 files changed, 63 insertions(+), 28 deletions(-)
---
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index 880c108..c153219 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -328,6 +328,7 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self,
goto out;
}
self->coloring_program.index = 3;
+ self->coloring_program.name = "coloring";
init_common_locations (self, builder, &self->coloring_program);
INIT_PROGRAM_UNIFORM_LOCATION (coloring_program, color_location, "uColor");
@@ -342,6 +343,7 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self,
goto out;
}
self->color_matrix_program.index = 4;
+ self->color_matrix_program.name = "color matrix";
init_common_locations (self, builder, &self->color_matrix_program);
INIT_PROGRAM_UNIFORM_LOCATION (color_matrix_program, color_matrix_location, "uColorMatrix");
INIT_PROGRAM_UNIFORM_LOCATION (color_matrix_program, color_offset_location, "uColorOffset");
@@ -357,6 +359,7 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self,
goto out;
}
self->linear_gradient_program.index = 5;
+ self->linear_gradient_program.name = "linear gradient";
init_common_locations (self, builder, &self->linear_gradient_program);
INIT_PROGRAM_UNIFORM_LOCATION (linear_gradient_program, color_stops_location, "uColorStops");
INIT_PROGRAM_UNIFORM_LOCATION (linear_gradient_program, color_offsets_location, "uColorOffsets");
@@ -858,6 +861,22 @@ gsk_gl_renderer_add_render_ops (GskGLRenderer *self,
int x = gsk_text_node_get_x (node);
int y = gsk_text_node_get_y (node);
+ /* If the font has color glyphs, we don't need to recolor anything */
+ if (has_color_glyphs)
+ {
+ ops_set_program (builder, &self->blit_program);
+ }
+ else
+ {
+ RenderOp op;
+
+ ops_set_program (builder, &self->coloring_program);
+
+ op.op = OP_CHANGE_COLOR;
+ op.color = *gsk_text_node_peek_color (node);
+ ops_add (builder, &op);
+ }
+
/* We use one quad per character, unlike the other nodes which
* use at most one quad altogether */
for (i = 0; i < num_glyphs; i++)
@@ -888,22 +907,6 @@ gsk_gl_renderer_add_render_ops (GskGLRenderer *self,
cx = (double)(x_position + gi->geometry.x_offset) / PANGO_SCALE;
cy = (double)(gi->geometry.y_offset) / PANGO_SCALE;
- /* If the font has color glyphs, we don't need to recolor anything */
- if (has_color_glyphs)
- {
- ops_set_program (builder, &self->blit_program);
- }
- else
- {
- RenderOp op;
-
- ops_set_program (builder, &self->coloring_program);
-
- op.op = OP_CHANGE_COLOR;
- op.color = *gsk_text_node_peek_color (node);
- ops_add (builder, &op);
- }
-
ops_set_texture (builder, gsk_gl_glyph_cache_get_glyph_image (&self->glyph_cache,
glyph)->texture_id);
@@ -1156,8 +1159,9 @@ gsk_gl_renderer_render_ops (GskGLRenderer *self,
break;
case OP_DRAW:
- OP_PRINT (" -> draw %ld and program %s\n", op->vao_offset, program->name);
- glDrawArrays (GL_TRIANGLES, op->vao_offset, GL_N_VERTICES);
+ OP_PRINT (" -> draw %ld, size %ld and program %s\n",
+ op->draw.vao_offset, op->draw.draw_size, program->name);
+ glDrawArrays (GL_TRIANGLES, op->draw.vao_offset, op->draw.draw_size);//GL_N_VERTICES);
break;
default:
diff --git a/gsk/gl/gskglrenderops.c b/gsk/gl/gskglrenderops.c
index a1621c6..6bc9e82 100644
--- a/gsk/gl/gskglrenderops.c
+++ b/gsk/gl/gskglrenderops.c
@@ -223,17 +223,45 @@ void
ops_draw (RenderOpBuilder *builder,
const GskQuadVertex vertex_data[GL_N_VERTICES])
{
- RenderOp op;
- gsize offset = builder->buffer_size / sizeof (GskQuadVertex);
+ RenderOp *last_op;
- op.op = OP_CHANGE_VAO;
- memcpy (&op.vertex_data, vertex_data, sizeof(GskQuadVertex) * GL_N_VERTICES);
- g_array_append_val (builder->render_ops, op);
- builder->buffer_size += sizeof (GskQuadVertex) * GL_N_VERTICES;
+ last_op = &g_array_index (builder->render_ops, RenderOp, builder->render_ops->len - 1);
+ /* If the previous op was a DRAW as well, we didn't change anything between the two calls,
+ * so these are just 2 subsequent draw calls. Same VAO, same program etc.
+ * And the offsets into the vao are in order as well, so make it one draw call. */
+ if (last_op->op == OP_DRAW)
+ {
+ /* We allow ourselves a little trick here. We still have to add a CHANGE_VAO op for
+ * this draw call so we can add our vertex data there, but we want it to be placed before
+ * the last draw call, so we reorder those. */
+ RenderOp new_draw;
+ new_draw.op = OP_DRAW;
+ new_draw.draw.vao_offset = last_op->draw.vao_offset;
+ new_draw.draw.draw_size = last_op->draw.draw_size + GL_N_VERTICES;
+
+ last_op->op = OP_CHANGE_VAO;
+ memcpy (&last_op->vertex_data, vertex_data, sizeof(GskQuadVertex) * GL_N_VERTICES);
+
+ /* Now add the DRAW */
+ g_array_append_val (builder->render_ops, new_draw);
+ }
+ else
+ {
+ RenderOp op;
+ gsize offset = builder->buffer_size / sizeof (GskQuadVertex);
- op.op = OP_DRAW;
- op.vao_offset = offset;
- g_array_append_val (builder->render_ops, op);
+ op.op = OP_CHANGE_VAO;
+ memcpy (&op.vertex_data, vertex_data, sizeof(GskQuadVertex) * GL_N_VERTICES);
+ g_array_append_val (builder->render_ops, op);
+
+ op.op = OP_DRAW;
+ op.draw.vao_offset = offset;
+ op.draw.draw_size = GL_N_VERTICES;
+ g_array_append_val (builder->render_ops, op);
+ }
+
+ /* We added new vertex data in both cases so increase the buffer size */
+ builder->buffer_size += sizeof (GskQuadVertex) * GL_N_VERTICES;
}
void
diff --git a/gsk/gl/gskglrenderopsprivate.h b/gsk/gl/gskglrenderopsprivate.h
index 11d69df..fee25af 100644
--- a/gsk/gl/gskglrenderopsprivate.h
+++ b/gsk/gl/gskglrenderopsprivate.h
@@ -85,7 +85,6 @@ typedef struct
int texture_id;
int render_target_id;
GdkRGBA color;
- gsize vao_offset;
GskQuadVertex vertex_data[6];
GskRoundedRect clip;
graphene_rect_t viewport;
@@ -96,6 +95,10 @@ typedef struct
graphene_point_t start_point;
graphene_point_t end_point;
} linear_gradient;
+ struct {
+ gsize vao_offset;
+ gsize draw_size;
+ } draw;
};
} RenderOp;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]