summaryrefslogtreecommitdiff
path: root/src/backends/native/meta-kms-impl.c
Commit message (Collapse)AuthorAgeFilesLines
* kms: Concentrate update processing in MetaKmsDeviceJonas Ådahl2022-01-251-17/+0
| | | | | | | | | | It was a bit scattered, with it being split between MetaKms and MetaKmsImpl, dealing with MetaKmsDevice and MetaKmsImplDevice differentation. Replace this by, for now, single entry point on MetaKmsDevice: meta_kms_device_process_update_sync() that does the right thing. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2159>
* native: Release output device files that are unusedJonas Ådahl2021-07-071-0/+10
| | | | | | | | | In order to make it possible to e.g. unload an unused DRM device, we need to make sure that we don't keep the file descriptor open if we don't need it; otherwise we block anyone from unloading the corresponding module. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1828>
* kms: Gracefully handle page flipping direct scanouts failingJonas Ådahl2021-07-021-3/+4
| | | | | | | | | | | | | | | | | | | | | | When drmModePageFlip() or drmModeAtomicCommit() unexpectedly failed (e.g. ENOSPC, which has been seen in the wild), this failure was not handled very gracefully. The page flip listener for the scanout was left in the MetaKmsUpdate, meaning when the primary plane composition was later page flipped, two page flip listeners were added, one for the primary plane, and one for the scanout. This caused the 'page-flipped' event to be handled twice, the second time being fatal. Handle this by making 'no-discard' listener flag be somewhat reversed, and say 'drop-on-error', and then drop all 'drop-on-error' listeners when a MetaKmsUpdate failed to be processed. Also for a "preserve" flagged update, don't ever trigger "discard" callbacks just yet, as preserved updates are used again for the primary plane composition, in order to not miss e.g. CRTC gamma updates, or cursor plane updates, which were added separately. Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1809 Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1910>
* backend/native: Split up KMS shutdown in two phasesJonas Ådahl2021-05-051-0/+15
| | | | | | | | | | The first phase happens early, which discards pending page flips, meaning the references held by those page flip closures are released. The second phase happens late, after other units depending on the KMS abstraction, have been cleaned up. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1822>
* kms: Move impl backend inherit MetaKmsImplDevice instead of MetaKmsImplJonas Ådahl2021-01-221-14/+27
| | | | | | | This allows different types of backends to coexist, would e.g. one device support atomic but another not. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
* kms/impl: Manage a list of impl devicesJonas Ådahl2021-01-221-0/+26
| | | | | | | Accessing the device list directly from MetaKms might not be safe if we introduce threads, so keep a list completely within the impl context. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
* native: Remove left-over flip waiting functionalityJonas Ådahl2021-01-221-6/+0
| | | | | | | With the frame clocks split up, we never wait for page flip callbacks anymore, so remove the functions that implement that. Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1488>
* kms-impl-simple: Add fake cursor planes if no real onesJonas Ådahl2020-03-071-0/+7
| | | | | | | | | | | | Non-atomic drivers may support drmModeSetCursor() even if no cursor plane is advertised. To deal with this, add a fake cursor plane for every CRTC when using MetaKmsImplSimple. This will eventually be translated to drmModeSetCursor() calls without any explicit cursor plane usage. Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/1058 https://gitlab.gnome.org/GNOME/mutter/merge_requests/1079
* kms: Make update processing return direct feedbackJonas Ådahl2020-02-111-5/+4
| | | | | | | | The current API as all synchronous, so they can be made to return feedback immediately. This will be needed for the cursor renderer which needs to know whether it should fall back to OpenGL cursor rendering. https://gitlab.gnome.org/GNOME/mutter/merge_requests/930
* kms: Process impl idle callbacks before pre dispatch flushPekka Paalanen2019-12-061-0/+7
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | mode_set_fallback() schedules a call to mode_set_fallback_feedback_idle(), but it is possible for Mutter to repaint before the idle callbacks are dispatched. If that happens, mode_set_fallback_feedback_idle() does not get called before Mutter enters wait_for_pending_flips(), leading to a deadlock. Add the needed interfaces so that meta_kms_device_dispatch_sync() can flush all the implementation idle callbacks before it checks if any "events" are available. This prevents the deadlock by ensuring mode_set_fallback_feedback_idle() does get called before potentially waiting for actual DRM events. Presumably this call would not be needed if the implementation was running in its own thread, since it would eventually dispatch its idle callbacks before going to sleep polling on the DRM fd. This call might even be unnecessary overhead in that case, synchronizing with the implementation thread needlessly. But the thread does not exist yet, so this is needed for now. This is part 1 of 2 fixing a complete desktop freeze when drmModePageFlip() fails with EINVAL and the fallback to drmModeSetCrtc() succeeds but the success is not registered correctly as completed "flip". The freeze occurs under wait_for_pending_flips() which calls down into meta_kms_impl_device_dispatch() which ends up poll()'ing the DRM fd even though drmModeSetCrtc() will not produce a DRM event, hence the poll() never returns. The freeze was observed when hotplugging a DisplayLink dock for the first time on Ubuntu 19.10. CC stable: gnome-3-34 https://gitlab.gnome.org/GNOME/mutter/merge_requests/953
* backend/native: Add and use transactional KMS APIJonas Ådahl2019-06-201-0/+22
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This commit introduces, and makes use of, a transactional API used for setting up KMS state, later to be applied, potentially atomically. From an API point of view, so is always the case, but in the current implementation, it still uses legacy drmMode* API to apply the state non-atomically. The API consists of various buliding blocks: * MetaKmsUpdate - a set of configuration changes, the higher level handle for handing over configuration to the impl backend. It's used to set mode, assign framebuffers to planes, queue page flips and set connector properties. * MetaKmsPlaneAssignment - the assignment of a framebuffer to a plane. Currently used to map a framebuffer to the primary plane of a CRTC. In the legacy KMS implementation, the plane assignment is used to derive the framebuffer used for mode setting and page flipping. This also means various high level changes: State, excluding configuring the cursor plane and creating/destroying DRM framebuffer handles, are applied in the end of a clutter frame, in one go. From an API point of view, this is done atomically, but as mentioned, only the non-atomic implementation exists so far. From MetaRendererNative's point of view, a page flip now initially always succeeds; the handling of EBUSY errors are done asynchronously in the MetaKmsImpl backend (still by retrying at refresh rate, but postponing flip callbacks instead of manipulating the frame clock). Handling of falling back to mode setting instead of page flipping is notified after the fact by a more precise page flip feedback API. EGLStream based page flipping relies on the impl backend not being atomic, as the page flipping is done in the EGLStream backend (e.g. nvidia driver). It uses a 'custom' page flip queueing method, keeping the EGLStream logic inside meta-renderer-native.c. Page flip handling is moved to meta-kms-impl-device.c from meta-gpu-kms.c. It goes via an extra idle callback before reaching meta-renderer-native.c to make sure callbacks are invoked outside of the impl context. While dummy power save page flipping is kept in meta-renderer-native.c, the EBUSY handling is moved to meta-kms-impl-simple.c. Instead of freezing the frame clock, actual page flip callbacks are postponed until all EBUSY retries have either succeeded or failed due to some other error than EBUSY. This effectively inhibits new frames to be drawn, meaning we won't stall waiting on the file descriptor for pending page flips. https://gitlab.gnome.org/GNOME/mutter/issues/548 https://gitlab.gnome.org/GNOME/mutter/merge_requests/525
* backends/native: Add basic KMS abstraction building blocksJonas Ådahl2019-06-201-0/+110
The intention with KMS abstraction is to hide away accessing the drm functions behind an API that allows us to have different kind of KMS implementations, including legacy non-atomic and atomic. The intention is also that the code interacting with the drm device should be able to be run in a different thread than the main thread. This means that we need to make sure that all drm*() API usage must only occur from within tasks that eventually can be run in the dedicated thread. The idea here is that MetaKms provides a outward facing API other places of mutter can use (e.g. MetaGpuKms and friends), while MetaKmsImpl is an internal implementation that only gets interacted with via "tasks" posted via the MetaKms object. These tasks will in the future potentially be run on the dedicated KMS thread. Initially, we don't create any new threads. Likewise, MetaKmsDevice is a outward facing representation of a KMS device, while MetaKmsImplDevice is the corresponding implementation, which only runs from within the MetaKmsImpl tasks. This commit only moves opening and closing the device to this new API, while leaking the fd outside of the impl enclosure, effectively making the isolation for drm*() calls pointless. This, however, is necessary to allow gradual porting of drm interaction, and eventually the file descriptor in MetaGpuKms will be removed. For now, it's harmless, since everything still run in the main thread. https://gitlab.gnome.org/GNOME/mutter/issues/548 https://gitlab.gnome.org/GNOME/mutter/merge_requests/525