Commit Graph

556 Commits

Author SHA1 Message Date
Matthias Clasen
cb339f85b8 testsuite: build fix
The statically linked tests need to have -DGTK_COMPILATION=1
in their cflags.
2024-08-12 19:19:15 -04:00
Benjamin Otte
68d73dcce5 nodeparser: Handle disallowed values for radial gradients
Make sure the radii are strictly positive.

Also handle the case where start >= end.
We can't really underline that error, because we don't track the
locations of the start/end properties until we know that there's an
error.
So just underline the whole radial gradient declaration.

Test included
2024-08-11 19:07:40 +02:00
Benjamin Otte
9643a21827 gl: Interpolate gradient colors as premultiplied
Tests included
2024-08-11 19:07:40 +02:00
Matthias Clasen
92bd85ba30 nodeparser: Support color states in text nodes
Test included.
2024-08-10 07:37:01 -04:00
Benjamin Otte
04ee41d7b0 Merge branch 'wip/otte/for-main' into 'main'
lots of small things

See merge request GNOME/gtk!7585
2024-08-10 01:10:12 +00:00
Benjamin Otte
23af1cd8ad gpu: When transforming to simpler transform, we might be all clipped
When transforming back from a complex transform to a simpler transform,
the resulting clip might turn out to clip everything, because clips can
grow while transforming, but the scissor rect won't. So when this
process happens, we can end up with an empty clip by transforming:

1. Set a clip that also sets the scissor
2. transform in a way that grows the clip, say rotate(45)
3. modify the clip to shrink it
4. transform in a way that simplifies the transform, say another
   rotate(45)
5. Figure out that this clip and the scissor rect do no longer overlap

Catch this case and avoid drawing anything.
2024-08-10 02:38:13 +02:00
Matthias Clasen
92c119e12c testsuite: Replay shadow nodes properly
Use the new apis for this.
2024-08-09 20:17:04 -04:00
Matthias Clasen
0f7c0f616c nodeparser: Handle shadows with color state
Test included.
2024-08-09 20:09:31 -04:00
Benjamin Otte
d6322c6389 gsk: Switch box shadow nodes to use offsets
Instead of
  float dx;
  float dy;
have a
  graphene_point_t offset;
in the object and in all APIs relating to them.
2024-08-10 01:40:45 +02:00
Matthias Clasen
4ea1319c6b Replay inset and outset shadow nodes properly 2024-08-08 16:01:06 -04:00
Matthias Clasen
ea28dc8cff nodeparser: Support color states for box shadows
Just switch from parse_color to parse_color2, and apply the
corresponding changes to serialization too.

Test included.
2024-08-08 15:49:55 -04:00
Benjamin Otte
99d291eb69 Merge branch 'wip/otte/occlusion' into 'main'
Implement advanced occlusion culling

See merge request GNOME/gtk!7570
2024-08-08 14:22:22 +00:00
Benjamin Otte
88c9a30f77 testsuite: Half the runtime of offscreens test
It times out too much in CI.
2024-08-07 23:26:03 +02:00
Matthias Clasen
2960bb7cb2 Add a compare test for colorstates in borders 2024-08-06 07:35:00 -04:00
Matthias Clasen
a3691d311b nodeparser: Support color states in border nodes
Test included.
2024-08-06 07:35:00 -04:00
Matthias Clasen
89d449352f testsuite: Replay border nodes properly
Use the new apis for this.
2024-08-06 07:35:00 -04:00
Matthias Clasen
582dba54b1 Try to fix win32 build of compare-render 2024-08-06 07:10:04 -04:00
Matthias Clasen
0775432ed9 Add a compare test for premultiplied colors
This test checks a that a specific combination of mask with alpha
inside opacity works as expected. We were treating the mask color
as premultiplied here, although it isn't.
2024-08-06 00:59:23 -04:00
Matthias Clasen
71d6392572 nodeparser: Rewrite the color parsing
Use gtk_css_parser_consume_function, for better error handling.
We are now getting the expected error for

  color(srgb 1 2 3 4 5 6)

