[gtk/wip/baedert/for-master: 197/198] gl renderer: Replace modelview matrix with just scale
- From: Timm Bäder <baedert src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [gtk/wip/baedert/for-master: 197/198] gl renderer: Replace modelview matrix with just scale
- Date: Fri, 12 Feb 2021 07:39:52 +0000 (UTC)
commit 7ee107f086e10a49a93d7cbec80c394dda0659ca
Author: Timm Bäder <mail baedert org>
Date: Sun Jan 24 08:38:01 2021 +0100
gl renderer: Replace modelview matrix with just scale
We don't support non-affine transforms in the general case. If we see a
non-affine transform node, just use a special shader to render it.
gsk/gl/gskglrenderer.c | 164 +++++++----------
gsk/gl/gskglrenderops.c | 234 +++++++++---------------
gsk/gl/gskglrenderopsprivate.h | 39 ++--
gsk/gl/opbuffer.c | 1 +
gsk/gl/opbuffer.h | 8 +-
gsk/gskrendernodeimpl.c | 37 +++-
gsk/meson.build | 1 +
gsk/resources/glsl/blend.glsl | 2 +-
gsk/resources/glsl/blit.glsl | 2 +-
gsk/resources/glsl/blur.glsl | 2 +-
gsk/resources/glsl/border.glsl | 6 +-
gsk/resources/glsl/color.glsl | 2 +-
gsk/resources/glsl/color_matrix.glsl | 2 +-
gsk/resources/glsl/coloring.glsl | 2 +-
gsk/resources/glsl/conic_gradient.glsl | 7 +-
gsk/resources/glsl/cross_fade.glsl | 2 +-
gsk/resources/glsl/custom.glsl | 3 +-
gsk/resources/glsl/inset_shadow.glsl | 6 +-
gsk/resources/glsl/linear_gradient.glsl | 10 +-
gsk/resources/glsl/outset_shadow.glsl | 4 +-
gsk/resources/glsl/preamble.fs.glsl | 2 +-
gsk/resources/glsl/preamble.vs.glsl | 23 ++-
gsk/resources/glsl/radial_gradient.glsl | 7 +-
gsk/resources/glsl/repeat.glsl | 2 +-
gsk/resources/glsl/transform.glsl | 22 +++
gsk/resources/glsl/unblurred_outset_shadow.glsl | 7 +-
26 files changed, 288 insertions(+), 309 deletions(-)
---
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index a68b45e663..54fcda7895 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -68,9 +68,9 @@
}G_STMT_END
static Program *gsk_gl_renderer_lookup_custom_program (GskGLRenderer *self,
- GskGLShader *shader);
+ GskGLShader *shader);
static Program *gsk_gl_renderer_create_custom_program (GskGLRenderer *self,
- GskGLShader *shader);
+ GskGLShader *shader);
typedef enum
{
@@ -328,37 +328,6 @@ gsk_rounded_rect_shrink_to_minimum (GskRoundedRect *self)
self->corner[1].height + self->corner[2].height);
}
-static inline gboolean G_GNUC_PURE
-node_supports_transform (GskRenderNode *node)
-{
- /* Some nodes can't handle non-trivial transforms without being
- * rendered to a texture (e.g. rotated clips, etc.). Some however
- * work just fine, mostly because they already draw their child
- * to a texture and just render the texture manipulated in some
- * way, think opacity or color matrix. */
- const guint node_type = gsk_render_node_get_node_type (node);
-
- switch (node_type)
- {
- case GSK_COLOR_NODE:
- case GSK_OPACITY_NODE:
- case GSK_COLOR_MATRIX_NODE:
- case GSK_TEXTURE_NODE:
- case GSK_CROSS_FADE_NODE:
- case GSK_LINEAR_GRADIENT_NODE:
- case GSK_DEBUG_NODE:
- case GSK_TEXT_NODE:
- return TRUE;
-
- case GSK_TRANSFORM_NODE:
- return node_supports_transform (gsk_transform_node_get_child (node));
-
- default:
- return FALSE;
- }
- return FALSE;
-}
-
static inline void
load_vertex_data_with_region (GskQuadVertex vertex_data[GL_N_VERTICES],
const graphene_rect_t *bounds,
@@ -1150,7 +1119,7 @@ compile_glshader (GskGLRenderer *self,
INIT_COMMON_UNIFORM_LOCATION (program, clip_rect);
INIT_COMMON_UNIFORM_LOCATION (program, viewport);
INIT_COMMON_UNIFORM_LOCATION (program, projection);
- INIT_COMMON_UNIFORM_LOCATION (program, modelview);
+ INIT_COMMON_UNIFORM_LOCATION (program, scale);
program->glshader.size_location = glGetUniformLocation(program->id, "u_size");
program->glshader.texture_locations[0] = glGetUniformLocation(program->id, "u_texture1");
program->glshader.texture_locations[1] = glGetUniformLocation(program->id, "u_texture2");
@@ -1328,12 +1297,18 @@ render_transform_node (GskGLRenderer *self,
case GSK_TRANSFORM_CATEGORY_2D_AFFINE:
{
- ops_push_modelview (builder, node_transform);
+ float dx, dy, scale_x, scale_y;
+
+ gsk_transform_to_affine (node_transform, &scale_x, &scale_y, &dx, &dy);
+
+ ops_push_modelview (builder, dx, dy, scale_x, scale_y);
gsk_gl_renderer_add_render_ops (self, child, builder);
ops_pop_modelview (builder);
}
break;
+ /* For non-affine transforms, we draw everything on a texture and then
+ * draw the texture transformed. */
case GSK_TRANSFORM_CATEGORY_2D:
case GSK_TRANSFORM_CATEGORY_3D:
case GSK_TRANSFORM_CATEGORY_ANY:
@@ -1341,42 +1316,34 @@ render_transform_node (GskGLRenderer *self,
{
TextureRegion region;
gboolean is_offscreen;
+ int filter_flag = 0;
- if (node_supports_transform (child))
- {
- ops_push_modelview (builder, node_transform);
- gsk_gl_renderer_add_render_ops (self, child, builder);
- ops_pop_modelview (builder);
- }
- else
+ if (!result_is_axis_aligned (node_transform, &child->bounds))
+ filter_flag = LINEAR_FILTER;
+
+ if (add_offscreen_ops (self, builder,
+ &child->bounds,
+ child,
+ ®ion, &is_offscreen,
+ RESET_CLIP | filter_flag))
{
- int filter_flag = 0;
-
- if (!result_is_axis_aligned (node_transform, &child->bounds))
- filter_flag = LINEAR_FILTER;
-
- if (add_offscreen_ops (self, builder,
- &child->bounds,
- child,
- ®ion, &is_offscreen,
- RESET_CLIP | filter_flag))
- {
- /* For non-trivial transforms, we draw everything on a texture and then
- * draw the texture transformed. */
- /* TODO: We should compute a modelview containing only the "non-trivial"
- * part (e.g. the rotation) and use that. We want to keep the scale
- * for the texture.
- */
- ops_push_modelview (builder, node_transform);
- ops_set_texture (builder, region.texture_id);
- ops_set_program (builder, &self->programs->blit_program);
-
- load_vertex_data_with_region (ops_draw (builder, NULL),
- &child->bounds, builder,
- ®ion,
- is_offscreen);
- ops_pop_modelview (builder);
- }
+ const float dx = builder->dx;
+ const float dy = builder->dy;
+
+ ops_set_program (builder, &self->programs->transform_program);
+ ops_set_transform (builder, node_transform);
+ ops_set_texture (builder, region.texture_id);
+
+ /* Quickly resetting these since ops_set_transform() adds them to the matrix
+ * and we don't want the geometry we're about to add picking the wrong offset */
+ builder->dx = 0;
+ builder->dy = 0;
+ load_vertex_data_with_region (ops_draw (builder, NULL),
+ &child->bounds, builder,
+ ®ion,
+ is_offscreen);
+ builder->dx = dx;
+ builder->dy = dy;
}
}
break;
@@ -1838,7 +1805,7 @@ blur_texture (GskGLRenderer *self,
ops_set_program (builder, &self->programs->blur_program);
prev_projection = ops_set_projection (builder, &item_proj);
- ops_set_modelview (builder, NULL);
+ ops_set_modelview (builder, 0, 0, 1, 1);
prev_viewport = ops_set_viewport (builder, &new_clip.bounds);
ops_push_clip (builder, &new_clip);
@@ -2086,7 +2053,7 @@ render_inset_shadow_node (GskGLRenderer *self,
&GRAPHENE_RECT_INIT (0, 0, texture_width, texture_height));
prev_projection = ops_set_projection (builder, &item_proj);
- ops_set_modelview (builder, NULL);
+ ops_set_modelview (builder, 0, 0, 1, 1);
prev_viewport = ops_set_viewport (builder, &GRAPHENE_RECT_INIT (0, 0, texture_width, texture_height));
ops_push_clip (builder, &GSK_ROUNDED_RECT_INIT (0, 0, texture_width, texture_height));
@@ -2277,6 +2244,9 @@ render_outset_shadow_node (GskGLRenderer *self,
texture_width = (int)ceil ((scaled_outline.bounds.size.width + blur_extra) * scale_x);
texture_height = (int)ceil ((scaled_outline.bounds.size.height + blur_extra) * scale_y);
+ if (texture_width <= 0 || texture_height <= 0)
+ return;
+
scaled_outline.bounds.origin.x = extra_blur_pixels;
scaled_outline.bounds.origin.y = extra_blur_pixels;
scaled_outline.bounds.size.width = texture_width - (extra_blur_pixels * 2);
@@ -2320,7 +2290,7 @@ render_outset_shadow_node (GskGLRenderer *self,
prev_render_target = ops_set_render_target (builder, render_target);
ops_begin (builder, OP_CLEAR);
prev_projection = ops_set_projection (builder, &item_proj);
- ops_set_modelview (builder, NULL);
+ ops_set_modelview (builder, 0, 0, 1, 1);
prev_viewport = ops_set_viewport (builder, &GRAPHENE_RECT_INIT (0, 0, texture_width, texture_height));
/* Draw outline */
@@ -2828,18 +2798,26 @@ apply_viewport_op (const Program *program,
}
static inline void
-apply_modelview_op (const Program *program,
+apply_scale_op (const Program *program,
+ const OpScale *op)
+{
+ OP_PRINT (" -> Scale %f, %f", op->scale[0], op->scale[1]);
+ glUniform2f (program->scale_location, op->scale[0], op->scale[1]);
+}
+
+static inline void
+apply_transform_op (const Program *program,
const OpMatrix *op)
{
float mat[16];
graphene_matrix_to_float (&op->matrix, mat);
- OP_PRINT (" -> Modelview { { %f,%f,%f,%f }, { %f,%f,%f,%f }, { %f,%f,%f,%f }, { %f,%f,%f,%f }",
+ OP_PRINT (" -> Transform { { %f,%f,%f,%f }, { %f,%f,%f,%f }, { %f,%f,%f,%f }, { %f,%f,%f,%f }",
mat[0], mat[1], mat[2], mat[3],
mat[4], mat[5], mat[6], mat[7],
mat[8], mat[9], mat[10], mat[11],
mat[12], mat[13], mat[14], mat[15]);
- glUniformMatrix4fv (program->modelview_location, 1, GL_FALSE, mat);
+ glUniformMatrix4fv (program->transform.transform_location, 1, GL_FALSE, mat);
}
static inline void
@@ -2858,7 +2836,7 @@ apply_projection_op (const Program *program,
}
static inline void
-apply_program_op (const Program *program,
+apply_program_op (const Program *program,
const OpProgram *op)
{
OP_PRINT (" -> Program: %d", op->program->index);
@@ -3328,6 +3306,7 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self,
{ "/org/gtk/libgsk/glsl/outset_shadow.glsl", "outset shadow" },
{ "/org/gtk/libgsk/glsl/repeat.glsl", "repeat" },
{ "/org/gtk/libgsk/glsl/unblurred_outset_shadow.glsl", "unblurred_outset shadow" },
+ { "/org/gtk/libgsk/glsl/transform.glsl", "transform" },
};
gsk_gl_shader_builder_init (&shader_builder,
@@ -3361,7 +3340,7 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self,
INIT_COMMON_UNIFORM_LOCATION (prog, clip_rect);
INIT_COMMON_UNIFORM_LOCATION (prog, viewport);
INIT_COMMON_UNIFORM_LOCATION (prog, projection);
- INIT_COMMON_UNIFORM_LOCATION (prog, modelview);
+ INIT_COMMON_UNIFORM_LOCATION (prog, scale);
}
/* color */
INIT_PROGRAM_UNIFORM_LOCATION (color, color);
@@ -3429,6 +3408,8 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self,
INIT_PROGRAM_UNIFORM_LOCATION (repeat, child_bounds);
INIT_PROGRAM_UNIFORM_LOCATION (repeat, texture_rect);
+ /* transform */
+ INIT_PROGRAM_UNIFORM_LOCATION (transform, transform);
/* We initialize the alpha uniform here, since the default value is important.
* We can't do it in the shader like a reasonable person would because that doesn't
@@ -3437,6 +3418,7 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self,
{
glUseProgram(programs->programs[i].id);
glUniform1f (programs->programs[i].alpha_location, 1.0);
+ glUniform2f (programs->programs[i].scale_location, 1.0, 1.0);
}
out:
@@ -3824,8 +3806,6 @@ add_offscreen_ops (GskGLRenderer *self,
gboolean *is_offscreen,
guint flags)
{
- const float dx = builder->dx;
- const float dy = builder->dy;
float scaled_width, scaled_height;
float scale_x;
float scale_y;
@@ -3934,14 +3914,10 @@ add_offscreen_ops (GskGLRenderer *self,
/* Clear since we use this rendertarget for the first time */
ops_begin (builder, OP_CLEAR);
prev_projection = ops_set_projection (builder, &item_proj);
- ops_set_modelview (builder, gsk_transform_scale (NULL, scale_x, scale_y));
prev_viewport = ops_set_viewport (builder, &viewport);
if (flags & RESET_CLIP)
ops_push_clip (builder, &GSK_ROUNDED_RECT_INIT_FROM_RECT (viewport));
- builder->dx = dx;
- builder->dy = dy;
-
prev_opacity = ops_set_opacity (builder, 1.0);
gsk_gl_renderer_add_render_ops (self, child_node, builder);
@@ -3961,14 +3937,10 @@ add_offscreen_ops (GskGLRenderer *self,
ops_set_opacity (builder, prev_opacity);
- builder->dx = dx;
- builder->dy = dy;
-
if (flags & RESET_CLIP)
ops_pop_clip (builder);
ops_set_viewport (builder, &prev_viewport);
- ops_pop_modelview (builder);
ops_set_projection (builder, &prev_projection);
ops_set_render_target (builder, prev_render_target);
@@ -4033,12 +4005,16 @@ gsk_gl_renderer_render_ops (GskGLRenderer *self)
switch (kind)
{
- case OP_CHANGE_PROJECTION:
- apply_projection_op (program, ptr);
+ case OP_CHANGE_TRANSFORM:
+ apply_transform_op (program, ptr);
break;
- case OP_CHANGE_MODELVIEW:
- apply_modelview_op (program, ptr);
+ case OP_CHANGE_SCALE:
+ apply_scale_op (program, ptr);
+ break;
+
+ case OP_CHANGE_PROJECTION:
+ apply_projection_op (program, ptr);
break;
case OP_CHANGE_PROGRAM:
@@ -4230,7 +4206,9 @@ gsk_gl_renderer_do_render (GskRenderer *renderer,
init_projection_matrix (&projection, viewport);
ops_set_projection (&self->op_builder, &projection);
ops_set_viewport (&self->op_builder, viewport);
- ops_set_modelview (&self->op_builder, gsk_transform_scale (NULL, scale_factor, scale_factor));
+ ops_set_modelview (&self->op_builder, 0, 0, scale_factor, scale_factor);
+ g_assert_cmpfloat (self->op_builder.scale_x, ==, scale_factor);
+ g_assert_cmpfloat (self->op_builder.scale_y, ==, scale_factor);
/* Initial clip is self->render_region! */
if (self->render_region != NULL)
@@ -4412,7 +4390,7 @@ gsk_gl_renderer_render_texture (GskRenderer *renderer,
ops_begin (&self->op_builder, OP_CLEAR);
ops_set_texture (&self->op_builder, texture_id);
- ops_set_modelview (&self->op_builder, NULL);
+ ops_set_modelview (&self->op_builder, 0, 0, 1, 1);
ops_set_viewport (&self->op_builder, &GRAPHENE_RECT_INIT (0, 0, width, height));
init_projection_matrix (&m, &GRAPHENE_RECT_INIT (0, 0, width, height));
graphene_matrix_scale (&m, 1, -1, 1); /* Undo the scale init_projection_matrix() does again */
diff --git a/gsk/gl/gskglrenderops.c b/gsk/gl/gskglrenderops.c
index 36f7e37e35..ffadef0ad2 100644
--- a/gsk/gl/gskglrenderops.c
+++ b/gsk/gl/gskglrenderops.c
@@ -79,9 +79,8 @@ ops_finish (RenderOpBuilder *builder)
builder->dy = 0;
builder->scale_x = 1;
builder->scale_y = 1;
- builder->current_modelview = NULL;
builder->current_clip = NULL;
- builder->clip_is_rectilinear = TRUE;
+ builder->clip_is_rectilinear = true;
builder->current_render_target = 0;
builder->current_texture = 0;
builder->current_program = NULL;
@@ -121,83 +120,33 @@ ops_pop_debug_group (RenderOpBuilder *builder)
ops_begin (builder, OP_POP_DEBUG_GROUP);
}
-static void
-extract_matrix_metadata (GskTransform *transform,
- OpsMatrixMetadata *md)
-{
- float dummy;
-
- switch (gsk_transform_get_category (transform))
- {
- case GSK_TRANSFORM_CATEGORY_IDENTITY:
- case GSK_TRANSFORM_CATEGORY_2D_TRANSLATE:
- md->scale_x = 1;
- md->scale_y = 1;
- break;
-
- case GSK_TRANSFORM_CATEGORY_2D_AFFINE:
- gsk_transform_to_affine (transform,
- &md->scale_x, &md->scale_y,
- &dummy, &dummy);
- break;
-
- case GSK_TRANSFORM_CATEGORY_UNKNOWN:
- case GSK_TRANSFORM_CATEGORY_ANY:
- case GSK_TRANSFORM_CATEGORY_3D:
- case GSK_TRANSFORM_CATEGORY_2D:
- {
- graphene_vec3_t col1;
- graphene_vec3_t col2;
- graphene_matrix_t m;
-
- gsk_transform_to_matrix (transform, &m);
-
- /* TODO: 90% sure this is incorrect. But we should never hit this code
- * path anyway. */
- graphene_vec3_init (&col1,
- graphene_matrix_get_value (&m, 0, 0),
- graphene_matrix_get_value (&m, 1, 0),
- graphene_matrix_get_value (&m, 2, 0));
-
- graphene_vec3_init (&col2,
- graphene_matrix_get_value (&m, 0, 1),
- graphene_matrix_get_value (&m, 1, 1),
- graphene_matrix_get_value (&m, 2, 1));
-
- md->scale_x = graphene_vec3_length (&col1);
- md->scale_y = graphene_vec3_length (&col2);
- }
- break;
- default:
- {}
- }
-}
-
void
-ops_transform_bounds_modelview (const RenderOpBuilder *builder,
+ops_transform_bounds_modelview (const RenderOpBuilder *self,
const graphene_rect_t *src,
graphene_rect_t *dst)
{
- graphene_rect_t r = *src;
-
- g_assert (builder->mv_stack != NULL);
- g_assert (builder->mv_stack->len >= 1);
+ g_assert (self->mv_stack != NULL);
+ g_assert (self->mv_stack->len >= 1);
+ g_assert (src);
+ g_assert (dst);
- r.origin.x += builder->dx;
- r.origin.y += builder->dy;
-
- gsk_transform_transform_bounds (builder->current_modelview, &r, dst);
+ dst->origin.x = (src->origin.x + self->dx) * self->scale_x;
+ dst->origin.y = (src->origin.y + self->dy) * self->scale_y;
+ dst->size.width = src->size.width * self->scale_x;
+ dst->size.height = src->size.height * self->scale_y;
}
void
-ops_init (RenderOpBuilder *builder)
+ops_init (RenderOpBuilder *self)
{
- memset (builder, 0, sizeof (*builder));
+ memset (self, 0, sizeof (*self));
- builder->current_opacity = 1.0f;
+ self->current_opacity = 1.0f;
+ self->scale_x = 1.0f;
+ self->scale_y = 1.0f;
- op_buffer_init (&builder->render_ops);
- builder->vertices = g_array_new (FALSE, TRUE, sizeof (GskQuadVertex));
+ op_buffer_init (&self->render_ops);
+ self->vertices = g_array_new (FALSE, TRUE, sizeof (GskQuadVertex));
}
void
@@ -270,6 +219,22 @@ ops_has_clip (RenderOpBuilder *self)
self->clip_stack->len > 1;
}
+void
+ops_set_transform (RenderOpBuilder *self,
+ GskTransform *transform)
+{
+ OpMatrix *op;
+
+ op = ops_begin (self, OP_CHANGE_TRANSFORM);
+
+ g_assert (gsk_transform_get_category (transform) < GSK_TRANSFORM_CATEGORY_2D_AFFINE);
+
+ gsk_transform_to_matrix (transform, &op->matrix);
+
+ /* Apply our own offset */
+ graphene_matrix_translate (&op->matrix, &(graphene_point3d_t) { self->dx, self->dy, 0 });
+}
+
/**
* ops_set_modelview:
* @builder
@@ -278,103 +243,83 @@ ops_has_clip (RenderOpBuilder *self)
* This sets the modelview to the given one without looking at the
* one that's currently set */
void
-ops_set_modelview (RenderOpBuilder *builder,
- GskTransform *transform)
+ops_set_modelview (RenderOpBuilder *self,
+ const float dx,
+ const float dy,
+ const float scale_x,
+ const float scale_y)
+
{
- MatrixStackEntry *entry;
+ ModelviewState *entry;
- if (G_UNLIKELY (builder->mv_stack == NULL))
- builder->mv_stack = g_array_new (FALSE, TRUE, sizeof (MatrixStackEntry));
+ g_assert (self);
- g_assert (builder->mv_stack != NULL);
+ if (G_UNLIKELY (self->mv_stack == NULL))
+ self->mv_stack = g_array_new (false, true, sizeof (ModelviewState));
- g_array_set_size (builder->mv_stack, builder->mv_stack->len + 1);
- entry = &g_array_index (builder->mv_stack, MatrixStackEntry, builder->mv_stack->len - 1);
+ g_assert (self->mv_stack != NULL);
- entry->transform = transform;
+ g_array_set_size (self->mv_stack, self->mv_stack->len + 1);
+ entry = &g_array_index (self->mv_stack, ModelviewState, self->mv_stack->len - 1);
- entry->metadata.dx_before = builder->dx;
- entry->metadata.dy_before = builder->dy;
- extract_matrix_metadata (entry->transform, &entry->metadata);
+ entry->dx_before = self->dx;
+ entry->dy_before = self->dy;
+ entry->scale_x_before = self->scale_x;
+ entry->scale_y_before = self->scale_y;
- builder->dx = 0;
- builder->dy = 0;
- builder->current_modelview = entry->transform;
- builder->scale_x = entry->metadata.scale_x;
- builder->scale_y = entry->metadata.scale_y;
+ self->dx = dx;
+ self->dy = dy;
+ self->scale_x = scale_x;
+ self->scale_y = scale_y;
}
-/* This sets the given modelview to the one we get when multiplying
- * the given modelview with the current one. */
void
-ops_push_modelview (RenderOpBuilder *builder,
- GskTransform *transform)
+ops_push_modelview (RenderOpBuilder *self,
+ const float dx,
+ const float dy,
+ const float scale_x,
+ const float scale_y)
{
- MatrixStackEntry *entry;
-
- if (G_UNLIKELY (builder->mv_stack == NULL))
- builder->mv_stack = g_array_new (FALSE, TRUE, sizeof (MatrixStackEntry));
+ ModelviewState *entry;
- g_assert (builder->mv_stack != NULL);
+ g_assert (self);
- g_array_set_size (builder->mv_stack, builder->mv_stack->len + 1);
- entry = &g_array_index (builder->mv_stack, MatrixStackEntry, builder->mv_stack->len - 1);
-
- if (G_LIKELY (builder->mv_stack->len >= 2))
- {
- const MatrixStackEntry *cur;
- GskTransform *t = NULL;
+ if (G_UNLIKELY (self->mv_stack == NULL))
+ self->mv_stack = g_array_new (false, true, sizeof (ModelviewState));
- cur = &g_array_index (builder->mv_stack, MatrixStackEntry, builder->mv_stack->len - 2);
- /* Multiply given matrix with current modelview */
+ g_assert (self->mv_stack != NULL);
- t = gsk_transform_translate (gsk_transform_ref (cur->transform),
- &(graphene_point_t) { builder->dx, builder->dy});
- t = gsk_transform_transform (t, transform);
- entry->transform = t;
- }
- else
- {
- entry->transform = gsk_transform_ref (transform);
- }
+ g_array_set_size (self->mv_stack, self->mv_stack->len + 1);
+ entry = &g_array_index (self->mv_stack, ModelviewState, self->mv_stack->len - 1);
- entry->metadata.dx_before = builder->dx;
- entry->metadata.dy_before = builder->dy;
- extract_matrix_metadata (entry->transform, &entry->metadata);
+ entry->dx_before = self->dx;
+ entry->dy_before = self->dy;
+ entry->scale_x_before = self->scale_x;
+ entry->scale_y_before = self->scale_y;
- builder->dx = 0;
- builder->dy = 0;
- builder->scale_x = entry->metadata.scale_x;
- builder->scale_y = entry->metadata.scale_y;
- builder->current_modelview = entry->transform;
+ /* This version is additive */
+ self->dx += dx;
+ self->dy += dy;
+ self->scale_x = scale_x * self->scale_x;
+ self->scale_y = scale_y * self->scale_y;
}
void
ops_pop_modelview (RenderOpBuilder *builder)
{
- const MatrixStackEntry *head;
+ const ModelviewState *head;
g_assert (builder->mv_stack);
g_assert (builder->mv_stack->len >= 1);
- head = &g_array_index (builder->mv_stack, MatrixStackEntry, builder->mv_stack->len - 1);
- builder->dx = head->metadata.dx_before;
- builder->dy = head->metadata.dy_before;
- gsk_transform_unref (head->transform);
+ head = &g_array_index (builder->mv_stack, ModelviewState, builder->mv_stack->len - 1);
+ builder->dx = head->dx_before;
+ builder->dy = head->dy_before;
+ builder->scale_x = head->scale_x_before;
+ builder->scale_y = head->scale_y_before;
builder->mv_stack->len --;
- head = &g_array_index (builder->mv_stack, MatrixStackEntry, builder->mv_stack->len - 1);
-
- if (builder->mv_stack->len >= 1)
- {
- builder->scale_x = head->metadata.scale_x;
- builder->scale_y = head->metadata.scale_y;
- builder->current_modelview = head->transform;
- }
- else
- {
- builder->current_modelview = NULL;
- }
+ head = &g_array_index (builder->mv_stack, ModelviewState, builder->mv_stack->len - 1);
}
graphene_matrix_t
@@ -635,15 +580,14 @@ ops_draw (RenderOpBuilder *builder,
program_state->projection = builder->current_projection;
}
- if (program_state->modelview == NULL ||
- !gsk_transform_equal (builder->current_modelview, program_state->modelview))
+ if (program_state->scale_x != builder->scale_x ||
+ program_state->scale_y != builder->scale_y)
{
- OpMatrix *opm;
-
- opm = ops_begin (builder, OP_CHANGE_MODELVIEW);
- gsk_transform_to_matrix (builder->current_modelview, &opm->matrix);
- gsk_transform_unref (program_state->modelview);
- program_state->modelview = gsk_transform_ref (builder->current_modelview);
+ OpScale *op_s = ops_begin (builder, OP_CHANGE_SCALE);
+ op_s->scale[0] = builder->scale_x;
+ op_s->scale[1] = builder->scale_y;
+ program_state->scale_x = builder->scale_x;
+ program_state->scale_y = builder->scale_y;
}
if (!rect_equal (&builder->current_viewport, &program_state->viewport))
diff --git a/gsk/gl/gskglrenderopsprivate.h b/gsk/gl/gskglrenderopsprivate.h
index b23060014b..acf1f42851 100644
--- a/gsk/gl/gskglrenderopsprivate.h
+++ b/gsk/gl/gskglrenderopsprivate.h
@@ -13,23 +13,17 @@
#include "opbuffer.h"
#define GL_N_VERTICES 6
-#define GL_N_PROGRAMS 15
+#define GL_N_PROGRAMS 16
#define GL_MAX_GRADIENT_STOPS 6
typedef struct
{
- float scale_x;
- float scale_y;
+ float scale_x_before;
+ float scale_y_before;
float dx_before;
float dy_before;
-} OpsMatrixMetadata;
-
-typedef struct
-{
- GskTransform *transform;
- OpsMatrixMetadata metadata;
-} MatrixStackEntry;
+} ModelviewState;
typedef struct
{
@@ -39,6 +33,9 @@ typedef struct
int source_texture;
graphene_rect_t viewport;
float opacity;
+ float scale_x;
+ float scale_y;
+
/* Per-program state */
union {
GdkRGBA color;
@@ -104,6 +101,7 @@ struct _Program
int projection_location;
int modelview_location;
int clip_rect_location;
+ int scale_location;
union {
struct {
int color_location;
@@ -177,6 +175,9 @@ struct _Program
int texture_locations[4];
GError *compile_error;
} glshader;
+ struct {
+ int transform_location;
+ } transform;
};
ProgramState state;
};
@@ -201,6 +202,7 @@ typedef struct {
Program outset_shadow_program;
Program repeat_program;
Program unblurred_outset_shadow_program;
+ Program transform_program;
};
};
GHashTable *custom_programs; /* GskGLShader -> Program* */
@@ -216,6 +218,7 @@ typedef struct
graphene_matrix_t current_projection;
graphene_rect_t current_viewport;
float current_opacity;
+
float dx, dy;
float scale_x, scale_y;
@@ -226,7 +229,6 @@ typedef struct
/* Stack of modelview matrices */
GArray *mv_stack;
- GskTransform *current_modelview;
/* Same thing */
GArray *clip_stack;
@@ -248,9 +250,17 @@ void ops_push_debug_group (RenderOpBuilder *builder,
void ops_pop_debug_group (RenderOpBuilder *builder);
void ops_finish (RenderOpBuilder *builder);
-void ops_push_modelview (RenderOpBuilder *builder,
- GskTransform *transform);
-void ops_set_modelview (RenderOpBuilder *builder,
+void ops_push_modelview (RenderOpBuilder *self,
+ const float dx,
+ const float dy,
+ const float scale_x,
+ const float scale_y);
+void ops_set_modelview (RenderOpBuilder *self,
+ const float dx,
+ const float dy,
+ const float scale_x,
+ const float scale_y);
+void ops_set_transform (RenderOpBuilder *self,
GskTransform *transform);
void ops_pop_modelview (RenderOpBuilder *builder);
void ops_set_program (RenderOpBuilder *builder,
@@ -345,7 +355,6 @@ GskQuadVertex * ops_draw (RenderOpBuilder *builder,
void ops_offset (RenderOpBuilder *builder,
float x,
float y);
-
gpointer ops_begin (RenderOpBuilder *builder,
OpKind kind);
OpBuffer *ops_get_buffer (RenderOpBuilder *builder);
diff --git a/gsk/gl/opbuffer.c b/gsk/gl/opbuffer.c
index 806b8f7ca4..0024ad9246 100644
--- a/gsk/gl/opbuffer.c
+++ b/gsk/gl/opbuffer.c
@@ -34,6 +34,7 @@ static guint op_sizes[OP_LAST] = {
sizeof (OpGLShader),
sizeof (OpExtraTexture),
sizeof (OpConicGradient),
+ sizeof (OpScale),
};
void
diff --git a/gsk/gl/opbuffer.h b/gsk/gl/opbuffer.h
index ea954249c5..6557876a34 100644
--- a/gsk/gl/opbuffer.h
+++ b/gsk/gl/opbuffer.h
@@ -15,7 +15,7 @@ typedef enum
OP_CHANGE_OPACITY = 1,
OP_CHANGE_COLOR = 2,
OP_CHANGE_PROJECTION = 3,
- OP_CHANGE_MODELVIEW = 4,
+ OP_CHANGE_TRANSFORM = 4,
OP_CHANGE_PROGRAM = 5,
OP_CHANGE_RENDER_TARGET = 6,
OP_CHANGE_CLIP = 7,
@@ -42,6 +42,7 @@ typedef enum
OP_CHANGE_GL_SHADER_ARGS = 28,
OP_CHANGE_EXTRA_SOURCE_TEXTURE = 29,
OP_CHANGE_CONIC_GRADIENT = 30,
+ OP_CHANGE_SCALE = 31,
OP_LAST
} OpKind;
@@ -97,6 +98,11 @@ typedef struct
graphene_matrix_t matrix;
} OpMatrix;
+typedef struct
+{
+ float scale[2];
+} OpScale;
+
typedef struct
{
const Program *program;
diff --git a/gsk/gskrendernodeimpl.c b/gsk/gskrendernodeimpl.c
index 896dfc6566..805f69ccac 100644
--- a/gsk/gskrendernodeimpl.c
+++ b/gsk/gskrendernodeimpl.c
@@ -2746,10 +2746,30 @@ gsk_transform_node_draw (GskRenderNode *node,
cairo_t *cr)
{
GskTransformNode *self = (GskTransformNode *) node;
+ GskTransformCategory category;
float xx, yx, xy, yy, dx, dy;
cairo_matrix_t ctm;
- if (gsk_transform_get_category (self->transform) < GSK_TRANSFORM_CATEGORY_2D)
+ category = gsk_transform_get_category (self->transform);
+
+ if (category == GSK_TRANSFORM_CATEGORY_IDENTITY)
+ {
+ gsk_render_node_draw (self->child, cr);
+ return;
+ }
+ else if (category == GSK_TRANSFORM_CATEGORY_2D_TRANSLATE)
+ {
+ gsk_transform_to_translate (self->transform, &dx, &dy);
+
+ cairo_translate (cr, dx, dy);
+ gsk_render_node_draw (self->child, cr);
+ cairo_translate (cr, -dx, -dy);
+ return;
+ }
+ else if (category == GSK_TRANSFORM_CATEGORY_2D_AFFINE)
+ {
+ }
+ else if (gsk_transform_get_category (self->transform) < GSK_TRANSFORM_CATEGORY_2D)
{
cairo_set_source_rgb (cr, 255 / 255., 105 / 255., 180 / 255.);
gsk_cairo_rectangle (cr, &node->bounds);
@@ -2757,6 +2777,8 @@ gsk_transform_node_draw (GskRenderNode *node,
return;
}
+ /*if (category == GSK_TRANSFORM_CATEGORY_2D_AFFINE)*/
+ {
gsk_transform_to_2d (self->transform, &xx, &yx, &xy, &yy, &dx, &dy);
cairo_matrix_init (&ctm, xx, yx, xy, yy, dx, dy);
GSK_NOTE (CAIRO, g_message ("CTM = { .xx = %g, .yx = %g, .xy = %g, .yy = %g, .x0 = %g, .y0 = %g }",
@@ -2765,16 +2787,15 @@ gsk_transform_node_draw (GskRenderNode *node,
ctm.x0, ctm.y0));
if (xx * yy == xy * yx)
{
- /* broken matrix here. This can happen during transitions
- * (like when flipping an axis at the point where scale == 0)
- * and just means that nothing should be drawn.
- * But Cairo thows lots of ugly errors instead of silently
- * going on. So We silently go on.
- */
+ /*broken matrix here. This can happen during transitions*/
+ /*(like when flipping an axis at the point where scale == 0)*/
+ /*and just means that nothing should be drawn.*/
+ /*But Cairo thows lots of ugly errors instead of silently*/
+ /*going on. So We silently go on.*/
return;
}
cairo_transform (cr, &ctm);
-
+ }
gsk_render_node_draw (self->child, cr);
}
diff --git a/gsk/meson.build b/gsk/meson.build
index 748f4738a1..b82fb40cf0 100644
--- a/gsk/meson.build
+++ b/gsk/meson.build
@@ -18,6 +18,7 @@ gsk_private_gl_shaders = [
'resources/glsl/blend.glsl',
'resources/glsl/repeat.glsl',
'resources/glsl/custom.glsl',
+ 'resources/glsl/transform.glsl',
]
gsk_public_sources = files([
diff --git a/gsk/resources/glsl/blend.glsl b/gsk/resources/glsl/blend.glsl
index 22323402ac..0587db304e 100644
--- a/gsk/resources/glsl/blend.glsl
+++ b/gsk/resources/glsl/blend.glsl
@@ -1,6 +1,6 @@
// VERTEX_SHADER:
void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+ gl_Position = gsk_project(aPosition);
vUv = vec2(aUv.x, aUv.y);
}
diff --git a/gsk/resources/glsl/blit.glsl b/gsk/resources/glsl/blit.glsl
index f01cd238ec..a5017c75fb 100644
--- a/gsk/resources/glsl/blit.glsl
+++ b/gsk/resources/glsl/blit.glsl
@@ -1,6 +1,6 @@
// VERTEX_SHADER:
void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+ gl_Position = gsk_project(aPosition);
vUv = vec2(aUv.x, aUv.y);
}
diff --git a/gsk/resources/glsl/blur.glsl b/gsk/resources/glsl/blur.glsl
index f782ab48cc..00bbd74e9f 100644
--- a/gsk/resources/glsl/blur.glsl
+++ b/gsk/resources/glsl/blur.glsl
@@ -11,7 +11,7 @@ const float PI = 3.14159265;
const float RADIUS_MULTIPLIER = 2.0;
void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+ gl_Position = gsk_project(aPosition);
vUv = vec2(aUv.x, aUv.y);
diff --git a/gsk/resources/glsl/border.glsl b/gsk/resources/glsl/border.glsl
index 677a0df7cd..2fa4f1ad8b 100644
--- a/gsk/resources/glsl/border.glsl
+++ b/gsk/resources/glsl/border.glsl
@@ -8,15 +8,15 @@ _OUT_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
_OUT_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+ gl_Position = gsk_project(aPosition);
final_color = gsk_premultiply(u_color) * u_alpha;
GskRoundedRect outside = gsk_create_rect(u_outline_rect);
GskRoundedRect inside = gsk_rounded_rect_shrink (outside, u_widths);
- gsk_rounded_rect_transform(outside, u_modelview);
- gsk_rounded_rect_transform(inside, u_modelview);
+ gsk_rounded_rect_transform(outside);
+ gsk_rounded_rect_transform(inside);
gsk_rounded_rect_encode(outside, transformed_outside_outline);
gsk_rounded_rect_encode(inside, transformed_inside_outline);
diff --git a/gsk/resources/glsl/color.glsl b/gsk/resources/glsl/color.glsl
index 636456ce0d..e6f2a84b2b 100644
--- a/gsk/resources/glsl/color.glsl
+++ b/gsk/resources/glsl/color.glsl
@@ -4,7 +4,7 @@ uniform vec4 u_color;
_OUT_ vec4 final_color;
void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+ gl_Position = gsk_project(aPosition);
final_color = gsk_premultiply(u_color) * u_alpha;
}
diff --git a/gsk/resources/glsl/color_matrix.glsl b/gsk/resources/glsl/color_matrix.glsl
index 79cb36434e..1d34607455 100644
--- a/gsk/resources/glsl/color_matrix.glsl
+++ b/gsk/resources/glsl/color_matrix.glsl
@@ -1,6 +1,6 @@
// VERTEX_SHADER:
void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+ gl_Position = gsk_project(aPosition);
vUv = vec2(aUv.x, aUv.y);
}
diff --git a/gsk/resources/glsl/coloring.glsl b/gsk/resources/glsl/coloring.glsl
index a675493030..b399ff3db0 100644
--- a/gsk/resources/glsl/coloring.glsl
+++ b/gsk/resources/glsl/coloring.glsl
@@ -4,7 +4,7 @@ uniform vec4 u_color;
_OUT_ vec4 final_color;
void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+ gl_Position = gsk_project(aPosition);
vUv = vec2(aUv.x, aUv.y);
diff --git a/gsk/resources/glsl/conic_gradient.glsl b/gsk/resources/glsl/conic_gradient.glsl
index 630a42c5e6..7f5dbd8db4 100644
--- a/gsk/resources/glsl/conic_gradient.glsl
+++ b/gsk/resources/glsl/conic_gradient.glsl
@@ -4,14 +4,11 @@ uniform vec4 u_geometry;
_NOPERSPECTIVE_ _OUT_ vec2 coord;
void main() {
- gl_Position = u_projection * (u_modelview * vec4(aPosition, 0.0, 1.0));
+ gl_Position = gsk_project(aPosition);
- vec2 mv0 = u_modelview[0].xy;
- vec2 mv1 = u_modelview[1].xy;
vec2 offset = aPosition - u_geometry.xy;
- coord = vec2(dot(mv0, offset),
- dot(mv1, offset));
+ coord = u_scale * offset;
}
// FRAGMENT_SHADER:
diff --git a/gsk/resources/glsl/cross_fade.glsl b/gsk/resources/glsl/cross_fade.glsl
index f824430f9d..5a73e532fb 100644
--- a/gsk/resources/glsl/cross_fade.glsl
+++ b/gsk/resources/glsl/cross_fade.glsl
@@ -1,6 +1,6 @@
// VERTEX_SHADER:
void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+ gl_Position = gsk_project(aPosition);
vUv = vec2(aUv.x, aUv.y);
}
diff --git a/gsk/resources/glsl/custom.glsl b/gsk/resources/glsl/custom.glsl
index d2aed97fc8..c3b22d9add 100644
--- a/gsk/resources/glsl/custom.glsl
+++ b/gsk/resources/glsl/custom.glsl
@@ -1,6 +1,7 @@
// VERTEX_SHADER:
void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+ gl_Position = gsk_project(aPosition);
+
vUv = vec2(aUv.x, aUv.y);
}
diff --git a/gsk/resources/glsl/inset_shadow.glsl b/gsk/resources/glsl/inset_shadow.glsl
index 9a21cdef09..0b8fa43d4e 100644
--- a/gsk/resources/glsl/inset_shadow.glsl
+++ b/gsk/resources/glsl/inset_shadow.glsl
@@ -9,7 +9,7 @@ _OUT_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
_OUT_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+ gl_Position = gsk_project(aPosition);
final_color = gsk_premultiply(u_color) * u_alpha;
@@ -18,8 +18,8 @@ void main() {
gsk_rounded_rect_offset(inside, u_offset);
- gsk_rounded_rect_transform(outside, u_modelview);
- gsk_rounded_rect_transform(inside, u_modelview);
+ gsk_rounded_rect_transform(outside);
+ gsk_rounded_rect_transform(inside);
gsk_rounded_rect_encode(outside, transformed_outside_outline);
gsk_rounded_rect_encode(inside, transformed_inside_outline);
diff --git a/gsk/resources/glsl/linear_gradient.glsl b/gsk/resources/glsl/linear_gradient.glsl
index cc90392c06..7530778e38 100644
--- a/gsk/resources/glsl/linear_gradient.glsl
+++ b/gsk/resources/glsl/linear_gradient.glsl
@@ -4,13 +4,10 @@ uniform vec4 u_points;
_NOPERSPECTIVE_ _OUT_ vec4 info;
void main() {
- gl_Position = u_projection * (u_modelview * vec4(aPosition, 0.0, 1.0));
+ gl_Position = gsk_project(aPosition);
- vec2 mv0 = u_modelview[0].xy;
- vec2 mv1 = u_modelview[1].xy;
vec2 offset = aPosition - u_points.xy;
- vec2 coord = vec2(dot(mv0, offset),
- dot(mv1, offset));
+ vec2 coord = u_scale * offset;
// Original equation:
// VS | maxDist = length(end - start);
@@ -31,8 +28,7 @@ void main() {
// 4. We can avoid the FS division by passing a scaled pos from the VS:
// offset = dot(gnorm, pos) / gradientLength = dot(gnorm, pos / gradientLength)
// 5. 1.0 / length(gradient) is inversesqrt(dot(gradient, gradient)) in GLSL
- vec2 gradient = vec2(dot(mv0, u_points.zw),
- dot(mv1, u_points.zw));
+ vec2 gradient = u_scale * u_points.zw;
float rcp_gradient_length = inversesqrt(dot(gradient, gradient));
info = rcp_gradient_length * vec4(coord, gradient);
diff --git a/gsk/resources/glsl/outset_shadow.glsl b/gsk/resources/glsl/outset_shadow.glsl
index 373c650179..db4139f939 100644
--- a/gsk/resources/glsl/outset_shadow.glsl
+++ b/gsk/resources/glsl/outset_shadow.glsl
@@ -6,14 +6,14 @@ _OUT_ vec4 final_color;
_OUT_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_outline;
void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+ gl_Position = gsk_project(aPosition);
vUv = vec2(aUv.x, aUv.y);
final_color = gsk_premultiply(u_color) * u_alpha;
GskRoundedRect outline = gsk_create_rect(u_outline_rect);
- gsk_rounded_rect_transform(outline, u_modelview);
+ gsk_rounded_rect_transform(outline);
gsk_rounded_rect_encode(outline, transformed_outline);
}
diff --git a/gsk/resources/glsl/preamble.fs.glsl b/gsk/resources/glsl/preamble.fs.glsl
index c2cd1cdc29..6d7bdee072 100644
--- a/gsk/resources/glsl/preamble.fs.glsl
+++ b/gsk/resources/glsl/preamble.fs.glsl
@@ -1,6 +1,6 @@
uniform sampler2D u_source;
uniform mat4 u_projection;
-uniform mat4 u_modelview;
+uniform vec2 u_scale;
uniform float u_alpha;// = 1.0;
uniform vec4 u_viewport;
uniform vec4[3] u_clip_rect;
diff --git a/gsk/resources/glsl/preamble.vs.glsl b/gsk/resources/glsl/preamble.vs.glsl
index 89ee6f74e0..2b44c8fe03 100644
--- a/gsk/resources/glsl/preamble.vs.glsl
+++ b/gsk/resources/glsl/preamble.vs.glsl
@@ -1,6 +1,6 @@
uniform mat4 u_projection;
-uniform mat4 u_modelview;
uniform float u_alpha;
+uniform vec2 u_scale;
#if defined(GSK_GLES) || defined(GSK_LEGACY)
attribute vec2 aPosition;
@@ -12,6 +12,12 @@ _IN_ vec2 aUv;
_OUT_ vec2 vUv;
#endif
+vec4
+gsk_project(vec2 pos)
+{
+ return u_projection * vec4(u_scale * pos, 0.0, 1.0);
+}
+
// amount is: top, right, bottom, left
GskRoundedRect
gsk_rounded_rect_shrink (GskRoundedRect r, vec4 amount)
@@ -39,16 +45,17 @@ gsk_rounded_rect_offset(inout GskRoundedRect r, vec2 offset)
r.corner_points2.zw += offset;
}
-void gsk_rounded_rect_transform(inout GskRoundedRect r, mat4 mat)
+void
+gsk_rounded_rect_transform(inout GskRoundedRect r)
{
- r.bounds.xy = (mat * vec4(r.bounds.xy, 0.0, 1.0)).xy;
- r.bounds.zw = (mat * vec4(r.bounds.zw, 0.0, 1.0)).xy;
+ r.bounds.xy = u_scale * r.bounds.xy;
+ r.bounds.zw = u_scale * r.bounds.zw;
- r.corner_points1.xy = (mat * vec4(r.corner_points1.xy, 0.0, 1.0)).xy;
- r.corner_points1.zw = (mat * vec4(r.corner_points1.zw, 0.0, 1.0)).xy;
+ r.corner_points1.xy = (u_scale * r.corner_points1.xy);
+ r.corner_points1.zw = (u_scale * r.corner_points1.zw);
- r.corner_points2.xy = (mat * vec4(r.corner_points2.xy, 0.0, 1.0)).xy;
- r.corner_points2.zw = (mat * vec4(r.corner_points2.zw, 0.0, 1.0)).xy;
+ r.corner_points2.xy = (u_scale * r.corner_points2.xy);
+ r.corner_points2.zw = (u_scale * r.corner_points2.zw);
}
#if defined(GSK_LEGACY)
diff --git a/gsk/resources/glsl/radial_gradient.glsl b/gsk/resources/glsl/radial_gradient.glsl
index 0ab3fdf07a..23a01ae4bd 100644
--- a/gsk/resources/glsl/radial_gradient.glsl
+++ b/gsk/resources/glsl/radial_gradient.glsl
@@ -4,13 +4,10 @@ uniform vec4 u_geometry;
_NOPERSPECTIVE_ _OUT_ vec2 coord;
void main() {
- gl_Position = u_projection * (u_modelview * vec4(aPosition, 0.0, 1.0));
+ gl_Position = gsk_project(aPosition);
- vec2 mv0 = u_modelview[0].xy;
- vec2 mv1 = u_modelview[1].xy;
vec2 offset = aPosition - u_geometry.xy;
- vec2 dir = vec2(dot(mv0, offset),
- dot(mv1, offset));
+ vec2 dir = u_scale * offset;
coord = dir * u_geometry.zw;
}
diff --git a/gsk/resources/glsl/repeat.glsl b/gsk/resources/glsl/repeat.glsl
index a9ebcc5e10..f5a756b69b 100644
--- a/gsk/resources/glsl/repeat.glsl
+++ b/gsk/resources/glsl/repeat.glsl
@@ -1,6 +1,6 @@
// VERTEX_SHADER:
void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
+ gl_Position = gsk_project(aPosition);
vUv = vec2(aUv.x, aUv.y);
}
diff --git a/gsk/resources/glsl/transform.glsl b/gsk/resources/glsl/transform.glsl
new file mode 100644
index 0000000000..a79d4a4b1f
--- /dev/null
+++ b/gsk/resources/glsl/transform.glsl
@@ -0,0 +1,22 @@
+// VERTEX_SHADER:
+uniform mat4 u_transform;
+
+void main() {
+ // We are not using gsk_project() here of course. That's the entire
+ // point of this shader.
+ mat4 scale_matrix = mat4(u_scale.x, 0.0, 0.0, 0.0,
+ 0.0, u_scale.y, 0.0, 0.0,
+ 0.0, 0.0, 1.0, 0.0,
+ 0.0, 0.0, 0.0, 1.0);
+ mat4 transform = scale_matrix * u_transform;
+ gl_Position = u_projection * transform * vec4(aPosition, 0.0, 1.0) ;
+
+ vUv = vec2(aUv.x, aUv.y);
+}
+
+// FRAGMENT_SHADER:
+void main() {
+ vec4 diffuse = GskTexture(u_source, vUv);
+
+ gskSetOutputColor(diffuse * u_alpha);
+}
diff --git a/gsk/resources/glsl/unblurred_outset_shadow.glsl b/gsk/resources/glsl/unblurred_outset_shadow.glsl
index f110370412..573bbf6153 100644
--- a/gsk/resources/glsl/unblurred_outset_shadow.glsl
+++ b/gsk/resources/glsl/unblurred_outset_shadow.glsl
@@ -9,8 +9,7 @@ _OUT_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
_OUT_ _GSK_ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
void main() {
- gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
-
+ gl_Position = gsk_project(aPosition);
final_color = gsk_premultiply(u_color) * u_alpha;
GskRoundedRect inside = gsk_create_rect(u_outline_rect);
@@ -18,8 +17,8 @@ void main() {
gsk_rounded_rect_offset(outside, u_offset);
- gsk_rounded_rect_transform(outside, u_modelview);
- gsk_rounded_rect_transform(inside, u_modelview);
+ gsk_rounded_rect_transform(outside);
+ gsk_rounded_rect_transform(inside);
gsk_rounded_rect_encode(outside, transformed_outside_outline);
gsk_rounded_rect_encode(inside, transformed_inside_outline);
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]