The old approach of using a signal is fundamentally broken for a common
usecase: When the waiter is ready, it's common to immediately finish and
free any resources associated with it.
Because of the semantics of wl_signal_emit_mutable() this is UB.
wl_signal_emit_mutable() always excepts that the waiter hasn't been freed
until the signal has finished being emitted.
Instead of over engineering the solution, let's just add a callback required
by wlr_drm_syncobj_timeline_waiter_init(). In this callback, the implementation
is free to finish() or free() any resource it likes.
It makes sense to use udmabuf when the backend wants shm, the
renderer wants DMA-BUFs, and we don't have a DRM FD because we're
running with a software renderer (e.g. llvmpipe or lavapipe).
udmabuf can create a DMA-BUF backed by a memfd. This is useful
when running with a software implementation of GL/Vulkan: the memfd
can be passed to the parent compositor via wl_shm and the DMA-BUF
can be imported via the usual APIs into GL/Vulkan.
The Vulkan renderer performs alpha blending in linear RGB space, which
preserves hue better than blending sRGB-encoded values directly (as the
gles and pixman renderers do), but unfortunately tends to give a
too-bright result when blending dark and light colors.
(In desktop usage, this especially affects dark, semi-transparent
tooltips, which appear significantly more transparent than expected,
affecting readability if light text underneath shows through.)
This is a novel (I think) approach to compensating for this effect by
adjusting the alpha value of the source texture - basically the result
is that dark semi-transparent pixels are made a little more opaque,
while light semi-transparent pixels are made a little more transparent.
Alpha values of 0 and 1 are unchanged.
I am somewhat new to science of color blending (Björn Ottosson's page,
"How software gets color wrong" is very enlightening) but I think this
approach makes at least a little bit of sense theoretically, and the
result seems to me subjectively to be an improvement.
Analysis from an expert on the subject would be greatly appreciated.
v2: compensate alpha in solid color conversions also
v3: un-premultiply average value for solid color conversion
Perform a primitive garbage collection of buffers that have not been
used in the past 10 seconds, an arbitrarily selected number.
As garbage collection also makes span buffer allocation happen much more
often, logging on allocation activity leads to a lot of log noise so get
rid of that while at it.
With this change vulkan renderer can be automatically chosen in two more cases:
GLES2 renderer is disabled at compile time
GLES2 renderer failed to be created
Main purpose of this change is to automatically choose vulkan as renderer when GLES2 renderer is not enabled.
Color transform can have multiple types and these different types
want to store different metadata. We previously stored this metadata
directly on wlr_color_transform even for transforms that don't use it.
Instead, let's take the prior art from wlr_scene where each scene node
is built on a base node. Notice how wlr_color_transform_lut3d now has
a `struct wlr_color_transform base`. This is advantageous in multiple
ways:
1. We don't allocate memory for metadata that will never be used.
2. This is more type safe: Compositors can pass around a
struct wlr_color_transform_lut3d if they know they only want to use a
3d_lut.
3. This is more scalable. As we add more transform types, we don't have
to keep growing a monolithic struct.
The spec for VkMemoryPropertyFlagBits says:
> device coherent accesses may be slower than equivalent accesses
> without device coherence [...] it is generally inadvisable to
> use device coherent or device uncached memory except when really
> needed
We don't really need coherent memory so let's not require it and
invalidate the memory range after mapping instead.
Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3868