Commit Graph

2957 Commits

Author SHA1 Message Date
Benjamin Otte
1b155341bd gpu: Implement add_first_node() for clip nodes
Clip nodes often appear in the widget tree.

And the implementation can be trivial because of the sanity checks
already performed before calling the vfunc.
2024-07-08 15:28:14 +02:00
Benjamin Otte
96c02c1eb4 gpu: Implement add_first_node() for transform nodes
This is required because transform nodes appear everywhere.

We just exit for all transforms that can't transform the clip rect
losslessly. Both because they are rare and because we'd make the
coverage possibilities much lower.
2024-07-08 15:28:14 +02:00
Benjamin Otte
116d662e0f gpu: Add early exit to add_first_node()
A node must cover the full clip region to be eligible for being the
first opaque node.

Do an early exit for all nodes that aren't big enough for that.
2024-07-08 15:28:14 +02:00
Benjamin Otte
d81cd4751f gpu: Add add_first_node for colors
Color nodes can set the default background of the renderpass, instead of
doing a clear op or running a shader.
2024-07-08 15:28:14 +02:00
Benjamin Otte
dd33068943 gpu: Implement add_first_node for containers
Containers can walk the list of children back to front, trying to find
the topmost node that fully covers the viewport.

And then they can skip drawing all the nodes before that one.
2024-07-08 15:28:14 +02:00
Benjamin Otte
09c1e51b8a gpu: Add gsk_gpu_node_processor_add_first_node()
Asks a node to add itself if it is fully covering the clip rectangle.
In that case, it is the first node that needs to be added.

If the node is not fully covering the clip, it should not draw itself,
because there might be stuff needing to be drawn below.

If a node adds itself, it should call gsk_gpu_render_pass_begin_op().
2024-07-08 15:28:14 +02:00
Benjamin Otte
af9a9422c4 gpu: Allow passing a background color to renderpasses
It's not used yet, everybody is passing GDK_RGBA_TRANSPARENT.
2024-07-08 15:28:14 +02:00
Benjamin Otte
df3c85ea7f gpu: Move renderpass handling into the nodeprocessor
There's no need for the frame to do this.
2024-07-08 15:28:14 +02:00
Benjamin Otte
b14a115fc0 container: Implement get_opaque_rect()
We find the first child that covers >80% of the container and return
that.

This is a nice speedup for the common case of a GtkWindow being covered
by a large opaque background.
It will fall apart for fancy themes that play with transparency or for
small windows because the shadow region gets too large.

But then we just scan the whole node tree.

We could think about adapting the 80% number, because that wasn't chosen
with any real scientific data behind it.
2024-07-08 15:28:14 +02:00
Benjamin Otte
355a88d002 roundedclip: Implement get_opaque_rect
This takes both the vertical and horizontal rectangle that isn't
covering the rounded corners and intersects both with the child's opaque
rect.
And then it returns the larger of the two.

This means the small slices of a window near the left/right (or
top/bottom) will never be covered, but if we wanted that, we'd need to
use something else than a rectangle - either a region or actually a
rounded rect.

But that is a lot more expensive to implement.
2024-07-08 15:28:14 +02:00
Benjamin Otte
1014b3d972 rendernode: Implement a bunch of simple opque_rect getters
Not much to write home about here.
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
9c032bec89 gsk: Add gsk_render_node_get_opaque_rect()
Gets a rectangle inside the rendernode that is opaque.

This function only adds the API. So far, no implementation exists.
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
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
Matthias Clasen
3a97b44321 Merge branch 'glshader-docs-typo' into 'main'
gskglshader: Fix typo in deprecation docs

See merge request GNOME/gtk!7426
2024-07-08 10:58:33 +00:00
Benjamin Otte
058252e895 vulkan: Can't blit to/from formats with a swizzle
Fixes grayscale images appearing red on some hardware.

