Enable scene-tree direct scanout of a single buffer with various options
for scaling and source crop. This is intended to support direct scanout
for fullscreen video with/without scaling, letterboxing/pillarboxing
(e.g. 4:3 content on a 16:9 display), and source crop (e.g. when
1920x1088 planes are used for 1920x1080 video).
This works by explicitly specifying the source crop and destination box
for the primary buffer in the output state. DRM atomic and libliftoff
backends will turn this into a crop and scale of the plane (assuming the
hardware supports that). For the Wayland/X11/DRM-legacy backends I just
reject this so scanout will be disabled.
The previous behaviour is preserved if buffer_src_box and buffer_dst_box
are unset: the buffer is displayed at native size at the top-left of the
output with no crop.
The change to `struct wlr_output_state` makes this a binary breaking
change (but this works transparently for scene-tree compositors like
labwc after a recompile).
We don't need to process all events, only those that come from the host
compositor. This also avoids running user event handlers while in the
middle of committing an output.
Fixes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3857
This commit fixes the following interaction:
1) The host compositor sends a configure sequence for an output.
2) Before handling it, the guest compositor disables and immediately
re-enables the output.
3) The guest compositor tries to ack the configure event from step 1
which isn't relevant anymore after unmapping and re-initialization.
Instead, ignore all configure events after unmapping until we're sure
the host compositor has processed the unmapping.
Also see
https://gitlab.freedesktop.org/wayland/wayland-protocols/-/issues/108.
- Reset all variables representing an initialized xdg_toplevel's state
on unmap.
- Send an initial commit only when an output is about to be enabled.
- If an output isn't configured yet, don't commit a buffer.
If the guest compositor disabled an output and then immediately
committed another state, we would perform a commit with a null buffer,
which is against the protocol, as the host compositor expects an
initial commit with no buffer at all.
Stop trying to maintain a per-file _POSIX_C_SOURCE. Instead,
require POSIX.1-2008 globally. A lot of core source files depend
on that already.
Some care must be taken on a few select files where we need a bit
more than POSIX. Some files need XSI extensions (_XOPEN_SOURCE) and
some files need BSD extensions (_DEFAULT_SOURCE). In both cases,
these feature test macros imply _POSIX_C_SOURCE. Make sure to not
define both these macros and _POSIX_C_SOURCE explicitly to avoid
POSIX requirement conflicts (e.g. _POSIX_C_SOURCE says POSIX.1-2001
but _XOPEN_SOURCE says POSIX.1-2008).
Additionally, there is one special case in render/vulkan/vulkan.c.
That file needs major()/minor(), and these are system-specific.
On FreeBSD, _POSIX_C_SOURCE hides system-specific symbols so we need
to make sure it's not defined for this file. On Linux, we can
explicitly include <sys/sysmacros.h> and ensure that apart from
symbols defined there the file only uses POSIX toys.
- Add POSIX 1993.09 compliance macro in source files that use
"struct timespec";
- Add POSIX 2001.12 compliance macro in source files that use
"struct sigaction" and the SA_SIGINFO macro, or the fchmod()
function;
- Add POSIX 2008.09 compliance macro in source files that use the
getline() function.
These compliance macros are enough for wlroots to compile with the
git-master version of uClibc-ng.
Signed-off-by: Paul Cercueil <paul@crapouillou.net>
Since headless and wayland-without-presentation-feedback were firing
present inside their commit impls, present was getting fired before
commit, which is cursed. Defer this with an idle timer so that commit
handlers can run before present handlers.
Up until now, frame/present events were only triggered when the
user submitted a buffer. Change the wlr_output API so that these
events are triggered when any commit is applied on an enabled
output.
Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3708
When integrating wlroots with another toolkit, wlroots may receive
wl_pointer.enter events for surfaces not backed by a wlr_output.
Ignore such surfaces by tagging the ones we're aware of with
wl_proxy_set_tag().
This changes the semantics of wlr_output_state. Instead of having
fields with uninitialized memory when missing from the committed
bitflag, all fields are always initialized (and maybe NULL/empty),
just like we do in wlr_surface_state. This reduces the chances of
footguns when reading a field, and removes the need to check for
the committed bitfield everywhere.
A new wlr_output_state_init() function takes care of initializing
the Pixman region.
Add a src_box state field. Use the SRC_* KMS props in the DRM
backend, reject the layers in the Wayland backend (for now, we can
support it later via viewporter).
This allows callers to set a destination size different from the
buffer size to scale them.
The DRM backend supports this. The Wayland backend doesn't yet
(we'd need to wire up viewporter).
- Simplifies the backends
- Avoids having two ways to do the same thing: previously one could
disable a layer by either omitting it from wlr_output_state.layers,
or by passing a NULL buffer
- We can change our mind in the future: we can allow users to omit
some layers and define a meaning without breaking the API.
References: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4017#note_1783997
We've had this struct for a while. It'd be useful for compositors
if they want to manage the swap chains themselves instead of being
forced to use wlr_output's. Some compositors might also want to use
a swapchain without an output.
During a modeset, the core wlr_output logic will allocate a buffer
with a new size and commit it. However if we still have a frame
callback pending we'd refuse to perform the commit. This is
inconsistent with the DRM backend, which performs a blocking
modeset.
This is visible when resizing the Wayland toplevel. The logs are
filled with "Skipping buffer swap", and the wlr_damage_ring's
bounds are not properly updated.
Fix this by destroying the pending frame wl_callback.
destroy_wl_buffer() is called from backend_destroy(). We need to
ensure the wlr_buffer is unlocked when we're waiting for a
wl_buffer.release event from the parent compositor.