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).
This piece of code checks for multi-GPU renderer support, so it
needs to run after the renderer is initialized.
Fixes: 514c4b4cce ("backend: add timeline feature flag")
Closes: https://github.com/swaywm/sway/issues/8382
The output feature flag has a flaw: it's not possible to check
whether the backend supports timelines during compositor
initialization when we need to figure out whether we want to enable
the linux-drm-syncobj-v1 protocol.
Introduce a backend-wide feature flag to indicate support for
timelines to address this defect.
Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3904
After a connector scan, new connectors might have appeared and old ones
gone away. At this point, old CRTC allocations are already gone, while
new allocations are not yet needed. Skip the call.
The page_flip can be destroyed, but it is unconditionally accessed later
on when setting present_flags. Fix this by simply setting the
present_flags before the page_flip gets destroyed.
../backend/drm/drm.c:415:49: error: ‘calloc’ sizes specified with ‘sizeof’ in the earlier argument and not in the later argument [-Werror=calloc-transposed-args]
415 | layer->candidate_planes = calloc(sizeof(bool), drm->num_planes);
| ^~~~
../backend/drm/drm.c:1435:24: error: incompatible types when returning type ‘_Bool’ but ‘struct wlr_drm_connector *’ was expected
1435 | return false;
| ^~~~~
This will let compositors know if changing adaptive_sync state has any
chance of working. When false, then the current state is the only
supported state, including if adaptive_sync is currently enabled as is
the case for Wayland and X11 backends.
When true, changing state might succeed, but no guarantee is made. It
just indicates that the backend does not already know it to be
impossible.
Our multi-gpu path currently needs to blit a buffer in order to have a
primaryfb to add to the commit. This is expensive, and we skip it
entirely during test commits. This in turn also means that we skip tests
commits entirely for such outputs, outside our own basic tests.
Backend-wide commits missed this check, and tried to perform test
commits for multi-gpu outputs despite no primaryfb having been attached,
making them always fail. Add the same exception as we have in the
per-connector commit-test.
When a compositors submits a wlr_output_state with
WLR_OUTPUT_STATE_ADAPTIVE_SYNC_ENABLED set and
adaptive_sync_enabled = false on an output which doesn't support
adaptive sync, we'd fail the commit. Fix this.
This bug was previously hidden because wlr_output_commit() drops
no-op changes from wlr_output_state.committed.
After disabling a connector, we need to cleanup the connector to
teardown the surfaces and unlock the FBs.
Move this logic into drm_connector_apply_commit() so that it's
applied when drm_commit() is called from somewhere else than
drm_connector_commit_state().
There is some duplicated logic between these two functions.
The commit codepath was calling the test function before doing the
real commit, so this also saves an unnecessary test-only commit
when performing a real commit.
This centralizes logic common for both the atomic and libliftoff
backends. Additionally, a struct will make it easier to implement
multi-connector commits (since it can be stored in an array).
In [1] we discovered a bug where wlr_drm_connector_state.primary_fb
would not be set up correctly because drm_connector_alloc_crtc() was
called after drm_connector_state_init(). This is tricky to discover,
so instead assert() that we have a usable CRTC by the time
drm_connector_state_init() is called.
[1]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4569
Use the same logic for cursor FBs as we currently use for primary
FBs. This also fixes the same bug as [1] but in a different, more
robust way.
The new logic integrates better with atomic and will be required
anyways in the future when set_cursor will be superseded by a better
API.
[1]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/4577