Commit graph

568 commits

Author SHA1 Message Date
Simon Ser
c675380c56 backend/drm: prevent out-of-bounds array access on unknown subpixel
If the kernel adds new enum entries for subpixel, don't read past
the end of the subpixel_map array.
2022-12-13 19:44:44 +00:00
Simon Ser
bde68b1df7 backend/drm: refuse to switch CRTC for enabled connector
match_obj() might return a configuration where the CRTC for an
enabled connector is switched to another one.

We don't support this correctly: the wlr_output common code would
need to query again the supported formats, re-allocate the
swapchain, etc.

What's more, the kernel doesn't even support this [1]: it
requires planes to be disabled to change their CRTC, it rejects
commits directly switching the CRTC used by a plane.

[1]: https://cgit.freedesktop.org/drm/drm-misc/tree/drivers/gpu/drm/drm_atomic.c?h=6e90293618ed476d6b11f82ce724efbb9e9a071b#n697
2022-12-13 19:15:09 +00:00
Simon Ser
99fb2fefc3 backend/drm: rename wlr_drm_backend.outputs to connectors
This list contains wlr_drm_connector entries, and there is no
guarantee that the wlr_output fields are initialized.
2022-12-13 19:15:09 +00:00
Simon Ser
2c042566eb backend/drm: clear pending cursor FB in drm_connector_commit_state()
Ensure we unlock any pending cursor FB when disabling a connector.
2022-12-13 19:12:12 +00:00
Simon Ser
ea14e9c95f backend/drm: update wlr_drm_connnector.crtc in drm_connector_commit_state()
If the commit fails, then our local state becomes out-of-sync with
the kernel's. Additionally, when disabling a connector without going
through dealloc_crtc(), conn->crtc would still be set.

Fix this by updating conn->crtc in drm_connector_commit_state().
2022-12-13 19:12:12 +00:00
Simon Ser
e59c3602f7 backend/drm: print stringified connector status in realloc_crtcs()
The raw enum value wasn't informative enough. It's not trivial to
tell whether 0 means connected or disconnected.

Drop the status from the state after realloc, since the exact same
information is printed right above.
2022-12-13 16:50:27 +00:00
Simon Ser
037b21647b backend/drm: store pending FB in state
Instead of having a pending_fb field on the struct wlr_drm_plane,
move it to struct wlr_drm_connector_state. That way, there's no
risk having a stale pending FB around: the state doesn't survive
across tests and commits.

The cursor is a special case because it's disconnected from the
atomic state: the wlr_backend_impl.set_cursor hook sets the cursor
for the next commit. Move the field to
wlr_drm_connector.cursor_pending_fb.
2022-12-07 17:45:59 +01:00
Simon Ser
ae61cd6bfb backend/drm: use separate field to store pending cursor FB
We'll move the pending primary FB into the connector state in the
next commit, dropping wlr_drm_plane.pending_fb in the process.
Introduce a dedicated field for the cursor, which has to be managed
in a special way due to our set_cursor API.
2022-12-07 17:44:51 +01:00
Simon Ser
72d1fd1446 backend/drm: simplify dealloc_crtc() commit
No need to manually call drm_connector_state_init() here, we can
just let drm_connector_commit_state() handle it.
2022-12-07 17:44:51 +01:00
Simon Ser
90a6c7b7e1 backend/drm: fix VRR test
We were calling drm_connector_supports_vrr() before
drm_connector_alloc_crtc(). Thus, when an output is currently off,
the VRR test would always fail, because it checks that the
vrr_enabled CRTC prop exists.
2022-12-07 10:43:02 +01:00
Simon Ser
4452ed0651 backend/drm: don't damage output on CRTC change
There's no reason why the output should be damaged here. The current
buffer doesn't need to be re-painted.
2022-11-17 09:17:32 +00:00
Simon Ser
ef5e2cc5e3 output: call wlr_output_update_enabled() after commit
Backends no longer need to manually call wlr_output_update_enabled()
in their commit hook: wlr_output will take care of that.
2022-11-17 09:12:25 +00:00
Simon Ser
f863b93c05 backend/drm: only request page-flip if active
It doesn't make sense to request a page-flip for a disabled output.

Fixes: 84e727daae ("backend/drm: request page-flip event on modeset")
Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3528
2022-11-15 14:14:18 +00:00
Simon Ser
a40ba16a64 backend/drm: fix FPE when disabling output
Fixes: 65836ce357 ("backend/drm: log modesetting commits")
Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3534
2022-11-15 10:06:23 +01:00
Simon Ser
65836ce357 backend/drm: log modesetting commits 2022-11-14 17:39:39 +00:00
Simon Ser
b3da33116e backend/drm: log refresh rate in Hz 2022-11-14 17:39:39 +00:00
Simon Ser
84e727daae backend/drm: request page-flip event on modeset
The old drm_connector_set_mode() function did that by calling
drm_crtc_page_flip(). We lost this in the refactoring.

