In order to make things more and more asynchronus and to each time we
paint be an isolated event, that can be potentially be applied
individually or together with other updates, make it so that each time
we draw, we use the transient MetaFrameNative (ClutterFrame) instance to
carry a KMS update for us.
For this to work, we also need to restructure how we apply mode sets.
Previously we'd amend the same KMS update each frame during mode set,
then after the last CRTC was composited, we'd apply the update that
contained updates for all CRTC.
Now each CRTC has its own KMS update, and instead we put them in a per
device table, and whenever we finished painting, we'll merge the new
update into any existing one, and then finally once all CRTCs have been
composited, we'll apply an update that contains all the mode sets for all
relevant CRTCs on a device.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2855>
MetaRendererViewNative is a MetaRendererView which contains logic
specific to views of the native backend. It will be used by following
commits.
In the future, per-view logic from MetaRendererNative can be moved to
MetaRendererViewNative where it makes more sense to have it.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2855>
Instead of using the "discarded" page flip callback when the
"discarding" happened during actual immediate processing, communicate
the same via the KMS update feedback.
The "discarded" page flip callback is instead used only for when a
posted page flip is discarded. In the atomic backend, this only happens
on shutdown, while in the simple backend, this also happens when a
asynchronous retry sequence eventually is abandoned.
This allows further improvements making KMS handling fully async.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2854>
With detach meaning having the onscreen stop listening on configuration
changes on the corresponding backing mode setting objects. We need to do
this as there is a time between rebuilding the views, and that the new
mode sets are called, where the old onscreen is kept alive, but the
stage view is gone. At this point in time, if privacy screen or gamma
configuration changes, e.g. by the night light temperature changing, the
onscreen would attempt to schedule an update on the now gone stage view.
This commit also renames the "keep onscreen alive" to "detached
onscreens" to more clearly communicate that it's detached onscreens from
their corresponding mode setting objects.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2621
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2863>
This means objects have an owner, where the chain eventually always
leads to a MetaContext. This also means that all objects can find their
way to other object instances via the chain, instead of scattered global
singletons.
This is a squashed commit originally containing the following:
cursor-tracker: Don't get backend from singleton
idle-manager: Don't get backend from singleton
input-device: Pass pointer to backend during construction
The backend is needed during construction to get the wacom database.
input-mapper: Pass backend when constructing
monitor: Don't get backend from singleton
monitor-manager: Get backend directly from monitor manager
remote: Get backend from manager class
For the remote desktop and screen cast implementations, replace getting
the backend from singletons with getting it via the manager classes.
launcher: Pass backend during construction
device-pool: Pass backend during construction
Instead of passing the (maybe null) launcher, pass the backend, and get
the launcher from there. That way we always have a way to some known
context from the device pool.
drm-buffer/gbm: Get backend via device pool
cursor-renderer: Get backend directly from renderer
input-device: Get backend getter
input-settings: Add backend construct property and getter
input-settings/x11: Don't get backend from singleton
renderer: Get backend from renderer itself
seat-impl: Add backend getter
seat/native: Get backend from instance struct
stage-impl: Get backend from stage impl itself
x11/xkb-a11y: Don't get backend from singleton
backend/x11/nested: Don't get Wayland compositor from singleton
crtc: Add backend property
Adding a link to the GPU isn't enough; the virtual CRTCs of virtual
monitors doesn't have one.
cursor-tracker: Don't get display from singleton
remote: Don't get display from singleton
seat: Don't get display from singleton
backend/x11: Don't get display from singleton
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2718>
The type of render device used for a specific GPU affects the mode
setting backend that can be used, more specifically, when the render
device is an EGLStream based one, atomic mode setting isn't possible, as
page flipping is done via EGL, not via atomic mode setting commits.
Preparing the render devices before KMS devices means can make a more
informed decision whether to deny-list atomic mode setting for when
a certain GPU uses a EGLStream based render device instance.
This also means we need to translate mode setting devices to render node
devices when creating the render device itself, as doing it later when
creating the mode setting device is already too late.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2578>
We disable modifiers for two reasons: an udev rule saying so, or the
lack of a working drmModeAddFB2(). However, to the users, this is not
granular enough. While the current user, whether to enable modifiers in
MetaRendererNative, doesn't need more granularity, we want to send
modifiers to Wayland clients even if the onscreen framebuffers should
still be allocated without modifiers.
Prepare for differentiating between how Wayland DMA buffers work and how
onscreen buffer allocation work by separating the relevant device flags.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2546>
Returns TRUE if the active renderer backend can allocate DMA buffers.
This is the case hardware accelerated GBM backends, but FALSE for
surfaceless (i.e. no render node) and EGLDevice (legacy NVIDIA paths).
While software based gbm devices can allocate DMA buffers, we don't want
to allocate them for offscreen rendering, as we really only use these
for inter process transfers, and as buffers allocated for scanout
doesn't use the relevant API, making it return FALSE for these solves
that.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1939>
Privacy screen events on connector are handled as notification events
that won't cause any monitors reconfiguration but will emit monitors
changed on DBus, so that the new value can be fetched.
We monitor the hardware state so that we can also handle the case of
devices with hw-switchers only.
In case a software state is available it means we can also support
changing the state, and if so expose the state as unlocked.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1952>
If there are any pending updates, for example if we painted one of
multiple monitors but without having posted the update due to waiting
for another monitor to be painted, but before we paint all of them and
post the update, another hotplug event happens, we'd have stale pending
KMS update. When that update eventually would be processed, we'd try to
apply out-of-date updates which may contain freed memory.
Fix this by discarding any update when we're rebuilding the views. We
can be sure not to need any of the old updates since we're rebuilding
the whole content anyway.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1928
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2216>
An incorrect assumption that after mode set there would be no pending
page flips was made. This meant that if there was a mode set, followed
by a page flip, if that page flip was for a CRTC on a now unused GPU,
we'd crash due to the renderer GPU data having already been freed. This
commit avoids that by keeping it alive as long as the page flips are
still in the air. It fixes crashes with backtraces such as
0) meta_render_device_get_egl_display (render_device=0x0)
at ../src/backends/native/meta-render-device.c:320
1) secondary_gpu_state_free (secondary_gpu_state=0x1c8cc30)
at ../src/backends/native/meta-onscreen-native.c:560
2) meta_onscreen_native_dispose (object=0x1cb65e0)
at ../src/backends/native/meta-onscreen-native.c:2168
3) g_object_unref (_object=<optimized out>)
at ../gobject/gobject.c:3540
4) g_object_unref (_object=0x1cb65e0)
at ../gobject/gobject.c:3470
5) clutter_stage_view_finalize (object=0x1cbb450)
at ../clutter/clutter/clutter-stage-view.c:1412
6) g_object_unref (_object=<optimized out>)
at ../gobject/gobject.c:3578
7) g_object_unref (_object=0x1cbb450)
at ../gobject/gobject.c:3470
8) meta_kms_page_flip_closure_free (closure=0x1d47e60)
at ../src/backends/native/meta-kms-page-flip.c:76
9) g_list_foreach (list=<optimized out>, func=0x7fb3ada67111 <meta_kms_page_flip_closure_free>, user_data=0x0)
at ../glib/glist.c:1090
10) g_list_free_full (list=0x1cb4d20 = {...}, free_func=<optimized out>)
at ../glib/glist.c:244
11) meta_kms_page_flip_data_unref (page_flip_data=0x1c65510)
at ../src/backends/native/meta-kms-page-flip.c:109
12) meta_kms_callback_data_free (callback_data=0x227ebf0)
at ../src/backends/native/meta-kms.c:372
13) flush_callbacks (kms=0x18e2630)
at ../src/backends/native/meta-kms.c:391
14) callback_idle (user_data=0x18e2630)
at ../src/backends/native/meta-kms.c
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2147>
This ensures we don't have any left over cursor GPU buffers (via
gbm_bo's) after destroying the corresponding gbm_device (owned by
MetaRenderDevice).
Fixes crashes with backtraces such as
1) meta_drm_buffer_gbm_finalize at ../src/backends/native/meta-drm-buffer-gbm.c:450
4) invalidate_cursor_gpu_state at ../src/backends/native/meta-cursor-renderer-native.c:1167
9) update_cursor_sprite_texture at ../src/wayland/meta-wayland-cursor-surface.c:70
10) meta_wayland_surface_role_apply_state at ../src/wayland/meta-wayland-surface.c:1869
11) meta_wayland_surface_apply_state at ../src/wayland/meta-wayland-surface.c:832
12) meta_wayland_surface_commit at ../src/wayland/meta-wayland-surface.c:993
13) wl_surface_commit at ../src/wayland/meta-wayland-surface.c:1158
14) ffi_call_unix64 at ../src/x86/unix64.S:76
15) ffi_call at ../src/x86/ffi64.c:525
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2147>
The GBM support in the NVIDIA driver is fairly new, and to make it
easier to identify whether a problem encountered is related to using GBM
instead of EGLStreams, add a debug environment variable to force using
EGLStream instead of GBM.
To force using EGLStream instead of GBM, use
MUTTER_DEBUG_FORCE_EGL_STREAM=1
Related: https://gitlab.gnome.org/GNOME/mutter/-/issues/2045
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2132>
When we use gbm together with the NVIDIA driver, we want the EGL/Vulkan
clients to do the same, instead of using the EGLStream paths. To achieve
that, make sure to only initialize the EGLStream controller when we
didn't end up using gbm as the renderer backend.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2052>
This switches the order of what renderer mode is tried first, so that
the gbm renderer mode is preferred on an NVIDIA driver where it is
supported.
We fall back to still try the EGLDevice renderer mode if the created gbm
renderer is not hardware accelerated.
The last fallback is still to use the gbm renderer, even if it is not
hardware accelerated, as this is needed when hardware acceleration isn't
available at all. The original reason for the old order was due to the
fact that a gbm renderer without hardware acceleration would succeed
even on NVIDIA driver that didn't support gbm.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2051>
This replaces functionality that MetaRenderDevice and friends has
learned, e.g. buffer allocation, EGLDisplay creation, with the usage of
those helper objects. The main objective is to shrink
meta-renderer-native.c and by extension meta-onscreen-native.c, moving
its functionality into more isolated objects.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1854>
This changes the setup phase of clutter to not be result of calling an
init function that sets up a few global singletons, via global singleton
setup vfuncs.
The way it worked was that mutter first did some initial setup
(connecting to the X11 server), then set a "custom backend" setup vfunc
global, before calling clutter_init().
During the clutter_init() call, the context and backend was setup by
calling the global singleton getters, which implicitly created the
backend and context on-demand.
This has now changed to mutter explicitly creating a `ClutterContext`
(which is actually a `ClutterMainContext`, but with the name shortened to
be consistent with `CoglContext` and `MetaContext`), calling it with a
backend constructor vfunc and user data pointer.
This function now explicitly creates the backend, without having to go
via the previously set global vfunc.
This changes the behavior of some "get_default()" like functions, which
will now fail if called after mutter has shut down, as when it does so,
it now destroys the backends and contexts, not only its own, but the
clutter ones too.
The "ownership" of the clutter backend is also moved to
`ClutterContext`, and MetaBackend is changed to fetch it via the clutter
context.
This also removed the unused option parsing that existed in clutter.
In some places, NULL checks for fetching the clutter context, or
backend, and fetching the cogl context from the clutter backend, had to
be added.
The reason for this is that some code that handles EGL contexts attempts
to restore the cogl EGL context tracking so that the right EGL context
is used by cogl the next time. This makes no sense to do before Cogl and
Clutter are even initialized, which was the case. It wasn't noticed
because the relevant singletons were initialized on demand via their
"getters".
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2002>
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>
The DRM buffers aren't really tied to mode setting, so they shouldn't
need to have an associated mode setting device. Now that we have a
device file level object that can fill this role, port over
MetaDrmBuffer and friends away from MetaKmsDevice to MetaDeviceFile.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1828>
Keep a private MetaDeviceFile instance for the GPU's managed by the
renderer. This is a step towards decoupling rendering from mode setting,
as well as on-demand holding of device file descriptors.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1828>
A view is only a 'CoglOnscreen' if it ends up on a CRTC, thus needs a
mode. Other views are for virtual monitors, and require no mode setting,
so exclude them from the pending mode set list.
This avoids a dead lock when we'll be waiting indefinitely for mode
setting on a virtual monitor.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1891>
With atomic mode setting, commits don't work when CRTCs aren't enabled,
which they aren't when we're power saving. This means the gamma state
fails to being update. To fix night light and for whatever other reason
gamma ramps was changed during power saving by marking the CRTC gamma
state as invalid when leaving power saving, as well as when resuming.
This means that the next frame will append the CRTC gamma state to the
KMS commit.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1755
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1835>
When a device only had mode sets which turned off monitors, not enabling
anything, there would be no KMS update created and posted, and the
active monitors would remain on.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1821>
The intel DRM driver is known for not being able to handle multi head
setups when KMS modifiers are enabled, due to the implicitly selected
modifiers, while being more suitable for single head setups, cause
bandwidth issues when a certain number of monitor times resolution and
refresh rate is configured.
We don't yet support automatically finding a combination of modifiers
that work, and have because of this disabled KMS modifiers unless the
driver actually needs it.
Lets flip this configuration the other way around, changing the current
udev rule to decide wen to *disable* KMS modifier support, as it so that
only the Intel driver has this problem, while on the other hand, there
several drivers that requires modifiers to function at all.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1792>
This eliminates the need for any render node or device nodes, thus can
be used without any graphics hardware available at all, or with a
graphics driver without any render node available.
The surfaceless mode currently requires EGL_KHR_no_config_context to
configure the initial EGL display.
This also means we can enable the native backend tests in CI, as it
should work without any additional privileges.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1698>
Virtual monitors are monitors that isn't backed by any monitor like
hardware. It would typically be backed by e.g. a remote desktop service,
or a network display.
It is currently only supported by the native backend, and whether the
X11 backend will ever see virtual monitors is an open question. This
rest of this commit message describes how it works under the native
backend.
Each virutal monitor consists of virtualized mode setting components:
* A virtual CRTC mode (MetaCrtcModeVirtual)
* A virtual CRTC (MetaCrtcVirtual)
* A virtual connector (MetaOutputVirtual)
In difference to the corresponding mode setting objects that represents
KMS objects, the virtual ones isn't directly tied to a MetaGpu, other
than the CoglFramebuffer being part of the GPU context of the primary
GPU, which is the case for all monitors no matter what GPU they are
connected to. Part of the reason for this is that a MetaGpu in practice
represents a mode setting device, and its CRTCs and outputs, are all
backed by real mode setting objects, while a virtual monitor is only
backed by a framebuffer that is tied to the primary GPU. Maybe this will
be reevaluated in the future, but since a virtual monitor is not tied to
any GPU currently, so is the case for the virtual mode setting objects.
The native rendering backend, including the cursor renderer, is adapted
to handle the situation where a CRTC does not have a GPU associated with
it; this in practice means that it e.g. will not try to upload HW cursor
buffers when the cursor is only on a virtual monitor. The same applies
to the native renderer, which is made to avoid creating
MetaOnscreenNative for views that are backed by virtual CRTCs, as well
as to avoid trying to mode set on such views.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1698>