Commit Graph

7679 Commits

Author SHA1 Message Date
Jonas Ådahl
8008f0b7b0 Explicitly create the clutter context and backend
This changes the setup phase of clutter to not be result of calling an
init function that sets up a few global singletons, via global singleton
setup vfuncs.

The way it worked was that mutter first did some initial setup
(connecting to the X11 server), then set a "custom backend" setup vfunc
global, before calling clutter_init().

During the clutter_init() call, the context and backend was setup by
calling the global singleton getters, which implicitly created the
backend and context on-demand.

This has now changed to mutter explicitly creating a `ClutterContext`
(which is actually a `ClutterMainContext`, but with the name shortened to
be consistent with `CoglContext` and `MetaContext`), calling it with a
backend constructor vfunc and user data pointer.

This function now explicitly creates the backend, without having to go
via the previously set global vfunc.

This changes the behavior of some "get_default()" like functions, which
will now fail if called after mutter has shut down, as when it does so,
it now destroys the backends and contexts, not only its own, but the
clutter ones too.

The "ownership" of the clutter backend is also moved to
`ClutterContext`, and MetaBackend is changed to fetch it via the clutter
context.

This also removed the unused option parsing that existed in clutter.

In some places, NULL checks for fetching the clutter context, or
backend, and fetching the cogl context from the clutter backend, had to
be added.

The reason for this is that some code that handles EGL contexts attempts
to restore the cogl EGL context tracking so that the right EGL context
is used by cogl the next time. This makes no sense to do before Cogl and
Clutter are even initialized, which was the case. It wasn't noticed
because the relevant singletons were initialized on demand via their
"getters".

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2002>
2021-10-18 14:36:15 +00:00
Jonas Ådahl
528ae91385 clutter: Remove option parsing support
For a long time we always passed NULL, lets take it one step further and
just remove all the options parsing stuff.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2002>
2021-10-18 14:36:15 +00:00
Sebastian Keller
3768efef2b clutter/offscreen-effect: Consider paint volumes at negative coordinates
When basing the offscreen texture position off the paint volume, the
code was assuming that the paint volume was always starting at 0,0 but
this is not the case if child widgets are placed at negative coordinates
or the widget itself is transformed. This could cause such widgets that
have been flattened and therefore rendered to an offscreen texture to
appear cut off in the top/left.

Related: https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/4561
Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1923
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2031>
2021-10-15 20:21:09 +00:00
Georges Basile Stavracas Neto
fbcb078513 clutter/container: Remove clutter_container_get_children
This one is a trivial wrapper around clutter_actor_get_children(), so just
use that in the two places where clutter_container_get_children() is used,
and remove clutter_container_get_children().

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2057>
2021-10-15 14:22:37 -03:00
Georges Basile Stavracas Neto
8d1105ae6c clutter/container: Remove clutter_container_raise_child
Also unused.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2057>
2021-10-15 14:22:37 -03:00
Georges Basile Stavracas Neto
d5dd8ebfa9 clutter: Remove clutter_container_lower_child
Also unused.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2057>
2021-10-15 14:22:37 -03:00
Georges Basile Stavracas Neto
1a978df4a7 clutter: Remove clutter_container_sort_depth_order
Unused.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2057>
2021-10-15 14:22:37 -03:00
Robert Mader
136caca5d5 clutter/stage: Only add paint volumes of mapped actors to stage clip
Right now we damage the stage even if an actor is not mapped, for
example in the overview.

Stop doing so, reducing over-paint significantly in some situations.
Clones will still do stage damage on their own.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2035>
2021-10-15 15:59:32 +00:00
Sebastian Keller
867db93043 clutter/text: Invalidate actor paint volume when it has changed
ClutterText implements its own get_paint_volume() with its own cache,
but was not invalidating the actor paint volume when when it has
changed. This sometimes could result in labels, especially quickly
changing ones, using the old paint volume which either would cut off the
label or leave parts of the old label on screen.

Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1943
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2006>
2021-10-06 20:16:09 +00:00
Corentin Noël
89a13b4557 clutter/stage: Remove inout from paint_to_buffer
Remove the (inout) annotation as we are only using the byte array directly and not
a pointer to the array.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/2026>
2021-09-29 09:56:20 +02:00
Jonas Ådahl
b10b77cc46 clutter/backend: Propagate error when initializing context
Any caught error message was silently dropped.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1994>
2021-09-20 16:37:37 +00:00
Michel Dänzer
62cdf8de5e clutter/stage: Remove clutter_stage_capture_into
Not used anymore.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1914>
2021-09-20 14:00:08 +00:00
Carlos Garnacho
f4a32cb7cd clutter: Forward button press/touch down onto ClutterText IM focus
So these can properly trigger reset of the IM.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1940>
2021-09-03 22:05:46 +00:00
Carlos Garnacho
765f41de80 clutter: Add ClutterPreeditResetMode hint to preedit text
This mode is passed along by the ClutterInputMethod, the
ClutterInputFocus will preserve it and ensure it is honored
whenever the IM is being reset.