Test included.
2024-08-06 00:23:07 -04:00
Matthias Clasen
c1a99bf901 tests: Link compare-render statically
This is a temporary change, only needed until we make the new
snapshot and rendernode apis public.
2024-08-05 16:09:42 -04:00
Matthias Clasen
b8989b7ff6 Add a compare test for color states
This checks that the red values in all 4 default color states
come out identical to a plain old red png.
2024-08-05 11:11:15 -04:00
Matthias Clasen
d6a6cfe6c5 gtk: Fix gtk_snapshot_collect_repeat
This creates a new color node that is meant to be identical to
an existing one, so we need to use gsk_color_node_new2 to preserve
the color state information.

Test included.
2024-08-05 11:11:15 -04:00
Matthias Clasen
16431da3f2 nodeparser: Add support for cicp color states
Allow defining cicp color states with an @-rule:

    @cicp "jpeg" {
      primaries: 1;
      transfer: 13;
      matrix: 6;
      range: full;
    }

And allow using them in color() like this:

    color("jpeg" 50% 0.5 1 / 75%)

Note that custom color states use a string, unlike default color
states which use an ident.

Test included.
2024-08-05 11:11:15 -04:00
Matthias Clasen
842949fcf3 nodeparser: Support color states
And allow using color states for colors with a syntax similar
to modern css color syntax.

color(srgb 50% 0.5 1 / 75%)

Both floating point numbers and percentages can be used.

Currently, this is only supported for color nodes.

Test included.
2024-08-05 11:11:15 -04:00
Matthias Clasen
d5ae94ca5d testsuite: Update replay nodes
We can't currently recreate color nodes with public api, so cheat
and reuse the node we got.
2024-08-05 11:11:15 -04:00
Benjamin Otte
9f71528a05 gpu: Fix shadows even more
Math is hard.

But this time, it comes with a test!
2024-07-30 18:01:45 +02:00
Benjamin Otte
4a94c91772 gpu: Don't blur tiny blur radii
We get those wrong, and there's not really a visual effect.

And since we do a check anyway, just disallow them and treat them as
unblurred.
2024-07-30 01:50:56 +02:00
Benjamin Otte
cc3ed89e34 gpu: Draw proper shadows again
The fix in commit 5e7f227d broke shadows while trying to make them
faster.
So use a better way to make them faster.

With the normalized blur radius, we can now conclude that all the values
too far from p.y will cause the gauss() call to return close to 0, so we
can skip any y value that is too far from p.y.

And that allows us to put an upper limit on the loop iterations.

Tests included

Fixes #6888
2024-07-30 01:50:56 +02:00
Simon McVittie
214f5a6f98 gskpathop: Introduce a type to represent an aligned graphene_point_t
When we allocate a graphene_point_t on the stack, there's no guarantee
that it will be aligned at an 8-byte boundary, which is an assumption
made by gsk_pathop_encode() (which wants to use the lowest 3 bits to
encode the operation). In the places where it matters, force the
points on the stack and embedded in structs to be nicely aligned.

By using a distinct type for this (a union with a suitable size and
alignment), we ensure that the compiler will warn or error whenever we
can't prove that a particular point is, in fact, suitably aligned.
We can go from a `GskAlignedPoint *` to a `graphene_point_t *`
(which is always valid, because the `GskAlignedPoint` is aligned)
via &aligned_points[0].pt, but we cannot go back the other way
(which is not always valid, because the `graphene_point_t` is not
necessarily aligned nicely) without a cast.

In practice, it seems that a graphene_point_t on x86_64 *is* usually
placed at an 8-byte boundary, but this is not the case on 32-bit
architectures or on s390x.

In many cases we can avoid needing an explicit reference to the more
complicated type by making use of a transparent union. There's already
at least one transparent union in GSK's public API, so it's presumably
portable enough to match GTK's requirements.