Fixes: f216e97983 ("backend/drm: drop drm_connector_set_mode()")
2022-11-11 14:46:51 +00:00
Simon Ser
fc3d8b228b backend/drm: get possible CRTCs in create_drm_connector()
This stuff is immutable for a given connector.
2022-11-02 14:48:30 +00:00
Simon Ser
92580a2f67 backend/drm: extract create_drm_connector()
Move a bit more logic out of the big loop in scan_drm_connectors().
2022-11-02 14:48:30 +00:00
Simon Ser
c6d8a11d2c backend/drm: fetch current CRTC once on startup
Once we are DRM master, the CRTC cannot be changed behind our back
except during a VT switch.

After a VT switch, we try to restore whatever KMS state we had last
programmed. Reloading the current CRTC from KMS breaks this and
can result in a modeset without a FB.

Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3432
2022-10-19 00:23:18 +00:00
Simon Ser
a2063c93ea backend/drm: drop drm_crtc_page_flip()
Inline it in drm_connector_commit_state(). Brings us a step closer
to unifying the test code-path and the commit code-path.
2022-10-17 17:39:41 +02:00
Simon Ser
98a83ce14c backend/drm: fix EINVAL atomic commits after VT switch
The drm_connector_commit_state() call in handle_session_active()
was not resulting in any atomic commit, because it didn't match any
of the if branches: active = true, no new buffer was committed,
and adaptive sync/gamma LUT were unchanged. Thus the commit was a
no-op.

Later on, when the compositor performs regular page-flips, the
kernel would return EINVAL indicating that a modeset was needed.

Rework the logic to use a non-blocking page-flip commit if a buffer
was committed, and use a blocking commit if the connector is on or
is being disabled. The only case where we should skip the atomic
commit is when disabling (active = false) an already-disabled
connector (conn->crtc == NULL).

Note, 6936e163b5 ("backend/drm: short-circuit no-op commits")
has introduced early returns for other situations where we don't
need to perform an atomic commit (e.g. updating scale or transform
of an output).

Fixes: f216e97983 ("backend/drm: drop drm_connector_set_mode()")
Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3432
2022-10-17 15:14:02 +00:00
Simon Ser
ca432ea539 backend/drm: extract current mode logic into separate function
Extract the logic to fetch the current mode to a separate function
to make it more readable. Stop dying in an assert when
get_drm_prop_blob() fails. Always make it so the drmModeModeInfo
pointer is allocated so that we can free() it unconditionally.
2022-10-17 11:36:58 +02:00
Simon Ser
eeb7a81138 backend/drm: extract connect_drm_connector() logic
We already have disconnect_drm_connector() to handle the
CONNECTED → DISCONNECTED transition. Let's add
connect_drm_connector() to handle DISCONNECTED → CONNECTED. This
makes scan_drm_connectors() shorter and easier to follow.

No functional change, literally just moving code around.
2022-10-15 12:20:55 +02:00
Simon Ser
9560a7eefd backend/drm: use atomic API to fetch current connector's CRTC
We were using the legacy API (with a detour through drmModeEncoder)
to find out the current CRTC for a connector. Use the atomic API
when available.

Also extract the whole logic into a separate function for better
readability, and better handle errors.
2022-10-14 15:13:14 +00:00
Simon Ser
0c0cea0258 backend/drm: use wl_container_of() instead of casts for wlr_drm_mode
Instead of casting a wlr_output_mode to wlr_drm_mode, use
wl_container_of() for slightly better type safety.
2022-10-13 16:11:39 +00:00
Simon Ser
f216e97983 backend/drm: drop drm_connector_set_mode()
Instead of special-casing modesets, we can just cut the wrapper
and directly call drm_crtc_page_flip(). drm_connector_test() should
already have the checks previously done in drm_connector_set_mode(),
all we need to do is update enabled/mode after a successful atomic
commit.
2022-10-10 07:48:25 +00:00
Simon Zeni
694e9bbb9d backend/drm: allocate connector CRTC on lease creation
This was leading to crash in compositors if the wanted connector had no CRTC
2022-10-07 15:54:51 -04:00
Simon Ser
f4cf0a8d86 backend/drm: nuke wlr_drm_connector.desired_enabled
This field becomes stale too easily: for instance, see 6adca4089c
("backend/drm: don't unconditionally set desired_enabled").
Additionally, drm_connector_alloc_crtc() needs to do some weird
dance, restoring its previous value.