This mode is immediate. The ClutterInputFocus commits the
text directly without queueing a CLUTTER_IM_COMMIT event.
This is important so events are serialized in the right order
in the wayland implementations (i.e. commit before wl_pointer.press).

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1940>
2021-09-03 22:05:46 +00:00
Carlos Garnacho
9c20b4144a clutter: Handle touch down and button press events in ClutterInputFocus
In line with GTK, the input method context should be reset when clicks
are handled by the ClutterInputFocus user. The reset action can then
either clear or commit the preedit text, as configured by the IM module.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1940>
2021-09-03 22:05:46 +00:00
Daniel van Vugt
da3ff9f6d0 clutter/frame-clock: Correct indentation
To resolve CI warnings.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1972>
2021-08-24 16:43:49 +08:00
Jonas Ådahl
18c414cca4 clutter/stage-view: Initialize view as damaged and awaiting frame
Make sure that when we've recreated views that we'll actually paint a
new frame for it. This was very rarely a problem, as views tend to
result in getting damage etc being queued as side effects of various
things, like layout, but e.g. when running certain tests, this might not
happen. There is no situation where we want to create a new view that
should remain unpainted, so just make sure we initialize it to become up
to date.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1947>
2021-08-22 17:06:53 +00:00
Ivan Molodetskikh
13a2a33257 clutter: Add clutter_stage_paint_to_content ()
Used in the new screenshot UI.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1899>
2021-08-22 12:44:38 +00:00
Florian Müllner
9252b7c6b4 clutter/text: Don't query preferred size without allocation
The size request functions query the resource scale, which hits
an assert if headless. The returned sizes are already only used
when clutter_actor_has_allocation() is true, so this doesn't
change the condition for calling either redraw or relayout.

https://gitlab.gnome.org/GNOME/gnome-shell/-/issues/4522

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1956>
2021-08-05 13:20:54 +02:00
Carlos Garnacho
a4c50ad123 clutter: Add COGL_HAS_TRACING checks around tracing code
This code sneaked unconditionally, even though we can disable
tracing code with -Dprofiler=false. Add some COGL_HAS_TRACING
checks so that this code is also optionally built.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1951>
2021-08-02 17:15:10 +02:00
Jonas Ådahl
6b1f49c153 clutter/actor: Optionally trace allocations
If 'detailed-trace' is enabled, trace the allocation of every actor every
frame, and pass along the type and name of the actor to sysprof.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1700>
2021-07-29 15:37:48 +02:00
Jonas Ådahl
5c7795dfa9 clutter/actor: Optionally trace painting
If 'detailed-trace' is enabled, trace the painting of every actor every
frame, and pass along the type and name of the actor to sysprof.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1700>
2021-07-29 15:37:29 +02:00
Jonas Ådahl
9d22e7153c clutter/actor: Sneakily remove the g from the debug names gchar
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1700>
2021-07-29 15:37:12 +02:00
Jonas Ådahl
6a0dd2a0fa clutter/actor: Always generate the same debug name
It's useful also for non-debug builds to have a more proper name for
actors, e.g. when tracing.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1700>
2021-07-29 15:37:12 +02:00
Jonas Ådahl
796eb005bc clutter/main: Add 'detailed-trace' debug flag
Will be used to trace a lot more, and with more details, and thus may
have a larger impact on what is actually measured. This potential impact
is the reason for enabling only when needed.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1700>
2021-07-29 15:37:12 +02:00
Jonas Ådahl
96b1ebb2fd clutter/layer-paint-node: Handle failure to allocate offscreen
The failure to allocate was not properly handled, causing crashes later
on due to the offscreen being NULL.

 #0  cogl_gl_framebuffer_bind (target=36160, gl_framebuffer=0x0)
 #1  _cogl_driver_gl_flush_framebuffer_state (...)
 #2  cogl_context_flush_framebuffer_state (read_buffer=0x55f48f386780, draw_buffer=0x55f48f386780, ...)
 #3  cogl_framebuffer_clear4f (framebuffer=0x55f48f386780, ...)
 #4  clutter_layer_node_pre_draw (...)
 #5  clutter_paint_node_paint (...)

