Fixes blurriness in shadows.
Not sure to do a proper test for this feature. Usually proper pixel
alignment is tested by drawing a crips line and checking that it is
indeed crisp. But we are testing the blur operation here...
Fixes#6380
This isn't really a useful thing in itself, because none of the callers
handle the NULL return.
But the resulting crash is easier to debug when it's a NULL image than
when add_node() is called on an uninitializes NodeProcessor.
In GSK the following pattern is used four times:
```
switch (self->filter)
{
default:
g_assert_not_reached ();
G_GNUC_FALLTHROUGH;
case GSK_GPU_BLIT_LINEAR:
filter = GL_LINEAR;
break;
case GSK_GPU_BLIT_NEAREST:
filter = GL_NEAREST;
break;
}
```
The G_GNUC_FALLTHROUGH macro is not required. When G_DISABLE_ASSERT
is defined the body of the `default` case is empty, thus there is
no need. When G_DISABLE_ASSERT is not defined the body of the `default`
case contains g_assert_not_reached() thus it won't fallthrough.
This resolves the following:
```
[221/1379] Compiling C object gsk/libgsk.a.p/gpu_gskgpublitop.c.o
[...]
error: fallthrough annotation in unreachable code [-Werror,-Wimplicit-fallthrough]
1 error generated.
```
This can be helpful to see that there is an enormous scale blowing
things up. We omit the matrix, since it is 16 floats that are hard
to interpret at a glance.
We can just check if the subsurfaces contain content - and if they do,
they will be offloading and we can ignore the diff.
This essentially reverts 48740de71a
The 2 callers of gsk_gpu_get_node_as_image() were already computing the
minimum clip region and in particular aligning it to the pixel grid, so
intersecting with node bounds again was causing that alignment to be
busted.
When using a window size and scale that don't multiply to an integer, we
were using the wrong method to adjust it.
The Wayland fractional scaling spec just says:
> For toplevel surfaces, the size is rounded halfway away from zero.
This is meant to be interpreted as "create a large enough buffer to hold
partial pixels) and the compositor will blend it mapping to the pixel
grid" even if that means the buffer slightly overhangs.
Example:
A 11 units wide window at 150% will need a 11 * 1.5 = 16.5 pixel wide
buffer. This should be rounded to 17 pixels but rendered as if only 16.5
pixels are occupied by the window, not as if all 17 pixels are occupied.
This commit is wrong.
It does achieve what it sets out to do, but the method doesn't work.
It confused multiple things in one commit, the commit message only
describes the symptoms it tries to fix and not why the fix is correct,
it includes no tests and it wsn't properly reviewed.
Related: !6871
We want to use a viewport that gives us the right scale back.
This fixes problems where glyph lookups were inefficient because
the scale part of the key would fluctuate ever so slightly.
The previous code was ignoring non-scissor clips, which would make it
overeager at punching holes.
It also was not working with fractional coordinates.
Fixes#6375
We can reach the code that removes the item from the hash table
before or after the weak unref has triggered. Just leave the
weakref in place and let it do its thing, if it hasn't gone
off yet. That matches what we do in free.
Fixes: #6377
We do gc in a timeout, when an arbitrary GL context might be
current, so we need to make sure its ours and we don't free
random textures in another context.
Fixes: #6366
Count dead pixels in textures (ie the number of pixels in GPU
textures that are no longer backed by an alive GdkTexture object),
and when the there's too many, do a gc before rendering the next
frame.
Count the uses of cached texture - from the device (via the linked
list) and from the texture (via render data / weak ref), and only
free the item once the use count reaches zero.
Instead of forever running a timeout to do gc, ensure the timeout
is scheduled whenever we render a frame (this is done by calling
gsk_gpu_device_maybe_gc () before gsk_gpu_frame_render (), and
gsk_gpu_device_queue_gc () after).
Read the GSK_CACHE_TIMEOUT environment variable to override the
default 15s timeout for cache gc. This is mainly meant for debugging.
Since we don't really need two knobs, reuse the gc timeout value
for the max age of items too.
The node processing wasn't skipping 0-size nodes when using the
uber shader, leading to assertions down the road. Since the ngl
renderer doesn't use uber shaders, this only affects vulkan.
Test included.
Fixes: #6370
GL needs version 4.2 before it supports explicit bindings. We use GLES
usually, and Mesa supports GL 4.6, so we didn't hit this case before.
However, MacOS does use GL and Mac OS is stuck on GL 4.1.
Fixes#6363
When a border side has a width of 0 but we're having rounded corners, we
draw content in the edges of that side, and naturally pick its color.
That is wrong though, when the width is zero, we're supposed to keep
using the color of the other side in that corner.
So do that.
Fixes the border-corner-zero-width-rendering.ui reftest.
Count how many dead pixels we have, and free the atlas if more than
half of its pixels are dead.
As part of this, change when glyphs are freed. We now keep them
in the hash table until their atlas is freed and we only do dead
pixel accounting when should_collect is called. This keeps the
glyphs available for use from the cache as long as are in the atlas.
If a stale glyph is sused, we 'revive' it by removing its pixels
from the dead.
This matches more closely what the gl renderer does.
If we gc a cached texture for which the GdkTexture is still alive,
the cached texture object will remain accessible via the render
data, so need to make sure not to leave a dangling pointer behind
here.
This is straightforward. If a texture hasn't been used for 4 seconds,
we consider it stale, and drop it the next time gc comes around.
The choice of 4 seconds is arbitrary.
Fixes: #6346
Add GSK_GPU_SKIP=glyph-align to turn off the glyph aligning.
FIXME: Should this be handled by the renderer at all or should we rely
on higher rendering layers to align glyphs properly?
This is kind of a tricky question just like with texture-scale nodes and
NEAREST filtering, because rendernodes can be embedded in other nodes
that disturb the pixel grid.
Previously, we only checked if the cache had exhausted the maximum
number of slices.
But we also need to check that the height of the slices doesn't exceed
the height of the texture.
This clip is different from "none" in that the bounds rect cannot be
ignored and that potential drawing outside the clip must be avoided.
In particular it means that clip nodes cannot be discarded if they
encompass the full clip region.
Fixes#6322
Make sure fallbacks and fill/stroke masks use image surfaces with the
same pixel grid as the target if possible.
Fixes blurriness with some path renderings.
We need to respect the offset when converting to the pixel grid, so pass
the current offset into the function.
Also move the rounded out of gsk_gpu_get_node_as_image() and into the 2
callers, because the offset is not passed into the function and I see no
reason to change that.
Instead of using the bounds of the clip region, emit individual
renderpasses for each rectangle of the clip region.
The benefit of this depends on how many pixels the clip region covers,
but for widget factory it reduces the required rendering by a huge
amount.
This is now the best clipping renderer - Cairo doesn't clip at all and
GL clips based on the extents.
Previously, we would set a scissor rect when doing a partial redraw, but
we would not clip the nodes based on that rectangle.
Do that now.
This massively reduces the amount of ops we emit for small redraws.
The Vulkan renderer can just be public API, because it doesn't expose
any Vulkan-specific APIs.
And it can just exist when compiled without Vulkan, because it can fail
to realize.
Also move get rid of the gsk/vulkan/gskvulkanrenderer.h header. It was
experimental and isn't necessary now that the renderer is included via
gsk.h.
If shaders don't support nonuniform indexing, we emulate it via if/else
ladders (or switch ladders) which get inlined by the GLSL compiles and
massively blow up the code.
And that makes compilation of the shaders take minutes and results in
shader code that isn't necessarily faster.
So we disable it on GL entirely and on Vulkan if the required features
aren't available.
As it's only an optimization and does not fall back to Cairo anymore,
this should be fine.
Make the generator generate calls for the correct glBindAttribLocation()
calls.
Usually this was done correctly, but we can't rely on it. So do it
explicitly.
When downscaling more than 2x in either dimension, force mipmap use for
the texture in a texture node.
It improves the quality of textures but takes extra work.
The GL renderer does this, too (for textures that aren't in the icon cache).
This can be disabled via GSK_GPU_SKIP=mipmap.
Fixes the big-checkerboard-scaled-down2 test.
Unless GSK_GPU_SKIP=gradients is given, we sample every point 4x instead
of 1x. That makes the shader run slower (by roughly a factor of 2.5x)
but it improves quality quite a bit.