summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--docs/reference/gsk/gsk4-sections.txt1
-rw-r--r--gsk/gl/gskglrenderer.c91
-rw-r--r--gsk/gl/gskglrenderops.c8
-rw-r--r--gsk/gl/gskglshaderbuilder.c12
-rw-r--r--gsk/gl/gskglshaderbuilderprivate.h2
-rw-r--r--gsk/gsktransform.c56
-rw-r--r--gsk/gsktransform.h5
-rw-r--r--gsk/meson.build1
-rw-r--r--gsk/resources/glsl/border.glsl25
-rw-r--r--gsk/resources/glsl/inset_shadow.glsl34
-rw-r--r--gsk/resources/glsl/outset_shadow.glsl13
-rw-r--r--gsk/resources/glsl/preamble.fs.glsl90
-rw-r--r--gsk/resources/glsl/preamble.glsl37
-rw-r--r--gsk/resources/glsl/preamble.vs.glsl72
-rw-r--r--gsk/resources/glsl/unblurred_outset_shadow.glsl34
-rw-r--r--gtk/gtkcssimageicontheme.c19
-rw-r--r--gtk/gtkcssimagepaintable.c9
-rw-r--r--gtk/gtkcssimagerecolor.c10
-rw-r--r--gtk/gtkcssimagescaled.c10
-rw-r--r--gtk/gtkwidget.c11
-rw-r--r--testsuite/gsk/compare/transform-in-transform-in-transform.node14
-rw-r--r--testsuite/gsk/compare/transform-in-transform-in-transform.pngbin0 -> 104 bytes
-rw-r--r--testsuite/gsk/compare/transform-in-transform.node10
-rw-r--r--testsuite/gsk/compare/transform-in-transform.pngbin0 -> 121 bytes
-rw-r--r--testsuite/gsk/meson.build2
25 files changed, 385 insertions, 181 deletions
diff --git a/docs/reference/gsk/gsk4-sections.txt b/docs/reference/gsk/gsk4-sections.txt
index 0f464bd195..201840b5c2 100644
--- a/docs/reference/gsk/gsk4-sections.txt
+++ b/docs/reference/gsk/gsk4-sections.txt
@@ -183,6 +183,7 @@ gsk_transform_perspective
gsk_transform_equal
<SUBSECTION>
gsk_transform_transform_bounds
+gsk_transform_transform_point
<SUBSECTION Private>
GSK_TYPE_TRANSFORM
gsk_transform_get_type
diff --git a/gsk/gl/gskglrenderer.c b/gsk/gl/gskglrenderer.c
index ddead714c7..65933080c0 100644
--- a/gsk/gl/gskglrenderer.c
+++ b/gsk/gl/gskglrenderer.c
@@ -535,17 +535,16 @@ transform_rect (GskGLRenderer *self,
RenderOpBuilder *builder,
const GskRoundedRect *rect)
{
- const float scale = ops_get_scale (builder);
GskRoundedRect r;
- int i;
- ops_transform_bounds_modelview (builder, &rect->bounds, &r.bounds);
+ r.bounds.origin.x = builder->dx + rect->bounds.origin.x;
+ r.bounds.origin.y = builder->dy + rect->bounds.origin.y;
+ r.bounds.size = rect->bounds.size;
- for (i = 0; i < 4; i ++)
- {
- r.corner[i].width = rect->corner[i].width * scale;
- r.corner[i].height = rect->corner[i].height * scale;
- }
+ r.corner[0] = rect->corner[0];
+ r.corner[1] = rect->corner[1];
+ r.corner[2] = rect->corner[2];
+ r.corner[3] = rect->corner[3];
return r;
}
@@ -745,24 +744,22 @@ render_border_node (GskGLRenderer *self,
GskRenderNode *node,
RenderOpBuilder *builder)
{
- const float scale = ops_get_scale (builder);
const float min_x = builder->dx + node->bounds.origin.x;
const float min_y = builder->dy + node->bounds.origin.y;
const float max_x = min_x + node->bounds.size.width;
const float max_y = min_y + node->bounds.size.height;
const GdkRGBA *colors = gsk_border_node_peek_colors (node);
const GskRoundedRect *rounded_outline = gsk_border_node_peek_outline (node);
- const float *og_widths = gsk_border_node_peek_widths (node);
- float widths[4];
+ const float *widths = gsk_border_node_peek_widths (node);
int i;
struct {
float w;
float h;
} sizes[4];
- if (og_widths[0] == og_widths[1] &&
- og_widths[0] == og_widths[2] &&
- og_widths[0] == og_widths[3] &&
+ if (widths[0] == widths[1] &&
+ widths[0] == widths[2] &&
+ widths[0] == widths[3] &&
gdk_rgba_equal (&colors[0], &colors[1]) &&
gdk_rgba_equal (&colors[0], &colors[2]) &&
gdk_rgba_equal (&colors[0], &colors[3]))
@@ -773,7 +770,7 @@ render_border_node (GskGLRenderer *self,
op = ops_begin (builder, OP_CHANGE_INSET_SHADOW);
op->color = &colors[0];
op->outline = transform_rect (self, builder, rounded_outline);
- op->spread = og_widths[0] * scale;
+ op->spread = widths[0];
op->offset[0] = 0;
op->offset[1] = 0;
@@ -781,9 +778,6 @@ render_border_node (GskGLRenderer *self,
return;
}
- for (i = 0; i < 4; i ++)
- widths[i] = og_widths[i];
-
/* Top left */
if (widths[3] > 0)
sizes[0].w = MAX (widths[3], rounded_outline->corner[0].width);
@@ -829,9 +823,6 @@ render_border_node (GskGLRenderer *self,
else
sizes[3].h = 0;
- for (i = 0; i < 4; i ++)
- widths[i] *= scale;
-
{
const GskQuadVertex side_data[4][6] = {
/* Top */
@@ -1189,17 +1180,16 @@ render_rounded_clip_node (GskGLRenderer *self,
RenderOpBuilder *builder)
{
const float scale = ops_get_scale (builder);
- GskRoundedRect child_clip = *gsk_rounded_clip_node_peek_clip (node);
- GskRoundedRect transformed_clip;
+ const GskRoundedRect *clip = gsk_rounded_clip_node_peek_clip (node);
GskRenderNode *child = gsk_rounded_clip_node_get_child (node);
+ GskRoundedRect transformed_clip;
gboolean need_offscreen;
int i;
if (node_is_invisible (child))
return;
- transformed_clip = child_clip;
- ops_transform_bounds_modelview (builder, &child_clip.bounds, &transformed_clip.bounds);
+ ops_transform_bounds_modelview (builder, &clip->bounds, &transformed_clip.bounds);
if (!ops_has_clip (builder))
need_offscreen = FALSE;
@@ -1215,8 +1205,8 @@ render_rounded_clip_node (GskGLRenderer *self,
* the new clip and add the render ops */
for (i = 0; i < 4; i ++)
{
- transformed_clip.corner[i].width *= scale;
- transformed_clip.corner[i].height *= scale;
+ transformed_clip.corner[i].width = clip->corner[i].width * scale;
+ transformed_clip.corner[i].height = clip->corner[i].height * scale;
}
ops_push_clip (builder, &transformed_clip);
@@ -1225,7 +1215,7 @@ render_rounded_clip_node (GskGLRenderer *self,
}
else
{
- graphene_matrix_t scale_matrix;
+ GskRoundedRect scaled_clip;
gboolean is_offscreen;
TextureRegion region;
/* NOTE: We are *not* transforming the clip by the current modelview here.
@@ -1234,18 +1224,19 @@ render_rounded_clip_node (GskGLRenderer *self,
*
* We do, however, apply the scale factor to the child clip of course.
*/
-
- graphene_matrix_init_scale (&scale_matrix, scale, scale, 1.0f);
- graphene_matrix_transform_bounds (&scale_matrix, &child_clip.bounds, &child_clip.bounds);
+ scaled_clip.bounds.origin.x = clip->bounds.origin.x * scale;
+ scaled_clip.bounds.origin.y = clip->bounds.origin.y * scale;
+ scaled_clip.bounds.size.width = clip->bounds.size.width * scale;
+ scaled_clip.bounds.size.height = clip->bounds.size.height * scale;
/* Increase corner radius size by scale factor */
for (i = 0; i < 4; i ++)
{
- child_clip.corner[i].width *= scale;
- child_clip.corner[i].height *= scale;
+ scaled_clip.corner[i].width = clip->corner[i].width * scale;
+ scaled_clip.corner[i].height = clip->corner[i].height * scale;
}
- ops_push_clip (builder, &child_clip);
+ ops_push_clip (builder, &scaled_clip);
if (!add_offscreen_ops (self, builder, &node->bounds,
child,
&region, &is_offscreen,
@@ -1455,6 +1446,9 @@ render_blur_node (GskGLRenderer *self,
GskRenderNode *child = gsk_blur_node_get_child (node);
TextureRegion blurred_region;
+ if (node_is_invisible (child))
+ return;
+
if (blur_radius <= 0)
{
gsk_gl_renderer_add_render_ops (self, child, builder);
@@ -1481,7 +1475,6 @@ render_unblurred_inset_shadow_node (GskGLRenderer *self,
GskRenderNode *node,
RenderOpBuilder *builder)
{
- const float scale = ops_get_scale (builder);
const float blur_radius = gsk_inset_shadow_node_get_blur_radius (node);
const float dx = gsk_inset_shadow_node_get_dx (node);
const float dy = gsk_inset_shadow_node_get_dy (node);
@@ -1494,9 +1487,9 @@ render_unblurred_inset_shadow_node (GskGLRenderer *self,
op = ops_begin (builder, OP_CHANGE_INSET_SHADOW);
op->color = gsk_inset_shadow_node_peek_color (node);
op->outline = transform_rect (self, builder, gsk_inset_shadow_node_peek_outline (node));
- op->spread = spread * scale;
- op->offset[0] = dx * scale;
- op->offset[1] = dy * scale;
+ op->spread = spread;
+ op->offset[0] = dx;
+ op->offset[1] = dy;
load_vertex_data (ops_draw (builder, NULL), node, builder);
}
@@ -1647,7 +1640,6 @@ render_unblurred_outset_shadow_node (GskGLRenderer *self,
GskRenderNode *node,
RenderOpBuilder *builder)
{
- const float scale = ops_get_scale (builder);
const GskRoundedRect *outline = gsk_outset_shadow_node_peek_outline (node);
const float spread = gsk_outset_shadow_node_get_spread (node);
const float dx = gsk_outset_shadow_node_get_dx (node);
@@ -1658,9 +1650,9 @@ render_unblurred_outset_shadow_node (GskGLRenderer *self,
op = ops_begin (builder, OP_CHANGE_UNBLURRED_OUTSET_SHADOW);
op->color = gsk_outset_shadow_node_peek_color (node);
op->outline = transform_rect (self, builder, outline);
- op->spread = spread * scale;
- op->offset[0] = dx * scale;
- op->offset[1] = dy * scale;
+ op->spread = spread;
+ op->offset[0] = dx;
+ op->offset[1] = dy;
load_vertex_data (ops_draw (builder, NULL), node, builder);
}
@@ -2163,14 +2155,24 @@ render_cross_fade_node (GskGLRenderer *self,
start_node,
&start_region, &is_offscreen1,
FORCE_OFFSCREEN | RESET_CLIP | RESET_OPACITY))
- g_assert_not_reached ();
+ {
+ gsk_gl_renderer_add_render_ops (self, end_node, builder);
+ return;
+ }
if (!add_offscreen_ops (self, builder,
&node->bounds,
end_node,
&end_region, &is_offscreen2,
FORCE_OFFSCREEN | RESET_CLIP | RESET_OPACITY))
- g_assert_not_reached ();
+ {
+ load_vertex_data_with_region (ops_draw (builder, NULL),
+ node,
+ builder,
+ &start_region,
+ TRUE);
+ return;
+ }
ops_set_program (builder, &self->cross_fade_program);
@@ -2576,6 +2578,7 @@ gsk_gl_renderer_create_programs (GskGLRenderer *self,
gboolean success = TRUE;
gsk_gl_shader_builder_init (&shader_builder,
+ "/org/gtk/libgsk/glsl/preamble.glsl",
"/org/gtk/libgsk/glsl/preamble.vs.glsl",
"/org/gtk/libgsk/glsl/preamble.fs.glsl");
diff --git a/gsk/gl/gskglrenderops.c b/gsk/gl/gskglrenderops.c
index 39916be36c..f113df5edf 100644
--- a/gsk/gl/gskglrenderops.c
+++ b/gsk/gl/gskglrenderops.c
@@ -180,13 +180,15 @@ ops_transform_bounds_modelview (const RenderOpBuilder *builder,
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);
- gsk_transform_transform_bounds (builder->current_modelview, src, dst);
+ r.origin.x += builder->dx;
+ r.origin.y += builder->dy;
- dst->origin.x += builder->dx * builder->scale_x;
- dst->origin.y += builder->dy * builder->scale_y;
+ gsk_transform_transform_bounds (builder->current_modelview, &r, dst);
}
void
diff --git a/gsk/gl/gskglshaderbuilder.c b/gsk/gl/gskglshaderbuilder.c
index f28bf127f7..a133527784 100644
--- a/gsk/gl/gskglshaderbuilder.c
+++ b/gsk/gl/gskglshaderbuilder.c
@@ -9,14 +9,17 @@
void
gsk_gl_shader_builder_init (GskGLShaderBuilder *self,
+ const char *common_preamble_resource_path,
const char *vs_preamble_resource_path,
const char *fs_preamble_resource_path)
{
memset (self, 0, sizeof (*self));
+ self->preamble = g_resources_lookup_data (common_preamble_resource_path, 0, NULL);
self->vs_preamble = g_resources_lookup_data (vs_preamble_resource_path, 0, NULL);
self->fs_preamble = g_resources_lookup_data (fs_preamble_resource_path, 0, NULL);
+ g_assert (self->preamble);
g_assert (self->vs_preamble);
g_assert (self->fs_preamble);
}
@@ -24,6 +27,7 @@ gsk_gl_shader_builder_init (GskGLShaderBuilder *self,
void
gsk_gl_shader_builder_finish (GskGLShaderBuilder *self)
{
+ g_bytes_unref (self->preamble);
g_bytes_unref (self->vs_preamble);
g_bytes_unref (self->fs_preamble);
}
@@ -102,13 +106,14 @@ gsk_gl_shader_builder_create_program (GskGLShaderBuilder *self,
"#version %d\n", self->version);
vertex_id = glCreateShader (GL_VERTEX_SHADER);
- glShaderSource (vertex_id, 7,
+ glShaderSource (vertex_id, 8,
(const char *[]) {
version_buffer,
self->debugging ? "#define GSK_DEBUG 1\n" : "",
self->legacy ? "#define GSK_LEGACY 1\n" : "",
self->gl3 ? "#define GSK_GL3 1\n" : "",
self->gles ? "#define GSK_GLES 1\n" : "",
+ g_bytes_get_data (self->preamble, NULL),
g_bytes_get_data (self->vs_preamble, NULL),
vertex_shader_start
},
@@ -119,6 +124,7 @@ gsk_gl_shader_builder_create_program (GskGLShaderBuilder *self,
-1,
-1,
-1,
+ -1,
fragment_shader_start - vertex_shader_start
});
glCompileShader (vertex_id);
@@ -130,13 +136,14 @@ gsk_gl_shader_builder_create_program (GskGLShaderBuilder *self,
}
fragment_id = glCreateShader (GL_FRAGMENT_SHADER);
- glShaderSource (fragment_id, 7,
+ glShaderSource (fragment_id, 8,
(const char *[]) {
version_buffer,
self->debugging ? "#define GSK_DEBUG 1\n" : "",
self->legacy ? "#define GSK_LEGACY 1\n" : "",
self->gl3 ? "#define GSK_GL3 1\n" : "",
self->gles ? "#define GSK_GLES 1\n" : "",
+ g_bytes_get_data (self->preamble, NULL),
g_bytes_get_data (self->fs_preamble, NULL),
fragment_shader_start
},
@@ -148,6 +155,7 @@ gsk_gl_shader_builder_create_program (GskGLShaderBuilder *self,
-1,
-1,
-1,
+ -1,
});
glCompileShader (fragment_id);
diff --git a/gsk/gl/gskglshaderbuilderprivate.h b/gsk/gl/gskglshaderbuilderprivate.h
index 209fa5ff91..ec9cd66845 100644
--- a/gsk/gl/gskglshaderbuilderprivate.h
+++ b/gsk/gl/gskglshaderbuilderprivate.h
@@ -8,6 +8,7 @@ G_BEGIN_DECLS
typedef struct
{
+ GBytes *preamble;
GBytes *vs_preamble;
GBytes *fs_preamble;
@@ -22,6 +23,7 @@ typedef struct
void gsk_gl_shader_builder_init (GskGLShaderBuilder *self,
+ const char *common_preamble_resource_path,
const char *vs_preamble_resource_path,
const char *fs_preamble_resource_path);
void gsk_gl_shader_builder_finish (GskGLShaderBuilder *self);
diff --git a/gsk/gsktransform.c b/gsk/gsktransform.c
index 388dad5b45..5d9d538d4c 100644
--- a/gsk/gsktransform.c
+++ b/gsk/gsktransform.c
@@ -1773,6 +1773,62 @@ gsk_transform_transform_bounds (GskTransform *self,
}
}
+/**
+ * gsk_transform_transform_point:
+ * @self: a #GskTransform
+ * @point: a #graphene_point_t
+ * @out_point: (out caller-allocates): return location for
+ * the transformed point
+ *
+ * Transforms a #graphene_point_t using the given transform @self.
+ */
+void
+gsk_transform_transform_point (GskTransform *self,
+ const graphene_point_t *point,
+ graphene_point_t *out_point)
+{
+ switch (gsk_transform_get_category (self))
+ {
+ case GSK_TRANSFORM_CATEGORY_IDENTITY:
+ *out_point = *point;
+ break;
+
+ case GSK_TRANSFORM_CATEGORY_2D_TRANSLATE:
+ {
+ float dx, dy;
+
+ gsk_transform_to_translate (self, &dx, &dy);
+ out_point->x = point->x + dx;
+ out_point->y = point->y + dy;
+ }
+ break;
+
+ case GSK_TRANSFORM_CATEGORY_2D_AFFINE:
+ {
+ float dx, dy, scale_x, scale_y;
+
+ gsk_transform_to_affine (self, &scale_x, &scale_y, &dx, &dy);
+
+ out_point->x = (point->x * scale_x) + dx;
+ out_point->y = (point->y * scale_y) + dy;
+ }
+ break;
+
+ case GSK_TRANSFORM_CATEGORY_UNKNOWN:
+ case GSK_TRANSFORM_CATEGORY_ANY:
+ case GSK_TRANSFORM_CATEGORY_3D:
+ case GSK_TRANSFORM_CATEGORY_2D:
+ default:
+ {
+ graphene_matrix_t mat;
+
+ gsk_transform_to_matrix (self, &mat);
+ graphene_matrix_transform_point (&mat, point, out_point);
+ }
+ break;
+ }
+}
+
static guint
gsk_transform_parse_float (GtkCssParser *parser,
guint n,
diff --git a/gsk/gsktransform.h b/gsk/gsktransform.h
index 56cafcc430..f3676bca63 100644
--- a/gsk/gsktransform.h
+++ b/gsk/gsktransform.h
@@ -116,6 +116,11 @@ GDK_AVAILABLE_IN_ALL
void gsk_transform_transform_bounds (GskTransform *self,
const graphene_rect_t *rect,
graphene_rect_t *out_rect);
+GDK_AVAILABLE_IN_ALL
+void gsk_transform_transform_point (GskTransform *self,
+ const graphene_point_t *point,
+ graphene_point_t *out_point);
+
G_END_DECLS
diff --git a/gsk/meson.build b/gsk/meson.build
index 6dd4925155..8aeae9e7e8 100644
--- a/gsk/meson.build
+++ b/gsk/meson.build
@@ -1,4 +1,5 @@
gsk_private_gl_shaders = [
+ 'resources/glsl/preamble.glsl',
'resources/glsl/preamble.fs.glsl',
'resources/glsl/preamble.vs.glsl',
'resources/glsl/border.glsl',
diff --git a/gsk/resources/glsl/border.glsl b/gsk/resources/glsl/border.glsl
index a47fe7e393..812d365431 100644
--- a/gsk/resources/glsl/border.glsl
+++ b/gsk/resources/glsl/border.glsl
@@ -1,7 +1,11 @@
// VERTEX_SHADER:
uniform vec4 u_color;
+uniform vec4 u_widths;
+uniform vec4[3] u_outline_rect;
_OUT_ vec4 final_color;
+_OUT_ _ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
+_OUT_ _ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
void main() {
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
@@ -9,25 +13,32 @@ void main() {
final_color = u_color;
final_color.rgb *= final_color.a; // pre-multiply
final_color *= u_alpha;
+
+ RoundedRect outside = create_rect(u_outline_rect);
+ RoundedRect inside = rounded_rect_shrink (outside, u_widths);
+
+ rounded_rect_transform(outside, u_modelview);
+ rounded_rect_transform(inside, u_modelview);
+
+ rounded_rect_encode(outside, transformed_outside_outline);
+ rounded_rect_encode(inside, transformed_inside_outline);
}
// FRAGMENT_SHADER:
-uniform vec4 u_widths;
uniform vec4[3] u_outline_rect;
_IN_ vec4 final_color;
+_IN_ _ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
+_IN_ _ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
void main() {
vec4 f = gl_FragCoord;
f.x += u_viewport.x;
f.y = (u_viewport.y + u_viewport.w) - f.y;
- RoundedRect outside = create_rect(u_outline_rect);
- RoundedRect inside = rounded_rect_shrink (outside, u_widths);
-
- float alpha = clamp (rounded_rect_coverage (outside, f.xy) -
- rounded_rect_coverage (inside, f.xy),
- 0.0, 1.0);
+ float alpha = clamp(rounded_rect_coverage(decode_rect(transformed_outside_outline), f.xy) -
+ rounded_rect_coverage(decode_rect(transformed_inside_outline), f.xy),
+ 0.0, 1.0);
setOutputColor(final_color * alpha);
}
diff --git a/gsk/resources/glsl/inset_shadow.glsl b/gsk/resources/glsl/inset_shadow.glsl
index 425b140391..b3ba05a41f 100644
--- a/gsk/resources/glsl/inset_shadow.glsl
+++ b/gsk/resources/glsl/inset_shadow.glsl
@@ -1,7 +1,12 @@
// VERTEX_SHADER:
uniform vec4 u_color;
+uniform float u_spread;
+uniform vec2 u_offset;
+uniform vec4[3] u_outline_rect;
_OUT_ vec4 final_color;
+_OUT_ _ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
+_OUT_ _ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
void main() {
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
@@ -9,26 +14,33 @@ void main() {
final_color = u_color;
final_color.rgb *= final_color.a;
final_color *= u_alpha;
+
+ RoundedRect outside = create_rect(u_outline_rect);
+ RoundedRect inside = rounded_rect_shrink(outside, vec4(u_spread));
+
+ rounded_rect_offset(inside, u_offset);
+
+ rounded_rect_transform(outside, u_modelview);
+ rounded_rect_transform(inside, u_modelview);
+
+ rounded_rect_encode(outside, transformed_outside_outline);
+ rounded_rect_encode(inside, transformed_inside_outline);
}
// FRAGMENT_SHADER:
-uniform float u_spread;
-uniform vec2 u_offset;
-uniform vec4[3] u_outline_rect;
-
_IN_ vec4 final_color;
+_IN_ _ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
+_IN_ _ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
void main() {
vec4 f = gl_FragCoord;
- vec4 color;
f.x += u_viewport.x;
f.y = (u_viewport.y + u_viewport.w) - f.y;
- RoundedRect outside = create_rect(u_outline_rect);
- RoundedRect inside = rounded_rect_shrink(outside, vec4(u_spread));
- color = final_color * clamp (rounded_rect_coverage (outside, f.xy) -
- rounded_rect_coverage (inside, f.xy - u_offset),
- 0.0, 1.0);
- setOutputColor(color);
+ float alpha = clamp (rounded_rect_coverage(decode_rect(transformed_outside_outline), f.xy) -
+ rounded_rect_coverage(decode_rect(transformed_inside_outline), f.xy),
+ 0.0, 1.0);
+
+ setOutputColor(final_color * alpha);
}
diff --git a/gsk/resources/glsl/outset_shadow.glsl b/gsk/resources/glsl/outset_shadow.glsl
index f0c5b3fede..4111ddcea8 100644
--- a/gsk/resources/glsl/outset_shadow.glsl
+++ b/gsk/resources/glsl/outset_shadow.glsl
@@ -1,7 +1,9 @@
// VERTEX_SHADER:
uniform vec4 u_color;
+uniform vec4[3] u_outline_rect;
_OUT_ vec4 final_color;
+_OUT_ _ROUNDED_RECT_UNIFORM_ transformed_outline;
void main() {
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
@@ -12,12 +14,15 @@ void main() {
// pre-multiply
final_color.rgb *= final_color.a;
final_color *= u_alpha;
+
+ RoundedRect outline = create_rect(u_outline_rect);
+ rounded_rect_transform(outline, u_modelview);
+ rounded_rect_encode(outline, transformed_outline);
}
// FRAGMENT_SHADER:
-uniform vec4[3] u_outline_rect;
-
_IN_ vec4 final_color;
+_IN_ _ROUNDED_RECT_UNIFORM_ transformed_outline;
void main() {
vec4 f = gl_FragCoord;
@@ -25,10 +30,8 @@ void main() {
f.x += u_viewport.x;
f.y = (u_viewport.y + u_viewport.w) - f.y;
- RoundedRect outline = create_rect(u_outline_rect);
-
float alpha = Texture(u_source, vUv).a;
- alpha *= (1.0 - clamp(rounded_rect_coverage(outline, f.xy), 0.0, 1.0));
+ alpha *= (1.0 - clamp(rounded_rect_coverage(decode_rect(transformed_outline), f.xy), 0.0, 1.0));
vec4 color = final_color * alpha;
diff --git a/gsk/resources/glsl/preamble.fs.glsl b/gsk/resources/glsl/preamble.fs.glsl
index 00a8c2135e..5107470e00 100644
--- a/gsk/resources/glsl/preamble.fs.glsl
+++ b/gsk/resources/glsl/preamble.fs.glsl
@@ -1,12 +1,3 @@
-#ifdef GSK_GL3
-precision highp float;
-#endif
-
-#ifdef GSK_GLES
-precision highp float;
-#endif
-
-
uniform sampler2D u_source;
uniform mat4 u_projection;
uniform mat4 u_modelview;
@@ -15,36 +6,23 @@ uniform vec4 u_viewport;
uniform vec4[3] u_clip_rect;
#if GSK_GLES
-#define _OUT_ varying
-#define _IN_ varying
#elif GSK_LEGACY
-#define _OUT_ varying
-#define _IN_ varying
_OUT_ vec4 outputColor;
#else
-#define _OUT_ out
-#define _IN_ in
_OUT_ vec4 outputColor;
#endif
+
_IN_ vec2 vUv;
-struct RoundedRect
+RoundedRect decode_rect(_ROUNDED_RECT_UNIFORM_ r)
{
- vec4 bounds;
- vec4 corner_widths;
- vec4 corner_heights;
-};
-
-// Transform from a GskRoundedRect to a RoundedRect as we need it.
-RoundedRect
-create_rect(vec4 data[3])
-{
- vec4 bounds = vec4(data[0].xy, data[0].xy + data[0].zw);
- vec4 widths = vec4(data[1].x, data[1].z, data[2].x, data[2].z);
- vec4 heights = vec4(data[1].y, data[1].w, data[2].y, data[2].w);
- return RoundedRect(bounds, widths, heights);
+#if defined(GSK_GLES) || defined(GSK_LEGACY)
+ return RoundedRect(r[0], r[1], r[2]);
+#else
+ return r;
+#endif
}
float
@@ -73,15 +51,15 @@ rounded_rect_coverage (RoundedRect r, vec2 p)
p.x >= r.bounds.z || p.y >= r.bounds.w)
return 0.0;
- vec2 rad_tl = vec2(r.corner_widths.x, r.corner_heights.x);
- vec2 rad_tr = vec2(r.corner_widths.y, r.corner_heights.y);
- vec2 rad_br = vec2(r.corner_widths.z, r.corner_heights.z);
- vec2 rad_bl = vec2(r.corner_widths.w, r.corner_heights.w);
+ vec2 rad_tl = r.corner_points1.xy - r.bounds.xy;
+ vec2 rad_tr = r.corner_points1.zw - r.bounds.zy;
+ vec2 rad_br = r.corner_points2.xy - r.bounds.zw;
+ vec2 rad_bl = r.corner_points2.zw - r.bounds.xw;
- vec2 ref_tl = r.bounds.xy + vec2( r.corner_widths.x, r.corner_heights.x);
- vec2 ref_tr = r.bounds.zy + vec2(-r.corner_widths.y, r.corner_heights.y);
- vec2 ref_br = r.bounds.zw + vec2(-r.corner_widths.z, -r.corner_heights.z);
- vec2 ref_bl = r.bounds.xw + vec2( r.corner_widths.w, -r.corner_heights.w);
+ vec2 ref_tl = r.corner_points1.xy;
+ vec2 ref_tr = r.corner_points1.zw;
+ vec2 ref_br = r.corner_points2.xy;
+ vec2 ref_bl = r.corner_points2.zw;
float d_tl = ellipsis_coverage(p, ref_tl, rad_tl);
float d_tr = ellipsis_coverage(p, ref_tr, rad_tr);
@@ -98,37 +76,8 @@ rounded_rect_coverage (RoundedRect r, vec2 p)
return 1.0 - dot(vec4(is_out), corner_coverages);
}
-// amount is: top, right, bottom, left
-RoundedRect
-rounded_rect_shrink (RoundedRect r, vec4 amount)
-{
- vec4 new_bounds = r.bounds + vec4(1.0,1.0,-1.0,-1.0) * amount.wxyz;
- vec4 new_widths = vec4(0);
- vec4 new_heights = vec4(0);
-
- // Left top
- if (r.corner_widths.x > 0.0) new_widths.x = r.corner_widths.x - amount.w;
- if (r.corner_heights.x > 0.0) new_heights.x = r.corner_heights.x - amount.x;
-
- // Top right
- if (r.corner_widths.y > 0.0) new_widths.y = r.corner_widths.y - amount.y;
- if (r.corner_heights.y > 0.0) new_heights.y = r.corner_heights.y - amount.x;
-
- // Bottom right
- if (r.corner_widths.z > 0.0) new_widths.z = r.corner_widths.z - amount.y;
- if (r.corner_heights.z > 0.0) new_heights.z = r.corner_heights.z - amount.z;
-
- // Bottom left
- if (r.corner_widths.w > 0.0) new_widths.w = r.corner_widths.w - amount.w;
- if (r.corner_heights.w > 0.0) new_heights.w = r.corner_heights.w - amount.z;
-
- return RoundedRect (new_bounds, new_widths, new_heights);
-}
-
vec4 Texture(sampler2D sampler, vec2 texCoords) {
-#if GSK_GLES
- return texture2D(sampler, texCoords);
-#elif GSK_LEGACY
+#if defined(GSK_GLES) || defined(GSK_LEGACY)
return texture2D(sampler, texCoords);
#else
return texture(sampler, texCoords);
@@ -141,9 +90,10 @@ void setOutputColor(vec4 color) {
f.x += u_viewport.x;
f.y = (u_viewport.y + u_viewport.w) - f.y;
-#if GSK_GLES
- gl_FragColor = color * rounded_rect_coverage(create_rect(u_clip_rect), f.xy);
-#elif GSK_LEGACY
+
+ // We do *NOT* transform the clip rect here since we already
+ // need to do that on the CPU.
+#if defined(GSK_GLES) || defined(GSK_LEGACY)
gl_FragColor = color * rounded_rect_coverage(create_rect(u_clip_rect), f.xy);
#else
outputColor = color * rounded_rect_coverage(create_rect(u_clip_rect), f.xy);
diff --git a/gsk/resources/glsl/preamble.glsl b/gsk/resources/glsl/preamble.glsl
new file mode 100644
index 0000000000..9dd711cbd2
--- /dev/null
+++ b/gsk/resources/glsl/preamble.glsl
@@ -0,0 +1,37 @@
+#ifndef GSK_LEGACY
+precision highp float;
+#endif
+
+#if defined(GSK_GLES) || defined(GSK_LEGACY)
+#define _OUT_ varying
+#define _IN_ varying
+#define _ROUNDED_RECT_UNIFORM_ vec4[3]
+#else
+#define _OUT_ out
+#define _IN_ in
+#define _ROUNDED_RECT_UNIFORM_ RoundedRect
+#endif
+
+
+struct RoundedRect
+{
+ vec4 bounds;
+ // Look, arrays can't be in structs if you want to return the struct
+ // from a function in gles or whatever. Just kill me.
+ vec4 corner_points1; // xy = top left, zw = top right
+ vec4 corner_points2; // xy = bottom right, zw = bottom left
+};
+
+// Transform from a GskRoundedRect to a RoundedRect as we need it.
+RoundedRect
+create_rect(vec4[3] data)
+{
+ vec4 bounds = vec4(data[0].xy, data[0].xy + data[0].zw);
+
+ vec4 corner_points1 = vec4(bounds.xy + data[1].xy,
+ bounds.zy + vec2(data[1].zw * vec2(-1, 1)));
+ vec4 corner_points2 = vec4(bounds.zw + (data[2].xy * vec2(-1, -1)),
+ bounds.xw + vec2(data[2].zw * vec2(1, -1)));
+
+ return RoundedRect(bounds, corner_points1, corner_points2);
+}
diff --git a/gsk/resources/glsl/preamble.vs.glsl b/gsk/resources/glsl/preamble.vs.glsl
index 94c4f276a4..76de2d6561 100644
--- a/gsk/resources/glsl/preamble.vs.glsl
+++ b/gsk/resources/glsl/preamble.vs.glsl
@@ -2,26 +2,68 @@ uniform mat4 u_projection;
uniform mat4 u_modelview;
uniform float u_alpha;
-#ifdef GSK_GLES
-precision highp float;
-#endif
-
-#if GSK_GLES
-#define _OUT_ varying
-#define _IN_ varying
-attribute vec2 aPosition;
-attribute vec2 aUv;
-_OUT_ vec2 vUv;
-#elif GSK_LEGACY
-#define _OUT_ varying
-#define _IN_ varying
+#if defined(GSK_GLES) || defined(GSK_LEGACY)
attribute vec2 aPosition;
attribute vec2 aUv;
_OUT_ vec2 vUv;
#else
-#define _OUT_ out
-#define _IN_ in
_IN_ vec2 aPosition;
_IN_ vec2 aUv;
_OUT_ vec2 vUv;
#endif
+
+// amount is: top, right, bottom, left
+RoundedRect
+rounded_rect_shrink (RoundedRect r, vec4 amount)
+{
+ vec4 new_bounds = r.bounds + vec4(1.0,1.0,-1.0,-1.0) * amount.wxyz;
+ vec4 new_corner_points1 = r.corner_points1;
+ vec4 new_corner_points2 = r.corner_points2;
+
+ if (r.corner_points1.xy == r.bounds.xy) new_corner_points1.xy = new_bounds.xy;
+ if (r.corner_points1.zw == r.bounds.zy) new_corner_points1.zw = new_bounds.zy;
+ if (r.corner_points2.xy == r.bounds.zw) new_corner_points2.xy = new_bounds.zw;
+ if (r.corner_points2.zw == r.bounds.xw) new_corner_points2.zw = new_bounds.xw;
+
+ return RoundedRect (new_bounds, new_corner_points1, new_corner_points2);
+}
+
+void
+rounded_rect_offset(inout RoundedRect r, vec2 offset)
+{
+ r.bounds.xy += offset;
+ r.bounds.zw += offset;
+ r.corner_points1.xy += offset;
+ r.corner_points1.zw += offset;
+ r.corner_points2.xy += offset;
+ r.corner_points2.zw += offset;
+}
+
+void rounded_rect_transform(inout RoundedRect r, mat4 mat)
+{
+ 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.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_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;
+}
+
+#if defined(GSK_LEGACY)
+// Can't have out or inout array parameters...
+#define rounded_rect_encode(r, uni) uni[0] = r.bounds; uni[1] = r.corner_points1; uni[2] = r.corner_points2;
+#else
+void rounded_rect_encode(RoundedRect r, out _ROUNDED_RECT_UNIFORM_ out_r)
+{
+#if defined(GSK_GLES)
+ out_r[0] = r.bounds;
+ out_r[1] = r.corner_points1;
+ out_r[2] = r.corner_points2;
+#else
+ out_r = r;
+#endif
+}
+
+#endif
diff --git a/gsk/resources/glsl/unblurred_outset_shadow.glsl b/gsk/resources/glsl/unblurred_outset_shadow.glsl
index f48288d05c..77c02be8e1 100644
--- a/gsk/resources/glsl/unblurred_outset_shadow.glsl
+++ b/gsk/resources/glsl/unblurred_outset_shadow.glsl
@@ -1,7 +1,12 @@
// VERTEX_SHADER:
uniform vec4 u_color;
+uniform float u_spread;
+uniform vec2 u_offset;
+uniform vec4[3] u_outline_rect;
_OUT_ vec4 final_color;
+_OUT_ _ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
+_OUT_ _ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
void main() {
gl_Position = u_projection * u_modelview * vec4(aPosition, 0.0, 1.0);
@@ -9,26 +14,33 @@ void main() {
final_color = u_color;
final_color.rgb *= final_color.a;
final_color *= u_alpha;
+
+ RoundedRect inside = create_rect(u_outline_rect);
+ RoundedRect outside = rounded_rect_shrink(inside, vec4(- u_spread));
+
+ rounded_rect_offset(outside, u_offset);
+
+ rounded_rect_transform(outside, u_modelview);
+ rounded_rect_transform(inside, u_modelview);
+
+ rounded_rect_encode(outside, transformed_outside_outline);
+ rounded_rect_encode(inside, transformed_inside_outline);
}
// FRAGMENT_SHADER:
-uniform float u_spread;
-uniform vec2 u_offset;
-uniform vec4[3] u_outline_rect;
-
_IN_ vec4 final_color;
+_IN_ _ROUNDED_RECT_UNIFORM_ transformed_outside_outline;
+_IN_ _ROUNDED_RECT_UNIFORM_ transformed_inside_outline;
void main() {
vec4 f = gl_FragCoord;
- vec4 color;
f.x += u_viewport.x;
f.y = (u_viewport.y + u_viewport.w) - f.y;
- RoundedRect inside = create_rect(u_outline_rect);
- RoundedRect outside = rounded_rect_shrink(inside, vec4(- u_spread));
- color = final_color * clamp (rounded_rect_coverage (outside, f.xy - u_offset) -
- rounded_rect_coverage (inside, f.xy),
- 0.0, 1.0);
- setOutputColor(color);
+ float alpha = clamp(rounded_rect_coverage(decode_rect(transformed_outside_outline), f.xy) -
+ rounded_rect_coverage(decode_rect(transformed_inside_outline), f.xy),
+ 0.0, 1.0);
+
+ setOutputColor(final_color * alpha);
}
diff --git a/gtk/gtkcssimageicontheme.c b/gtk/gtkcssimageicontheme.c
index c2a21c41b9..508c90d435 100644
--- a/gtk/gtkcssimageicontheme.c
+++ b/gtk/gtkcssimageicontheme.c
@@ -94,21 +94,22 @@ gtk_css_image_icon_theme_snapshot (GtkCssImage *image,
if (symbolic)
{
+ const GdkRGBA *fg = &icon_theme->color;
+ const GdkRGBA *sc = &icon_theme->success;
+ const GdkRGBA *wc = &icon_theme->warning;
+ const GdkRGBA *ec = &icon_theme->error;
graphene_matrix_t matrix;
graphene_vec4_t offset;
- GdkRGBA fg = icon_theme->color;
- GdkRGBA sc = icon_theme->success;
- GdkRGBA wc = icon_theme->warning;
- GdkRGBA ec = icon_theme->error;
+
graphene_matrix_init_from_float (&matrix,
(float[16]) {
- sc.red - fg.red, sc.green - fg.green, sc.blue - fg.blue, 0,
- wc.red - fg.red, wc.green - fg.green, wc.blue - fg.blue, 0,
- ec.red - fg.red, ec.green - fg.green, ec.blue - fg.blue, 0,
- 0, 0, 0, fg.alpha
+ sc->red - fg->red, sc->green - fg->green, sc->blue - fg->blue, 0,
+ wc->red - fg->red, wc->green - fg->green, wc->blue - fg->blue, 0,
+ ec->red - fg->red, ec->green - fg->green, ec->blue - fg->blue, 0,
+ 0, 0, 0, fg->alpha
});
- graphene_vec4_init (&offset, fg.red, fg.green, fg.blue, 0);
+ graphene_vec4_init (&offset, fg->red, fg->green, fg->blue, 0);
gtk_snapshot_push_color_matrix (snapshot, &matrix, &offset);
}
diff --git a/gtk/gtkcssimagepaintable.c b/gtk/gtkcssimagepaintable.c
index 327ca90862..d4056ab263 100644
--- a/gtk/gtkcssimagepaintable.c
+++ b/gtk/gtkcssimagepaintable.c
@@ -150,6 +150,14 @@ gtk_css_image_paintable_dispose (GObject *object)
G_OBJECT_CLASS (gtk_css_image_paintable_parent_class)->dispose (object);
}
+static gboolean
+gtk_css_image_paintable_is_computed (GtkCssImage *image)
+{
+ GtkCssImagePaintable *self = GTK_CSS_IMAGE_PAINTABLE (image);
+
+ return (gdk_paintable_get_flags (self->paintable) & GDK_PAINTABLE_IMMUTABLE) == GDK_PAINTABLE_IMMUTABLE;
+}
+
static void
gtk_css_image_paintable_class_init (GtkCssImagePaintableClass *klass)
{
@@ -164,6 +172,7 @@ gtk_css_image_paintable_class_init (GtkCssImagePaintableClass *klass)
image_class->compute = gtk_css_image_paintable_compute;
image_class->equal = gtk_css_image_paintable_equal;
image_class->is_dynamic = gtk_css_image_paintable_is_dynamic;
+ image_class->is_computed = gtk_css_image_paintable_is_computed;
image_class->get_dynamic_image = gtk_css_image_paintable_get_dynamic_image;
object_class->dispose = gtk_css_image_paintable_dispose;
diff --git a/gtk/gtkcssimagerecolor.c b/gtk/gtkcssimagerecolor.c
index 36cc7bd9c4..4094de8a78 100644
--- a/gtk/gtkcssimagerecolor.c
+++ b/gtk/gtkcssimagerecolor.c
@@ -308,6 +308,15 @@ gtk_css_image_recolor_get_height (GtkCssImage *image)
return gdk_texture_get_height (recolor->texture);
}
+static gboolean
+gtk_css_image_recolor_is_computed (GtkCssImage *image)
+{
+ GtkCssImageRecolor *recolor = GTK_CSS_IMAGE_RECOLOR (image);
+
+ return recolor->texture &&
+ (!recolor->palette || gtk_css_value_is_computed (recolor->palette));
+}
+
static void
_gtk_css_image_recolor_class_init (GtkCssImageRecolorClass *klass)
{
@@ -320,6 +329,7 @@ _gtk_css_image_recolor_class_init (GtkCssImageRecolorClass *klass)
image_class->snapshot = gtk_css_image_recolor_snapshot;
image_class->parse = gtk_css_image_recolor_parse;
image_class->print = gtk_css_image_recolor_print;
+ image_class->is_computed = gtk_css_image_recolor_is_computed;
object_class->dispose = gtk_css_image_recolor_dispose;
}
diff --git a/gtk/gtkcssimagescaled.c b/gtk/gtkcssimagescaled.c
index 5fce72949b..6dd3b05b4e 100644
--- a/gtk/gtkcssimagescaled.c
+++ b/gtk/gtkcssimagescaled.c
@@ -203,6 +203,15 @@ gtk_css_image_scaled_parse (GtkCssImage *image,
return TRUE;
}
+static gboolean
+gtk_css_image_scaled_is_computed (GtkCssImage *image)
+{
+ GtkCssImageScaled *self = GTK_CSS_IMAGE_SCALED (image);
+
+ return self->n_images == 1 &&
+ gtk_css_image_is_computed (self->images[0]);
+}
+
static void
_gtk_css_image_scaled_class_init (GtkCssImageScaledClass *klass)
{
@@ -216,6 +225,7 @@ _gtk_css_image_scaled_class_init (GtkCssImageScaledClass *klass)
image_class->parse = gtk_css_image_scaled_parse;
image_class->compute = gtk_css_image_scaled_compute;
image_class->print = gtk_css_image_scaled_print;
+ image_class->is_computed = gtk_css_image_scaled_is_computed;
object_class->dispose = gtk_css_image_scaled_dispose;
}
diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c
index f3224d2cb6..283c5163e3 100644
--- a/gtk/gtkwidget.c
+++ b/gtk/gtkwidget.c
@@ -10502,12 +10502,15 @@ gtk_widget_do_pick (GtkWidget *widget,
{
transform = NULL;
}
- if (gsk_transform_get_category (transform) >= GSK_TRANSFORM_CATEGORY_2D_TRANSLATE)
+
+ if (gsk_transform_get_category (transform) >= GSK_TRANSFORM_CATEGORY_2D_AFFINE)
{
- float dx, dy;
+ graphene_point_t transformed_p;
- gsk_transform_to_translate (transform, &dx, &dy);
- graphene_point3d_init (&res, x + dx, y + dy, 0.);
+ gsk_transform_transform_point (transform,
+ &(graphene_point_t) { x, y },
+ &transformed_p);
+ graphene_point3d_init (&res, transformed_p.x, transformed_p.y, 0.);
}
else
{
diff --git a/testsuite/gsk/compare/transform-in-transform-in-transform.node b/testsuite/gsk/compare/transform-in-transform-in-transform.node
new file mode 100644
index 0000000000..6c8a2f11aa
--- /dev/null
+++ b/testsuite/gsk/compare/transform-in-transform-in-transform.node
@@ -0,0 +1,14 @@
+transform {
+ child: transform {
+ child: transform {
+ child: color {
+ bounds: 0 0 20 20;
+ color: blue;
+ }
+ transform: translate(0, -20);
+ }
+ transform: rotate(90);
+ }
+
+ transform: translate(300, 200);
+}
diff --git a/testsuite/gsk/compare/transform-in-transform-in-transform.png b/testsuite/gsk/compare/transform-in-transform-in-transform.png
new file mode 100644
index 0000000000..8b8846daca
--- /dev/null
+++ b/testsuite/gsk/compare/transform-in-transform-in-transform.png
Binary files differ
diff --git a/testsuite/gsk/compare/transform-in-transform.node b/testsuite/gsk/compare/transform-in-transform.node
new file mode 100644
index 0000000000..25689f479b
--- /dev/null
+++ b/testsuite/gsk/compare/transform-in-transform.node
@@ -0,0 +1,10 @@
+transform {
+ child: transform {
+ child: color {
+ bounds: 0 0 20 20;
+ color: blue;
+ }
+ transform: translate(0, -20);
+ }
+ transform: scale(2) rotate(90);
+}
diff --git a/testsuite/gsk/compare/transform-in-transform.png b/testsuite/gsk/compare/transform-in-transform.png
new file mode 100644
index 0000000000..90b7de6096
--- /dev/null
+++ b/testsuite/gsk/compare/transform-in-transform.png
Binary files differ
diff --git a/testsuite/gsk/meson.build b/testsuite/gsk/meson.build
index aadc40642b..bee40fd32e 100644
--- a/testsuite/gsk/meson.build
+++ b/testsuite/gsk/meson.build
@@ -64,6 +64,8 @@ compare_render_tests = [
'inset-shadow-multiple',
'borders-rotated',
'blend-invisible-child',
+ 'transform-in-transform',
+ 'transform-in-transform-in-transform',
]
# these are too sensitive to differences in the renderers