I just spent an hour trying to figure out why things don't work. And it
was an optional dependency hidden 3 layers deep in some meson file.
This really has to stop.
And because just like in GTK, GStreamer's dmabuf APIs are always
available (they will just fail on Windows etc), there's no need to have
any conditions.
The only difference is that the GStreamer media backend now requires
GStreamer 1.24.
In the case of no offloading, we want to pass through to the child
(which is likely a big texture doing occlusion).
In the case of punching a hole, we want to punch the hole and not draw
anything behind it, so we start an occlusion pass with transparency.
And in the final case with offloading active, we don't draw anything,
so we don't draw anything.
This should fix concerns about drawing the background behind the video
as mentioned for example in
https://github.com/Rafostar/clapper/issues/343#issuecomment-1445425004
Container nodes save their opaque region, so it's quick to access. Use
that to check if the largest opaque region even qualifies for culling -
and if not, just exit.
Speeds up walking node trees by a lot.
Now that we can specify the min size for an occlusion pass, we can
specify that we want the full clip rect to be occluded for occlusion to
trigger.
The benefit of this is that for partial redraws we almost
always get the background color to cover the redrawn rectangle, so
occlusion will kick in.
When trying to cull, try culling from the largest rectangle of the
remaining draw region first. That region has the biggest chance of
containing a large area to skip.
As a side effect, we can stop trying to cull once the largest rectangle
isn't big enough anymore to contain anything worth culling.
When querying clip bounds, also check the scissor rect, because
sometimes that one is tighter than the clip bounds, because the clip
bounds need to track some larger rounded corners.
Makes a few tests harder to break.
Instead of requiring an occlusion pass to cover the whole given scissor
rect, allow using a smaller rect to start the pass.
When starting such a pass, we adjust the scissor rect to the size of
that pass and do not grow it again until the pass is done.
The rectangle subtraction at the end will then take care of subtraction
that rectangle from the remaining pixels.
To not end up with lots of tiny occlusion passes, add a limit for how
small such a pass may be.
For now that limit is arbitrarily chosen at 100k pixels.
gsk_gpu_node_processor_rect_to_device() is a useful function to have,
even if it has to return FALSE sometimes when there is no simple 1:1
mapping - ie when the modelview contains a rotation.
Instead of just iterating over all the rectangles of the region,
always draw the first rectangle of the region and subtract it when done.
This sounds more complicated, but it will allow us to modify the
rectangle in future commits.
Also change the way rectangles are printed by including the bottom right
coordinate, too.
I'm still not sure what the best way is, but at least I no longer get
confused and it has the infos I want.
We were comparing with destination stride, not with source stride, and
in rare cases when those were different, this would trigger aborts in
the testsuite.
Add a function that tracks whether a render node's content is
in a wide gamut color state (in practice, that means non-sRGB).
This will be used in render_texture to determine the color
state to use when creating a texture.
Each time we create a new window, we create a new EGLSurface. Each time
we destroy a window, we failed to destroy the EGLSurface, due to passing
a GdkDisplay instead of a EGLDisplay to eglDestroySurface().
This effectively leaked not only the EGL surface metadata, but also the
associated DMA buffers. For applications where one opens and closes many
windows over the lifetime of the application, and where the application
runs for a long time; for example a terminal emulator server, this
causes a significant memory leak, as the memory will only ever be freed
once once the application process itself exits, if ever.
Fix this passing an actual EGLDisplay instead of an GdkDisplay, to
eglDestroySurface().