Age | Commit message (Collapse) | Author |
|
When a connector ID is specified in a hotplug event, don't scan all
connectors. Only scan the connector that has changed.
|
|
The BO handle table exists to avoid double-closing a BO handle,
which aren't reference-counted by the kernel. But if we can
guarantee that there is only ever a single ref for each BO handle,
then we don't need the BO handle table anymore.
This is possible if we create the handle right before the ADDFB2
IOCTL, and close the handle right after. The handles are very
short-lived and we don't need to track their lifetime.
Because of multi-planar FBs, we need to be a bit careful: some
FB planes might share the same handle. But with a small check, it's
easy to avoid double-closing the same handle (which wouldn't be a
big deal anyways).
There's one gotcha though: drmModeSetCursor2 takes a BO handle as
input. Saving the handles until drmModeSetCursor2 time would require
us to track BO handle lifetimes, so we wouldn't be able to get rid
of the BO handle table. As a workaround, use drmModeGetFB to turn the
FB ID back to a BO handle, call drmModeSetCursor2 and then immediately
close the BO handle. The overhead should be minimal since these IOCTLs
are pretty cheap.
Closes: https://github.com/swaywm/wlroots/issues/3164
|
|
|
|
Previously used by attempt_enable_needs_modeset, but this has been
dropped in the previous commit.
|
|
Previously, we were copying wlr_output_state on the stack and
patching it up to be guaranteed to have a proper drmModeModeInfo
stored in it (and not a custom mode). Also, we had a bunch of
helpers deriving DRM-specific information from the generic
wlr_output_state.
Copying the wlr_output_state worked fine so far, but with output
layers we'll be getting a wl_list in there. An empty wl_list stores
two pointers to itself, copying it on the stack blindly results in
infinite loops in wl_list_for_each.
To fix this, rework our DRM backend to stop copying wlr_output_state,
instead add a new struct wlr_drm_connector_state which holds both
the wlr_output_state and additional DRM-specific information.
|
|
"state" is easily confused with wlr_output_state.
|
|
Using GBM to import DRM dumb buffers tends to not work well. By
using GBM we're calling some driver-specific functions in Mesa.
These functions check whether Mesa can work with the buffer.
Sometimes Mesa has requirements which differ from DRM dumb buffers
and the GBM import will fail (e.g. on amdgpu).
Instead, drop GBM and use drmPrimeFDToHandle directly. But there's
a twist: BO handles are not ref'counted by the kernel and need to
be ref'counted in user-space [1]. libdrm usually performs this
bookkeeping and is used under-the-hood by Mesa.
We can't re-use libdrm for this task without using driver-specific
APIs. So let's just re-implement the ref'counting logic in wlroots.
The wlroots implementation is inspired from amdgpu's in libdrm [2].
Closes: https://github.com/swaywm/wlroots/issues/2916
[1]: https://gitlab.freedesktop.org/mesa/drm/-/merge_requests/110
[2]: https://gitlab.freedesktop.org/mesa/drm/-/blob/1a4c0ec9aea13211997f982715fe5ffcf19dd067/amdgpu/handle_table.c
|
|
Unless we're dealing with a multi-GPU setup and the backend being
initialized is secondary, we don't need a renderer nor an allocator.
Stop initializing these.
|
|
We can't nuke it completely, we still need it for multi-GPU.
|
|
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
|
|
Doesn't make a lot of sense to split the cursor fields between
wlr_drm_plane and wlr_drm_connector. Let's just move everything to
wlr_drm_connector.
|
|
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.
|
|
All of the information is in wlr_output_state.
|
|
Replace it with drm_connector_state_mode, which computes the mode
from the wlr_output_state to be applied.
|
|
Replace it with drm_connector_state_active, which figures out
whether the connector is active depending on the wlr_output_state
to be applied.
|
|
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.
|
|
Instead of relying on wlr_output.pending to be empty when performing
backend-initiated CRTC commits, use a zero wlr_output_state.
|
|
Any use of the DRM FD after the remove event results in a "Permission
denied" error.
|
|
|
|
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.
|
|
|
|
Instead of importing buffers to GBM and KMS at each frame, cache them
and re-use them while the wlr_buffer is alive.
This is the same as [1] and [2] but for the DRM backend.
[1]: https://github.com/swaywm/wlroots/pull/2538
[2]: https://github.com/swaywm/wlroots/pull/2539
|
|
This will be useful once we start re-using wlr_drm_fb.
|
|
|
|
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.
|
|
Use the "<object>_<event>" notation for listeners, use
"handle_<listener>" for handlers.
|
|
Make it clearer that this is a bitmask of CRTC indices.
|
|
|
|
Instead of hand-rolling our own manual wlr_output cleanup function, rely
on wlr_output_destroy to remove an output from the compositor's state.
|
|
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.
|
|
Save the DRM device name in a wlr_drm_backend field, so that we can
easily use it for logging purposes.
|
|
This allows the DRM code to have direct access to the wlr_drm_backend
without having to go through an upcast via get_drm_backend_from_backend.
|
|
We don't do anything with them. Once we do, we can easily add this back.
|
|
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.
|
|
|
|
Stop using drmModeObjectSetProperty, set the property in the crtc_commit
function instead.
|
|
Closes: https://github.com/swaywm/wlroots/issues/2216
|
|
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?
|
|
Since this is an internal DRM backend function, there's no reason we
need to take a generic wlr_output.
|
|
Merge enable_drm_connector into drm_connector_set_mode. This allows us
to de-duplicate logic since enabling an output performs a modeset.
|
|
wlr_output_set_gamma is now double-buffered and applies the gamma LUT on
the next output commit.
|
|
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.
|
|
Use crtc_commit instead.
|
|
|
|
Add a new wlr_drm_crtc.pending bitfield which keeps track of pending
output changes. More fields will be added in the future (e.g. active,
gamma).
|
|
|