Increasing the alignment of GskAlignedPoint also requires adjusting how
a GskStandardContour is allocated and initialized. This data structure
allocates extra memory to hold an array of GskAlignedPoint outside the
bounds of the struct itself, and that array now needs to be aligned
suitably. Previously the array started with at next byte after the
flexible array of gskpathop, but the alignment of a gskpathop is only
4 bytes on 32-bit architectures, so depending on the number of gskpathop
in the trailing flexible array, that pointer might be an unsuitable
location to allocate a GskAlignedPoint.

Resolves: https://gitlab.gnome.org/GNOME/gtk/-/issues/6395
Signed-off-by: Simon McVittie <smcv@debian.org>
2024-07-28 17:31:41 +01:00
Simon McVittie
660c6c8d6f gsk, testsuite: Avoid undefined behaviour in half_to_float_one()
Similar to the previous commit, to avoid undefined behaviour we need
to avoid evaluating out-of-bounds shifts, even if their result is going
to ignored by being multiplied by 0 later.

Detected by running a subset of the test suite with
-Dsanitize=address,undefined on x86_64.

Signed-off-by: Simon McVittie <smcv@debian.org>
2024-07-27 20:22:09 +01:00
Simon McVittie
ad679187d3 gsk, testsuite: Avoid undefined behaviour in float_to_half_one()
If, for example, e == 0, it is undefined behaviour to compute an
expression involving an out-of-range shift by (125 - e), even if the
result is in fact irrelevant because it's going to be multiplied by 0.

This was already fixed for the memorytexture test in
commit 5d1b839 "testsuite: Fix another ubsan warning", so use the
implementation from that test everywhere. It's in the header as an
inline function to keep the linking of the relevant tests simple:
its only caller in production code is fp16.c, so there will be no
duplication outside the test suite.

Detected by running a subset of the test suite with
-Dsanitize=address,undefined on x86_64.

Signed-off-by: Simon McVittie <smcv@debian.org>
2024-07-27 20:22:09 +01:00
Benjamin Otte
9e27acb0a6 gpu: Allocate Vulkan descriptor pools dynamically
Instead of allocating one large descriptor pool and hoping we never run
out of descriptors, allocate small ones dynamically, so we know we never
run out.

Test incldued, though the test doesn't fail in CI, because llvmpipe
doesn't care about pool size limits. It does fail on my AMD though.

A fun side note about that test is that the GL renderer handles it best
in normal operationbecause it caches offscreens per node and we draw the
same node repeatedly.
But, the replay test expands them to duplicated unique nodes, and then
the GL renderer runs out of command queue length, so I had to disable
the test on it.
2024-07-22 19:40:24 +02:00
Benjamin Otte
31e0ec71f2 png: Add color state support
When loading or saving png files, encode the CICP flags of the color
state into the PNG.

When loading, decode the CICP flags if available and detect the
colorstate they use.
If we do not support the cicp tags, we do not load the image.

So far, we ignore the ICC profiles.

Includes regeneration of nodeparse test *reference* output to include
the new tags we write to PNGs.
The original tests do not include those tags, so we implicitly test that
we read untagged files correctly.
2024-07-16 22:04:10 +02:00
Benjamin Otte
1001445d3e testsuite: Add test for empty glshader node
Everyone should draw the error pink here, because that's what the
renderers not supporting it do, and it's also what the default shader
does.

So no matter if a renderer supports GL shaders or not, it should draw
the same pink.
2024-07-11 13:34:36 +02:00
Benjamin Otte
efacf2ff09 testsuite: Add tests for dihedral transforms
Just to make sure stuff shows up in the right place.
2024-07-10 21:34:12 +02:00
Benjamin Otte
83c2766e3f rendernode: Handle rotation transforms in opacity calculations
Tests included.
2024-07-10 21:34:12 +02:00
Benjamin Otte
9a6e61e510 rect: There's no coverage witout overlap
The rectangles need to touch/overlap in both directions, otherwise
there's no coverage that covers both rectangles.

Test included.

Fixes rendering glitches in various apps when redrawing.

