When picking which frame clock to use, we traverse up in the actor
hierarchy until a suitable frame clock is found. ClutterTimeline
also listens to the 'stage-views-changed' to make sure it's always
attached to the correct frame clock.
However, there is one special situation where neither of them would
work: when the stage doesn't have a frame clock yet, and the actor
of the timeline is outside any stage view. When that happens, the
returned frame clock is NULL, and 'stage-views-changed' is never
emitted by the actor.
Monitor the stage for stage view changes when the frame clock is
NULL.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
An actor may be placed without being on any current stage view; in this
case, to get the ball rolling, walk up the actor tree to find the first
actor where a frame clock can be picked from.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
The frame clock owner should be able to explicitly destroy (i.e. make
defunct) a frame clock, e.g. when a stage view is destructed. This is so
that other objects can keep reference to its without it being left
around even after stopped being usable.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
Replace the default master clock with multiple frame clocks, each
driving its own stage view. As each stage view represents one CRTC, this
means we draw each CRTC with its own designated frame clock,
disconnected from all the others.
For example this means we when using the native backend will never need
to wait for one monitor to vsync before painting another, so e.g. having
a 144 Hz monitor next to a 60 Hz monitor, things including both Wayland
and X11 applications and shell UI will be able to render at the
corresponding monitor refresh rate.
This also changes a warning about missed frames when sending
_NETWM_FRAME_TIMINGS messages to a debug log entry, as it's expected
that we'll start missing frames e.g. when a X11 window (via Xwayland) is
exclusively within a stage view that was not painted, while another one
was, still increasing the global frame clock.
Addititonally, this also requires the X11 window actor to schedule
timeouts for _NET_WM_FRAME_DRAWN/_NET_WM_FRAME_TIMINGS event emitting,
if the actor wasn't on any stage views, as now we'll only get the frame
callbacks on actors when they actually were painted, while in the past,
we'd invoke that vfunc when anything was painted.
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/903
Closes: https://gitlab.gnome.org/GNOME/mutter/-/issues/3https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
We'd emit multiple "presented" signals per frame, one for "sync" and one
for "completion". Only the latter were ever used, and removing the
differentiation eases the avoidance of cogl onscreen framebuffer frame
callback details leaking into clutter.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
Right now the stage only had a signal called 'after-paint' which was not
tied to painting but updating. Change this to offer 4 signals, for the 4
different stages:
* before-update - emitted in the beginning before the actual stage
updating
* before-paint - emitted before painting if there will be any stage
painting
* after-paint - emitted after painting if there was any stage painting
* after-update - emitted as a last step of updating, no matter whether
there were any painting or not
Currently there were only one listener, that should only really have
been called if there was any painting, so no changes to listeners are
needed.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
The mutexes was used by ClutterTexture's async upload and to match GDK's
mutexes on X11. GDK's X11 connection does not share anything with
Clutter's, we don't have the Gdk Clutter backend left, and we have
already removed ClutterTexture, so lets remove these mutexes as well.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
A frame clock dispatch doesn't necessarily result in a frame drawn,
meaning we'll end up in the idle state. However, it may be the case that
something still requires another frame, and will in that case have
requested one to be scheduled. In order to not dead lock, try to
reschedule directly if requested after dispatching, if we ended up in
the idle state.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
The frame clock wouldn't be useable yet, but none the less, add API to
get the frame clock best suited for driving the actor. Currently this
translates to the fastest one, but that might change.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
The frame clock is meant to eventually drive the painting of the view,
in contrast to the master frame clock painting every view on the stage.
Right now it's a useless place holder.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
The native backend had a plain counter, and the X11 backend used the
CoglOnscreen of the screen; change it into a plain counter in
ClutterStageCogl. This also moves the global frame count setting to the
frame info constuctor.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
We currently have mutter set a global frame counter on the frame info in
the native backend, but in order to do this from clutter, change the
frame info construction from being implicitly done so when swapping
buffers to having the caller create the frame info and passing that to
the swap buffers call.
While this commit doesn't introduce any other changes than the API, the
intention is later to have the caller be able to pass it's own state
(e.g. the global frame count) along with the frame info.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
We had time unit conversion helpers (e.g. us2ms(), ns2us(), etc) in
multiple places. Clean that up by moving them all to a common file. That
file is clutter-private.h, as it's accessible by both from clutter/ and
src/.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
Currently unused, but it's intention is to use as a initial refresh rate
for a with the stage view associated frame clock. It defaults to 60 Hz
if nothing sets it, but the native backend sets it to the associated
CRTCs current mode's refresh rate.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
Without an associated actor, or explicit frame clock set, in the future
a timeline will not know how to progress, as there will be no singe
frame clock to assume is the main one. Thus, deprecate the construction
of timelines without either an actor or frame clock set.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
The association is inactive, as in it doesn't do anything yet, but it
will later be used to determine what frame clock should be driving the
timeline by looking at what stage view the actor is currently on.
This also adapts sub types (ClutterPropertyTransition) to have
constuctors that takes an actor just as the new ClutterTimeline
constructor.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
This is so something outside of clutter-stage.c (i.e.
clutter-stage-view.c) can eventually do various things
_clutter_stage_do_update() does now while not redrawing the whole stage.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
Devices are updated (repicked) as part of the stage update phase, as
their stacking, position and transform might have changed since since
the last update.
The redraw clip was used to avoid unnecessary updating of devices, if
the device in question had it's position outside of the redraw clip. If
the device coordinate was outside of the redraw clip, what was
underneith the device couldn't have changed.
What it failed to do, however, was to update devices if a relayout had
happened in the same update, as it checked the state whether a layout
had happened before attempting to do a relayout, effectively delaying
the device updating to the next update.
This commit changes the behavior to always update the device given the
complete redraw clip caused by all possible relayouts of the same update
as the device update happens in.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
We'd check if there was any queued redraw on the stage, but this is
inappropriate for two reasons:
1) A monitor and area screen cast source only cares about damage on a
subset of the stage.
2) The global pending-redraw is going away when paint scheduling will be
more view centric.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
This will allow anyone to finish any queued redraws making their
corresponding damage end up being posted to the stage views. This will
allow units to check whether, so far, any updates are queued on a
particular stage view.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
Add API to add and remove ClutterTimeline objects to the frame clock.
Just as the legacy master clock, having a timeline added to the frame
clock causes the frame clock to continuously reschedule updates until
the timeline is removed.
ClutterTimeline is adapted to be able to be driven by a
ClutterFrameClock. This is done by adding a 'frame-clock' property, and
if set, the timeline will add and remove itself to the frame clock
instead of the master clock.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
The timestamp comes from the GSource, meaning it's a more accurate
representation of when the frame started to be dispatched compared to
getting the current time in any callback.
Currently unused.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
In certain scenarios, the frame clock needs to handle present feedback
long before the assumed presentation time happens. To avoid scheduling
the next frame to soon, avoid scheduling one if we were presented half a
frame interval within the last expected presentation time.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
This adds a current unused, apart from tests, frame clock. It just
reschedules given a refresh rate, based on presentation time feedback.
The aiming for it is to be used with a single frame listener (stage
views) that will notify when a frame is presented. It does not aim to
handle multiple frame listeners, instead, it's assumed that different
frame listeners will use their own frame clocks.
Also add a test that verifies that the basic functionality works.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1285
When a transition is created for the allocation change, it will delay
the new allocation box getting set depending on transition details.
This, however, means that e.g. the 'needs_allocation' flag never gets
cleared if a transition is created, causing other parts of the code to
get confused thinking it didn't pass through a layout step before paint.
Fix this by calling clutter_actor_allocate_internal() with the current
allocation box if a transition was created, so that we'll properly clear
'needs_allocation' flag.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1345