Instead, add a connector arg to realloc_crtcs() to indicate a new
connector we want to enable.
2022-10-07 16:28:36 +00:00
Simon Ser
5a207aea72 backend/drm: drop unnecessary wlr_drm_connector.crtc checks
drm_connector_alloc_crtc() already checks this.
2022-10-07 16:09:05 +00:00
Simon Ser
0613fb0159 backend/drm: remove outdated TODO
This has been addressed in 8795dde94e ("Initialize connectors
current mode to the mode used by KMS on startup.").
2022-10-03 12:07:10 +02:00
Simon Ser
6adca4089c backend/drm: don't unconditionally set desired_enabled
We were unconditonally setting desired_enabled = true for all
connected connectors. This makes realloc_crtcs() always keep a CRTC
active for these, even if the user doesn't want to enable them.
2022-10-03 12:04:12 +02:00
Simon Ser
651c876e79 backend/drm: fix missing wlr_output_state.allow_artifacts
Without allow_artifacts, applying the new state will fail because
it requires ALLOW_MODESET.

Fixes VT switch and disabling CRTCs.
2022-09-30 13:35:07 +02:00
Simon Ser
a0345f2854 output: add wlr_output_state.allow_artifacts
When starting up, the compositor might call wlr_output_set_mode()
with a mode which is already the current one. wlroots will detect
this and make the wlr_output_set_mode() call a no-op. During the
next wlr_output_commit() call, wlroots will perform an atomic
commit without the ALLOW_MODESET flag.

This is an issue, because some drivers need ALLOW_MODESET even if
the mode is the same. For instance, if the FB stride or modifier
changed, some drivers require a modeset.

Add a new flag "allow_artifacts" which is set when the compositor
calls mode-setting functions. Use this flag to figure out whether
we want to perform atomic commits with ALLOW_MODESET.

(The name "allow_artifacts" is picked because ALLOW_MODESET is a
misnomer, see [1].)

[1]: https://patchwork.freedesktop.org/patch/505107/

Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3499
2022-09-30 10:58:17 +00:00
Simon Ser
0cabc83046 backend/drm: pass through mode picture aspect ratio 2022-09-22 09:38:27 +02:00
Simon Ser
800ea7d52d backend/drm: de-duplicate wlr_drm_mode creation
Introduce a function to convert a drmModeModeInfo into a new
wlr_drm_mode.
2022-09-21 01:35:30 +00:00
vanfanel
8795dde94e Initialize connectors current mode to the mode used by KMS on startup. 2022-09-16 14:15:58 +00:00
Simon Ser
8c70245d5f output: fail commits if adaptive sync cannot be enabled
Previously, adaptive sync was just a hint and wouldn't make any
atomic commit fail if the backend didn't support it. The main reason
is wlr_output_test wasn't supported at the time.

Now that we have a way for compositors to test whether a change can
work, let's remove the exception for adaptive sync and convert it to
a regular output state field.
2022-08-30 17:53:50 +00:00
Alexander Orzechowski
8bd7170fd9 Use env helpers 2022-08-22 10:18:52 -04:00
Alexander Orzechowski
ef4baea0e2 Use wl_signal_emit_mutable 2022-08-18 07:16:16 -04:00
Simon Ser
f244094682 backend/drm: drop enum wlr_drm_connector_status
We can just use libdrm's drmModeConnection enum instead.
2022-08-10 14:19:58 +00:00
Simon Ser
08973d2430 backend/drm: drop WLR_DRM_CONN_NEEDS_MODESET
- Add wlr_output.enabled checks to CONNECTED checks
- Replace NEEDS_MODESET with CONNECTED
2022-08-10 14:19:58 +00:00
Simon Ser
7b5e890e61 backend/drm: use drmModeConnectorGetPossibleCrtcs
This function has been merged in libdrm.

References: 3ee004ef52
2022-07-25 17:28:33 +00:00
Simon Ser
bd587a7f43 backend/drm: use drmModeGetConnectorTypeName
No need to manually maintain this table now.

The wlroots names and the libdrm (= kernel) names all match.

References: 50f8d51773
2022-07-25 17:28:33 +00:00
Simon Ser
1d581656c7 backend/drm: set "max bpc" to the max
"max bpc" is a maximum value, the driver is free to choose a
smaller value depending on the bandwidth available.

Some faulty monitors misbehave with higher bpc values. We'll add
a workaround if users get hit by these in practice.

References: https://gitlab.freedesktop.org/wayland/weston/-/issues/612
2022-06-19 16:55:36 +00:00
Simon Ser
1f1c0275be backend/drm: remove unused CRTC count check
drmIsKMS already checks for this.
2022-06-19 16:48:44 +00:00
Simon Ser
1f96f388e9 backend/drm: make serial optional
The EDID 1.4 spec says that the serial number is optional:

> If this field is not used, then enter “00h, 00h, 00h, 00h”.

Leave the wlr_output.serial field NULL in that case, and hide it
from the output description.
2022-06-07 13:27:18 +00:00
Isaac Freund
2b10ae62ad
backend/drm: fix check for no-op commits
Since 6936e163b, we short-circut no-op commits as an optimization.
However, the logic in the check was slightly off.
2022-06-02 20:18:16 +02:00
Simon Ser
6936e163b5 backend/drm: short-circuit no-op commits
Some output commits (changing e.g. the output scale or transform)
don't require any change in the KMS state. Instead of going through
a KMS commit, return early. Blocking KMS commits can be expensive.
2022-06-02 11:46:31 +00:00
Simon Ser
25dd3cc0cd output: pass wlr_output_state to backend
Groundwork for the following commits. The goal is to allow users
to specify their own wlr_output_state instead of wlr_output.pending.
2022-05-30 11:34:57 +02:00
Simon Ser
e646d882cf backend/drm: fetch EDID manufacturer from udev_hwdb
Maintaining our internal table up-to-date is tedious: one needs to
manually go through the PnP ID registry [1] and check whether we're
missing any entry.

udev_hwdb already has an API to fetch a manufacturer name from its
PnP ID. Use that instead.

[1]: https://uefi.org/pnp_id_list
2022-05-11 14:06:11 +00:00
Simon Ser
6c350799b2 Zero-initialize structs in init functions
Ensures there is no field left to its previous undefined value after
calling an init function.
2022-04-28 10:09:50 +02:00
Samuel Čavoj
5c17452ae0
Pass O_CLOEXEC to drmModeCreateLease calls
The lease_fd is currently being leaked to child processes

Link: https://github.com/swaywm/sway/issues/4286#issuecomment-1065987957
2022-03-13 13:28:48 +01:00
Simon Ser
a15c327718 backend/drm: use drmModeFormatModifierBlobIterNext
This avoids open-coding our own logic. The resulting code is more
readable.

References: https://gitlab.freedesktop.org/mesa/drm/-/merge_requests/146
2021-12-14 13:21:09 +00:00
Simon Ser
36a2b19485 output: introduce wlr_output_set_name
wlroots picks names for all outputs, but it might be desirable for
compositor to override it.

For instance, Sway will use a headless output as a fallback in
case no outputs are connected. Sway wants to clearly label the
fallback output as such and label "real" headless outputs starting
from HEADLESS-1.
2021-12-09 15:46:46 +01:00
Simon Ser
ef1669d33e backend/drm: always add LINEAR to supported modifiers 2021-11-26 16:40:53 +00:00
Simon Ser
affe9eda57 Require INVALID for implicit format modifiers
See [1] for the motivation.

[1]: https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/75
2021-11-26 16:40:53 +00:00
Simon Ser
e656697a7d backend/drm: scan leases on uevent
Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3181
2021-11-19 16:06:07 +00:00
Simon Ser
86f5ecf468 backend/drm: introduce wlr_drm_lease
Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3183
2021-11-19 16:06:07 +00:00
Simon Ser
e13f3f8608 backend/drm: handle per-connector hotplug events
When a connector ID is specified in a hotplug event, don't scan all
connectors. Only scan the connector that has changed.
2021-11-02 13:36:43 +01:00
Kirill Primak
2af8cc769a output: add presented flag to presentation event 2021-10-15 09:38:58 +02:00
Simon Ser
1d7e438d8a Revert "Require INVALID for implicit format modifiers"
This reverts commit ea7357b703.
2021-10-01 09:26:05 -06:00
Simon Ser
ea7357b703 Require INVALID for implicit format modifiers
See [1] for the motivation.

[1]: https://gitlab.freedesktop.org/wayland/wayland-protocols/-/merge_requests/75
2021-10-01 09:21:50 -06:00
Simon Ser
2e12de96ca backend/drm: add support for panel orientation
Expose the panel orientation with wlr_drm_connector_get_panel_orientation.
Leave it to the compositor to consume this information and configure the
output accordingly.

Closes: https://github.com/swaywm/wlroots/issues/1581
2021-09-21 11:40:37 -06:00
Simon Zeni
94ed8f9496 backend/drm: introduce wlr_drm_backend_get_non_master_fd 2021-09-08 11:09:07 +02:00
Simon Zeni
e5a949a955 backend/drm: implement drm lease function 2021-09-08 11:09:07 +02:00
Simon Ser
42dba9dc90 backend/drm: drop wlr_drm_connector.desired_mode
Previously used by attempt_enable_needs_modeset, but this has been
dropped in the previous commit.
2021-09-07 22:33:40 +02:00
Simon Ser
b01d97a38f backend/drm: drop attempt_enable_needs_modeset
Modesets require a buffer. The DRM backend tried to auto-enable
outputs when a CRTC becomes available in the past, but now that
fails because no buffer is available.

Instead of having this magic inside the DRM backend, a better
approach is to do it in the compositor or in an optional helper.
2021-09-07 22:33:40 +02:00
Simon Ser
0c8fba1a2f backend/drm: drop drm_connector_init_renderer
drm_connector_set_pending_fb already takes care of this.
2021-09-07 15:16:30 +02:00
Simon Ser
de1c73021c backend/drm: drop unused arg from get_possible_crtcs
Constify drmModeConnector while at it.
2021-09-07 08:45:08 -04:00
Simon Ser
3c74bd0c91 backend/drm: introduce wlr_drm_connector_state
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.
2021-09-07 11:18:18 +02:00
Simon Ser
3fbf6e02a3 backend/drm: rename enum wlr_drm_connector_state to status
"state" is easily confused with wlr_output_state.
2021-09-07 11:18:18 +02:00
Simon Ser
5aa5137fae backend/drm: handle drm_surface_blit errors
drm_surface_blit returns NULL on error. This can happen e.g. when
the source buffer cannot be imported into EGL.

Closes: https://github.com/swaywm/wlroots/issues/3154
2021-09-03 17:57:38 +02:00
Simon Ser
5dfaf5ea9c backend/drm: introduce wlr_drm_bo_handle_table
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]: 1a4c0ec9ae/amdgpu/handle_table.c
2021-08-25 10:05:37 -04:00
Simon Ser
65c0ab00b6 backend/drm: generate CVT reduced modes
The Coordinated Video Timings (CVT) spec [1] defines two types of
timings: the "CVT standard CRT" timings and the "CVT reduced blanking"
timings (see section 3.6).