Fixes: #6849
2024-07-10 00:28:33 +02:00
Benjamin Otte
1dd905d976 gpu: Fix wrong rect check in occlusion fallback path
We need to check that the clip is inside the opaque region, not that the
opaque region is inside the clip.

Test included, using the only not that hits the fallback path with an
opaque region smaller than its bounds.
2024-07-08 23:07:36 +02:00
Benjamin Otte
6d564075f3 gsk: texture-scale nodes with non-integer bounds aren't opaque
Due to the way the intermediate offscreen gets drawn, we might end up
with seams at the edges.

And I don't think it's worth spending more time on than saying "not
opaque".

Fixes the compare-render testsuite

New testcase included.
2024-07-08 15:28:14 +02:00
Benjamin Otte
329dc9e0cf gpu: Change get_opaque() implementation of containers
We want to be able to express opaque grids. This means that the app
provides either a row of columns of opaque nodes or a column of rows,
and then the containers will magically figure it out.

The main use case for this is terminals, which are uilt using cells. And
when there's a transparent background configured but the contents are
opaque, it'd be nice if we could figure that out.

Also remove the 80% requirement. It is rather arbitrary and while it
helps for some cases, the aforementioned grid would suffer.
2024-07-08 15:28:14 +02:00
Benjamin Otte
1a2b1575d6 rendernode: Add fully-opaque flag
Allows rendernodes to advertise themselves as fully opaque.

This is used as a fast path for get_opaque_rect().
2024-07-08 15:28:14 +02:00
Benjamin Otte
cc25fdf602 testsuite: Add test runner for opacity tests
Tests are node files dumped into testsuite/gsk/opaque
They are named "name-X-Y-W-H.node" with X Y W H being the expected
opaque rectangle or "name.node" if there is no opacity.

A simple example is included here.
2024-07-08 15:28:14 +02:00
Matthias Clasen
5a59548d72 Merge branch 'fix-offload-transforms' into 'main'
offload: Don't assert things that might fail

Closes #6824

See merge request GNOME/gtk!7407
2024-07-08 12:58:28 +00:00
Matthias Clasen
a858736516 Merge branch 'matthiasc/for-main' into 'main'
ci: Add another offload test

See merge request GNOME/gtk!7414
2024-07-08 12:16:49 +00:00
Matthias Clasen
880c33a777 offload: Don't assert things that might fail
We can in fact meet complex transforms here. Asserting that they
are simple doesn't make it so. Instead, simply bail out if a
transform is too complex; in this case we can't offload anyway,
so no need to walk the tree further.

Test included.

Fixes: #6824
2024-07-08 08:15:02 -04:00
Benjamin Otte
31a907be35 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.
2024-07-07 12:54:05 +02:00
Benjamin Otte
10a7650411 testsuite: Generate mask correctly
There's a corner case with width/height being exactly 25 pixels.
And of course I was hitting it with one of my tests.
2024-07-07 12:54:05 +02:00
Benjamin Otte
a8238c2251 testsuite: Make png file argument optional
Just default to the node file but with a .png extension.
2024-07-05 10:43:28 +02:00
Benjamin Otte
32625381fa gsk: Deprecate GskGLShader and the rendernode
The new renderers don't support them due to the required complexity of
integrating them with Vulkan and the assumptions those nodes make about
the renderer (the GL renderer exports its internal APIs into the
GLShader).

There haven't been any complaints that I'm aware of since 4.14 was
released where the default renderer does not support the nodes, so usage
in public seems to be close to nonexistant.

The 2 uses I know of were workarounds about missing features in GTK that
have stopped since GTK now supports them:

1. GStreamer used in to do premultiplication when the old GL renderer
   did not do so in hardware but on the CPU.
2. Adwaita used it for masking before the mask node wa added in 4.10.
2024-07-04 21:28:06 +02:00
Matthias Clasen
7f7e4ab69e ci: Add another offload test
Sadly, it fails to demonstrate the crash I'm after.
But its still useful to have.
2024-07-04 06:41:09 -04:00