Related: https://gitlab.freedesktop.org/mesa/mesa/-/issues/11467
2024-07-08 10:51:37 +02:00
Benjamin Otte
c594de8302 vulkan: Code more defensively
Check for identity swizzle too, even though we don't use it.
2024-07-08 10:51:37 +02:00
Sebastian Dröge
8eaf05a3ef gskglshader: Fix typo in deprecation docs 2024-07-08 09:21:43 +03:00
Benjamin Otte
ba05963729 gpu: Make get_node_as_image() always return premultiplied images
We wanted premultiplied images in all cases anyway, and moving that
requirement means we can also move the caching code for re-caching
textures into the texture specific code.
2024-07-07 14:39:07 +02:00
Benjamin Otte
f14f7e7df6 gpu: Add GSK_GPU_DISABLE=offscreen
This uses offscreens for every call to get_node_as_image().

This is useful both for benchmarking benefits of those implementations
as well as checking that the node-specific paths produce identical
results.
2024-07-07 14:39:07 +02:00
Benjamin Otte
daa97d4b79 gpu: Refactor functions
gsk_gpu_node_processor_ensure_image() was a weird amalgamation of stuff
withe weird required and disallowed flags.

Refactor it to make the two operations we actually do there more
explicit: Removing straight alpha and generating mipmaps.

This untangling is also desirable in the future when we also want to
handle colorstates here.
2024-07-07 14:39:07 +02:00
Benjamin Otte
4822b85cb0 gpu: Make gsk_gpu_node_processor_get_node_as_image() more restrictive
Always return premultiplied images.

2 fallback cases for clip and transform nodes did not require that. If
those cases turn out to be important, they can call
gsk_gpu_get_node_as_image() directly as that's the more flexible option.
2024-07-07 14:39:07 +02:00
Benjamin Otte
7f61d7ac8b gpu: Implement get_node_as_image() for subsurface nodes
Pass through to the child instead of offscreening.

I mainly implemented it for the assertion, because this might be a
sneaky way to introduce bugs without exhaustive checking that we don't
offload stuff that is offscreened.

No actual bugs that I'm aware of, so no tests.
Strictly defensive coding.
2024-07-07 14:39:04 +02:00
Benjamin Otte
010ca5feef gpu: Implement get_node_as_image() for debug nodes
Just pass through to the child instead of offscreening.
2024-07-07 12:54:05 +02: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
ab37fed974 gpu: vfuncify get_node_as_image()
The switch statement was ugly.

Plus, the code should be close to the add_node() vfunc implementation,
so they can be modified together.

See future commits for an example where this matters.
2024-07-07 12:54:05 +02:00
Benjamin Otte
d7308f2d73 gsk: Rename GSK_DEBUG=glyphcache to GSK_DEBUG=cache
1. I mistype it all the time
2. It's shorter
3. We use it for all caching these days, not just glyphs.
2024-07-07 05:24:45 +02:00
Benjamin Otte
012c4b9425 gpu: Remove the ubershader
It didn't bring any noticable benefits and it isn't compatible with the
way we intend to do colorstate support.

And nobody seems to want to spend time on it, so let's get rid of it.

We can bring it back later if someone wants to work on it.
2024-07-07 05:19:32 +02:00
Benjamin Otte
16c2e0a642 gl: Use GdkTextureDownloader
Cairo surfaces are so outdated.
2024-07-05 13:55:18 +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
Benjamin Otte
0f55b3bc18 Merge branch 'wip/otte/for-main' into 'main'
gpu: Split out the cache

See merge request GNOME/gtk!7411
2024-07-03 19:51:10 +00:00
Benjamin Otte
9c249fefc3 gpu: Improve periodic cache debug message
I was watching the log in my terminal and nothing happened.
And I wasn't sure if that was because nothing was printed or because the
same thing was printed every few seconds.

