summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2021-05-13 17:32:52 -0400
committerMatthias Clasen <mclasen@redhat.com>2021-05-13 19:37:16 -0400
commit8e7bc8d74264324bccc4334d9ead0aba2c048a0d (patch)
tree734edf9593f19cd630e6d0f8af7f96fe05bbc772
parent809299f9e48662c731123181d54f4fc66891aca4 (diff)
downloadgtk+-8e7bc8d74264324bccc4334d9ead0aba2c048a0d.tar.gz
Improve transformed offscreen rendering
Preserve the scale for 2D transforms to avoid a pixellated appearance.
-rw-r--r--gsk/ngl/gsknglrenderjob.c47
1 files changed, 40 insertions, 7 deletions
diff --git a/gsk/ngl/gsknglrenderjob.c b/gsk/ngl/gsknglrenderjob.c
index e23d4741c6..d08d45a04f 100644
--- a/gsk/ngl/gsknglrenderjob.c
+++ b/gsk/ngl/gsknglrenderjob.c
@@ -524,7 +524,7 @@ gsk_ngl_render_job_push_modelview (GskNglRenderJob *job,
GskNglRenderModelview,
job->modelview->len - 2);
- /* Multiply given matrix with our previews modelview */
+ /* Multiply given matrix with our previous modelview */
t = gsk_transform_translate (gsk_transform_ref (last->transform),
&(graphene_point_t) {
job->offset_x,
@@ -1972,6 +1972,7 @@ gsk_ngl_render_job_visit_transform_node (GskNglRenderJob *job,
else
{
GskNglRenderOffscreen offscreen = {0};
+ float sx = 1, sy = 1;
offscreen.bounds = &child->bounds;
offscreen.force_offscreen = FALSE;
@@ -1980,15 +1981,37 @@ gsk_ngl_render_job_visit_transform_node (GskNglRenderJob *job,
if (!result_is_axis_aligned (transform, &child->bounds))
offscreen.linear_filter = TRUE;
+ if (category == GSK_TRANSFORM_CATEGORY_2D)
+ {
+ graphene_matrix_t m;
+ double a, b, c, d, tx, ty;
+
+ g_assert (transform != NULL);
+ gsk_transform_to_matrix (transform, &m);
+ if (graphene_matrix_to_2d (&m, &a, &b, &c, &d, &tx, &ty))
+ {
+ sx = sqrt (a * a + b * b);
+ sy = sqrt (c * c + d * d);
+ }
+ else
+ sx = sy = 1;
+
+ if (sx != 1 || sy != 1)
+ {
+ GskTransform *scale;
+
+ scale = gsk_transform_translate (gsk_transform_scale (NULL, sx, sy), &GRAPHENE_POINT_INIT (tx, ty));
+ gsk_ngl_render_job_push_modelview (job, scale);
+ transform = gsk_transform_transform (gsk_transform_invert (scale), transform);
+ }
+ }
+
if (gsk_ngl_render_job_visit_node_with_offscreen (job, child, &offscreen))
{
/* 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.
- */
- gsk_ngl_render_job_push_modelview (job, transform);
+ if (transform)
+ gsk_ngl_render_job_push_modelview (job, transform);
gsk_ngl_render_job_begin_draw (job, CHOOSE_PROGRAM (job, blit));
gsk_ngl_program_set_uniform_texture (job->current_program,
@@ -1999,7 +2022,17 @@ gsk_ngl_render_job_visit_transform_node (GskNglRenderJob *job,
gsk_ngl_render_job_draw_offscreen (job, &child->bounds, &offscreen);
gsk_ngl_render_job_end_draw (job);
- gsk_ngl_render_job_pop_modelview (job);
+ if (transform)
+ gsk_ngl_render_job_pop_modelview (job);
+ }
+
+ if (category == GSK_TRANSFORM_CATEGORY_2D)
+ {
+ if (sx != 1 || sy != 1)
+ {
+ gsk_ngl_render_job_pop_modelview (job);
+ gsk_transform_unref (transform);
+ }
}
}
break;