Commit Graph

3148 Commits

Author SHA1 Message Date
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
dbd16cd9da Rename GDK_COLOR_INIT_SRGB
Rename the macro to GDK_COLOR_SRGB, and make it usable as
a compound literal as well.

Update all users.
2024-08-06 00:06:41 -04:00
Matthias Clasen
f9c9a03404 gsk: Improve handling of fill and stroke nodes
Use GdkColor here. We still convert to sRGB as the last step, though.
2024-08-05 15:59:28 -04:00
Matthias Clasen
7dab23e38a gl: Handle color nodes with color states
Since we don't have proper color management here, just convert
any color we meet to sRGB and hope for the best.
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
3d3e935c91 offload: Use gsk_color_node_get_color2
We want the blackest black.
2024-08-05 11:11:15 -04:00
Matthias Clasen
87e9c940a4 gsk: Use the private color node api
Use the color state returned by this function instead of assuming
the color of a color node is always sRGB.

Node colors are converted to the css on the cpu. That is necessary
since we don't know if they are in one of the default color states,
and our shaders can't deal with non-default color states.
2024-08-05 11:11:14 -04:00
Matthias Clasen
6a02fa4be8 gsk: Add private color node api
Add a constructor that takes a color state, a getter for it, and
also a getter for the color coordinates that avoids GdkRGBA.
2024-08-05 11:11:14 -04:00
Matthias Clasen
9f548efd32 gsk: Change color op apis
Make color-related ops take the ccs and a GdkColor, and make
decisions about color conversion on the cpu vs the gpu.

This makes the node processor code simpler, and lets use convert
the color directly into the op instance without extra copying.

We also pass opacity to the op, so it can be applied when we
write the color into the instance.

Lastly, rorder the offset to come right after the opacity argument.

Treat the color and rounded color ops the same way.

Update all callers.

With this, the prepare_color apis in gskgpunodeprocessor.c are
no longer used and have been dropped.
2024-08-05 11:11:14 -04:00
Matthias Clasen
9eebe8e547 gsk: Change the clear op api
A clear op is just a fancy memcpy. Make it the callers responsibility
to convert the color to the right color state before passing it
to the clear op.
2024-08-05 11:11:14 -04:00
Benjamin Otte
126d689086 gpu: Rename function
We want to reuse gsk_gpu_color_to_float() for use with GdkColor and this
function will be replaced. But until that's fully done, we need 2
different names.

So rename this one to something else
2024-08-03 20:59:40 -04:00
Matthias Clasen
2be48a8f86 Pass ccs to the cairo blur code
This is needed to set the color properly.
2024-08-02 09:13:41 -04:00
Matthias Clasen
9e0f41bd05 Fix a copy-paste error
We were using the wrong api to get the color of an outset shadow
node. This just worked by luck.
2024-08-02 09:00:51 -04:00
Matthias Clasen
86b59ba643 Cosmetics: Remove a leftover line
This looks just like a copy-paste leftover. Suprisingly, it compiled
just fine and worked too.
2024-08-01 17:19:50 -04:00
Matthias Clasen
67080dab21 vulkan: Don't try srgb for the atlas
This makes the Emoji rendering come out wrong.

Fixes: #6887
2024-08-01 14:43:49 -04:00
Benjamin Otte
809b98c96e vulkan: Don't leak fds
It makes sense to close the fds before doing an early return.
D'oh.
2024-08-01 12:51:46 +02:00
Benjamin Otte
059af1365a vulkan: Add error checking in a place
Doesn't hurt to have, but I just added it while debugging something
unrelated.
2024-08-01 12:51:46 +02: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
defc4d335e gpu: Fix shadows some more
It turns out the "step" variable could up as 0 when p.y ~= 3.0 ||
p.y ~= r.y - 3.0
That was not enough to trigger it though because if "start" and "end"
were the same value, the "y <= end" check in the loop would immediately
terminate it.

However, if start + epsilon == end so that end != start but (end - start)
/ 7 == 0, then step would end up as 0 and the loop would never
terminate.

And if that happened, it would bring down GPUs.
So recode this whole machinery to make it impossible to infloop.

Fixes #6896
2024-07-30 16:09:38 +02:00
Benjamin Otte
bdcfcfa5b9 Merge branch 'wip/otte/for-main' into 'main'
gpu: Draw proper shadows again

Closes #6888

