From 54ff4fd45ff6026ea4854f567d7077d9f092e7f2 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 2 Apr 2021 18:33:01 -0400 Subject: [PATCH 1/3] ngl: Fix downscaled textures It is not pretty, but at least it works now. --- gsk/ngl/gsknglrenderjob.c | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/gsk/ngl/gsknglrenderjob.c b/gsk/ngl/gsknglrenderjob.c index 1e62b4ecc7..07b61dc151 100644 --- a/gsk/ngl/gsknglrenderjob.c +++ b/gsk/ngl/gsknglrenderjob.c @@ -3624,6 +3624,9 @@ gsk_ngl_render_job_visit_node_with_offscreen (GskNglRenderJob *job, render_target->framebuffer_id); } + if (downscale_x != 1 || downscale_y != 1) + gsk_ngl_render_job_push_modelview (job, gsk_transform_scale (NULL, downscale_x, downscale_y)); + gsk_ngl_render_job_transform_bounds (job, offscreen->bounds, &viewport); /* Code above will scale the size with the scale we use in the render ops, * but for the viewport size, we need our own size limited by the texture size */ @@ -3632,8 +3635,6 @@ gsk_ngl_render_job_visit_node_with_offscreen (GskNglRenderJob *job, gsk_ngl_render_job_set_viewport (job, &viewport, &prev_viewport); gsk_ngl_render_job_set_projection_from_rect (job, &job->viewport, &prev_projection); - if (downscale_x != 1 || downscale_y != 1) - gsk_ngl_render_job_push_modelview (job, gsk_transform_scale (NULL, downscale_x, downscale_y)); prev_alpha = gsk_ngl_render_job_set_alpha (job, 1.0f); prev_fbo = gsk_ngl_command_queue_bind_framebuffer (job->command_queue, render_target->framebuffer_id); From 3ff04976e3a096e82ddefe9848e38b53756ffcbd Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 2 Apr 2021 18:41:53 -0400 Subject: [PATCH 2/3] ngl: Plug a memory leak This was introduced in f9457af128012fd3935a69fdcefb. --- gsk/ngl/gsknglrenderjob.c | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/gsk/ngl/gsknglrenderjob.c b/gsk/ngl/gsknglrenderjob.c index 07b61dc151..890983f07d 100644 --- a/gsk/ngl/gsknglrenderjob.c +++ b/gsk/ngl/gsknglrenderjob.c @@ -1503,6 +1503,7 @@ gsk_ngl_render_job_visit_clipped_child (GskNglRenderJob *job, offscreen.bounds = &child->bounds; offscreen.force_offscreen = TRUE; + offscreen.reset_clip = FALSE; scaled_clip = GSK_ROUNDED_RECT_INIT ((job->offset_x + clip->origin.x) * job->scale_x, (job->offset_y + clip->origin.y) * job->scale_y, @@ -1898,6 +1899,7 @@ gsk_ngl_render_job_visit_transform_node (GskNglRenderJob *job, GskNglRenderOffscreen offscreen = {0}; offscreen.bounds = &child->bounds; + offscreen.force_offscreen = FALSE; offscreen.reset_clip = TRUE; if (!result_is_axis_aligned (transform, &child->bounds)) @@ -3625,7 +3627,11 @@ gsk_ngl_render_job_visit_node_with_offscreen (GskNglRenderJob *job, } if (downscale_x != 1 || downscale_y != 1) - gsk_ngl_render_job_push_modelview (job, gsk_transform_scale (NULL, downscale_x, downscale_y)); + { + GskTransform *transform = gsk_transform_scale (NULL, downscale_x, downscale_y); + gsk_ngl_render_job_push_modelview (job, transform); + gsk_transform_unref (transform); + } gsk_ngl_render_job_transform_bounds (job, offscreen->bounds, &viewport); /* Code above will scale the size with the scale we use in the render ops, From 8d603dfe99001aafd346aa2ab7b16bc8d1e0a0f9 Mon Sep 17 00:00:00 2001 From: Matthias Clasen Date: Fri, 2 Apr 2021 19:33:44 -0400 Subject: [PATCH 3/3] ngl: Avoid huge intermediate textures Instead of rendering the unclipped child to a texture (and risking blowing the texture size limit, and bad downscaling), just render the clipped region, and live with the fact that we can't cache the rendered texture. This avoid bad artifacts when scrolling long textviews in rounded clips. --- gsk/ngl/gsknglrenderjob.c | 15 ++++----------- 1 file changed, 4 insertions(+), 11 deletions(-) diff --git a/gsk/ngl/gsknglrenderjob.c b/gsk/ngl/gsknglrenderjob.c index 890983f07d..0bd6c94b68 100644 --- a/gsk/ngl/gsknglrenderjob.c +++ b/gsk/ngl/gsknglrenderjob.c @@ -1498,21 +1498,14 @@ gsk_ngl_render_job_visit_clipped_child (GskNglRenderJob *job, } else { - GskRoundedRect scaled_clip; GskNglRenderOffscreen offscreen = {0}; - offscreen.bounds = &child->bounds; + offscreen.bounds = clip; offscreen.force_offscreen = TRUE; - offscreen.reset_clip = FALSE; + offscreen.reset_clip = TRUE; + offscreen.do_not_cache = TRUE; - scaled_clip = GSK_ROUNDED_RECT_INIT ((job->offset_x + clip->origin.x) * job->scale_x, - (job->offset_y + clip->origin.y) * job->scale_y, - clip->size.width * job->scale_x, - clip->size.height * job->scale_y); - - gsk_ngl_render_job_push_clip (job, &scaled_clip); gsk_ngl_render_job_visit_node_with_offscreen (job, child, &offscreen); - gsk_ngl_render_job_pop_clip (job); g_assert (offscreen.texture_id); @@ -1522,7 +1515,7 @@ gsk_ngl_render_job_visit_clipped_child (GskNglRenderJob *job, GL_TEXTURE_2D, GL_TEXTURE0, offscreen.texture_id); - gsk_ngl_render_job_draw_offscreen_rect (job, &child->bounds); + gsk_ngl_render_job_draw_offscreen_rect (job, clip); gsk_ngl_render_job_end_draw (job); } }