aboutsummaryrefslogtreecommitdiff
path: root/backend/drm
AgeCommit message (Collapse)Author
2023-01-18backend/drm: disable all CRTCs after VT switchSimon Ser
When the user switches away from the VT where wlroots is running, the new DRM master may mutate the KMS state in an arbitrary manner. For instance, let's say wlroots uses the following connector/CRTC mapping: - CRTC 42 drives connector DP-1 - CRTC 43 drives connector DP-2 Then the new DRM master may swap the mapping like so: - CRTC 42 drives connector DP-2 - CRTC 43 drives connector DP-1 wlroots needs to restore its own state when the user switches back. Some state is attached to wlr_drm_crtc (e.g. current FB), so reading back and adopting the CRTC/connector mapping left by the previous DRM master would be complicated (this was the source of other bugs in the past, see [1]). With the previous logic, wlroots merely tries to restore the state of each connector one after the other. This fails in the scenario described above: the kernel refuses to use CRTC 42 for DP-1, because that CRTC is already in-use for DP-2. Unfortunately with the legacy uAPI it's not possible to restore the state in one go. We need to support both legacy and atomic uAPIs, so let's fix the bug for the legacy uAPI first, and then improve the situation for the atomic uAPI as a second step [2]. We need to disable the CRTCs we're going to switch the connectors for. This sounds complicated, so let's just disable all CRTCs to simplify. This causes a black screen because of the on/off modesets, but makes VT switch much more reliable, so I'll take it. [1]: https://gitlab.freedesktop.org/wlroots/wlroots/-/commit/c6d8a11d2c438d514473b1cbe20e5550e7227472 [2]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3794 Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3342
2022-12-16backend/drm: check return value of get_drm_{connector,crtc}_props()Simon Ser
We already do it for get_drm_plane_props().
2022-12-15backend/drm: remove wlr_drm_crtc.legacy_crtcSimon Ser
We only need it for one thing: gamma size. Moreover, some bits in the drmModeCrtc will become out-of-date, for instance the current mode, so let's avoid caching the whole struct and only keep what we know won't change.
2022-12-15backend/drm: fetch fresh legacy CRTC in connector_get_current_mode()Simon Ser
connect_drm_connector() may be called long after create_drm_connector(). During that time the DRM mode might have changed. Avoid working with stale information.
2022-12-13backend/drm: drop unused arg in connector_get_current_mode()Simon Ser
2022-12-13backend/drm: prevent out-of-bounds array access on unknown subpixelSimon Ser
If the kernel adds new enum entries for subpixel, don't read past the end of the subpixel_map array.
2022-12-13backend/drm: refuse to switch CRTC for enabled connectorSimon Ser
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-13backend/drm: rename wlr_drm_backend.outputs to connectorsSimon Ser
This list contains wlr_drm_connector entries, and there is no guarantee that the wlr_output fields are initialized.
2022-12-13backend/drm: clear pending cursor FB in drm_connector_commit_state()Simon Ser
Ensure we unlock any pending cursor FB when disabling a connector.
2022-12-13backend/drm: update wlr_drm_connnector.crtc in drm_connector_commit_state()Simon Ser
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-13backend/drm: print stringified connector status in realloc_crtcs()Simon Ser
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-13backend/drm: add drm_connector_status_str()Simon Ser
Helper to stringify a connector status.
2022-12-07backend/drm: store pending FB in stateSimon Ser
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-07backend/drm: use separate field to store pending cursor FBSimon Ser
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-07backend/drm: pass fb as arg in set_plane_props()Simon Ser
plane_get_next_fb() will go away in subsequent commits. Primary and cursor will differ with the new logic. Let's prepare for this.
2022-12-07backend/drm: stop using goto in set_plane_props()Simon Ser
We only have one error code-path, no need for goto here.
2022-12-07backend/drm: simplify dealloc_crtc() commitSimon Ser
No need to manually call drm_connector_state_init() here, we can just let drm_connector_commit_state() handle it.
2022-12-07backend/drm: fix VRR testSimon Ser
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-11-25backend/session: make optionalSimon Ser
Some compositors are not interested in wlr_session, for instance nested compositors. Disabling wlr_session removes the udev dependency.
2022-11-17backend/drm: don't damage output on CRTC changeSimon Ser
There's no reason why the output should be damaged here. The current buffer doesn't need to be re-painted.
2022-11-17output: call wlr_output_update_enabled() after commitSimon Ser
Backends no longer need to manually call wlr_output_update_enabled() in their commit hook: wlr_output will take care of that.
2022-11-15backend/drm: only request page-flip if activeSimon Ser
It doesn't make sense to request a page-flip for a disabled output. Fixes: 84e727daae67 ("backend/drm: request page-flip event on modeset") Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3528
2022-11-15backend/drm: fix FPE when disabling outputSimon Ser
Fixes: 65836ce357e4 ("backend/drm: log modesetting commits") Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3534
2022-11-14backend/drm: log modesetting commitsSimon Ser
2022-11-14backend/drm: log refresh rate in HzSimon Ser
2022-11-11backend: remove const casts for pixman_region32_tSimon Ser
Pixman 0.42.0 has constified APIs for pixman_region32_t. We no longer need the casts.
2022-11-11backend/drm: ensure disconnected outputs are disabled after VT switchSimon Ser
The following situation can be dangerous: - Output DP-1 is plugged in, compositor enables it. - User VT switches away. - User unplugs DP-1. - User VT switches back. - scan_drm_connectors() figures out the output is now disconnected, uninitializes the struct wlr_output. - The loop restoring previous output state in handle_session_active() accesses the struct wlr_output to figure out what to restore. By chance, we zero out the struct wlr_output after uninitializing it, so enabled and current_mode will always be zero. But let's make sure we handle this case explicitly, to remind future readers that it exists and make the code less fragile.
2022-11-11backend/drm: request page-flip event on modesetSimon Ser
The old drm_connector_set_mode() function did that by calling drm_crtc_page_flip(). We lost this in the refactoring. Fixes: f216e979836a ("backend/drm: drop drm_connector_set_mode()")
2022-11-09backend/drm: use pnp.ids to fetch EDID datailliliti
2022-11-08Revert "backend/drm: fetch EDID manufacturer from udev_hwdb"Simon Ser
This reverts commit e646d882cf4949d290fff2ba3b7ae4c124f6f13d. This commit has added a dependency on udev_hwdb. This API isn't available on all platforms (e.g. FreeBSD), and further deepens our udev dependency. A better solution is being worked on in [1]. [1]: https://gitlab.freedesktop.org/wlroots/wlroots/-/merge_requests/3638
2022-11-02backend/drm: get possible CRTCs in create_drm_connector()Simon Ser
This stuff is immutable for a given connector.
2022-11-02backend/drm: extract create_drm_connector()Simon Ser
Move a bit more logic out of the big loop in scan_drm_connectors().
2022-10-19backend/drm: fetch current CRTC once on startupSimon Ser
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-18backend/drm: log failures in drm_surface_blit()Simon Ser
Can make issues like [1] easier to debug. [1]: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3451
2022-10-17backend/drm: drop drm_crtc_page_flip()Simon Ser
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-17backend/drm: log when restoring mode after VT switch failsSimon Ser
Can make it easier to track down issues.
2022-10-17backend/drm: fix EINVAL atomic commits after VT switchSimon Ser
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, 6936e163b514 ("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: f216e979836a ("backend/drm: drop drm_connector_set_mode()") Closes: https://gitlab.freedesktop.org/wlroots/wlroots/-/issues/3432
2022-10-17backend/drm: extract current mode logic into separate functionSimon Ser
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-15backend/drm: extract connect_drm_connector() logicSimon Ser
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-14backend/drm: use atomic API to fetch current connector's CRTCSimon Ser
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-13backend/drm: use wl_container_of() instead of casts for wlr_drm_modeSimon Ser
Instead of casting a wlr_output_mode to wlr_drm_mode, use wl_container_of() for slightly better type safety.
2022-10-13backend/drm/legacy: Fix whitespaceAlexander Orzechowski
This confused me while reading through.
2022-10-10backend/drm: drop drm_connector_set_mode()Simon Ser
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-07backend/drm: allocate connector CRTC on lease creationSimon Zeni
This was leading to crash in compositors if the wanted connector had no CRTC
2022-10-07backend/drm: nuke wlr_drm_connector.desired_enabledSimon Ser
This field becomes stale too easily: for instance, see 6adca4089cf4 ("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-07backend/drm: drop unnecessary wlr_drm_connector.crtc checksSimon Ser
drm_connector_alloc_crtc() already checks this.
2022-10-03backend/drm: remove outdated TODOSimon Ser
This has been addressed in 8795dde94eeb ("Initialize connectors current mode to the mode used by KMS on startup.").
2022-10-03backend/drm: don't unconditionally set desired_enabledSimon Ser
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-09-30backend/drm: fix missing wlr_output_state.allow_artifactsSimon Ser
Without allow_artifacts, applying the new state will fail because it requires ALLOW_MODESET. Fixes VT switch and disabling CRTCs.
2022-09-30output: add wlr_output_state.allow_artifactsSimon Ser
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