The standard CRT timings include pauses in the video stream to allow
CRT displays to reposition their electron beam at the end of each
horizontal scan line [2]. While this was desirable a few decades ago,
nowadays we can just generate a CVT reduced blanking timing by default.
wlroots users can still set full custom DRM modes via
wlr_drm_connector_add_mode.

[1]: https://glenwing.github.io/docs/VESA-CVT-1.2.pdf
[2]: https://en.wikipedia.org/wiki/Coordinated_Video_Timings#Reduced_blanking
2021-08-25 08:37:35 +02:00
Rouven Czerwinski
9b7803a9b3 backend/drm: try to allocate crtc for formats
To retrieve the formats, an allocated crtc is required. If there is no
currently no crtc available, try to allocate it. This reproducable by
having a disabled output and going through a suspend cycle with amdgpu.
On start CRTCs look like this:

  00:00:00.588 [DEBUG] [wlr] [backend/drm/drm.c:1099] Reallocating CRTCs
  00:00:00.588 [DEBUG] [wlr] [backend/drm/drm.c:1110] State before reallocation:
  00:00:00.588 [DEBUG] [wlr] [backend/drm/drm.c:1116]   'DP-1' crtc=0 state=1 desired_enabled=1
  00:00:00.588 [DEBUG] [wlr] [backend/drm/drm.c:1116]   'DP-2' crtc=1 state=1 desired_enabled=1
  00:00:00.588 [DEBUG] [wlr] [backend/drm/drm.c:1116]   'HDMI-A-1' crtc=-1 state=0 desired_enabled=0
  00:00:00.588 [DEBUG] [wlr] [backend/drm/drm.c:1116]   'HDMI-A-2' crtc=-1 state=0 desired_enabled=0
  00:00:00.588 [DEBUG] [wlr] [backend/drm/drm.c:1116]   'DVI-D-1' crtc=-1 state=0 desired_enabled=0
  00:00:00.588 [DEBUG] [wlr] [backend/drm/drm.c:1167] State after reallocation:
  00:00:00.588 [DEBUG] [wlr] [backend/drm/drm.c:1174]   'DP-1' crtc=0 state=1 desired_enabled=1
  00:00:00.588 [DEBUG] [wlr] [backend/drm/drm.c:1174]   'DP-2' crtc=1 state=1 desired_enabled=1
  00:00:00.588 [DEBUG] [wlr] [backend/drm/drm.c:1174]   'HDMI-A-1' crtc=-1 state=0 desired_enabled=0
  00:00:00.588 [DEBUG] [wlr] [backend/drm/drm.c:1174]   'HDMI-A-2' crtc=-1 state=0 desired_enabled=0
  00:00:00.588 [DEBUG] [wlr] [backend/drm/drm.c:1174]   'DVI-D-1' crtc=-1 state=0 desired_enabled=0