See merge request GNOME/gtk!7518
2024-07-30 00:19:37 +00: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
Benjamin Otte
5059ae1d7b gpu: Simplify box-shadow shader
Instead of doing complicated math, normalize the values to a sigma
of 1.0, and then use that.
This should also be beneficial for shader performance, because 1.0 is a
constant and constant-elimination can kick in on the inlined functions.
2024-07-29 19:14:10 +02:00
Benjamin Otte
50bb42f0f3 gl: Don't crash on box shadows with negative scales
Some places didn't fabs() the scale values properly, leading to
assertions when offscreens with negative sizes were created.
2024-07-29 19:14:10 +02:00
Matthias Clasen
bfb779ac2f gsk: Add missing cicp transfer functions
This was overlooked in 50ea9450ea.
2024-07-29 10:35:32 -04: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
Matthias Clasen
e2d337740f gpu: Don't mess up color states
When uploading textures, we were unintentionally converting to
srgb. Avoid that, so that yuv data survives unmolested.
2024-07-26 17:34:48 -04:00
Matthias Clasen
150f57f706 gpu: Fix the cicp conversion
The fragment shader was mixing up pixel and color variables.
And the compilers don't have 'uninitialized variable' warnings :(
2024-07-26 07:24:48 -04:00
Matthias Clasen
33131ad24d gpu: Fix the cicp conversion shader for ngl
The compiler was unhappy with using signed labels with an unsigned
variable in a switch. Talk about being picky.
2024-07-26 07:23:18 -04:00
Matthias Clasen
d53b3f9941 gpu: More debug spew
Print out the direction of the cicp conversion.
2024-07-26 07:22:45 -04:00
Benjamin Otte
6f9a70bd4e gpu: Add a version of a function
With the changes in !7473 we now use sampler2D arguments in functions.
However, when there's a function we call with a samplerExternalOES -
which means we need to overload it with that shader variant.
2024-07-25 18:53:55 +02:00
Benjamin Otte
de1dfb99bc gpu: Add shader name to error message
When a shader cant be compiled, we produce a long error dump, but
nowhere did we mention the actual shader.

Fix that.
2024-07-25 18:53:55 +02:00
Benjamin Otte
1f3c88b995 build: Skip vulkan parts in generated GLSL
Make the #include parsing script able to skip a predefined list of terms
with #ifdef

Put "VULKAN" in that list to skip the vulkan parts.
2024-07-25 17:32:19 +02:00
Benjamin Otte
5e7f227d92 gpu: Don't run long loops in shaders
If the border radius is too big, take bigger steps when computing the
shadow.

I randomly chose 8 because that looked good and was fast enough.
2024-07-25 17:32:19 +02:00
Matthias Clasen
d8775d0194 gsk: Make shader matrices match
We were using slightly different numbers here, which isn't good.

The matrices in gdkcolordefs.h are tested in the colorstate-internal
tests, so they are at least properly inverse, and the products match.

It would be better to generate the glsl definitions, somehow.
2024-07-24 16:45:21 -06:00
Matthias Clasen
e415ec9ca5 gsk: Use the cicp convert shader
When we the image color state is not a default one, use the cicp
convert op to convert it to the ccs. And when the target color
state is a non-default one, use the shader in the reverse direction.
2024-07-24 08:16:08 -06:00
Matthias Clasen
226652edb0 gsk: Add a cicp convert shader
This shader receives cicp parameters via uniforms, and converts
the texture data from or to the output colorstate. It computes
the matrix in the vertex shader, and then picks the eotf/oetf
according to the cicp parameters in the fragment shader.
2024-07-24 08:16:08 -06:00
Benjamin Otte
293d2fd19f gpu: Use correct shader clip mode for glyph nodes
We were passing the wrong rect to the clip mode computation, resulting
in a rounded rect every time, even though it should pretty much always
be unclipped.

The visual results are unaffected, because the clip sent to the shader
was still correct.
2024-07-23 10:03:11 +02:00
Benjamin Otte
40e25218e2 gpu: Compile with AMD's compiler, too
Apparently AMD's GLSL compiler doesn't like our #if statements. Turn
them into simple #ifdefs and compute them in the preamble instead.
2024-07-22 19:40:24 +02: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
67b9fb43d0 gpu: Completely revamp YCbCr handling
There is now a GskGpuYcbcr struct that maintains all the Vulkan
machinery related to YCbCrConversions.
It's a GskGpuCached, so it will make itself go away when it is no longer
used, ie a video stopped playing.
2024-07-22 19:40:24 +02:00
Benjamin Otte
762b981dfe gpu: Make the device queryable from the cache
That's needed in cached subclasses during destruction, when they want to
destroy system resources.
2024-07-22 19:40:24 +02:00
Benjamin Otte
5e027ae5d9 gpu: Allow creating GskGpuCached objects externally
Export the GskGpuCached and GskGpuCachedClass objects in the header, and
make gsk_gpu_cached_new() available.
2024-07-22 19:40:24 +02:00
Benjamin Otte
7dd3680d7d gpu: Refactor code a bit
Turn the 2 ways to construct cached items into 2 constructors.

Useful for next commit.
2024-07-22 19:40:24 +02:00
Benjamin Otte
14a7b4b4b4 vulkan: Remove unused features
Now that we don't use the fancy features anymore, we don't need to
enable them.
And that also means we don't need an env var to disable it for testing.
2024-07-22 19:40:24 +02:00
Benjamin Otte
f5096fd11a vulkan: No need for different shaders anymore
Now that we don't do fancy texture stuff anymore, we don't need fancy
shaders either, so we can just compile against Vulkan 1.0 again.

And that means we need no fallback shaders for Vulkan 1.0 anymore.
2024-07-22 19:40:24 +02:00
Benjamin Otte
9c5ac13301 gpu: Remove now unused variables
No need to track them anymore.
2024-07-22 19:40:24 +02:00