This is the cause of the spurious "drmHandleEvent failed" messages
at exit. restore_drm_outputs calls handle_drm_event in a loop without
checking whether the FD is readable, so drmHandleEvent ends up with a
short read (0 bytes) and returns an error.
The loop's goal is to wait for all queued page-flip events to complete,
to allow drmModeSetCrtc calls to succeed without EBUSY. The
drmModeSetCrtc calls are supposed to restore whatever KMS state we were
started with. But it's not clear from my PoV that restoring the KMS
state on exit is desirable.
KMS clients are supposed to save and restore the (full) KMS state on VT
switch, but not on exit. Leaving our KMS state on exit avoids unnecessary
modesets and allows flicker-free transitions between clients. See [1]
for more details, and note that with Pekka we've concluded that a new
flag to reset some KMS props to their default value on compositor
start-up is the best way forward. As a side note, Weston doesn't restore
the CRTC by does disable the cursor plane on exit (see
drm_output_deinit_planes, I still think disabling the cursor plane
shouldn't be necessary on exit).
Additionally, restore_drm_outputs only a subset of the KMS state.
Gamma and other atomic properties aren't accounted for. If the previous
KMS client had some outputs disabled, restore_drm_outputs would restore
a garbage mode.
[1]: https://blog.ffwll.ch/2016/01/vt-switching-with-atomic-modeset.html
Right now callers of drm_crtc_commit need to check whether the
interface is legacy or atomic before passing the TEST_ONLY flag.
Additionally, the fallbacks for legacy are in-place in the common
code.
Add a test_only arg to the crtc_commit hook. This way, there's no
risk to pass atomic-only flags to the legacy function (add an assert
to ensure this) and all of the legacy-specific logic can be put back
into legacy.c (done in next commit).
Instead of passing a wlr_texture to the backend, directly pass a
wlr_buffer. Use get_cursor_size and get_cursor_formats to create
a wlr_buffer that can be used as a cursor.
We don't want to pass a wlr_texture because we want to remove as
many rendering bits from the backend as possible.
Backend-initiated mode changes can use this function instead of
going through drm_connector_set_mode. drm_connector_set_mode becomes
a mere drm_connector_commit_state helper.
Replace it with a new drm_connector_state_is_modeset function that
decides whether a modeset is necessary directly from the
wlr_output_state which is going to be applied.
Stop assuming that the state to be applied is in output->pending in
crtc_commit. This will allow us to remove ephemeral fields in
wlr_drm_crtc, which are used scratch fields to stash temporary
per-commit data.
To unify the code style of the project, absolute paths have been used in
some places, such as '#include "render/allocator.h"' in
"render/gbm_allocator.h". Except for include the wayland protocol
headers should be consistent.
The subconnector property indicates the connector sub-type. This is
useful because that usually indicates what kind of connector the user
has plugged in to their monitor, e.g. a DisplayPort-to-DVI cable will
indicate a DVI subconnector. Also some laptops have non-DP connectors
that are internally linked to a DP port on the GPU.
Set the output description accordingly.
See https://drmdb.emersion.fr/properties/3233857728/subconnector
Stop keeping track of buffers on the parent GPU when multi-GPU is used.
This removes support for export_dmabuf on secondary GPUs, but renderer
v6 will bring this back by managing the swapchains in wlr_output instead
of the backends.
wlr_drm_connector.crtc may be updated by the DRM backend while a
page-flip is pending. In this case, the page-flip handler won't be able
to find the right wlr_drm_connector from the CRTC ID.
Save the CRTC when performing a page-flip to ensure we always find the
right connector when we get the event.
This callback allowed compositors to customize the EGL config used by
the renderer. However with renderer v6 EGL configs aren't used anymore.
Instead, buffers are allocated via GBM and GL FBOs are rendered to. So
customizing the EGL config is a no-op.
We now properly mark the cursor plane's formats as linear-only, and we
now have a version of wlr_drm_format_intersect that handles the case of
linear-only formats and implicit modifiers.
We can remove the special drm_plane_init_surface flag we had for cursor
planes. This also allows us to use a non-linear layout for cursor planes
on drivers that support it.
Tested on amdgpu GFX9.
The DRM backend is a little special when it comes to wlr_outputs: the
wlr_drm_connectors are long-lived and are created even when no screen is
connected.
A wlr_drm_connector only advertises a wlr_output to the compositor when
a screen is connected. As such, most of wlr_output's state is invalid
when the connector is disconnected.
We want to stop using wlr_output state on disconnected connectors.
Introduce wlr_drm_connector.name which is always valid regardless of the
connector status to avoid reading wlr_output.name when disconnected.
Simplify and unify connector-specific logging with a new
wlr_drm_conn_log macro. This makes it easier to understand which
connector a failure is about, without having to explicitly integrate the
connector name in each log message.
gbm_bo_create_with_modifiers doesn't take GBM flags, so our
wlr_gbm_allocator interface doesn't either. We were still internally
using GBM flags in the DRM backend, leading to awkward back-and-forth
conversions.
The only flag passed to drm_plane_init_surface was GBM_BO_USE_LINEAR, so
turn that into a bool to make sure other flags can't be passed in.
Move the "force linear" logic out of init_drm_surface, because the
supplied wlr_drm_format should already contain that information.