where DP-1 is than disabled. After suspend/resume, allocation turns into:

  00:30:22.680 [DEBUG] [wlr] [backend/drm/drm.c:1099] Reallocating CRTCs
  00:30:22.680 [DEBUG] [wlr] [backend/drm/drm.c:1110] State before reallocation:
  00:30:22.680 [DEBUG] [wlr] [backend/drm/drm.c:1116]   'DP-1' crtc=-1 state=1 desired_enabled=0
  00:30:22.680 [DEBUG] [wlr] [backend/drm/drm.c:1116]   'DP-2' crtc=1 state=3 desired_enabled=1
  00:30:22.680 [DEBUG] [wlr] [backend/drm/drm.c:1116]   'HDMI-A-1' crtc=-1 state=0 desired_enabled=0
  00:30:22.680 [DEBUG] [wlr] [backend/drm/drm.c:1116]   'HDMI-A-2' crtc=-1 state=0 desired_enabled=0
  00:30:22.680 [DEBUG] [wlr] [backend/drm/drm.c:1116]   'DVI-D-1' crtc=-1 state=0 desired_enabled=0
  00:30:22.680 [DEBUG] [wlr] [backend/drm/drm.c:1167] State after reallocation:
  00:30:22.680 [DEBUG] [wlr] [backend/drm/drm.c:1174]   'DP-1' crtc=-1 state=1 desired_enabled=0
  00:30:22.680 [DEBUG] [wlr] [backend/drm/drm.c:1174]   'DP-2' crtc=1 state=3 desired_enabled=1
  00:30:22.680 [DEBUG] [wlr] [backend/drm/drm.c:1174]   'HDMI-A-1' crtc=-1 state=0 desired_enabled=0
  00:30:22.680 [DEBUG] [wlr] [backend/drm/drm.c:1174]   'HDMI-A-2' crtc=-1 state=0 desired_enabled=0
  00:30:22.680 [DEBUG] [wlr] [backend/drm/drm.c:1174]   'DVI-D-1' crtc=-1 state=0 desired_enabled=0

