Commit Graph

30660 Commits

Author SHA1 Message Date
Jonas Ådahl
7a821345db tests/kms/device: Test cursor updates just before turning off CRTC
If we turn of a CRTC, we might have invalidated the cursor manager for
the same CRTC, but that should not mean a cursor plane is assigned when
turning off the CRTC.

Add a test case for this.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-18 23:51:34 +02:00
Jonas Ådahl
6d873036e0 Add KMS cursor manager
This new manager object intends to take over management of the cursor
plane from the native cursor renderer. It's API is intended to be used
from the main thread, except for the _in_input() function, but mainly
operates in the KMS context, i.e. the KMS thread.

It makes use of an "update filter" that is called before each
MetaKmsUpdate is turned into a atomic KMS commit or a set of legacy
drmMode*() API calls. When the cursor position has been invalidated,
it'll assign the cursor plane in the filter callback, using an as up to
date as possible pointer position as the source for the cursor plane
position.

Cursor updates from the input thread schedules updates for the affected
CRTCs which will cause the filter to be run, potentially for cursor-only
commits.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-18 23:51:34 +02:00
Jonas Ådahl
5a798989c4 seat/native: Add run impl task helper
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-18 23:51:34 +02:00
Jonas Ådahl
ef64279035 seat/impl: Add signal for pointer motions
This signal is emitted directly in the input thread.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 23:42:38 +02:00
Jonas Ådahl
f4b76727db stage-view: Add API to inhibit cursor overlay painting
This adds some plumbing to get the "default" paint flags for regular
stage painting, where one either wants to paint the overlay, or not.

If inhibited, the 'no-cursors' paint flag is used, otherwise the 'none'
flag. This will be used to allow having a per stage view hw cursor
state.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 23:42:38 +02:00
Jonas Ådahl
5d35138df0 cursor-renderer: Make 'handled_by_backend' state 'needs_overlay'
This will, conceptually, and eventually, allow a backend to both want an
overlay, while still handling it by default.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 23:42:38 +02:00
Jonas Ådahl
3b2f95cb1f kms/update: Add destroy-notify to result listener user data
No thread guarantees, users need to handle it themselves.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 23:42:38 +02:00
Jonas Ådahl
27ed069766 kms/impl-device: Add deadline based KMS commit scheduling
This makes it possible to post KMS updates that will always defer until
just before the scanout deadline. This is useful to allow queuing cursor
updates where we don't want to post them to KMS immediately, but rather
wait until as late as possible to get lower latency.

We cannot delay primary plane compositions however, and this is due to
how the kernel may prioritize GPU work - not until a pipeline gets
attached to a atomic commit will it in some drivers get bumped to high
priority. This means we still need to post any update that depends on
OpenGL pipelines as soon as possible.

To avoid working on compositing, then getting stomped on the feet by the
deadline scheduler, the deadline timer is disarmed whenever there is a
frame currently being painted. This will still allow new cursor updates
to arrive during composition, but will delay the actual KMS commit until
the primary plane update has been posted.

Still, even for cursor-only we still need higher than default timing
capabilities, thus the deadline scheduler depends on the KMS thread
getting real-time scheduling priority. When the thread isn't realtime
scheduled, the KMS thread instead asks the main thread to "flush" the
commit as part of the regular frame update. A flushing update means one
that isn't set to always defer and has a latching CRTC.

The verbose KMS debug logging makes the processing take too long, making
us more likely to miss the deadline. Avoid this by increasing the
evasion length when debug logging is enabled. Not the best, but better
than changing the behavior completely.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 23:42:38 +02:00
Jonas Ådahl
48501236ec kms: Move error codes to main header
Some will be used outside of meta-kms*.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 21:19:34 +02:00
Jonas Ådahl
ee87654224 kms/update: Add helper to checking if an update passed
Instead of comparing values, just add a `did_pass()` helper.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 21:19:34 +02:00
Jonas Ådahl
5bed90114d kms/update: Treat NULL main context as default for page flips too
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 21:19:34 +02:00
Jonas Ådahl
40caa6d87c kms/update: Use callback helper to free page flip listener data
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 21:19:34 +02:00
Jonas Ådahl
6059d8f42d kms/page-flip: Make destroy notify function optional
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 21:19:34 +02:00
Jonas Ådahl
587da92b0a kms: Mark mode set updates as such
This is currently unused, but will be later used to distinguish betwen
per frame/CRTC updates and device wide ones.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 21:19:34 +02:00
Jonas Ådahl
a7954f4a75 onscreen/native: Move out timeval to timestamp helper
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 21:19:34 +02:00
Jonas Ådahl
17a78303d0 kms: Make result listener take a vtable too
As with the page flip listener, prepare to make result listeners more
capable by allowing more vfuncs for the same listener instance in the
future.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 21:19:34 +02:00
Jonas Ådahl
f97f0f2781 thread: Document the behavior of meta_thread_post_impl_task()
Specifically in what contexts things are invoked.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 21:19:34 +02:00
Jonas Ådahl
6ed75c6253 thread: Allow passing a NULL callback vfunc
This is useful when one just wants to free something, which can be done
using the passed destroy notify function.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 21:19:34 +02:00
Jonas Ådahl
0d5d1745ce thread: Push the thread-default main context
Makes g_main_context_get_thread_default() do the right thing.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 21:19:34 +02:00
Jonas Ådahl
59ba952661 thread: Always add impl thread context as callback source
This is helpful when we add callbacks that should be dispatched in the
KMS impl thread.

