This is used as the minimum refresh rate in the variable refresh rate
range.
This value is expected to be found in the DisplayPort and eDP EDID of
every monitor that supports variable refresh rate.
It is also found in the HDMI EDID of some monitors that support
variable (FreeSync), but most likely not all of them. The rest require
parsing the AMD vendor extension which libdisplay-info doesn't
support.
No fallback is implemented for cases where libdisplay-info support is
disabled.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3576>
Find a surface actor that meets the criteria to drive the refresh
rate for the view. If a new surface actor is found, add a
reference to it and request frame synchronization to be enabled
for the relevant MetaRendererViewNative.
Whenever the surface actor schedules a repaint or an update, and
in case frame synchronization is enabled for the
MetaRendererViewNative, schedule the update to occur "now". This
effectively makes the surface actor's frame rate drive the refresh
rate of the monitor.
If the actor is frozen or destroyed, it is no longer expected to
schedule repaints or updates and should stop driving the refresh
rate.
When there is no surface actor to drive the refresh rate, request
frame synchronization to be disabled for the MetaRendererViewNative.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1154>
This makes all stage updates that result from applying the pending
state of a Wayland surface emit an "update-scheduled" signal in the
context of the relevant surface actor.
A common case where an "update-scheduled" signal is needed is
when applying "empty" client commits. In this case a
"repaint-scheduled" signal would not be emitted since the commit
doesn't trigger a repaint. However, it is still important to add
handling for such updates with variable refresh rate when the
releavnt actor is also driving the refresh rate.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1154>
This function allows scheduling a stage update in the context of a
surface actor and emit the "update-scheduled" signal. This signal is
similar to "repaint-scheduled", but can be used to be notified of
updates that do not necessarily result in a repaint.
With variable refresh rate, any update potentially affecting the
frame pacing of a surface actor needs to be handled differently
depending on whether that surface actor drives the refresh rate or
not.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1154>
Frame synchronization is enabled for a view as long as it's
applicable to be enabled. It is considered applicable if it's both
requested for the onscreen and if the onscreen uses a CRTC which is
configured with a variable refresh rate mode.
When frame synchronization is enabled, it enables both the the variable
scheduling mode of ClutterFrameClock and the variable refresh rate
property for the CRTC.
Changes in the frame synchronization mode are applied asynchronously,
before the next frame is drawn.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1154>
Add variable refresh rate output modes for connectors that are VRR
capable when VRR is not disabled for the GPU.
Variable refresh rate output modes are sorted before their fixed
refresh rate counterparts. They are also marked as the preferred mode
for the output between the two.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1154>
When VRR is not disabled for a GPU, create two variants of every
display mode: one with fixed refresh rate and another with variable
refresh rate.
The variable refresh rate modes are not used yet. They will be used
in a following commit.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1154>
This can be used to disable VRR in specific drivers and hardware
combinations where it is found to be problematic.
No default rules are added for now to encourage testing.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1154>
Require the "variable-refresh-rate" keyword under the
"experimental-features" gsetting to enable the feature for now.
It would no longer be required once the experience with variable
refresh rate is good enough for general use and handles all common
use cases well.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1154>
Use a sufficiently low refresh rate to calculate the CRTC deadline
when variable refresh rate is enabled. This is done to avoid cursor
updates from driving the monitor refresh rate.
It's not great solution and is sometimes not enough, but it avoids
stutter in the main content as a result of cursor movement in most
cases.
The unfortunate downside of this approach is that cursor movement
would usually only update with the main content and would not be
smooth when the main content updates are not frequent enough.
A better solution may use an approach similar to LFC (Low Framerate
Compensation) to insert cursor-only updates between updates of the
main content, but achieving adequate results with an approach of this
nature requires more research and experimentation.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1154>
It is not trivial to accurately estimate the expected presentation
time with variable refresh rate, and not doing so only affects debug
prints.
No change in behavior for now because the expected presentation time
is always calculated. A following commit will introduce a case where
it is not.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1154>
Add functions to update and monitor the value of the "VRR_ENABLED"
KMS property.
This requires the addition of functions to process CRTC property
updates in both the atomic and the simple KMS backends. The
implementation is similar to the implemention of processing
connector updates.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1154>
Commit d48129f5ee broke the displaying of our own drag cursor during window
drags, as now the window cursor is always used, even during stage grabs
(window grabs are just a kind of stage grab).
To fix it, while not regressing on the intention of the other commit, unset
the MetaWaylandPointer surface in case a window drag is active (instead of
all kinds of grabs) by checking via meta_display_is_grab().
Fixes: d48129f5ee ("wayland: Fix pointer cursor during Wayland grabs")
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/3316
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3624>
Move the bulk of the implementation inside MetaWaylandPointer
files, like it happens in other places (e.g. MetaWaylandTabletSeat).
This avoids MetaWaylandPointer struct peeking from outside.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3627>
The _MUTTER_FRAME_EXTENTS need to have the correct size before the
window is shown, otherwise the client window size will effectively have
the headarbar height subtracted when initially syncing the frame/client
geometries.
This reverts commit f10b3eac62.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3628>
QueryDeviceString can successfully return NULL. The convention however
is that when NULL is returned, the error will be set.
This commit makes the returned string an output parameter which allows
us to return the success status and have the error set accordingly.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3614>
The convention is that when a function returns FALSE or NULL, the error
will be set. In this file we call set_egl_error but it might not set an
error. Code of the form
if (egl_do_thing (..., &error))
use_error (error);
will crash in those cases.
This commit makes sure we always set the error even if EGL doesn't give
us an error.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3614>
We depend on Gio for many introspection features (GSettings, GFile...)
without this we'd end up not having many symbols being exposed.
And errors such as
Warning: Meta: meta_display_add_keybinding: argument settings:
Unresolved type: 'GSettings*'
As per previous commit we now have this dependency implicitly, but still
it's better to make it clearer in case Clutter would drop it.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3620>
This is added as a hint so that the caller can optionally use it, e.g.
in the case that a window drag is driven by the mouse. This will be used
to more accurately follow the drag position, other than starting at the
current pointer position.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3546>
Pointer constraints obey to logical pointer focus changes, and looking
up the current surface in order to maybe enable them is getting ahead
of itself, since the pointer focus might differ from the current surface
due to other factors (e.g. grabs).
Change the code checking whether constraints should be enabled to again
check the pointer logical focus, this will be influenced by the
MetaWaylandEventInterface mechanism, and correctly reflect the logical
state accounting for those factors.
Fixes: 125ba92169 ("wayland: Port pointer constraints to using MetaWaylandEventInterface")
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/3303
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3618>
Currently, we don't handle too well the removal of a MetaWaylandEventInterface
during meta_wayland_event_interface_invalidate_all_focus(), since the
MetaWaylandEventInterface may be freed at an intermediate point in that function
while handling the focus change for all input devices.
Turn this invalidate_all_focus() function into a MetaWaylandInput method, and
always ensure to use the currently effective MetaWaylandEventInterface when
resetting the focus for each device.
This fixes the situation through handling reentrancy naturally, a focus
sync (say, triggered by a grab) would reset a device focus (say, pointer), which
would remove an event interface (say, a pointer constraint), which would
invalidate_all_focus() again underneath using the new effective
MetaWaylandEventInterface. When that is done, the initial invalidate_all_focus()
call would re-apply the same focus to the same currently effective
MetaWaylandEventInterface, resulting in a no-op for the remainder of the function.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3618>
Even though the logical focus is typically business that only the
MetaWaylandEventInterface mechanism minds about, there are some pointer
subsystems that want to look this up, as opposed to the current surface.
Add a getter to make this easier, without struct peeking.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3618>
This also removes some g_return_if_fail's because the test suite expects
to be able to create arbitrary KmsUpdates even if they don't make sense
for the real state. We just get lucky that the test suite isn't
constructing updates with color space and hdr changes, yet.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3552>
Currently querying support for some output features is done partially
through the OutputInfo and partially via KMS CRTC and Connector objects.
Let's be consistent and use OutputInfo always which works with all
backends and backend types.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3552>
We're currently pretending the gamma LUT has another size. This becomes
a problem when we try to reset the LUT to passthrough, create an
identity LUT for it and it has a size that the kernel doesn't accept.
We do track the size and have utility for creating the LUTs, so let's
just use them.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3552>
The kernel doesn't let us set gamma to passthrough with the legacy API
so we have to trick a bit and create an identity LUT, and also when we
read the KMS state, detect when an identity LUT is active.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3552>
The frame size_allocate() will set it correctly once show() is called by
the window tracker.
This is less code and also help reduces the chance of a brief visual
glitch in fullscreen games during startup. If the window is initially
still decorated the gray area would still show up until the next redraw,
which due to loading times can take a while.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3608>
Relying on the content size_allocate() to determine the content position
can fail in situations where the position of the content has changed,
but not its size.
This happens for example when the window initially is sized fullscreen
height + headerbar height while not considered fullscreen yet. Then when
the window is resized to just the fullscreen height and marked as
fullscreen, the content size has not changed and size_allocate() is not
called on the content. Thus the previous position which assumes the
presence of a headerbar still applies. As a result the window is shifted
down, revealing a headerbar sized area showing the gtk window background
color.
This issue can be avoided by using the frame's size_allocate(), which
gets called in response to all relevant events, such as any headerbar
size changes, headerbar visibility changes, window resizes and
fullscreen status changes.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2937
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3608>
Allows to mark a wayland client window as a DOCK window. The reason for
this is that in Gala (elementary OS's window manager) we would like to
continue using GTK apps as panel and dock on wayland.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3612>
Assigning the corresponding stack layer of DOCK windows is currently X11
specific, because there is no way for wayland clients to set the DOCK
window type. This is about to change, so move the code to the generic
layer handling.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3612>
adaita-icon-theme cleaned up its cursor set, and now only provides
names defined by GTK/CSS. Update the cursor-hotplug test to not
use legacy cursor that will fail with a recent cursor theme.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3613>
meta_window_update_monitor() can emit "::highest-scale-monitor-changed",
and we connected to that signal right before. Let's avoid calling
meta_wayland_surface_notify_highest_scale_monitor() twice and move the
g_signal_connect() for that signal and the initial call to
meta_wayland_surface_notify_highest_scale_monitor() to happen after
meta_window_update_monitor().
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3598>
Turns out there is a better solution: Almost always, MetaWindow already has
an idea on which monitor it will be, even if it isn't positioned yet. Since
the last commit we're now using that monitor for setting the
highest-output-scale of the window, so this fallback is no longer necessary.
While we could keep this fallback around and also return a valid scale in
case the surface is not even mapped yet, this means we report fractional
scale twice for new surfaces: Once from
wp_fractional_scale_manager::get_fractional_scale() (here we'll enter the
fallback), and a second time (this time with correct scale) right after
creating the MetaWindow.
Note that wp_fractional_scale_v1 doesn't specify that a preferred_scale
event must be sent immediately after
wp_fractional_scale_manager::get_fractional_scale(), so we can safely remove
the fallback.
This reverts commit 8cfbdb4313.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3598>
MetaWindow always tries to have a main monitor: If the frame rect is empty
and the window has not been positioned, in meta_window_constructed() we fall
back to asking the backend for the current monitor, and in
meta_window_wayland_update_main_monitor() we fall back to
meta_window_find_monitor_from_id(), which then falls back to the primary
monitor.
In general this means that window->monitor is always set as long as there is
a monitor around.
For getting the highest-scale-monitor the window is on, we currently rely
completely on the frame rect. If the frame rect is empty, we set the
highest-scale-monitor to NULL. Since we usually know though which monitor
the window is, or will be on, and window->monitor is even set to that, we
can just fall back to window->monitor for the highest-scale-monitor.
This makes sure ::highest-scale-monitor-changed is emitted right after the
window is created, and it's set to the correct monitor that the window will
be on. This in turn means that we can send a correct wp_fractional_scale
fraction_scale event to clients right away.
https://gitlab.gnome.org/GNOME/mutter/-/issues/3262
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3598>
The existing comment tells us this is necessary:
> there may be drawing between the last damage event and the
> XDamageSubtract() that needs to be flushed as well.
But the commit message for 551101c65c also tells us that
synchronization is necessary before-update. Assuming both are correct
then it needs to be done in both places.
I did try optimizing out the second sync to only do it if damage
arrived during the update, but that doesn't seem to be the issue.
The damage event is arriving before the update starts and it's some
secondary changes within the damage region running late that need
flushing. So this means the client is reporting damage more frequently
than the frame rate and we're ignoring the secondary damage reports
for efficiency (XDamageReportBoundingBox), which is still a good thing.
Fixes: 551101c65c ("compositor-x11: Move synchronization to before-update")
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/2880
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3590>
Do not include it at header side as it is not part of the installed headers.
Only keep it in cogl-gl-headers.h as it is a private header.
Add it to all the source files that depend on it.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3593>
This change adds modifier-aware screencasting support to Mutter.
Implicit modifier support is kept for backward compatibility and the
code fallbacks to implicit modifiers in case any new functionality added
for explicit modifier support fails.
The advertised modifiers are retrieved by a call to
eglQueryDmaBufModifiersEXT() function. The "external only" modifiers are
excluded as Mutter uses the buffers created with the explicit modifiers
as renderbuffers. Support for implicit modifiers is checked with a test
allocation since there are drivers that do not support them.
This change also removes various implicit modifier support checks that
disable DMA-BUF screen casting support globally as they are no longer
needed. DMA-BUF support for screencasting is determined by the available
formats and modifiers case-by-case now.
It also effectively enables DMA-BUF screencasting on NVIDIA hardware as
well since GBM buffer objects with linear modifiers are no longer used
by default to create a renderbuffer object for screencasting.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3537>
meta_render_device_gbm_allocate_dma_buf() function is updated to take a
list of modifiers. If no modifiers are specified, the modifier is
selected by the allocator, and implicit modifiers are used to import the
created DMA-BUF.
Co-authored-by: Jonas Ådahl <jadahl@gmail.com>
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3537>