where the crtc for DP-1 is now NULL. Trying to enable the output results
in:

  10:43:36.906 [DEBUG] [sway/config/output.c:351] Turning on output DP-1
  10:43:36.906 [DEBUG] [sway/config/output.c:360] Set preferred mode
  10:43:36.906 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.906 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.906 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.906 [DEBUG] [sway/config/output.c:366] Preferred mode rejected, falling back to another mode
  10:43:36.906 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.906 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.906 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.906 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.906 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.906 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.906 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.906 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.906 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.906 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.906 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.906 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.906 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.906 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.906 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.906 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.906 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.906 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.906 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.906 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.906 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.906 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.906 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.906 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.906 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.906 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.906 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.906 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.906 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.906 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.906 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.906 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.906 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.906 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.906 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.906 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.906 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.906 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.906 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.906 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.906 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.906 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.906 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.906 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.906 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.906 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.907 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.907 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.907 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.907 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.907 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.907 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.907 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.907 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.907 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.907 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.907 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.907 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.907 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.907 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.907 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.907 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.907 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.907 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.907 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.907 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.907 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.907 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.907 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.907 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.907 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.907 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.907 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.907 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.907 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.907 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.907 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.907 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.907 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.907 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.907 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.907 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.907 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.907 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.907 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.907 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.907 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.907 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.907 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.907 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.907 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.907 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.907 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.907 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.907 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.907 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.907 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.907 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.907 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.907 [DEBUG] [sway/config/output.c:400] Auto-detected output scale: 1.000000
  10:43:36.907 [DEBUG] [sway/config/output.c:430] Committing output DP-1
  10:43:36.907 [DEBUG] [wlr] [backend/drm/drm.c:464] connector DP-1: Can't enable an output without a buffer
  10:43:36.907 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
  10:43:36.907 [ERROR] [wlr] [types/wlr_output.c:512] Failed to get primary display formats
  10:43:36.907 [ERROR] [sway/config/output.c:435] Failed to commit output DP-1

where the primary format can't be queried since there is no crtc
allocated for the connector. Allocating the connector inside
drm_connector_get_primary_formats() fixes this issue. This is possible
since the only user of get_primary_formats() is the swapchain allocation
function, which is only called on output enable. Do the same thing for
the cursor formats in case the user queries them before the output is
enabled.
2021-08-20 10:24:30 +02:00
Rouven Czerwinski
cdd9a60f72 Revert "backend/drm: Check if output is enabled before sending frame event"
This reverts commit 85757665e6.

We now check if the output is enabled within wlr_output_send_frame, no
need to handle this explicitly in the DRM backend. This also fixes a
race which was introduced with this commit: if we schedule the flip,
disable and commit the output before the flip happens,
output.frame_pending will not be reset to false. We than always fail to
enable the output subsequently:

      00:07:13.276 [INFO] [sway/commands.c:257] Handling command 'output DP-2 enable'
      00:07:13.276 [DEBUG] [sway/commands.c:428] Subcommand: enable
      00:07:13.276 [DEBUG] [sway/config/output.c:204] Merging on top of existing output config
      00:07:13.276 [DEBUG] [sway/config/output.c:227] Config stored for output DP-2 (enabled: 1) (-1x-1@-1.000000Hz position 0,0 scale -1.000000 subpixel unknown transform -1) (bg /home/phoenix/Pictures/Wallpapers/mine/oper.jpg fill) (dpms 1) (max render time: -1)
      00:07:13.276 [DEBUG] [sway/config/output.c:351] Turning on output DP-2
      00:07:13.276 [DEBUG] [sway/config/output.c:360] Set preferred mode
      00:07:13.276 [DEBUG] [wlr] [backend/drm/drm.c:465] connector DP-2: Can't enable an output without a buffer
      00:07:13.276 [DEBUG] [wlr] [types/wlr_output.c:689] Attaching empty buffer to output for modeset
      00:07:13.277 [DEBUG] [sway/config/output.c:329] Output DPI: 162.560000x161.364706
      00:07:13.277 [DEBUG] [sway/config/output.c:400] Auto-detected output scale: 1.000000
      00:07:13.277 [DEBUG] [sway/config/output.c:430] Committing output DP-2
      00:07:13.277 [DEBUG] [wlr] [types/wlr_output.c:729] Tried to commit a buffer while a frame is pending

since the basic_output_test will always fail.
Reset frame_pending to false even if the output has been disabled in the
meantime.