...

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1942>
2021-07-29 11:16:21 +00:00
Jonas Ådahl
5e5c7fe1af clutter/layer-paint-node: Fix variable naming
It's elsewhere in the file referred to as lnode. No idea what "res"
means.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1942>
2021-07-29 11:16:21 +00:00
Carlos Garnacho
c80ef12c79 clutter: Remove unused EGL header
This just pulled cogl headers, so not very useful.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1862>
2021-07-16 19:08:06 +02:00
Carlos Garnacho
1f67e4650c clutter: Remove leftovers from backend code in build system
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1862>
2021-07-16 19:08:06 +02:00
Carlos Garnacho
229b52872e clutter: Drop generation of x11 pkgconfig file
This is no longer needed, at least from the Clutter API perspective.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1862>
2021-07-16 19:08:06 +02:00
Carlos Garnacho
dc6d3cead2 backends: Shuffle ClutterBackendX11 code into MetaClutterBackendX11
We have a Clutter implementation of the X11, just to subclass it in
our backends. Move the implementation entirely to src/backends/x11.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1862>
2021-07-16 19:08:06 +02:00
Carlos Garnacho
1e84c00d86 clutter: Drop dead X11 code
We don't use the ClutterBackendX11 direct constructor.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1862>
2021-07-16 19:08:06 +02:00
Carlos Garnacho
7fcc7a6edb clutter: Drop Xsettings client code
We only listen to it for 2 settings (drag threshold, double click
time), and we already have the stock ClutterSettings object tracking
the source of these. This code is redundant.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1862>
2021-07-16 19:08:06 +02:00
Carlos Garnacho
8f839b2f9c clutter: Move ClutterStageCogl[View] code to src/backends
This is now MetaStageImpl in backend code.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1862>
2021-07-16 19:08:06 +02:00
Carlos Garnacho
7712b58170 clutter: Export private function to get debug flags
We're shuffling some code into src/backends, that needs knowing
about these flags to minimize immediate refactors.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1862>
2021-07-16 19:08:06 +02:00
Carlos Garnacho
dd9d40aedb clutter: Make ClutterStageView API public to mutter
All subclasses and stage implementations will come from src/backends,
so this internal API must be accessible there.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1862>
2021-07-16 19:08:06 +02:00
Carlos Garnacho
5beba8b99b clutter: Make ClutterDamageHistory API public to mutter
We are moving things to src/backends, make this helper object able
to be used there. This is a temporary measure as ClutterDamageHistory
itself should be moved too.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1862>
2021-07-16 19:08:06 +02:00
Carlos Garnacho
c58909dc0f clutter: Demote CLUTTER_NOTE to g_debug in clutter-stage-cogl.c
This code is being shuffled out of Clutter code, so cut the ties with
it before doing that.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1862>
2021-07-16 19:08:06 +02:00
Jonas Ådahl
07384e18c5 clutter: Remove clutter_init_with_args()
Not used anymore.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1861>
2021-07-15 11:25:21 +02:00
Daniel van Vugt
0555a5bbc1 clutter/frame-clock: Apply error diffusion (dithering) to dispatch times
But only the dispatch times used when `last_presentation_time_us == 0`
(Nvidia + Xorg).

This ensures the average dispatch interval is always precisely equal
to the refresh interval, regardless of any jitter in the mainloop.

Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/1751,
       https://gitlab.gnome.org/GNOME/mutter/-/issues/1758,
       https://gitlab.gnome.org/GNOME/mutter/-/issues/1870

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1826>
2021-07-13 17:18:17 +08:00
Daniel van Vugt
ba1490ec9c clutter/frame-clock: Remember the refresh interval
Instead of recalculating it every time we need it. The performance
gain is not important; this is more because it will be needed in
multiple functions soon.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1826>
2021-07-13 17:18:14 +08:00
Ivan Molodetskikh
a5d1d48bf1 clutter: Add a max render time debug HUD
Not sure how to update the damage or redraw clip or something; at least
this works properly when under a constantly-redrawing window, which is
ok for debugging purposes.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1762>
2021-07-13 08:09:43 +00:00
Ivan Molodetskikh
f55c9af618 clutter: Add an lg command to set max render time constant
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1762>
2021-07-13 08:09:43 +00:00
Ivan Molodetskikh
565e34b4d2 clutter: Add a flag to disable heuristic max render time
Debugging purposes: allows to check if frame drops are caused by
heuristic max render time or if they are there even with the old
behavior.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1762>
2021-07-13 08:09:43 +00:00
Ivan Molodetskikh
592fbee065 clutter: Compute max render time heuristically
Max render time shows how early the frame clock needs to be dispatched
to make it to the predicted next presentation time. Before this commit
it was set to refresh interval minus 2 ms. This means Mutter would
always start compositing 14.7 ms before a display refresh on a 60 Hz
screen or 4.9 ms before a display refresh on a 144 Hz screen. However,
Mutter frequently does not need as much time to finish compositing and
submit buffer to KMS:

      max render time
      /------------\
