We don't have enough Xlib code in mutter ...
Joking aside, it can be useful to make the cursor invisible
without hiding it, for example for replacing the actual cursor
with an actor in gnome-shell; the real cursor should still
update the focus surface in that case, and not sneak into
screenshots or -casts.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1244
We're iterating inside the PipeWire loop when detecting PipeWire errors,
and shouldn't destroy the PipeWire objects mid-iteration. Avoid this by
first disabling the stream src (effectively stopping the recording),
then notifying about it being closed in an idle callback. The
notification eventually makes the rest of the screen cast code clean up
the objects, including the src and the associated PipeWire objects, but
will do so outside the PipeWire loop iteration.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1251https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1251
In the native backend, the MetaRenderer manages the view by creating one
per CRTC, but until now the MetaStageX11 managed the view for the X11
backend. This caused some issues as it meant meta_renderer_get_views()
not returning anything, and that the view of the X11 screen not being a
MetaRendererView, while in the other backends, all views are.
Fix this by moving the view management responsibility to
MetaRendererX11Cm, and have MetaStageX11 only operate on it via
meta_renderer_x11_cm_*() API. The MetaRendererX11Cm takes care of making
sure the view is always added to the list in the renderer, and turning
X11 screen sizes into "layouts" etc.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1251
"Legacy" is a misleading name, it's just how the native backend and the
X11 backend behaves differently. Instead rename it to 'add_view()' and
add the sanity check to the caller.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1251
They all checked that the remote session service talked with the
correct peer, and some of them did check that there is an associated
screencast session.
Add a new check for the session being started (as it's state is
decoupled with screencast session availability) and move all checks
to a function that is called from all input-oriented DBus methods.
Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1254https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1258
It was removed in 3.34 as part of 6ed5d2e2. And we thought that was the
only thread that might exist and use X11. But the top gnome-shell crasher
in 3.36 seems to suggest otherwise.
We don't know what or where the offending thread is, but since:
1. We used XInitThreads for years already prior to 3.34; and
2. Extensions or any change to mutter/gnome-shell could conceivably use
threads to make X calls, directly or indirectly,
it's probably a good idea to reintroduce XInitThreads. The failing assertion
in libx11 is also accompanied by a strong hint:
```
fprintf(stderr, "[xcb] Most likely this is a multi-threaded client " \
"and XInitThreads has not been called\n");
```
https://bugs.launchpad.net/bugs/1877075
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1252https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1256
Commit e06daa58c3 changed the tested values to use corresponding valid
enum values instead of negative ones. Unfortunately that made one value
become a duplicate of an existing one and also in part defeated the original
intention of checking the implementation of
`meta_output_crtc_to_logical_transform`.
Use `meta_monitor_transform_invert` to fix both shortcomings.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1242
The 'assert_size' command checks that the size of the window, both
client side and compositor side, corresponds to an expected size set by
the test case.
The size comparison can only be done when the window is using 'csd', in
order for both the client and server to have the same amount of
understanding of the title bar. For ssd, the client cannot know how
large the title bar, thus cannot verify the full window size.
Sizes can be specified to mean the size of the monitor divided by a
number. This is that one can make sure a window is maximized or
fullscreened correctly.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1171
We were iterating through evcodes, but using API that expects Clutter button
numbers. Instead of transforming those to Clutter numbers to have those translated
back, use the inner seat API that already takes evcodes.
Fixes stuck buttons keys after a virtual device is destroyed while those are
pressed.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1239
Inhibiting remote access means any current remote access session is
terminated, and no new ones can be created, until remote access is
uninhibited. The inhibitation is ref counted, meaning there can be more
than one inhibitor.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1212
It takes coordinates in stage coordinate space, and will result in
a screen cast stream consisting of that area, but scaled up by the scale
factor of the view that overlaps with the area and has the highest scale
factor.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1207
Will be used by the stage to not paint the overlays. We skip all
overlays since overlays are only ever used for pointer cursors when the
hardware cursors cannot or should not be used.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1207
These phase callbacks are not intended to be inovked when something
secondary is painting the stage, such as a screen cast stream, or
similar. Thus, only invoke the callbacks when there is a view associated
with the paint context, which will not be the case for offscreen
painting.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1207
If there is a paint context available (i.e. for the phases that are
during the actual stage paint), pass it along the callbacks, so that
the callback implementations can change their operation depending on the
paint context state.
This also means we can get the current view from the paint context,
instead of the temporarily used field in the instance struct.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1207
If drmModePageFlip() or custom_page_flip_func fails, process_page_flip() was
forgetting to undo the ref taken for that call. This would leak page_flip_data.
The reference counting works like this:
- when created, ref count is 1
- when calling drmModePageFlip, ref count is increased to 2
- new: if flip failed, ref count is decreased back to 1
- if calling schedule_retry_page_flip(), it takes a ref internally
- if calling mode_set_fallback(), it takes a ref internally
- all return FALSE paths have an explicit unref
- return TRUE path has an explicit unref
This issue was found by code inspection and while debugging an unrelated issue
with debug prints sprinkled around. I am not aware of any end-user visible
issues being fixed by this, as the leak is small and probably very rare.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1209
When testing a laptop with intel and DisplayLink devices, attempting to set the
DL output as the only active output resulted in GNOME/Wayland freezing. The
main event loop was running fine, but nothing on screen would get updated once
the DL output become the only one. This patch fixes that issue.
DisplayLink USB 3 devices use an out-of-tree kernel DRM driver called EVDI.
EVDI can sometimes fail drmModePageFlip(). For me, the flip fails reliably when
hotplugging the DL dock and when changing display configuration to DL only.
Mutter has a workaround for failing flips, it just calls drmModeSetCrtc() and
that succeeds.
What does not work reliably in the fallback path is Mutter keeping track of the
pageflip. Since drmModePageFlip() failed, there will not be a pageflip event
coming and instead Mutter queues a callback in its stead. When you have more
than one output, some other output repainting will attempt to swap buffers and
calls wait_for_pending_flips() which has the side-effect of dispatching any
queued flip callbacks. With multiple outputs, you don't get stuck (unless they
all fail the exact same way at the same time?). When you have only one output,
it cannot proceed to repaint and buffer swap because the pageflip is not marked
complete yet. Nothing dispatches the flip callback, leading to the freeze.
The flip callback is intended to be an idle callback, implemented with a
GSource. It is supposed to be called as soon as execution returns to the main
event loop. The setup of the GSource is incomplete, so it will never dispatch.
Fix the GSource setup by setting its ready-time to be always in the past. That
gets it dispatched on the next cycle of the main event loop. This is now the
default behavior for all sources created by meta_kms_add_source_in_impl().
Sources that need a delay continue to do that by overriding the ready-time
explicitly.
An alternative solution could have been to implement GSource prepare and check
callbacks returning TRUE. However, since meta_kms_add_source_in_impl() is used
by flip retry code as well, and that code needs a delay through the ready-time,
I was afraid I might break the flip retry code. Hence I decided to use
ready-time instead.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1209
When closing the lid of a laptop, we reconfigure all the monitors in order
to update the CRTCs and (if enabled) the global UI scaling factor.
To do this, we try first to reuse the current configuration for the usable
monitors, but if we have only monitor enabled and this one is on the laptop
lid we just end up creating a new configuration where the primary monitor is
the laptop one (as per find_primary_monitor() in MetaMonitorConfigManager),
but ignoring the user parameters.
In case the user selected a different resolution / scaling compared to the
default one, while the laptop lid is closed we might change the monitors
layout, causing applications to rescale or reposition.
To avoid this, when creating the monitors configuration from the current
current state, in case we have only one monitor available and that one is
the laptop panel, let's just reuse this configuration.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1200
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.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/798
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.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/798
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.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/798
The CRTC level transform (not necessarily the hw transform) must be
taken into account when calculating the position of the CRTC in the
stage coordinate space, when placing the hw cursor, otherwise we'll
place the cursor as if the monitor was not rotated.
This wasn't a problem in the past, as with rotation, we always used the
OpenGL cursor, so the issue newer showed.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1199
The port to per CRTC views was incomplete; we still used the logical
monitor layout as the stage view layout, while still using one view per
CRTC.
This worked fine for most cases, e.g. regular monitors, tiled or
non-tiled, transformed or non-transformed. Where it broke, however, was
when a monitor consists of multiple CRTCs. We already have the layout a
CRTC corresponds to on the stage kept with the CRTC metadata, so use
this directly.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1170https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1199`
The CRTC level transform (i.e. not necessarily the one set on the
hardware) is what is relevant for calculating the layout the CRTC will
have on the stage, so only use the one that can be handled by the
hardware for the CRTC assignment.
This makes the CRTC layout valid for tiled monitors.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1199
Previously the tile coordinate was used to offset a CRTC scanout
coordinate within a larger framebuffer. Since 3.36 we're always
scanning out from (0, 0) as we always have one framebuffer per CRTC; we
instead use the tile coordinate to calculate the coordinate the tile has
in the stage view. Adapt calculation to fulfil this promise instead of
the old one.
This also corrects the tiled custom monitor test case.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1199
Dereference the loop variable rather than the original list head. This
fixes a regression introduced in 4413b86a3 ("backends: Replace
ClutterDeviceManager usage in favor of ClutterSeat", 2019-10-04) which
broke button scrolling with trackballs.
Closes:https://gitlab.gnome.org/GNOME/mutter/-/issues/1120
The motion events of tablets for example need to be mapped on the
selected screen area if the input device is configured to use only a
part of the active logical monitor.
To achieve this behavior each motion event is transformed using the
transformation matrix set for the input device.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1118
At some point we crossed the streams... In a short timespan we had
1f00aba92c merged, pushing WacomDevice to a common parent object,
and dcaa45fc0c implementing device grouping for X11.
The latter did not rely on the former, and just happened to
merge/compile without issues, but would promptly trigger a crash
whenever the API would be used.
Drop all traces of the WacomDevice internal to MetaInputDeviceX11.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1183
GObject recommends to break references to other objects on dispose
instead of finalize, also we want to release the pressed virtual buttons
as early as possible if we know the object is getting destroyed.
So release the pressed buttons and unref our virtual
MetaInputDeviceNative when the dispose vfunc is called, which also
allows us to release the buttons immediately from javascript instead of
waiting for the garbage collector by calling run_dispose() on the
object.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1157
Just like what's done for monitor screencasting. Unfortunately, there's
no mechanism to share fences with PipeWire clients yet, which forces
us to guarantee that a frame is completed after blitting.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1129
MetaScreenCastWindowStreamSrc connects to the "damaged" signal of
MetaWindowActor. This signal is not exactly tied to the paint cycle
of the stage, and a damage may take quite a while to arrive when
a client doesn't want to draw anything. For that reason, the window
screencast can start empty, waiting for a damage to arrive.
Ensure at least one frame is recorded when enabling the window stream.
Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/1097https://gitlab.gnome.org/GNOME/mutter/merge_requests/1129
When calculating the transform we should apply to the cursor sprite
before uploading it to the cursor plane, we must also take into
account non upright mounted LCD panels.
Otherwise the cursor ends up 90 degrees rotated on devices where the
LCD panel is mounted 90 degrees rotated in its enclosure.
This commit fixes this by calling meta_monitor_logical_to_crtc_transform
in get_common_crtc_sprite_transform_for_logical_monitors to adjust the
transform for each Monitor in the LogicalMonitor.
Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1123https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1153
The transactional KMS API has been modelled after atomic KMS. Atomic KMS
currently doesn't support forwarding cursor hotspot metadata, thus it
was left out of the transactional KMS API having the user set the simply
create a plane assigment with the cursor sprite assigned to a cursor
plane using regular coordinates.
This, however, proved to be inadequate for virtual machines using
"seamless mouse mode" where they rely on the cursor position to
correspond to the actual cursor position of the virtual machine, not the
cursor plane. In effect, this caused cursor positions to look "shifted".
Fix this by adding back the hotspot metadata, right now as a optional
field to the plane assignment. In the legacy KMS implementation, this is
translated into drmModeSetCursor2() just as before, while still falling
back to drmModeSetCursor() with the plane coordinates, if either there
was no hotspot set, or if drmModeSetCursor2() failed.
Eventually, the atomic KMS API will learn about hotspots, but when
adding our own atomic KMS backend to the transacitonal KMS API, we must
until then still fall back to legacy KMS for virtual machines.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1136
For HiDPI pointer cursors backed by Wayland surfaces, the hotspot must
be placed using integers on the logical pixel grid. In practice what
this means is that if the client loads a cursor sprite with the buffer
scale 2, and it's hotspot is not dividable by 2, it will be rounded
down to an integer that can. E.g. a wl_surface with buffer scale 2 and a
cursor image with hotspot coordinate (7, 7) will have the coordinate
(3.5, 3.5) in surface coordinate space, and will in practice be rounded
down to (3, 3) as the hotspot position in wl_pointer only takes
integers.
To not potentially shift by 1 pixel on HiDPI monitors when switching
between wl_surface backend cursor sprites and built-in ones, make the
built in one emulate the restrictions put up by the Wayland protocol.
This also initializes the theme scale of the xcursor sprite instances to
1, as they may not have been set prior to being used, it'll only happen
in response to "prepare-at" signals being emitted prior to rendering.
Fixes: https://gitlab.gnome.org/GNOME/mutter/issues/1092https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1107
A user may have configured an output to be panning, e.g. using xrandr
--output <output> --mode <mode> --panning <size>. Respect this by making
the logical monitor use the panning size, instead of the mode. This
makes e.g. makes the background cover the whole panning size, and panels
etc will cover the whole top of the panned area, instead of just the top
left part covering the monitor if having panned to (0, 0).
No support is added to configuring panning, i.e. a panned monitor
configuration cannot be stored in monitors.xml.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1085
This is so that cogl-trace.h can start using things from cogl-macros.h,
and so that it doesn't leak cogl-config.h into the world, while exposing
it to e.g. gnome-shell so that it can make use of it as well. There is
no practical reason why we shouldn't just include cogl-trace.h via
cogl.h as we do with everything else.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1059
The upper layers (OSDs basically) want to know the monitor that a
tablet is currently assigned to, not the monitor just as configured
through settings.
This broke proper OSD positioning for display-attached tablets since
commit 87858a4e01, as the MetaInputMapper kicks in precisely when
there is no configured monitor for the given device.
Consulting both about the assigned output will make OSDs pop up
again in the right place.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/971
This class sits between ClutterInputDevice and the backend implementations,
it will be the despositary of features we need across both backends, but
don't need to offer through Clutter's API.
As a first thing to have there, add a getter for a WacomDevice. This is
something scattered across and somewhat inconsistent (eg. different places
of the code create wacom devices for different device types). Just make it
here for all devices, so users can pick.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1109
Most people just see a harmless warning when applying this setting to
all touchpads (which this patch fixes). But tap[-and-drag] is supposed
to remain enabled for display-less Wacom tablets, despite configuration
changes.
Fix this by using the mapping function, so the setting is forced on for
wacom devices. This happens on a per-device basis, so the warning is
gone too.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1145
Some tablets like the Cintiq 24HDT have several mode switch buttons
per group. Those are meant to jump straight to a given mode, however
we just handle cycling across modes (as most other tablets have a
single mode switch button per group).
So spice up the mode switch handling so we handle multiple mode
switch buttons, assigning each of them a mode. If the device only
has one mode switch button, we do the old-fashioned cycling.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/970
When a page flip fails with a certain error code, we've treated this as
a hint that page flipping is broken and we should try to use mode
setting instead.
On some drivers, it seems that this error is also reported when there
was no mode set, which means we'll have no cached mode set to use in the
fallback. The lack of prior mode set tends to happen when we hit a race
when the DRM objects change before we have the time to process a hotplug
event.
Handle the lack a missing mode set in the flip fallback path, with the
assumption that we'll get a hotplug event that'll fix things up for us
eventually.
Closes: https://gitlab.gnome.org/GNOME/mutter/issues/917
If the CRTCs the cursor is visible on do not share a common scale
and transform, we can't use the cursor hardware plane as we only have one.
We therefore fall back to software / gl cursor.
The check for that currently happens after we tried to upload the cursor image
to the hardware plane though.
This is made worse by the fact that in the scaling step, where we scale the
cursor image to the desired size, until now we expected a valid common scale -
otherwise scaling the image by an uninitialized float.
Make sure we bail out early during the scale/upload step if we don't have common
scales and transforms - to avoid that bug and save some unnecessary work.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1125
Listen for GPU hotplug events to initialize their cursor support.
This fixes one reason for why DisplayLink devices may not be using a hardware
cursor. Particularly, when a DisplayLink device is hotplugged for the first
time such that EVDI creates a new DRM device node after gnome-shell has already
started, we used to forget to initialize the cursor support.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1097
Extract the code to initialize a single GPU cursor support into its own
function. The new function will be used by GPU hotplug in the future.
This is a pure refactoring without any behavioral changes.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1097
For every stream src, we created and attached a GSource. Upon stream
src destruction, we g_source_destroy():ed the GSource. What
g_source_destroy() does, hawever, is not really "destroy" it but only
detaches it from the main context removing the reference the context had
added for it via g_source_attach(). This caused the GSource to leak,
although in a detached state, as the reference taken on creation was
still held.
Fix this by also removing our own reference to it when finalizing.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1106
PipeWire will be unable to dequeue a buffer if all are already busy.
This can happen for valid reasons, e.g. the stream consumer not being
fast enough, so don't complain in the journal if it happens.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1115
While we will always have cursor planes, as we'll currently create fake
ones when real ones are missing (See #1058), eventually we will run into
situations where we can't create fake ones, for example for atomic KMS
drivers that don't advertise any cursor planes.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1079
Even though cogl_framebuffer_flush() was supposed to be enough,
it ends up creating streams with odd visual glitches that look
very much like unfinished frames.
Switch back to cogl_framebuffer_finish(), which is admittedly
an overkill, but it's what works for now. There is anedoctal
evidence showing it doesn't incur in worse performance.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1086
Much like monitor streaming, implement window streaming by
making the window actor draw itself with a paint context
that used the passed framebuffer.
Now that all MetaScreenCastStreamSrc subclasses implement
blit_to_framebuffer, remove the conditional check from
meta_screen_cast_stream_src_blit_to_framebuffer().
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1086
Implement PipeWire's add_buffer and remove buffer, try and export
a DMA buffer first and, on failure, fallback to memfd.
When DMA buffers are successfully created and shared, blit the
framebuffer contents when drawing instead of downloading the pixels.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1086
Create a new gbm_bo using the same given geometry, and export the new
bo's DMA buffer fd. The new bo lives as long as necessary to be used,
and reused, by PipeWire.
Unfortunately, PipeWire doesn't support modifiers properly, so use the
linear format for now. For now, a hardcoded format of DRM_FORMAT_XRGB8888
is set, so we don't need to negotiate the format with PipeWire early.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1086
If the cursor sprite does not match the scale factor or transformation
of the monintor, we currently fall back to a software cursor, causing
redraws of the shell. This commit implements scaling and transforming
of the cursor sprite, so we can use it with hardware planes, too.
This commit does the following steps:
1. Make sure we reupload the cursor image if the cursor is over
a logical monitor not matching the scale or transform from the previous
update.
2. Before upload to the hardware plane, scale and transform the cursor
image if possible and necessary.
3. Make sure we always use the hardware cursor if possible (only fall
back to software/OGL cursor if it is visible on multiple logical monitors
with differet scales/transforms).
4. Transform or scale the cursor coordinates if necessary.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/526
In Wayland clients can commit transformed surfaces, so the compositor
can directly use them on hardware planes. We already support that
for other surfaces, this is the first step to also support it on
cursor sprites.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/526
This may be used indirectly before creation as we dispatch libinput events
right after creation (to let input devices be known), so those device
additions would trigger the touch-mode checks.
Creating it in advance results in checks being correctly performed, although
redundantly.
Spotted by Bastien Nocera.
Closes: https://gitlab.gnome.org/GNOME/mutter/issues/1067
When applying a configuration to XRANDR, we first disable CRTCs that
happen to extend outside of the to-be X11 screen size. While doing so,
we fail to actually check whether the CRTC is active or not, meaning
we'll try to query the content of the CRTC configuration even though it
has none, leading to a NULL pointer dereference.
Fix this by simply ignoring non-configured CRTCs.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1093
Prior to this commit the stage was drawn separately for each logical
monitor. This allowed to draw different parts of the stage with
different transformations, e.g. with a different viewport to implement
HiDPI support.
Go even further and have one view per CRTC. This causes the stage to
e.g. draw two mirrored monitors twice, instead of using the same
framebuffer on both. This enables us to do two things: one is to support
tiled monitors and monitor mirroring using the EGLStreams backend; the
other is that it'll enable us to tie rendering directly to the CRTC it
will render for. It is also a requirement for rendering being affected
by CRTC state, such as gamma.
It'll be possible to still inhibit re-drawing of the same content
twice, but it should be implemented differently, so that it will still
be possible to implement features requiring the CRTC split.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042