[gtk] gl renderer: Save some matrix multiplications
- From: Timm Bäder <baedert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk] gl renderer: Save some matrix multiplications
- Date: Thu, 11 Oct 2018 10:38:06 +0000 (UTC)
commit d15df65a9d78a7cfd40bbdbde604582a4032b5e9
Author: Timm Bäder <mail baedert org>
Date: Sat Oct 6 09:23:26 2018 +0200
gl renderer: Save some matrix multiplications
We do this for every single node, which is a little costly, especially
since the common case for the modelview matrix these days is a simple
translation. So, check whether the new modelview matrix is only a
translation matrix and if so, don't do a full matrix multiplication per
node.
gsk/gl/gskglrenderer.c | 7 +++---
gsk/gl/gskglrenderops.c | 56 ++++++++++++++++++++++++++++++++++++++++++
gsk/gl/gskglrenderopsprivate.h | 7 ++++++
3 files changed, 66 insertions(+), 4 deletions(-)
---
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index ceaf499d00..5ba5840a53 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -2140,10 +2140,9 @@ gsk_gl_renderer_add_render_ops (GskGLRenderer *self,
{
graphene_rect_t transformed_node_bounds;
- graphene_matrix_transform_bounds (&builder->current_modelview,
- &node->bounds,
- &transformed_node_bounds);
- graphene_rect_offset (&transformed_node_bounds, builder->dx, builder->dy);
+ ops_transform_bounds_modelview (builder,
+ &node->bounds,
+ &transformed_node_bounds);
if (!graphene_rect_intersection (&builder->current_clip.bounds,
&transformed_node_bounds, NULL))
diff --git a/gsk/gl/gskglrenderops.c b/gsk/gl/gskglrenderops.c
index 21223ee157..eba7c8fb47 100644
--- a/gsk/gl/gskglrenderops.c
+++ b/gsk/gl/gskglrenderops.c
@@ -19,6 +19,61 @@ ops_get_scale (const RenderOpBuilder *builder)
graphene_matrix_get_y_scale (mv));
}
+static inline gboolean
+matrix_is_only_translation (const graphene_matrix_t *mat)
+{
+ graphene_vec4_t row1;
+ graphene_vec4_t row2;
+ graphene_vec4_t row3;
+ graphene_vec4_t row;
+
+ graphene_vec4_init (&row1, 1, 0, 0, 0);
+ graphene_vec4_init (&row2, 0, 1, 0, 0);
+ graphene_vec4_init (&row3, 0, 0, 1, 0);
+
+ graphene_matrix_get_row (mat, 0, &row);
+ if (!graphene_vec4_equal (&row1, &row))
+ return FALSE;
+
+ graphene_matrix_get_row (mat, 1, &row);
+ if (!graphene_vec4_equal (&row2, &row))
+ return FALSE;
+
+ graphene_matrix_get_row (mat, 2, &row);
+ if (!graphene_vec4_equal (&row3, &row))
+ return FALSE;
+
+ graphene_matrix_get_row (mat, 3, &row);
+ if (graphene_vec4_get_w (&row) != 1)
+ return FALSE;
+
+ return TRUE;
+}
+
+void
+ops_transform_bounds_modelview (const RenderOpBuilder *builder,
+ const graphene_rect_t *src,
+ graphene_rect_t *dst)
+{
+ if (builder->modelview_is_translation)
+ {
+ graphene_vec4_t row4;
+
+ /* TODO: We could do the get_row here only once, when setting the new modelview matrix. */
+ graphene_matrix_get_row (&builder->current_modelview, 3, &row4);
+ *dst = *src;
+ graphene_rect_offset (dst, graphene_vec4_get_x (&row4), graphene_vec4_get_y (&row4));
+ }
+ else
+ {
+ graphene_matrix_transform_bounds (&builder->current_modelview,
+ src,
+ dst);
+ }
+
+ graphene_rect_offset (dst, builder->dx, builder->dy);
+}
+
void
ops_set_program (RenderOpBuilder *builder,
const Program *program)
@@ -156,6 +211,7 @@ ops_set_modelview (RenderOpBuilder *builder,
prev_mv = builder->current_modelview;
builder->current_modelview = *modelview;
+ builder->modelview_is_translation = matrix_is_only_translation (modelview);
return prev_mv;
}
diff --git a/gsk/gl/gskglrenderopsprivate.h b/gsk/gl/gskglrenderopsprivate.h
index 917c3fc8de..c77de348b4 100644
--- a/gsk/gl/gskglrenderopsprivate.h
+++ b/gsk/gl/gskglrenderopsprivate.h
@@ -221,7 +221,10 @@ typedef struct
int current_render_target;
int current_texture;
GskRoundedRect current_clip;
+
graphene_matrix_t current_modelview;
+ guint modelview_is_translation : 1;
+
graphene_matrix_t current_projection;
graphene_rect_t current_viewport;
float current_opacity;
@@ -246,6 +249,10 @@ GskRoundedRect ops_set_clip (RenderOpBuilder *builder,
graphene_matrix_t ops_set_modelview (RenderOpBuilder *builder,
const graphene_matrix_t *modelview);
+void ops_transform_bounds_modelview (const RenderOpBuilder *builder,
+ const graphene_rect_t *src,
+ graphene_rect_t *dst);
+
graphene_matrix_t ops_set_projection (RenderOpBuilder *builder,
const graphene_matrix_t *projection);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]