---|---------------|---------------|---> presentations
      D----S          D--S

      D - frame clock dispatch
      S - buffer submission

This commit aims to automatically compute a shorter max render time to
make Mutter start compositing as late as possible (but still making it
in time for the presentation):

         max render time
             /-----\
---|---------------|---------------|---> presentations
             D----S          D--S

Why is this better? First of all, Mutter gets application contents to
draw at the time when compositing starts. If new application buffer
arrives after the compositing has started, but before the next
presentation, it won't make it on screen:

---|---------------|---------------|---> presentations
      D----S          D--S
        A-------------X----------->

                   ^ doesn't make it for this presentation

        A - application buffer commit
        X - application buffer sampled by Mutter

Here the application committed just a few ms too late and didn't make on
screen until the next presentation. If compositing starts later in the
frame cycle, applications can commit buffers closer to the presentation.
These buffers will be more up-to-date thereby reducing input latency.

---|---------------|---------------|---> presentations
             D----S          D--S
        A----X---->

                   ^ made it!

Moreover, applications are recommended to render their frames on frame
callbacks, which Mutter sends right after compositing is done. Since
this commit delays the compositing, it also reduces the latency for
applications drawing on frame callbacks. Compare:

---|---------------|---------------|---> presentations
      D----S          D--S
           F--A-------X----------->
              \____________________/
                     latency

---|---------------|---------------|---> presentations
             D----S          D--S
                  F--A-------X---->
                     \_____________/
                      less latency

           F - frame callback received, application starts rendering

So how do we actually estimate max render time? We want it to be as low
as possible, but still large enough so as not to miss any frames by
accident:

         max render time
             /-----\
---|---------------|---------------|---> presentations
             D------S------------->
                   oops, took a little too long

For a successful presentation, the frame needs to be submitted to KMS
and the GPU work must be completed before the vblank. This deadline can
be computed by subtracting the vblank duration (calculated from display
mode) from the predicted next presentation time.

We don't know how long compositing will take, and we also don't know how
long the GPU work will take, since clients can submit buffers with
unfinished GPU work. So we measure and estimate these values.

The frame clock dispatch can be split into two phases:
1. From start of the dispatch to all GPU commands being submitted (but
   not finished)—until the call to eglSwapBuffers().
2. From eglSwapBuffers() to submitting the buffer to KMS and to GPU
   work completing. These happen in parallel, and we want the latest of
   the two to be done before the vblank.

We measure these three durations and store them for the last 16 frames.
The estimate for each duration is a maximum of these last 16 durations.
Usually even taking just the last frame's durations as the estimates
works well enough, but I found that screen-capturing with OBS Studio
increases duration variability enough to cause frequent missed frames
when using that method. Taking a maximum of the last 16 frames smoothes
out this variability.

The durations are naturally quite variable and the estimates aren't
perfect. To take this into account, an additional constant 2 ms is added
to the max render time.

How does it perform in practice? On my desktop with 144 Hz monitors I
get a max render time of 4–5 ms instead of the default 4.9 ms (I had
1 ms manually configured in sway) and on my laptop with a 60 Hz screen I
get a max render time of 4.8–5.5 ms instead of the default 14.7 ms (I
had 5–6 ms manually configured in sway). Weston [1] went with a 7 ms
default.

The main downside is that if there's a sudden heavy batch of work in the
compositing, which would've made it in default 14.7 ms, but doesn't make
it in reduced 6 ms, there is a delayed frame which would otherwise not
be there. Arguably, this happens rarely enough to be a good trade-off
for reduced latency. One possible solution is a "next frame is expected
to be heavy" function which manually increases max render time for the
next frame. This would avoid this single dropped frame at the start of
complex animations.

[1]: https://www.collabora.com/about-us/blog/2015/02/12/weston-repaint-scheduling/

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1762>
2021-07-13 08:09:43 +00:00
Ivan Molodetskikh
4a4e61c1f1 clutter: Add FRAME_TIMINGS debug key
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1762>
2021-07-13 08:09:43 +00:00
Ivan Molodetskikh
8d51c5ac55 clutter/frame-clock: Store dispatch timings
Will be used to adjust max render time dynamically.

Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1762>
2021-07-13 08:09:43 +00:00
Ivan Molodetskikh
8c4a91ddd6 clutter: Add swap time and GPU rendering duration to FrameInfo
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1762>
2021-07-13 08:09:43 +00:00
Ivan Molodetskikh
8c258d1de1 cogl: Add CPU swap time and GPU rendering query to CoglFrameInfo
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1762>
2021-07-13 08:09:42 +00:00
Ivan Molodetskikh
3aa0e3074f clutter: Store vblank duration in ClutterFrameClock
Part-of: <https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1762>
2021-07-13 08:09:42 +00:00