This invalidates an assumption about callbacks not being in the impl
context, so some asserts for that are also removed.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 21:19:34 +02:00
Jonas Ådahl
84ff167328 thread: Add private API to flush callbacks for main context
This will be used to flush out certain callbacks when switching thread
type.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 21:19:34 +02:00
Jonas Ådahl
2617bd8e72 thread/impl: Add 'reset' signal
This signal is emitted before terminating the thread, but also when
resetting the thread type. This is to allow thread implementations to
make sure they have no stale pending callbacks to any old main contexts.

This commit "terminates" the impl thread even if there is no actual
thread; this is to trigger the "reset" signal, also when switching from
a user thread to a kernel thread.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 21:19:34 +02:00
Jonas Ådahl
bedec579b8 tests/kms/updates: Use async update API
We ignored the feedback and entered a temporary main loop, so no need to
do things sync.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 21:19:34 +02:00
Jonas Ådahl
15a91e9fd4 kms/update: Stop sealing updates
This isn't very useful anymore, since posting an update takes ownership
of it. Not sealing it also means e.g. more listeners can be added after
posting.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 21:19:34 +02:00
Jonas Ådahl
54d9fab161 kms: Ask to be real time scheduled
This will allow more time sensitive scheduling strategies.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 21:19:34 +02:00
Jonas Ådahl
6da3e9eb69 thread/impl: Add API to tell whether its realtime scheduled
Will be used by thread impl's to decide whether they can rely on real
time scheduling or not.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 21:19:34 +02:00
Jonas Ådahl
e92e4fe64d thread: Register with profiler
This means we can add COGL_TRACE*() instrumentation that is grouped
correctly in sysprof. If kernel threading is enabled, they will end up
in a "Compositor (KMS thread)" group (ignoring translations).

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 21:19:34 +02:00
Jonas Ådahl
bd2fa92c29 thread: Support making threads real time scheduled
Real time scheduling is needed for better control of when we commit
updates to the kernel, so add a property to MetaThread that, if the
thread implementation uses a kernel thread and not a user thread, RTKit
is asked to make the thread real time scheduled using the maximum
priority allowed.

Currently RTKit doesn't support the GetAll() D-Bus properties method, so
some fall back code is added, as GDBusProxy depends on GetAll() working
to make the cached properties up to date. Once
https://github.com/heftig/rtkit/pull/30 lands and becomes widely
available in distributions, the work around can be dropped.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 21:19:34 +02:00
Jonas Ådahl
276ebbf5ee kms: Use a kernel thread by default
Also add an API to inhibit the kernel thread from being used, and make
MetaRenderDeviceEglStream inhibit the kernel thread from being used if
it's active.

The reason for this is that the MetaRenderDeviceEGlStream is used when
using EGLStreams instead of KMS for page flipping. This means the actual
page flipping happens as a side effect of using EGL/OpenGL, which can't
easily be done off thread.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 21:19:34 +02:00
Jonas Ådahl
788ad43e17 thread: Allow switching thread type
This will be necessary in order to default to 'kernel' and then switch
to 'user' if the thread instance can no longer be properly multi
threaded.

To avoid having the same thread impl creating and destroying
GMainContext's, this also means always creating a GMainContext for the
thread-impl. When running in user-thread mode, the GMainContext is
wrapped in a wrapper source and dispatched as part of the real main
thread GMainContext, and when in kernel-thread mode, it runs
independently in the dedicated thread.

This has the consequence that the wrapper source will always have the
priority of the highest impl context GSource, but only after it has
dispatched once. Would we need it earlier than that, we either need a
way to introspect existing sources in a GMainContext and their
priorities, or manually track known sources in MetaThreadImpl.

