The previous fix tried to side-step cursor->pending_fb completely.
However that messes up our buffer locking mechanism.
Instead, stop clearing the pending cursor FB on a failed commit. The
pending cursor FB will remain for the next commit.
Fixes: 6c3d080e25 ("backend/drm: populate cursor plane's current_fb")
This reverts commit 6c3d080e25.
Populating wlr_drm_plane.current_fb messes up the buffer's locking.
The previous buffer is released while it's still being displayed
on-screen.
Custom backends and renderers need to implement
wlr_backend_impl.get_buffer_caps and
wlr_renderer_impl.get_render_buffer_caps. They can't if enum
wlr_buffer_cap isn't made public.
Right now, when a new output state field is added, all backends by
default won't reject it. This means we need to add new checks to
each and every backend when we introduce a new state field.
Instead, introduce a bitmask of supported output state fields in
each backend, and error out if the user has submitted an unknown
field.
Some fields don't need any backend involvment to work. These are
listed in WLR_OUTPUT_STATE_BACKEND_OPTIONAL as a convenience.
This moves the magic incantation into libdrm and is clearer. See
[1] for details.
While at it, fixup the doc comment and improve logging.
[1]: 523b3658aa
The set_cursor() hook is a little bit special: it's not really
synchronized to commit() or test(). Once set_cursor() returns true,
the new cursor is part of the current state.
This fixes a state where wlr_drm_connector.cursor_enabled is true
but there is no FB available. This is triggered by set_cursor()
followed by a failed commit(), which resets pending_fb.
We should definitely fix the output interface to make the cursor part
of the pending state, but that's a more involved change.
Instead of trying to perform a real modeset in init_renderer,
perform an atomic test-only commit to find out whether disabling
modifiers is necessary because of bandwidth limitations.
This decouples init_renderer from the actual commit, making it
possible to modeset an output with a user-supplied buffer instead
of a black frame.
We loose the ability to make sure the buffers coming from the
swapchain will work fine when using the legacy interface. This
can break i915 when atomic is disabled and modifiers enabled.
But i915 always has atomic (so the user must explicitly disable it
to run into potential bandwidth limitations) and is the only known
problematic driver.
Rely on wlr_output's generic swapchain support instead of creating our
own. The headless output now simply keeps a reference to the front buffer
and does nothing else.
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.
When picking a format, the backend needs to know whether the
buffers allocated by the allocator will be DMA-BUFs or shared
memory. So far, the backend used the renderer's supported
buffer types to guess this information.
This is pretty fragile: renderers in general don't care about the
SHM cap (they only care about the DATA_PTR one). Additionally,
nothing stops a renderer from supporting both DMA-BUFs and shared
memory, but this would break the backend's guess.
Instead, use wlr_allocator.buffer_caps. This is more reliable since
the buffers created with the allocator are guaranteed to have these
caps.
Instead of managing our own renderer and allocator, let the common
code do it.
Because wlr_headless_backend_create_with_renderer needs to re-use
the parent renderer, we have to hand-roll some of the renderer
initialization.
This new functions cleans up the common backend state. While this
currently only emits the destroy signal, this will also clean up
the renderer and allocator in upcoming patches.
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.
Populate the wlr_output_state when setting a mode. This will allow
drm_connector_set_mode to stop relying on ephemeral fields in
wlr_drm_crtc. Also drm_connector_set_mode will be able to apply
both a new buffer and a new mode atomically.
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.
On multi-GPU setups, there is a primary DRM backend and secondary
DRM backends. wlr_backend_get_drm_fd will always return the parent
DRM FD even on secondary backends, so that users always use the
primary device for rendering.
However, for our internal rendering we want to use the secondary
device. Use allocator_autocreate_with_drm_fd to make sure the
allocator will create buffers on the secondary device.
We do something similar to ensure our internal rendering will
happen on the secondary device with renderer_autocreate_with_drm_fd.
Fixes: cc1b66364c ("backend: use wlr_allocator_autocreate")
This function is only required because the DRM backend still needs
to perform multi-GPU magic under-the-hood. Remove the wlr_ prefix
to make it clear it's not a candidate for being made public.
This reverts commit f9f90b4173.
gbm_bo_get_modifier may return a modifier in these cases:
- The kernel doesn't support modifiers but Mesa does
- WLR_DRM_NO_MODIFIERS=1 is set
However, in both of these cases, the gbm_bo has been allocated
without modifiers.
There is already a check in drm_fb_create for modifiers:
wlr_drm_format_set_has will make sure buffers with an explicit
modifier will be rejected if the DRM backend doesn't support them.
So no need for an additional check in get_fb_for_bo.
Closes: https://github.com/swaywm/wlroots/issues/2896
The previous code would always print "falling back to legacy method",
even if the format wasn't ARGB8888.
Drop get_fb_for_bo_legacy, since the code can just be inlined without
hurting readability.
Ideally we should only fallback to drmModeAddFB if the error code
indicates the BE failure, but the original PR [1] doesn't say what
error code is returned by the kernel.
[1]: https://github.com/swaywm/wlroots/pull/2569
We shouldn't strip a modifiers from buffers, because the will make
the kernel re-interpret the data as LINEAR on most drivers,
resulting in an incorrect output on screen.
libseat provides all session functionality, so there is no longer need
for a session backend abstraction. The libseat device ID, seat handle
and event loop handle are moved to the main wlr_session and wlr_device
structs.
The get_drm_fd was made available in an internal header with a53ab146f. Move it
now to the public header so consumers opting in to the unstable interfaces can
make use of it.
PRIME support for buffer sharing has become mandatory since the renderer
rewrite. Make sure we check for the appropriate capabilities in backend,
allocator and renderer.
See also #2819.
wlroots' dependency on this library doesn't change the features
exposed to compositors. It's purely a wlroots implementation detail.
Thus downstream compositors shouldn't really care about it.
Introduce an "internal_features" dictionary to store the status of
such internal dependencies.
Downgrade errors to DEBUG level, because drm_fb_create is used in
test_buffer, so errors aren't always fatal. Add ERROR logs at call
sites where a failure is fatal, to make it clear something wrong
happened.
If the import to KMS succeeds, we have a better chance to be able to
scan it out.
Importing is also necessary for test-only commits, which we want to
add in the future.
This allows libseat to be compiled as a Meson subproject when it's
not installed system-wide. This can ease development and compilation
on distributions where libseat isn't packaged.
Split render/display setups have two separate devices: one display-only
with a primary node, and one render-only with a render node. However
in these cases the EGL implementation and the Wayland compositor will
advertise the display device instead of the render device [1]. The EGL
implementation will magically open the render device when the display
device is passed in.
So just pass the display device as if it were a render device. Maybe in
the future Mesa will advertise the render device instead and we'll be
able to remove this workaround.
[1]: https://gitlab.freedesktop.org/mesa/mesa/-/issues/4178
Compute only the transform matrix in the output. The projection matrix
will be calculated inside the gles2 renderer when we start rendering.
The goal is to help the pixman rendering process.
When a new texture is set, the hotspot may actually belong to the
previous texture and be out of bounds. Rather than incur X errors for
these, clamp the hotspot to be inside of the texture.
This fixes weston examples updating their cursors (e.g.
weston-eventdemo).
It turns out wl_event_source_check is not enough to guarantee that the
remote wl_display will be flushed after we queue requests. We need to
explicitly flush, just like we do in our X11 code.
References: https://gitlab.freedesktop.org/wayland/wayland/-/issues/187
When we receive an Expose event, that means that we must redraw that
region of the X11 window. Keep track of these regions with pixman
regions, and merge them with the additional output damaged regions.
Fixes#2670
The region variable was shadowed in an if block. As a result, in the
outer block region was always XCB_NONE and was never destroyed (causing
a memory leak on the server).
Reported-by: Ilia Mirkin <imirkin@alum.mit.edu>
This actually simplifies the logic since we no longer have to wait for
enter/leave events, and also improves the UX when e.g. handling a crash
with gdb attached.
See #2659
In 93cd3a79b2 ("backend/drm: stop using GBM flags"), we stopped
using the GBM_BO_USE_LINEAR flag in favor of a modifier list set
to { DRM_FORMAT_MOD_LINEAR }. However, the last argument of
drm_plane_init_surface disables modifiers -- so the buffer will just
get allocated with an implicit modifier, without necessarily being
LINEAR.
To fix this, allow modifiers when allocating the cursor buffers.
wlr_drm_plane.formats should already have the necessary LINEAR
restrictions.
Fixes: 93cd3a79b2 ("backend/drm: stop using GBM flags")
This allows a compositor to get a KMS connector object ID from a
wlr_output. The compositor can then query more information about
the connector via libdrm.
This gives more freedom to compositors and allows them to read
KMS properties that wlroots doesn't know about. For instance,
they could read the EDID or the suggested_{X,Y} properties and
change their output configuration based on that.
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
The new wlr_renderer_autocreate API is great for compositors, however
it causes some issues with DRM multi-GPU support.
A DRM child backend wants the compositor to use the parent GPU, so it
exposes the parent's DRM FD in get_drm_fd. However, in order to be able
to perform multi-GPU buffer copies, the child DRM backend still needs to
create a local renderer.
Use the new private wlr_renderer_autocreate_with_drm_fd function to
avoid creating a renderer for the parent GPU.
Fixes: e128e6c08d ("render: drop egl parameters from wlr_renderer_autocreate")
Instead of requiring callers to manually make the EGL context current
before binding a buffer and unsetting it after unbinding a buffer, do
it inside wlr_renderer_bind_buffer.
This hides renderer-specific implementation details inside the
wlr_renderer interface. Non-GLES2 renderers may not use EGL.
This removes all EGL dependencies from the backends.
References: https://github.com/swaywm/wlroots/issues/2618
References: https://github.com/swaywm/wlroots/pull/2615#issuecomment-756687006
Since 5b1b43c68c ("backend/drm: make wlr_drm_plane.{pending,queued,current}_fb
pointers"), current_fb can be NULL if there's no buffer. If current_fb
is not NULL, current_fb->wlr_buf is guaranteed to not be NULL.
Closes: https://github.com/swaywm/wlroots/issues/2634