From 31a907be35d783e09df592caa42427d538780a95 Mon Sep 17 00:00:00 2001 From: Benjamin Otte Date: Sun, 7 Jul 2024 07:19:43 +0200 Subject: [PATCH] gpu: Make sure textures used as image are mipmapped When getting a texture as image, we were always returning the texture unconditionally. However, we want to mipmap textures when the scale factor is too large, and this code path did not do that. The same codepath on the GL renderer doesn't do that either, so the test is disabled for it. --- gsk/gpu/gskgpunodeprocessor.c | 23 ++++++++++-- .../texture-offscreen-mipmap-nogl.node | 33 ++++++++++++++++++ .../compare/texture-offscreen-mipmap-nogl.png | Bin 0 -> 141 bytes testsuite/gsk/meson.build | 1 + 4 files changed, 54 insertions(+), 3 deletions(-) create mode 100644 testsuite/gsk/compare/texture-offscreen-mipmap-nogl.node create mode 100644 testsuite/gsk/compare/texture-offscreen-mipmap-nogl.png diff --git a/gsk/gpu/gskgpunodeprocessor.c b/gsk/gpu/gskgpunodeprocessor.c index 33fd4d50fa..e3976ce9f3 100644 --- a/gsk/gpu/gskgpunodeprocessor.c +++ b/gsk/gpu/gskgpunodeprocessor.c @@ -1420,6 +1420,22 @@ gsk_gpu_node_processor_add_border_node (GskGpuNodeProcessor *self, colors); } +static gboolean +texture_node_should_mipmap (GskRenderNode *node, + GskGpuFrame *frame, + const graphene_vec2_t *scale) +{ + GdkTexture *texture; + + texture = gsk_texture_node_get_texture (node); + + if (!gsk_gpu_frame_should_optimize (frame, GSK_GPU_OPTIMIZE_MIPMAP)) + return FALSE; + + return gdk_texture_get_width (texture) > 2 * node->bounds.size.width * graphene_vec2_get_x (scale) || + gdk_texture_get_height (texture) > 2 * node->bounds.size.height * graphene_vec2_get_y (scale); +} + static void gsk_gpu_node_processor_add_texture_node (GskGpuNodeProcessor *self, GskRenderNode *node) @@ -1448,9 +1464,7 @@ gsk_gpu_node_processor_add_texture_node (GskGpuNodeProcessor *self, } } - if (gsk_gpu_frame_should_optimize (self->frame, GSK_GPU_OPTIMIZE_MIPMAP) && - (gdk_texture_get_width (texture) > 2 * node->bounds.size.width * graphene_vec2_get_x (&self->scale) || - gdk_texture_get_height (texture) > 2 * node->bounds.size.height * graphene_vec2_get_y (&self->scale))) + if (texture_node_should_mipmap (node, self->frame, &self->scale)) { guint32 descriptor; @@ -1504,6 +1518,9 @@ gsk_gpu_get_texture_node_as_image (GskGpuFrame *frame, gint64 timestamp = gsk_gpu_frame_get_timestamp (frame); GskGpuImage *image; + if (texture_node_should_mipmap (node, frame, scale)) + return gsk_gpu_get_node_as_image_via_offscreen (frame, clip_bounds, scale, node, out_bounds); + image = gsk_gpu_cache_lookup_texture_image (gsk_gpu_device_get_cache (device), texture, timestamp); if (image == NULL) image = gsk_gpu_frame_upload_texture (frame, FALSE, texture); diff --git a/testsuite/gsk/compare/texture-offscreen-mipmap-nogl.node b/testsuite/gsk/compare/texture-offscreen-mipmap-nogl.node new file mode 100644 index 0000000000..c71d2336ce --- /dev/null +++ b/testsuite/gsk/compare/texture-offscreen-mipmap-nogl.node @@ -0,0 +1,33 @@ +texture { + bounds: 0 0 25 25; + texture: "texture1" url("data:image/png;base64,\ +iVBORw0KGgoAAAANSUhEUgAAAMgAAADICAYAAACtWK6eAAACkElEQVR4nO3XoQHDMBAEwXMqcP9V\ +qoMEBDtgUcAMWyb2uuts7/ucbdu5722b1vrb1855/8NDtP7Hfg14dPliaf3cLgj8YINobYNAY4No\ +bYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNA\ +Y4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4No\ +bYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNA\ +Y4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4No\ +bYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNA\ +Y4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4No\ +bYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNA\ +Y4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4No\ +bYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNA\ +Y4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4NobYNAY4No\ +bYNAY4No/aM/Uzkk29ZNdeQAAAAASUVORK5CYII=\ +"); +} +color-matrix { + child: texture { + bounds: 25 0 25 25; + texture: "texture1"; + } +} +color-matrix { + child: debug { + message: "magic bugfix"; + child: texture { + bounds: 50 0 25 25; + texture: "texture1"; + } + } +} diff --git a/testsuite/gsk/compare/texture-offscreen-mipmap-nogl.png b/testsuite/gsk/compare/texture-offscreen-mipmap-nogl.png new file mode 100644 index 0000000000000000000000000000000000000000..ce3521ae2247b1e50b7000874bd513185a5a260f GIT binary patch literal 141 zcmeAS@N?(olHy`uVBq!ia0vp^-astL!3HENIWCIBDw-+3F4;Tm>*syIy y|6i}fO5e#jEP>z7*mQ@VyUtjj6qY~&EMT0Tz%*0cK`{epK7*&LpUXO@geCxDGAw-n literal 0 HcmV?d00001 diff --git a/testsuite/gsk/meson.build b/testsuite/gsk/meson.build index fd5d744a6e..02344e5a32 100644 --- a/testsuite/gsk/meson.build +++ b/testsuite/gsk/meson.build @@ -171,6 +171,7 @@ compare_render_tests = [ 'text-mixed-color-nocairo', 'text-mixed-color-colrv1', 'texture-coords', + 'texture-offscreen-mipmap-nogl', 'texture-scale-filters-nocairo', 'texture-scale-magnify-10000x', 'texture-scale-magnify-rotate',