Fixes https://github.com/swaywm/wlroots/issues/3109
2021-08-17 21:07:43 +02:00
Rouven Czerwinski
59b292b691 backend/drm: return true on test if no crtc
This should fix the following backtrace, seen on my desktop with one
output disabled:

  #0  atomic_crtc_commit (conn=0x270f5c0, state=0x270f6d0, flags=0, test_only=<optimized out>) at ../backend/drm/atomic.c:178
          drm = 0x1ae9c10
          output = 0x270f5c0
          crtc = 0x0
          modeset = false
          active = false
          mode_id = 43989232
          gamma_lut = 0
          prev_vrr_enabled = <optimized out>
          vrr_enabled = <optimized out>
          atom = {req = 0x270f5c0, failed = 48}
          ok = <optimized out>
  #1  0x00007f1104f33128 in drm_crtc_commit (conn=conn@entry=0x270f5c0, state=state@entry=0x270f6d0, flags=flags@entry=0, test_only=test_only@entry=true) at ../backend/drm/drm.c:339
          __PRETTY_FUNCTION__ = "drm_crtc_commit"
          drm = <optimized out>
          crtc = 0x0
          ok = <optimized out>
  #2  0x00007f1104f34e6c in drm_connector_test (output=output@entry=0x270f5c0) at ../backend/drm/drm.c:488
          conn = 0x270f5c0
          unsupported = <optimized out>
  #3  0x00007f1104f35424 in drm_connector_commit (output=0x270f5c0) at ../backend/drm/drm.c:578
          conn = 0x270f5c0
  #4  0x00007f1104f600b7 in wlr_output_commit (output=output@entry=0x270f5c0) at ../types/wlr_output.c:837
          now = {tv_sec = 7732, tv_nsec = 623813006}
          pre_event = {output = 0x270f5c0, when = 0x7ffecc1be570}
          back_buffer = 0x0
          scale_updated = <optimized out>
          geometry_updated = <optimized out>
          committed = <optimized out>
          event = {output = 0x0, committed = 4401048, when = 0x29f38f0}
  #5  0x0000000000433047 in apply_output_config (oc=oc@entry=0x29f38f0, output=output@entry=0x2710720) at ../sway/config/output.c:431
          wlr_output = 0x270f5c0
          output_box = <optimized out>
  #6  0x0000000000433aaf in apply_output_config_to_outputs (oc=0x2308400) at ../sway/config/output.c:649
          current = 0x29f38f0
          name = <optimized out>
          wildcard = true
          id = "Dell Inc. DELL U2410 F525M9AK0MML\000\060\060\060ACD7\000\000\000\000\000\000\000\220\063\240\002\000\000\000\000L5C\000\000\000\000\000\377\377\377\377\000\000\000\000\377\377\377\377\000\000\000\000\377\377\377\377\000\000\000\000\377\377\377\377\000\000\000\000\355\240E\000\000\000\000\000\377\377\377\377\000\000\000\000@\206+\002\000\000\000\000`\260.\002\000\000\000"
          sway_output = 0x2710720
          tmp = 0x2242030
          seat = <optimized out>
  #7  0x000000000043df6b in cmd_output (argc=<optimized out>, argv=0x2a03390) at ../sway/commands/output.c:108
          error = <optimized out>
          output = <optimized out>
          background = false
  #8  0x0000000000410304 in execute_command (_exec=_exec@entry=0x2975d20 "output * dpms off", seat=0x22a3280, seat@entry=0x0, con=con@entry=0x0) at ../sway/commands.c:291
          res = <optimized out>
          argc = 4
          argv = 0x2a03370
          handler = 0x479230 <handlers+560>
          cmd = <optimized out>
          matched_delim = 0 '\000'
          containers = 0x0
          using_criteria = false
          __PRETTY_FUNCTION__ = "execute_command"
          exec = 0x28f63c0 "output * dpms off"
          head = 0x0
          res_list = 0x2a2e9d0
  #9  0x0000000000418b65 in ipc_client_handle_command (client=client@entry=0x2a6ac80, payload_length=<optimized out>, payload_type=IPC_COMMAND) at ../sway/ipc-server.c:645
          line = <optimized out>
          res_list = <optimized out>
          json = <optimized out>
          length = <optimized out>
          __PRETTY_FUNCTION__ = "ipc_client_handle_command"
          buf = 0x2975d20 "output * dpms off"
  #10 0x000000000041964c in ipc_client_handle_readable (client_fd=<optimized out>, mask=<optimized out>, data=0x2a6ac80) at ../sway/ipc-server.c:267
          pending_length = <optimized out>
          pending_type = <optimized out>
          client = 0x2a6ac80
          read_available = 31
          buf = "i3-ipc\021\000\000\000\000\000\000"
          received = 14
  #11 0x00007f1104fc3492 in wl_event_loop_dispatch () from /nix/store/ridk7k2ka6dbk4ly7qqjgmc523s4fj89-wayland-1.19.0/lib/libwayland-server.so.0
  No symbol table info available.
  #12 0x00007f1104fc1135 in wl_display_run () from /nix/store/ridk7k2ka6dbk4ly7qqjgmc523s4fj89-wayland-1.19.0/lib/libwayland-server.so.0
  No symbol table info available.
  #13 0x000000000041ac10 in server_run (server=server@entry=0x47b0c0 <server>) at ../sway/server.c:261
  No locals.
  #14 0x000000000041a3fc in main (argc=<optimized out>, argv=0x7ffecc1bec68) at ../sway/main.c:395
          verbose = 0
          debug = 0
          validate = 0
          allow_unsupported_gpu = 0
          long_options = {{name = 0x45b516 "help", has_arg = 0, flag = 0x0, val = 104}, {name = 0x45ee69 "config", has_arg = 1, flag = 0x0, val = 99}, {name = 0x45b51b "validate", has_arg = 0, flag = 0x0, val = 67}, {
              name = 0x45b524 "debug", has_arg = 0, flag = 0x0, val = 100}, {name = 0x45b3ac "version", has_arg = 0, flag = 0x0, val = 118}, {name = 0x45a55c "verbose", has_arg = 0, flag = 0x0, val = 86}, {name = 0x45b52a "get-socketpath",
              has_arg = 0, flag = 0x0, val = 112}, {name = 0x45b539 "unsupported-gpu", has_arg = 0, flag = 0x0, val = 117}, {name = 0x45b549 "my-next-gpu-wont-be-nvidia", has_arg = 0, flag = 0x0, val = 117}, {name = 0x0, has_arg = 0,
              flag = 0x0, val = 0}}
          config_path = 0x0
          usage = 0x45b830 "Usage: sway [options] [command]\n\n  -h, --help", ' ' <repeats 13 times>, "Show help message and quit.\n  -c, --config <config>  Specify a config file.\n  -C, --validate         Check the validity of the config file, th"...
          c = <optimized out>

