We don't want triple buffering when the estimated maximum update time is
known and no larger than a refresh interval. In that case, regular frame
clock dispatch is scheduled after the previous frame is presented, so no
third buffer is necessary.
Allowing triple buffering anyway was problematic when frames are skipped
for reasons other than the frame update taking too long (e.g.
https://gitlab.gnome.org/GNOME/mutter/-/issues/3884):
1. First frame dispatches, targets display refresh cycle (DRC) n, but
skips
2. Second frame dispatches, targets DRC n+1
3. First frame is presented at DRC n+1
4. Second frame is presented at DRC n+2
Without triple buffering:
2. First frame is presented at DRC n+1
3. Second frame dispatches, targets DRC n+2
4. Second frame is presented at DRC n+2
The second frame is presented at DRC n+2 in both cases, but with triple
buffering it targeted n+1, i.e. its contents might not be consistent
with when it's presented.
It gets worse with triple buffering if the second frame also skips:
4. Second frame skips, is presented at DRC n+3
That's a discrepancy of 2 refresh cycles between the target and
effective presentation time, which might be noticeable as more severe
stutter.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4282>
With triple buffering, frame_clock->next_presentation_time_us
corresponds to a different frame in
clutter_frame_clock_notify_presented.
Also remove superfluous has_next_presentation_time field, any
target_presentation_time value > 0 is valid.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4282>
This is a CPU-based transformation method that performs the
same transformation implemented on GPU shaders.
The transformation gets an array of pixels in RGB float format and
returns an array of pixels transformed.
This will be used in the next commit to compare the results
between CPU and GPU, validating the shader implementations.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4230>
Use a Clutter event flag to communicate the the fact that the event
is an a11y modifier first click. The accessibility modifiers will
require special handling in the input and main threads.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4217>
_clutter_actor_get_animation_info() creates a new info when the actor
currently doesn't have one. That's unnecessary and wasteful in case
where we only need to check for transitions to remove, so switch to
_clutter_actor_get_animation_info_or_default() that falls back to
an empty static info.
Fixes: c250f602bd ("clutter/actor: Remove transitions when removing an effect")
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4260>
While the `get_key_focus()` method returned the stage itself when
no explicit focus was set, it made sense for the corresponding
setter to accept the stage as synonym for NULL.
But now that the getter always returns the property value, it
makes more sense to expect NULL to unset the key focus.
Keep the current behavior of normalizing the key focus to NULL
in that case to minimize breakage, but print a warning to
use NULL instead.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4256>
The method currently returns the stage itself when the property
is NULL.
This has become particularly problematic as the method is detected
as getter by gobject introspection, and gjs now optimizes property
accesses by calling the getter method instead.
Address this by turning the method into a genuine getter without
falling back to the stage.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4256>
While the existing `get_key_focus()` methods looks like a getter of the
`key-focus` property and is detected as such by gobject introspection,
it behaves differently in that it returns the stage if no explicit
focus has been set.
This is about to change, so adjust the couple of cases that rely
on the fallback to the stage.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4256>
Previously if we had no measurements then `compute_max_render_time_us`
would pessimise its answer to ensure triple buffering could be reached:
if (frame_clock->state >= CLUTTER_FRAME_CLOCK_STATE_DISPATCHED_ONE)
ret += refresh_interval_us;
But that also meant entering triple buffering even when not required.
Now we make `compute_max_render_time_us` more honest and return failure
if the answer isn't known (or is disabled). This in turn allows us to
optimize `calculate_next_update_time_us` for this special case, ensuring
triple buffering can be used, but isn't blindly always used. So when
TIMESTAMP_QUERY support is missing we now take the same path as if
presentation timestamps are missing (introduced in 56fc09151d and
improved in 0555a5bbc1), which has the benefit of naturally switching
from double to triple buffering as required without actually having to
measure render times.
This makes a visible difference to the latency when dragging windows in
Xorg, but will also help Wayland sessions on platforms lacking
TIMESTAMP_QUERY such as Raspberry Pi.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1441>
This replaces the DISPATCHED state with new sub-states that are possible
with triple buffering:
DISPATCHED_ONE: Double buffering
DISPATCHED_ONE_AND_SCHEDULED: Scheduled switch to triple buffering
DISPATCHED_ONE_AND_SCHEDULED_NOW: Scheduled switch to triple buffering
DISPATCHED_ONE_AND_SCHEDULED_LATER: Scheduled switch to triple buffering
DISPATCHED_TWO: Triple buffering
Triple buffering is currently disabled until the test cases get updated to
handle it in the next commit.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1441>
Chronologically they already overlap in time as presentation may
complete in the middle of the dispatch function, otherwise they are
contiguous in time. And most switch statements treated the two states
the same already so they're easy to merge into a single `DISPATCHED`
state.
Having fewer states now will make life easier when we add more states
later.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1441>
Error diffusion was introduced in 0555a5bbc15 for Nvidia where last
presentation time is always unknown (zero). Dispatch times would drift
apart always being a fraction of a frame late, and accumulated to cause
periodic frame skips. So error diffusion corrected that precisely and
avoided the skips.
That works great with double buffering but less great with triple
buffering. It's certainly still needed with triple buffering but
correcting for a lateness of many milliseconds isn't a good idea. That's
because a dispatch being that late is not due to main loop jitter but due
to Nvidia's swap buffers blocking when the queue is full. So scheduling
the next frame even earlier using last_dispatch_lateness_us would just
perpetuate the problem of swap buffers blocking for too long.
So now we lower the threshold of when error diffusion gets disabled. It's
still high enough to fix the original smoothness problem it was for, but
now low enough to detect Nvidia's occasionally blocking swaps and backs
off in that case.
Since the average duration of a blocking swap is half a frame interval
and we want to distinguish between that and sub-millisecond jitter, the
logical threshold is halfway again: refresh_interval_us/4.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1441>
It's not a single-element-tuple but something we can iterate and
produces strings.
Also ignore typing for the requests module because we'd have to install
more things for it to be available.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4267>
If there are any in-progress transitions on any properties of the
effect, these will cause a crash next time they tick and update, as they
will try to access a `@effects.${effect_name}.${property_name}` property
on the `ClutterActor` which no longer resolves to an effect. In some
cases this will be because `priv->effects` itself is now `NULL` on the
`ClutterActor`.
This can be triggered by rapidly toggling screen time limits on and off
in gnome-shell with a low screen time limit which has already been
reached for the day. It will alternately add a desaturation effect and
fade-in transition, then remove the effect, then the transition will
update and crash.
Avoid this by removing relevant transitions when removing an effect.
Do the same for the other two groups of metas: constraints and actions,
as they will be subject to the same bug (under different reproducer
conditions). And the same for when any of these three meta groups are
cleared, as that could also trigger the same bug.
Signed-off-by: Philip Withnall <pwithnall@gnome.org>
Closes: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/8168
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4222>
Currently, this has been living in StWidget, moving that to Clutter
allows us to properly track the accessibility state changes in the
actors provided inside Clutter as well as simplifying things for a
future move from Atk.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4089>
This is intended to allow being notified about a stage update happening,
but painting didn't happen. This is possible today by using other
signals and keeping track of painting happened, but it saves us some
state tracking by just being told so.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4067>
In this scenario:
1. Only an "empty" content update (which results in no visible output
change) from client A arrives before the frame deadline, so a frame
event is sent for that at the deadline.
2. Another "empty" content update from client A results in a frame event
being scheduled for the next frame deadline.
3. A non-"empty" content update from client B arrives before start of
vblank, and the resulting output frame manages to hit the next
display refresh cycle.
The result was that the frame events from steps 1+2 were sent during the
same display refresh cycle, so the frame rate reported by client A was
higher than the display refresh rate.
This change fixes that, at the cost of frame events being sent out
later in the display refresh cycle if there's no new frame for the
next cycle.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/3559
Fixes: 8f27ebf87eee ("clutter/frame-clock: Start next update ASAP after idle period")
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3878>
Allow creating a queue of future times to tick at. This adds a new clock
state where we let the clock go idle, but will wake at a time in the
future to tick.
We can still schedule ticks while in this new state, but we're assured a
tick at or shortly after the scheduled time.
This will be used later by wayland code that schedules future presentation.
Signed-off-by: Derek Foreman <derek.foreman@collabora.com>
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/3355>
Allowing to disable font rendering integration, making it possible to
build Mutter without pango/harfbuzz/fribidi dependencies.
This commit also adds a new clutter-pango header that is used to include
pango specific bits.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4106>
There is no real need to re-create a new cairo_font_options_t now that
the API is internal. Instead, create the font_options once and just
update it attributes.
Actors already register for the emitted font-changed signal to re-create
a new PangoContext.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4106>
When the `org.gnome.desktop.interface` schema is not found, currently
we were not initializing the font_options which means we needed to
handle that on the backend side. Instead, generate the font_options at
that moment.
As the settings are loaded the moment we assign a backend to the
settings `_clutter_settings_set_backend` which is called just after the
backend is constructed which is too early for any actor to use it for
creating a PangoContext, so the change is safe.
Also, as the font_options getter is only used in ClutterActor when
creating the PangoContext, drop the getter. As we might just store that
info somewhere else in the future.
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/4106>