Fix that by printing a timestamp, so that in a few seconds something
else will be printed.
2024-07-03 20:36:56 +02:00
Benjamin Otte
eae7ee6c25 gpu: Track atlas differently
Previously we tracked the dead pixels, but that meant we didn't know the
alive pixels (because there's also unused pixels never accounted for).
And we would free the current atlas randomly due to that.

Now we track if any pixels are alive, and if so, we never gc the current
atlas.
2024-07-03 20:36:56 +02:00
Benjamin Otte
bf7f302ff5 gpu: gc atlas, too
After 60s, we gc the atlas, too. This ensures that after that time, we
free all cache resources, so if an application gets moved to the
background, it will no longer use GPU resources. (Well, at least the
cache won't.)
2024-07-03 19:55:18 +02:00
Benjamin Otte
0d6981bd54 gpu: Make the cache track if it's empty
Only if a non-stale item is in the cache do we consider the cache not
empty.

Once the cache is empty, the device frees it and stops running the
periodic GC.
2024-07-03 19:55:18 +02:00
Benjamin Otte
148d7bcc25 gpu: Don't remove gc timeout unless cache is empty
If the cache isn't empty, we want to rerun the GC.
2024-07-03 19:55:18 +02:00
Benjamin Otte
71161b6352 gpu: Split cache and device
This is for 3 reasons:

1. Separation of concerns
   The device is meant to manage the Vulkan/GL device and check stuff
   like image sizes.
   Caching is not part of that.

2. Refcounting
   Images etc want to reference the device, but the cache wants to
   reference images. If the cache is the device, that's a refcycle.

3. Flexibility
   It's now easier to implement >1 cache, say one per depth or one per
   color state.
2024-07-03 19:55:15 +02:00
Benjamin Otte
dd33a2f280 rendernode: Make sure depth variable has enough bits
This will be relevant when we add new values to it.
2024-07-03 19:55:15 +02:00
Emmanuele Bassi
554045de6e Use the appropriate annotations for a callback closure
The (closure) annotation with an parameter is meant to be used on the
callback argument, and point to the user data argument.
2024-07-03 17:21:04 +01:00
Matthias Clasen
f9856d547f gsk: Avoid a crash
The subsurface in subsurface nodes can be NULL, so check before
poking at it.
2024-07-02 15:52:51 -04:00
Benjamin Otte
9f7254a2d0 gl: Fix wrong drawing of mask node corner case
An empty mask with inverted-alpha means the source is visible.
2024-07-02 02:04:06 +02:00
Benjamin Otte
43c2b53811 rendernode: Remove default empty draw function
No node ever wants to draw nothing. So make sure code crashes if the
draw func is not set instead of silently drawing nothing.
2024-07-01 20:30:25 +02:00
Benjamin Otte
33d87bc22e gdk: Add GDK_N_DEPTHS to the enum
We are indexing arrays by the number of depths, and when adding depths
we don't want to forget to grow those arrays.
2024-07-01 20:07:22 +02:00
Maximiliano Sandoval
9126bf2c9d
docs: gsk: Add docstring for BroadwayRenderer 2024-06-29 15:14:33 +02:00
Maximiliano Sandoval
c73ff197e0
gsk: meson: Document renderers
These contain docstrings.
2024-06-29 15:14:32 +02:00
Benjamin Otte
72a4fae8dc vulkan: More slight refactoring
This applies the same refactoring as commit
5fbdec2a29 to another function.
2024-06-29 07:13:27 -04:00
Matthias Clasen
36c7d05445 gpu: Keep actual clear values in clear op
Keeping the GdkRGBA requires doing later conversions, which isn't
necessary if we just keep the already converted float[4].

It also prepares for future color states, where the color will need to
be converted using the colorstate.
2024-06-29 07:12:28 -04:00
Matthias Clasen
f3d5683f67 rendernode: Fix container nodes preferred depth
The current code injects an implicit GDK_MEMORY_U8 into this.
It is harmless now, but may not be in future. So avoid it.
2024-06-29 07:12:10 -04:00
Benjamin Otte
120887979d rendernode: Set proper values for fill and stroke nodes
Fill and stroke nodes were not reporting proper offscreen-for-opacity
and preferred depth.

This was unlikely to have been noticed as their child is usually a solid
color.
2024-06-29 07:12:10 -04:00