The wrapper source will never be below 0, as that'd mean it could reach
INT_MAX priority if it had no more sources attached to it, meaning it'd
never be dispatched again.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 21:19:34 +02:00
Jonas Ådahl
33b33aa370 onscreen/native: Post updates asynchronously
Results are handled in callbacks anyway, there is no need to wait for
the KMS thread to finish.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 17:23:31 +02:00
Jonas Ådahl
718c78a365 kms: Add API to pass updates asynchronously
While doing this, rename the old synchronous functions to more clearly
communicate that they expect to actually process the update during the
call, not just post it.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 17:23:31 +02:00
Jonas Ådahl
e4a8fc93a1 thread: Add destroy notify function for post user data
The destroy notify function can be called on any thread.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 17:23:31 +02:00
Jonas Ådahl
7c9d4b8c7c kms/result-listener: Allow setting a custom main context
While the default when passing NULL will be the main context of the main
thread, make it possible to specify another main context, so that
result handlers can be invoked on the right thread.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 17:23:31 +02:00
Jonas Ådahl
1e0367bf08 tests/kms/update: Move out some repetitive code into helper
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 17:23:31 +02:00
Jonas Ådahl
1350b5e260 thread: Make it possible to run sync tasks from any thread
When a task is posted from a non-main thread, a user thread still needs
to go via the queue and be signalled using the condition, just as if it
was a kernel thread.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 17:23:31 +02:00
Jonas Ådahl
d77b5935cd kms/update: Allow page flip callback listeners on any thread
This hooks into the MetaThread GMainContext callback machinery just
added; and allows receiving page flip callbacks on any thread.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 17:23:31 +02:00
Jonas Ådahl
f83c30bae5 thread: Support queuing callbacks on any thread
Callbacks could be queued to be invoked either on the impl side or the
main thread side of the thread; change this to take a GMainContext,
which effectively means a callback can be queued to be invoked on any
thread that has a GMainLoop running on its own GMainContext.

Flushing is made to handle flushing callbacks synchronously on all
threads. This works by keeping a hash table of queued callbacks per
thread (GMainContext); when flushing (from the main thread), callbacks
on the main thread context is flushed, followed by synchronization with
all the other threads.

meta_thread_flush_callbacks() is changed to no longer return the number
of dispatched callbacks; it becomes much harder when there are N queues
spread across multiple threads. Since it wasn't used for anything, just
drop the counting, making life slightly easier.

Feedback to thread tasks are however always queued on the callers
thread.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 17:23:31 +02:00
Jonas Ådahl
ae48019cce tests/kms: Run tests with kernel/user thread too
This means each test is run 4 times:

 * with atomic mode setting using a kernel thread,
 * with atomic mode setting using a user thread,
 * with legacy mode setting using a kernel thread, and
 * with legacy mode setting using a user thread.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 12:51:36 +02:00
Jonas Ådahl
f1356ce5d3 kms: Add debug env var to configure thread implementation type
Set MUTTER_DEBUG_KMS_THREAD_TYPE to either 'kernel' or 'user', and the
MetaThread backend will be either a kernel thread or a user thread.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 12:51:36 +02:00
Jonas Ådahl
8b612a6150 thread: Introduce kernel thread support
This commit makes it possible to create a MetaThread where the
MetaThreadImpl side runs in a real thread, instead of a artificially
separated impl context.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 12:51:36 +02:00
Jonas Ådahl
4c317eae07 thread: Make callback handling thread safe
This is in preparation for introducing kernel threads, where proper
synchronization becomes necessary.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 12:51:36 +02:00
Jonas Ådahl
915bceb5a0 thread: Add name to threads
So far this is used to assign names to relevant sources, but will used
to name the kernel threads, when they are introduced.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 12:51:36 +02:00
Jonas Ådahl
251722ec4e thread: Flush tasks and callbacks on finalize
This will make sure no tasks or callbacks are unexpectedly dropped,
potentially leaking or leaving things in an unexpected state.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 12:51:36 +02:00
Jonas Ådahl
261624538c tests/thread: Quit main loop in idle callback if in impl thread
This isn't a problem for user space threads, as there are no race
conditions, but when kernel thread support is introduced, we must make
sure that e.g. the main loop is actually running before quitting it.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 12:51:36 +02:00
Jonas Ådahl
50b0d8cb18 tests/thread: Test mixing async and sync task
The expected behaivor is that the sync task will "flush" the async
tasks, i.e. to maintain task order.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 12:51:36 +02:00
Jonas Ådahl
069bee0ce8 tests/thread: Test multiple queued tasks
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 12:51:36 +02:00
Jonas Ådahl
aa723e7207 thread: Add support for posting async task
This uses the queue that was introduced when migrating impl task
management from MetaThread to MetaThreadImpl, with the exception that
it's now fully used as an actual queue. It now has a GSource that sits
on the right GMainContext that is dispatched whenever there are tasks to
execute.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 12:51:36 +02:00
Jonas Ådahl
fda883e859 thread: Move context and task management to impl side
It's the impl side that wants to add impl side idle sources, or fd
sources, etc, so make it part of MetaThreadImpl.

This changes things to be GAsyncQueue based. While things are still
technically single threaded, the GAsyncQueue type is used as later we'll
introduce queuing tasks asynchronously, then eventually queuing across
thread barriers.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 12:51:36 +02:00
Jonas Ådahl
229904cb4b kms: Use MetaThread source helpers directly
No need to have thin meta_kms_* wrappers, just use the meta_thread_*
functions directly.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2777>
2023-07-17 12:51:36 +02:00