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.
Instead of operating on FDs in {open,close}_device, operate on
wlr_devices. This avoids the device lookup in wlr_session and allows
callers to have access to wlr_device fields.
For now, we use it to remove wlr_session_signal_add and replace it with
a more idiomatic wlr_session.events.change field. In the future, other
events will be added.
Previously, we only had the pending state (crtc->pending, crtc->mode and
crtc->active). This causes issues when a commit fails: the pending state
is left as-is, and the next commit may read stale data from it.
This will also cause issues when implementing test-only commits: we need
to rollback the pending CRTC state after a test-only commit.
Introduce separate pending and current CRTC states. Properly update the
current state after a commit.
retry_pageflip is now dead code, since drm_connector_start_renderer
isn't called anymore. It was previously called when enabling an output.
The name "retry_pageflip" was a little confusing because the function
retried a modeset and the timer wasn't set up while performing a simple
page-flip.
Let's just remove this altogether for now. We can discuss whether it's
worth it to bring it back. Should we only do it on failed page-flips?
Should we only do it on EBUSY?
We don't need a per-CRTC atomic request anymore. Let's make the request
per-commit so that it's easier to debug.
This is also groundwork for supporting wlr_output_test properly.
GAMMA_LUT_SIZE isn't an atomic property. It can be used with the legacy
interface too. So we can unify both codepaths and remove
wlr_drm_interface.crtc_get_gamma_size.
It's no guaranteed to exist though, so we still need to keep the
fallback.
This is a type which manages gbm_surfaces and imported dmabufs in the
same place, and makes the lifetime management between the two shared. It
should lead to easier to understand code, and fewer special cases.
This also contains a fair bit of refactoring to start using this new
type.
Co-authored-by: Simon Ser <contact@emersion.fr>
Check that buffer can be scanned out in wlr_output_test instead of
wlr_output_attach_buffer. This allows the backend to have access to the
whole pending state when performing the check.
This brings the wlr_output API more in line with the KMS API.
This removes the need for wlr_output_attach_buffer to return a value,
and for wlr_output_impl.attach_buffer.
This fixes a heap-use-after-free when the session is destroyed before
the backend during wl_display_destroy:
==1085==ERROR: AddressSanitizer: heap-use-after-free on address 0x614000000180 at pc 0x7f88e3590c2d bp 0x7ffdc4e33f90 sp 0x7ffdc4e33f80
READ of size 8 at 0x614000000180 thread T0
#0 0x7f88e3590c2c in find_device ../subprojects/wlroots/backend/session/session.c:192
#1 0x7f88e3590e85 in wlr_session_close_file ../subprojects/wlroots/backend/session/session.c:204
#2 0x7f88e357b80c in libinput_close_restricted ../subprojects/wlroots/backend/libinput/backend.c:24
#3 0x7f88e21af274 (/lib64/libinput.so.10+0x28274)
#4 0x7f88e21aff1d (/lib64/libinput.so.10+0x28f1d)
#5 0x7f88e219ddac (/lib64/libinput.so.10+0x16dac)
#6 0x7f88e21b415d in libinput_unref (/lib64/libinput.so.10+0x2d15d)
#7 0x7f88e357c9d6 in backend_destroy ../subprojects/wlroots/backend/libinput/backend.c:130
#8 0x7f88e3545a09 in wlr_backend_destroy ../subprojects/wlroots/backend/backend.c:50
#9 0x7f88e358981a in multi_backend_destroy ../subprojects/wlroots/backend/multi/backend.c:54
#10 0x7f88e358a059 in handle_display_destroy ../subprojects/wlroots/backend/multi/backend.c:107
#11 0x7f88e314acde (/lib64/libwayland-server.so.0+0x8cde)
#12 0x7f88e314b466 in wl_display_destroy (/lib64/libwayland-server.so.0+0x9466)
#13 0x559fefb52385 in main ../main.c:67
#14 0x7f88e2639152 in __libc_start_main (/lib64/libc.so.6+0x27152)
#15 0x559fefb4297d in _start (/home/simon/src/glider/build/glider+0x2297d)
0x614000000180 is located 320 bytes inside of 416-byte region [0x614000000040,0x6140000001e0)
freed by thread T0 here:
#0 0x7f88e3d0a6b0 in __interceptor_free /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:122
#1 0x7f88e35b51fb in logind_session_destroy ../subprojects/wlroots/backend/session/logind.c:270
#2 0x7f88e35905a4 in wlr_session_destroy ../subprojects/wlroots/backend/session/session.c:156
#3 0x7f88e358f440 in handle_display_destroy ../subprojects/wlroots/backend/session/session.c:65
#4 0x7f88e314acde (/lib64/libwayland-server.so.0+0x8cde)
previously allocated by thread T0 here:
#0 0x7f88e3d0acd8 in __interceptor_calloc /build/gcc/src/gcc/libsanitizer/asan/asan_malloc_linux.cc:153
#1 0x7f88e35b911c in logind_session_create ../subprojects/wlroots/backend/session/logind.c:746
#2 0x7f88e358f6b4 in wlr_session_create ../subprojects/wlroots/backend/session/session.c:91
#3 0x559fefb51ea6 in main ../main.c:20
#4 0x7f88e2639152 in __libc_start_main (/lib64/libc.so.6+0x27152)
This requires functions without a prototype definition to be static.
This allows to detect dead code, export less symbols and put shared
functions in headers.
Instead of waiting for the next pageflip, destroy the output immediately
since we can now handle flips for outputs which no longer exist.
Also demote the missing crtc on flip to debug.
Fixes#1739
The documentation for wayland-server.h says:
> Use of this header file is discouraged. Prefer including
> wayland-server-core.h instead, which does not include the server protocol
> header and as such only defines the library PI, excluding the deprecated API
> below.
Replacing wayland-server.h with wayland-server-core.h allows us to drop the
WL_HIDE_DEPRECATED declaration.
On DRM resume, such as switching back to a TTY, the output needs to be
modeset to the current mode. However, wlr_output_set_mode will return
early when attempting to set the mode to the current mode. This just
steps around wlr_output_set_mode and calls drm_connector_set_mode
directly.
In order for a surface to be used as a cursor plane framebuffer, it
appears that requiring the buffer to be linear is sufficient.
GBM_BO_USE_SCANOUT is added in case GBM_BO_USE_LINEAR isn't sufficient
on untested hardware.
Fixes#1323
Removed wlr_drm_plane.cursor_bo as it does not serve any purpose
anymore.
Relevant analysis (taken from the PR description):
While trying to implement a fix for #1323, I found that when exporting
the rendered surface into a DMA-BUF and reimporting it with
`GBM_BO_USE_CURSOR`, the resulting object does not appear to be valid.
After some digging (turning on drm-kms debugging and switching to legacy
mode), I managed to extract the following error: ```
[drm:__setplane_check.isra.1 [drm]] Invalid pixel format AR24
little-endian (0x34325241), modifier 0x100000000000001 ``` The format
itself refers to ARGB8888 which is the same format as
`renderer->gbm_format` used in master to create the cursor bo. However,
using `gbm_bo_create` with `GBM_BO_USE_CURSOR` results in a modifier of
0. A modifier of zero represents a linear buffer while the modifier of
the surface that is rendered to is `I915_FORMAT_MOD_X_TILED` (see
https://git.kernel.org/pub/scm/linux/kernel/git/stable/linux.git/tree/include/uapi/drm/drm_fourcc.h?h=v4.20.6#n263).
In order to fix this mismatch in modifier, I added the
`GBM_BO_USE_LINEAR` to the render surface and everything started to work
just fine. I wondered however, whether the export and import is really
necessary. I then decided to test if the back buffer of the render
surface works as well, and at least on my hardware (Intel HD 530 and
Intel UHD 620) it does. This is the patch in this PR and this requires
no exporting and importing.
I have to note that I cheated in order to import DMA_BUFs into a cursor
bo when doing the first tests, since on import the Intel drivers check
that the cursor is 64x64. This is strange since cursor sizes other than
64x64 have been around for quite some time now
(https://lists.freedesktop.org/archives/mesa-commit/2014-June/050268.html).
Removing this check made everything work fine. I later (while writing
this PR) found out that `__DRI_IMAGE_USE_CURSOR` (to which
`GBM_BO_USE_CURSOR` translates) has been deprecated in mesa
(https://gitlab.freedesktop.org/mesa/mesa/blob/master/include/GL/internal/dri_interface.h#L1296),
which makes me wonder what the usecase of `GBM_BO_USE_CURSOR` is. The
reason we never encountered this is that when specifying
`GBM_BO_USE_WRITE`, a dumb buffer is created trough DRM and the usage
flag never reaches the Intel driver directly. The relevant code is in
https://gitlab.freedesktop.org/mesa/mesa/blob/master/src/gbm/backends/dri/gbm_dri.c#L1011-1089
. From this it seems that as long as the size, format and modifiers are
right, any surface can be used as a cursor.