This fixes the memory leak in wlr_keyboard_group.keys. The leak happened
because wlr_keyboard.keycodes never contains duplicated keycodes while
wlr_keyboard_group.keys can, so calling wlr_keyboard_finish() for all
the wlr_keyboards in wlr_keyboard_group doesn't always free all the keys
in wlr_keyboard_group.keys.
drmModePageFlip() will fail with EBUSY on a disabled CRTC.
We can't fix this by clearing the DRM_MODE_PAGE_FLIP_EVENT when
performing a commit which disables CRTCs, because some device-wide
commits might also page-flip other enabled CRTCs (and skipping the
page-flip event would mess up our buffer tracking).
Fix this by immediately completing page-flips which disable a CRTC
on the legacy uAPI.
Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3918
We were always creating a custom mode object when the output didn't
have a fixed mode. This is important to handle two cases:
- Virtual outputs with no concept of fixed modes.
- DRM outputs with a list of fixed modes but with a custom mode set.
However, in the case where an output didn't have a fixed mode and
was disabled, we were also creating the custom mode object. Clients
would then see a "ghost" mode: a mode object with no properties at
all.
Fix this by only creating the custom mode object if the output is
enabled.
Fixes: 5de9e1a99d ("wlr-output-management: Send custom modes to clients")
Closes: https://github.com/swaywm/sway/issues/8420
wl_buffer.release event delivery becomes undefined when using the
linux-drm-syncobj-v1 protocol, so we need to wait for buffer
release via a timeline point instead.
The protocol requires both wait and signal timelines to be set, so
we need to create one when the compositor only supplies a wait
timeline.
Client buffers backed by wl_shm is aggressively released, in which case
we are not allowed to access it. Locking an already released buffer and
later unlocking it will also re-trigger release, confusing clients.
As a quick workaround, guard the unwrap by checking if the buffer is
locked, which will be the case for non-wl_shm buffers.
wlr_renderer and wlr_allocator will print out errors as they go, and end
with a final error if they fail to create anything. The caller of this
function will also log when it fails.
Skip the redundant errors emitted here.
If an mgpu device does not have a renderer, continue without one rather
than ignoring it entirely. It is not guaranteed that we will be able to
scan out to it in any particular configuration, but that is true for any
output regardless, and having the output visible is not harmful even if
it cannot light up.
To proceed safely, we strip implicit modifier support from all planes,
while avoiding duplication of the same logic for mdgpu_formats.
This helps GUD and DisplayLink scenarios.
We create a renderer for the sole purpose of blitting buffers from a
primary renderer that we might not be able to scan-out from. If we end
up with the pixman renderer, it either won't work becuase it cannot
import dmabufs from the primary renderer, or won't have any effect
because the primary renderer already uses dumb buffers.
We test for DMA-BUF capabilities specifically to make it clear what our
interest is, rather than focusing too much on the pixman renderer.
If init_drm_renderer failed, it would destroy the renderer but would not
set it to NULL, leading to use-after-free.
NULL the renderer after destroying it.
create_immed() is a bit dangerous because on failure, either the
connection is closed or the buffer is silently ignored.
Use create() with a roundtrip to figure out whether the import
succeeded.
Passing the wlr_client_buffer directly has a downsides because a
fresh wlr_buffer pointer is passed each output commit instead of
cycling through existing wlr_buffer objects:
- The FDs are re-imported each time in the backend.
- Any import failure is logged every output commit [1].
- The Wayland backend cannot handle import failures without
roundtripping each output commit [2].
Instead, extract the source buffer from the wlr_client_buffer and
pass that to the backend.
[1]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4836
[2]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4841
If we are trying directly scan-out a shm buffer, we create a temporary
buffer pool to instantiate a wl_buffer from, created in accordance to
our buffers size. If the buffer has an offset, it will end up out of
bounds of the created pool.
Extend the temporary pool by the buffer offset to compensate. Matching
the original pool size does matter unless we want to optimize away the
temporary pool to reduce mappings in the parent compositor.
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.
The event time used for zwp_tablet_pad_group_v2_send_mode_switch was
tv_nsec / 1000, which is microseconds resetting every whole second.
Use get_current_time_msec to get milliseconds including whole seconds.
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.
timeline feature will never be applicable to backends without it, so
don't check it. Before this commit, it would cause timeline to be set
to false if libinput ended up being the last item in the list (which is
the case currently).
We store both queued and current buffers to be able to retain both the
framebuffer currently on screen and the one queued to replace it. From a
re-use perspective, we only care about the last committed framebuffer.
The viewport is only stored in order to be re-used together with the
last committed framebuffer, so do away with the queued/current
distinction and store a single viewport updated every time a commit
completes.
Instead of trying to restore the drm state when the session is activated
again, just disconnect all outputs when the session is deactivated. The
scan that triggers on session activation will rediscover the connectors.
Accessing the output state viewport require a buffer, and that might not
have a state with a buffer when preparing the plane properties for an
atomic commit.
Instead, store the properties at the same time as the fb, and use a
similar mechanism to carry the state around.