The warning gets triggered by rounding errors.
In particular when using fractional scales, the final tile may end up
not accurately matching the computed final value (in the example I was
debugging it was computing 1 vs 1.00000036 for the final tile index,
but that result computed a 0px wide tile size.
And for that tile size we hit that exit condition.
Since cairos gradient code isn't flexible enough to let us
interpolate in oklch, add additional color stops and let cairo
interpolate in the ccs. This isn't as accurate as interpolating
in oklch, but it gets an ok result for fallback situations.
Make all our gradient ops adjust the hue according to
the hue interpolation.
This is currently modifying the values in the vertex array.
If reading those values back is bad, we may need to change that.
If the interpolation color state is not a default one, use the
offscreen we already for rendering big gradients, interpolate
the gradient into it, and then use a cicp convert shader to
convert the result to the ccs.
Pass the ccs, opacity, interpolation color state and hue
interpolation explicitly, and change the argument order to
match other ops.
Since we now apply opacity in the op, change the node processor
to pass colors as-is. For now, it always passes GDK_COLOR_STATE_SRGB
for ics and GSK_HUE_INTERPOLATION_SHORTER for hue interpolation.
It is nicer if gsk_gpu_color_states_create_explicit (a, a) works
regardless of whether the two are default colorstates or not.
The gradient shaders will rely on this when the ics is a non-default
color state and we use ccs == ics.
This is useful for testing of repeat nodes - both performance
and conformance, and potentially even driver issues with GL_REPEAT.
We have code for manual repeating anyway, so adding a flag to force
always using it is easy.
The current context might be the last reference to the context, which
would make it go away when the renderer calls make_current().
See commit 0fa2ae48d4 for a similar case.
When we use download in the middle of an upload operation (or the
other way around), we may end up making a different GL context
current. The downloader code is reponsible for reestablishing
the previous context when it is done. The old GL renderer was
doing that, NGL wasn't, until now.
For dmabufs, the format is not an exact description of the data, it only
gives the closest memory format for a given fourcc.
This of course means that multiple different fourccs may report the same
format.
So when deciding if we need to copy the image to get the right data to
download, we need to check if the fourcc is correct, not if the format
is.
Related: #7046
When we want to download a dmabuf, we want to download the actual
dmabuf.
If we just grab the cached image and use that, we might get the
(reuploaded) copy of the dmabuf. This happens when this renderer
doesn't support downloading this dmabuf but has used it before.
Worse, this is a reentrancy issue, where this renderer is trying to
render the dmabuf and has already scheduled the upload but the upload
has not finished. We will then download from an empty image, which is
very wrong.
The way to check that we have the actual dmabuf is a bit brittle, but it
should work.
Fixes#7046
The clip might be different from the scissor due to incompatible
intersections.
But the resulting intersection might be fully clipped, so we should
consider it.
Testsuite with longer explanation attached.
Fixes#7044
Instead of using glBuffer(Sub)Data() every time we set new globals, fill
a single buffer with all the globals and use glBindBufferRange() on that
buffer to set the current globals.
For some formats, we could not download the dmabuf directly - in
particular YUV formats.
For those, do a copy on the GPU into the correct format.
While we're at it, also check the desired format and colorstate and if
they don't match, do the conversion on the GPU instead of using
gdk_memory_convert().
Reserve the CPU conversion for situations where the GPU doesn't support
the final format - like for example G8A8 (or often also RGB16).
Make gsk_gpu_cache_cache_texture_image() API safer by accepting all
color states as input and just not caching the images for colorstates we
don't care about.
Instead of passing down the depth and extracting format/srgb from it at
the end, extract format/srgb in the nodeprocessor and pass it down.
This allows creating offscreens for weirder formats in the future.
... and use it for the dmabuf downloader
Splits the download op into 2 separate ops: One for downloading textures
and one for downloading into preallocated memory.
The download into memory is the fallback for the texture downloading op,
so they need to share code.
But keeping them separate ensures that the different codepaths for
dmabuf download and render_texture() don't get mixed up in weird ways
that potentially call into each other.
By passing the emory down into the op we can also avoid an extra memcpy
which can lead to quite large speedups for big textures.