Skip to content

Conversation

@Sunderland93
Copy link
Contributor

@Sunderland93 Sunderland93 commented Aug 20, 2025

This is my second attempt to backport support for unredirecting fullscreen Wayland surfaces from GNOME. All issues I encounter with previous PR is solved, Cinnamon runs fine. Although it still need some tests. I split this PR in separate commits to facilitate reviewing and keep original commit messages from GNOME, as well as links to the original Mutter MR's.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/798

Also I'm not sure if this part is also needed to be backported to Cinnamon

@Sunderland93 Sunderland93 force-pushed the wayland_direct_scanout branch 2 times, most recently from 1047e6e to 7b27d99 Compare September 20, 2025 17:18
@Sunderland93
Copy link
Contributor Author

Hm, with latest master session is crashed at startup

Currently a buffer use count always reaches zero before it is replaced.
This is due to the fact that at the point a new buffer is attached, the
last potential user releases it (the stage) since the currently
displayed frame has a composited copy of the buffer.

This may however change, if a buffer is scanned out directly, meaning it
should not be released until the page flip callback is invoked.

Prepare for this by making the buffer reference a heap allocated struct,
enabling us to keep a pointer to it longer than the buffer is attached.

Original Mutter commit: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/798/diffs?commit_id=47002bf0cd9983cb5e45121d566d203baef71103
Surface buffers are created with meta_drm_buffer_new_acquire(), taking a
gbm_surface acquiring the gbm itself, and meta_drm_buffer_new_take()
that takes over ownership of a passed gbm_bo.

Original Mutter commit: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/798/diffs?commit_id=282aada13a5d744dd29eedf3255b6a9f6d0e370c
This removes the MetaWindowX11::priv pointer. It is replaced with a
meta_window_x11_get_private() helper function, and another method to get
the client rect without going through MetaWindowX11Private.
Better to have the relevant object figure out whether it is a good
position to be unredirectable other than the actor, which should be
responsible for being composited.

Original Mutter commit: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/798/diffs?commit_id=5dad87cfb9058a0be96d9ec1a530e09a6d418a6e
Transitions are used for animating actors when e.g. going from/to
fullscreen, and the like. We need to know such things when deciding
whether to avoid compositing a window actor, so make add API visible to
mutter that checks whether there are any transitions active.

Original Mutter commit: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/798/diffs?commit_id=bc178b711ffbd8db0b7cfecefb6f67edf4e0254f
Instead of always swapping buffers and flipping the back buffer, make it
possible to scan out a provided buffer directly without swapping any EGL
buffers.

A buffer is passed as an object implementing the empty CoglScanout
interface. It is only possible to do this in the native backend; and the
interface is implemented by MetaDrmBufferGbm. When directly scanned out,
instead of calling gbm_surface_lock_front_buffer() to get the gbm_bo and
fbid, get it directly from the MetaDrmBufferGbm, and use that to create
the page flip KMS update.

Original Mutter commit: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/798/diffs?commit_id=3da8c1bfdc1fa486111c1e1dff363fb931612468
Make it possible to cause the next frame to scan out directly from the
passed CoglScannout. This makes it possible to completely bypass
compositing for the following frame.

Original Mutter commit: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/798/diffs?commit_id=753066598ff83fa9bdbd1be23d1e22663ae59297
While this is fairly incomplete, as to check things fully we need to use
TEST_ONLY in atomic to try out a complete assignment on the device, but
this works well enough for legacy non-modifier cases.

Original Mutter commit: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/798/diffs?commit_id=b9fe9c736a3b7ef298bda5f785938275805a47f0
Advertising support for modifiers means we will most likely not not be
able to scan out client buffers directly, meaning it just as likely that
we won't be able to scan out even fullscreen windows without atomic KMS.

When we have atomic support, we should advertise support for modifiers
if atomic is used to drive the CRTCs, as we by then can check whether we
can scan out directly, place in an overlay plane, etc.

Original Mutter commit: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/798/diffs?commit_id=cb05b164140dc6934ff5a00cb4354a5dbf4593ef
We might still have a MetaWaylandBuffer for a wl_buffer that was
destroyed. Handle trying to fetch the MetaWaylandDmaBufBuffer from such
a buffer gracefully.

