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
With the following sequence of events, the cursor FB fields could
end up being all set to NULL while the cursor is enabled:
1. set_cursor is called, conn->cursor_pending_fb is set to a FB
pointer.
2. The output is committed with a buffer. crtc->cursor->queued_fb
is set to the FB pointer, conn->cursor_pending_fb is reset to
NULL. A page-flip event is expected in the future.
3. The output is committed with a modeset before the page-flip
event is triggered. crtc->cursor->queued_fb is reset to NULL.
At this point all of crtc->cursor->current_fb,
crtc->cursor->queued_fb and conn->cursor_pending_fb are NULL which
is a bogus state when the cursor plane is enabled.
To avoid this issue, avoid overwriting crtc->cursor->queued_fb
with a NULL pointer on commit. The cursor logic still isn't great,
but let's keep a rework of that for a separate patch.
Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3734
Only print the list of connectors once, with both the old and new
status. Use CRTC object IDs instead of CRTC indices. Make it obvious
when a connector keeps the same CRTC.
If a connector has no current/queued buffer, but has a pending
buffer in the commit, we need to process that pending buffer before
checking pending.primary_fb.
When turning off a CRTC, we don't need a buffer.
It doesn't matter whether this is a modeset or not: we always need
a buffer even for regular page-flips as long as a connector is
active.
Fixes: 374daeb256 ("backend/drm: Ensure a primary fb is available when configuring an output")
We can never hit the case where we try to light up an output without
a buffer. output_ensure_buffer() will catch this for now, and when that's
removed, output_basic_test() will catch this case.
drm_connect_state_init() will set primary_fd to null if no CRTC is active
for the connector and can crash later if the code expects a CRTC (like
when lighting up an output).
On startup, we fetch the previous MODE_ID blob ID so that
compositors can keep using the previous mode if they want to.
However, that blob doesn't belong to us, it belongs to the
previous DRM master. As a result, we get an error when trying to
destroy it.
Fix this by tracking whether the blob belongs to us or not.
Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3811
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.
If all connectors and planes already have the right CRTC set, or
are disabled, we can skip the device-wide reset after a VT switch.
I've contemplated using a more fine-grained logic to only reset
the connectors, CRTCs and planes that need to be migrated. However,
writing a correct algorithm for this would be quite involved, and it
doesn't seem worth the trouble anyways.
Closes: https://github.com/swaywm/sway/issues/7956
This function fetches property IDs. These don't change for the
lifetime of the connector. Instead of refreshing the property IDs
on hotplug (and leaving property IDs unset for disconnected
connectors), only fetch the property IDs when we create the
connector.
Since we only use the backend capabilities here we can simply pass
them in directly. This allows other locations to create an allocator
even if they don't have a backend. They can simply specify the caps
they want instead.
wlr_output.refresh is populated by core wlr_output, and thus will
be zero for a custom mode with an unset refresh rate.
Save the refresh rate from the drmModeModeInfo in wlr_drm_connector
instead.
Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3791
It can be useful for compositors to get the real DRM FD instead of
the one from the parent compositor. For instance, some compositors
might want to perform some DRM IOCTLs there to check the driver
name, fetch some DRM resources, etc. This will also be a requirement
for direct scanout on secondary GPUs.
RMFB implicitly performs a modeset to turn off any CRTC which is
using the FB. This prevents seamless transitions between two DRM
masters from working.
Use the new CLOSEFB IOCTL which doesn't turn off anything and leave
it up to the compositor to turn off outputs on shutdown if it wants
to.
wl_display holds a lot more than wlr_session needs: wlr_session
only needs to wait for a FD to become readable, but wl_display
provides full access to the Wayland client and protocol objects.
Switch to wl_event_loop to better reflect the above.
Introduce a per-page-flip tracking struct passed to the kernel
when we request a page-flip event for an atomic commit. The kernel
will pass us back this pointer when delivering the event.
This eliminates any risk of mixing up events together. In particular,
if two events are pending, or if the CRTC of a connector is swapped,
we no longer blow up in the page-flip event handler.
Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3753
since 4932e0d347f("backend/drm: ensure plane surfaces are cleaned up on shutdown")
at finish_drm_resources called drm_plane_finsh_surface has already free the fb
Signed-off-by: zhoulei zhoulei@kylinos.cn
Signed-off-by: sunzhguy <sunzhigang1@kylinos.cn>
Right now this is done "by chance" because we disable all CRTCs
on shutdown. However, we'll stop doing this. Plus, if disabling
a CRTC fails, we don't cleanup properly.
We can just assume CLOCK_MONOTONIC everywhere.
Simplifies the backend API, and fixes clock mismatches when multiple
backends are used together with different clocks.
We currently only perform non-blocking commits for non-modeset commits
with a buffer attached.
Perform non-blocking commits whenever there is no pending pageflip
event. If a non-blocking modeset commit fails, which can happen if the
driver implicitly added more CRTCs to the commit that we did not know we
had to wait for, retry with a blocking commit.
References: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/2239
The name "allow_artifacts" and associated description is very vague, and
theoretically allow for tearing behavior. Clarify that we only intend to
mean artifacts related to output configuration (e.g., modesets).
References: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3740
DRM_MODE_PAGE_FLIP_ASYNC doesn't allow user-space to submit new
buffers before waiting for the uevent: the kernel will return EBUSY
in that case.
Fixes: c2aa7fd965 ("backend/drm: Add async page flip support to legacy")
Since e5fc8cd4c7 ("output: trigger frame/present events on all
commits on enabled output"), any commit on an enabled output is
supposed to trigger frame/present events.
The DRM backend was skipping the commit completely for no-op
commits. Stop doing so.
Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3719
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
We were only restoring fixed modes here. The DRM backend no longer
creates fixed modes when the compositor sets a custom mode, so we
need to handle this situation when restoring.
Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3698
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.
The kernel complains when the damage exceeds the FB bounds:
[73850.448326] i915 0000:00:02.0: [drm:drm_atomic_check_only] [PLANE:31:plane 1A] invalid damage clip 0 0 2147483647 2147483647
Make the DRM backend behave like the Wayland one and allow compositors
to damage (0, 0, INT32_MAX, INT32_MAX) to repaint everything without
needing to know the exact buffer size.
Closes: https://github.com/swaywm/sway/issues/7632
Based on five calls:
wlr_render_timer_create - creates a timer which can be reused across
frames on the same renderer
wlr_renderer_begin_buffer_pass - now takes a timer so that backends can
record when the rendering starts and finishes
wlr_render_timer_get_time - should be called as late as possible so that
queries can make their way back from the GPU
wlr_render_timer_destroy - self-explanatory
The timer is exposed as an opaque `struct wlr_render_timer` so that
backends can store whatever they want in there.
Commit 90d08f8f1c changed the way
wlr_drm_format_intersect worked, including passing in a destination
format list. This breaks scenarios where the intersection doesn't
find any matching formats, since we still have a valid destination
format set. This changes it to only return true if more than one
matching format is present in the intersection list.