where the second output is not enabled:

  (gdb) frame 4
  #4  0x00007f1104f600b7 in wlr_output_commit (output=output@entry=0x270f5c0) at ../types/wlr_output.c:837
  837	in ../types/wlr_output.c
  (gdb) p output->enabled
  $3 = false
  (gdb)

The culprit being that since 604674dc54 we
always try to perform a commit, even on a disabled output.
2021-08-17 14:07:51 +02:00
Simon Ser
604674dc54 backend/drm: always perform a test commit in drm_connector_test
This allows callers to use wlr_output_test to check whether a mode
can be enabled, for instance.

Closes: https://github.com/swaywm/wlroots/issues/2250
2021-08-10 16:38:22 +02:00
Simon Ser
1936e136df backend/drm: require buffer on modeset in drm_connector_test
When testing a modeset, make sure the caller has also provided a
buffer. This allows df0e75ba05 ("output: try skipping buffer
allocation if the backend allows it") to work as expected with the
DRM backend.

Closes: https://github.com/swaywm/wlroots/issues/3086
2021-08-04 22:51:40 +02:00
Simon Ser
923258b0be backend/drm: preserve mode order from kernel
The kernel orders the mode list from highest to lowest. Preserve
this ordering in the wlr_output.modes list.
2021-08-02 09:28:21 -04:00
Simon Ser
3132c0ab10 output: drop wlr_output_state.buffer_type
This is now unconditionally set to WLR_OUTPUT_STATE_BUFFER_SCANOUT.
2021-07-29 09:48:33 -04:00
Simon Ser
55ac7e335a backend/drm: fix wrong type for get_cursor_format return values
These are bools but should be pointers.
2021-07-28 16:59:21 -04:00
Simon Ser
c55f70c8b7 backend/drm: stop initializing renderer for parent backend
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.
2021-07-28 22:52:35 +02:00
Simon Ser
ebb661532c backend/drm: remove SCANOUT check in drm_connector_test
We only accept SCANOUT, the buffer type should never be set to RENDER.
2021-07-28 22:52:35 +02:00
Simon Ser
f5900c1f00 backend/drm: remove primary swapchain
We can't nuke it completely, we still need it for multi-GPU.
2021-07-28 22:52:35 +02:00
Simon Ser
d6f0fc251e backend/drm: implement get_primary_formats 2021-07-28 22:52:35 +02:00
Simon Ser
cc8bc0db20 backend/drm: stop restoring CRTCs on exit
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
2021-07-20 15:33:26 +02:00
Simon Ser
709190c4c8 backend/drm: remove wlr_output_impl.export_dmabuf
This is now provided by the generic wlr_output implementation.
2021-07-12 13:29:03 -04:00
Simon Ser
f67cfb2ce2 backend/drm: remove backend arg from wlr_drm_interface.crtc_commit
The callee can just get it from the wlr_drm_connector.
2021-07-09 15:31:19 -04:00
Simon Ser
fde56c20b4 backend/drm: move legacy-specific checks to legacy.c
Now that we have a test_only arg in crtc_commit, we can move the
legacy checks to legacy.c.
2021-07-09 15:31:19 -04:00
Simon Ser
017555651b backend/drm: add test_only arg to wlr_drm_interface.crtc_commit
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).
2021-07-09 15:31:19 -04:00
Simon Zeni
e192d87731 move wlr_box from /types to /util 2021-07-06 21:43:17 +02:00
Simon Ser
4dee7a2f6f backend/drm: don't clear pending cursor FB on failed commit
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")
2021-07-05 10:55:41 -04:00
Simon Ser
5f26360bd8 Revert "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.
2021-07-05 10:55:41 -04:00
Simon Ser
a38baec1f8 buffer: make enum wlr_buffer_cap public
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.
2021-07-01 16:40:19 -04:00
Simon Ser
264d4e2bce backend/drm: rename page_flip_handler to handle_page_flip
This is more consistent with the rest of the wlroots naming.
2021-06-24 11:56:45 +02:00
Simon Ser
2f615468b6 backend: add output state allow-lists
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.
2021-06-20 23:17:08 +02:00
Simon Ser
6c3d080e25 backend/drm: populate cursor plane's current_fb
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.
2021-06-17 00:25:27 +02:00
Simon Ser
3345eaca89 backend/drm: remove test_buffer
Instead, call drm_connector_set_pending_fb.
2021-06-13 10:57:17 +02:00