Original Mutter commit: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/798/diffs?commit_id=4b1805c3065eea293aefb1e3d1dc0ba685bcc1fc
This will check whether the current backing buffer is compatible with
the primary plane of the passed CoglOnscreen. Since this will extend the
time before a buffer is released, the MetaWaylandBufferRef is swapped
and orphaned if a new buffer is committed before the previous one was
released. It'll eventually be released, usually by the next page flip
callback.

Currently implemented for EGLImage and DMA-BUF buffer types.

Original Mutter commit: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/798/diffs?commit_id=ff7a42b8bc25c24d3e0fc0a277b1d628f5ea599a
While at it, fix some style inconsistencies, for now use a single
singleton struct instead of multiple static variables, and
other non-functional cleanups. Semantically, there is no changes
introduced.

Original Mutter commit: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/798/diffs?commit_id=d682cdb078f281b03084e3e0d7ab40d3ea382c1f
MetaCompositor is the place in muffin that manages the higher level
state of compositing, such as handling what happens before and after
paint. In order for other units that depend on having a compositor
instance active, but should be initialized before the X11 implementation
of MetaCompositor registers as a X11 compositing manager, split the
initialization of compositing into two steps:

 1) Instantiate the object - only construct the instance, making it
    possible for users to start listening to signals etc
 2) Manage - this e.g. establishes the compositor as the X11 compositing
    manager and similar things.

This will enable us to put compositing dependent scattered global
variables into a MetaCompositor owned object.

For now, compositor management is internally done by calling a new
`meta_compositor_do_manage()`, as right now we can't change the API of
`meta_compositor_manage()` as it is public. For the next version, manual
management of compositing will removed from the public API, and only
managed internally.

Original Mutter commit: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/798/diffs?commit_id=dc4fe780f790c8fbd3624a7e75fd25c9a3918d0b
Since the order of destruction during MetaDisplay tear down is a bit
unordered, there are pieces that try to destruct its compositing
dependent pieces (i.e. queued MetaLater callbacks) after MetaCompositor
has been cleaned up, meaning we need to put some slightly awkward NULL
checks to avoid crashing.

Original Mutter commit: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/798/diffs?commit_id=2e7d02f1ce8cb8eba15968c7facd815a7ce43080
We need to coordinate with MetaCompositor during pre-paint so that we
have control over whether MetaLater callbacks happen first, or the
MetaCompositor pre-paint logic.

In order to do so, make MetaLater listen to a new signal "pre-paint" on
MetaCompositor, that is called MetaCompositors own pre-paint handling.

This fixes an issue where the top window actor was calculated after the
MetaCompositor pre-paint handling, meaning the top actor being painted
was out-of-date.

Original Mutter commit: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/798/diffs?commit_id=b51c468c0facc3be5df597a6fe0c8c35b95a1fff
Try to bypass compositing if there is a fullscreen toplevel window with
a buffer compatible with the primary plane of the monitor it is
fullscreen on. Only non-mirrored is currently supported; as well as
fullscreened on a single monitor. It should be possible to extend with
more cases, but this starts small.

It does this by introducing a new MetaCompositor sub type
MetaCompositorNative specific to the native backend, which derives from
MetaCompositorServer, containing functionality only relevant for when
running on top of the native backend.

Original Mutter commit: https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/798/diffs?commit_id=65a6c4c361b7dad10b19f9bcabdcf7b576d7daa0
@Sunderland93
Copy link
Contributor Author

Hm, with latest master session is crashed at startup

Nevermind, fixed now. Ready for review and test

@Sunderland93
Copy link
Contributor Author

To test (from orifinal GNOME's MR):

one can test this by enabling the damage painting overlay: alt+f2 -> lg -> Meta.add_clutter_debug_flags(0, Clutter.DrawDebugFlag.PAINT_DAMAGE_REGION, 0)/Meta.remove_clutter_debug_flags(0, Clutter.DrawDebugFlag.PAINT_DAMAGE_REGION, 0)
The overlay will not get painted when this is active - it's not a bug, it's a feature! :)

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant