Add a helper that scales and clamps a region, aimed to be used when
transforming between framebuffer coordinate space and view coordinate
spaces.
This helps readability by moving out the verbose for loops that deals
with the individual rects of a region to the helper, making the logic
where it's used much simpler.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
The 'have_clip' variable has repeatedly confused me to meaning that
there is a clip. What it actually means is that the effective clip
covers the whole view; the 'redraw_clip == NULL' meaning full redraw is
an important implementation detail for the context, and makes the
intention of the variable unclear; especially since we will after a
couple of blocks will *always* have a clip, just that it covers the
whole view.
Rename the variable to 'is_full_redraw' and negate the meaning, aiming
to make things a lot more clear.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
When calculating the fallback framebuffer clip region, which should be
the region in framebuffer coordinates, we didn't scale the view layout
with the view framebuffer scale, meaning for any other scale than 1,
we'd draw a too small region of the view. Fix this by just using the
size of the framebuffer directly, avoiding any scale dependent
calculation all together.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
We'll expect a swap event if any of the view paints resulted in a swap;
make the logic dealing with this clearer by making changing the less
vilible '|| swap_event' postfix with a up front '|=' operator.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1042
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
This only needs to be initialized once but is in the hot path of creating
new paint nodes (for which we create many). Instead, do this as part of
the clutter_init() workflow to keep it out of the hot path.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1087
When calculating regions, a lot of temporary allocations are created. For
the array of rects (which is often a short number of them) we can use
stack allocations up to 1 page (256 cairo_rectangle_int_t). For building
a region of rectangles, cairo and pixman are much faster if you have all
of the rectangles up front or else it mallocs quite a bit of temporary
memory.
If we re-use the cairo_rectangle_int_t array we've already allocated (and
preferably on the stack), we can delay the creation of regions until after
the tight loop.
Additionally, it requires fewer allocations to union two cairo_region_t
than to incrementally union the rectangles into the region.
Before (percentages are of total number of allocations)
TOTAL FUNCTION
[ 100.00%] [Everything]
[ 100.00%] [gnome-shell --wayland --display-server]
[ 99.67%] _start
[ 99.67%] __libc_start_main
[ 99.67%] main
[ 98.60%] meta_run
[ 96.90%] g_main_loop_run
[ 96.90%] g_main_context_iterate.isra.0
[ 96.90%] g_main_context_dispatch
[ 90.27%] clutter_clock_dispatch
[ 86.54%] _clutter_stage_do_update
[ 85.00%] clutter_stage_cogl_redraw
[ 84.98%] clutter_stage_cogl_redraw_view
[ 81.09%] cairo_region_union_rectangle
After (overhead has much dropped)
TOTAL FUNCTION
[ 100.00%] [Everything]
[ 99.80%] [gnome-shell --wayland --display-server]
[ 99.48%] _start
[ 99.48%] __libc_start_main
[ 99.48%] main
[ 92.37%] meta_run
[ 81.49%] g_main_loop_run
[ 81.49%] g_main_context_iterate.isra.0
[ 81.43%] g_main_context_dispatch
[ 39.40%] clutter_clock_dispatch
[ 26.93%] _clutter_stage_do_update
[ 25.80%] clutter_stage_cogl_redraw
[ 25.60%] clutter_stage_cogl_redraw_view
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1071
g_signal_emit_by_name() is used to emit signals on ClutterContainer when
actors are removed or added. It happens to do various interface lookups
which are a bit unneccessary and can allocate memory.
Simply using emission wrappers makes all of that go away.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1083
Add API to ClutterSeat that allows inhibiting the unsetting of the
pointer focus surface. This can be useful for drawing custom cursor
textures like the magnifier of gnome-shell does.
In the future this API should also control unsetting of Clutters
focus-actor, not just the focus surface, that's not really needed right
now since we never unset the focus-actor anyway.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1077
Which offscreens actor rendering only in cases where it hasn't changed for
2 frames or more. This avoids the performance penalty of offscreening an
actor whose content is trying to animate at full frame rate. It will
switch automatically.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1069
If the transform matrix is an identity, then positioning wont change and
we can avoid creating the transform node altogether. This is based on
a similar find in GTK today while reducing temporary allocations.
This cuts the number of transforms created in clutter_actor_paint() by
about half under light testing of GNOME Shell from 6.8% to 2.4% of
allocations.
Before:
ALLOCATED TOTAL FUNCTION
[ 20.4 MiB] [ 21.20%] clutter_actor_paint
[ 11.0 MiB] [ 11.45%] clutter_paint_node_paint
[ 6.6 MiB] [ 6.84%] clutter_transform_node_new
[ 2.5 MiB] [ 2.61%] clutter_actor_node_new
After:
ALLOCATED TOTAL FUNCTION
[ 33.4 MiB] [ 24.12%] clutter_actor_paint
[ 26.2 MiB] [ 18.91%] clutter_paint_node_paint
[ 3.4 MiB] [ 2.43%] clutter_actor_node_new
[ 3.3 MiB] [ 2.41%] clutter_transform_node_new
Allocation amounts will have differed due to different amounts of running
time, but the % of allocations has now dropped below
clutter_actor_node_new() which should be expected.
https://gitlab.gnome.org/GNOME/mutter/issues/1056
And the corresponding getter. This property returns FALSE by default
and must be overridden by subclasses. This will allow gnome-shell to
hook up specific behavior that should not happen on mouse+keyboard
setups.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1044
If an actor sets flag `CLUTTER_ACTOR_NO_LAYOUT` then that means it
is (or should be) unaffected by `queue_relayout` calls in its children.
So we can avoid propagating `queue_relayout` all the way up to the stage
and avoid a full stage relayout each time.
But those children whose parent has `CLUTTER_ACTOR_NO_LAYOUT` still need
to be allocated at some point. So we do it at the same point where it
happened before. Only we now queue a *shallow* relayout so the `allocate`
run on the next frame doesn't need to descend the whole actor tree anymore.
Only a subtree and hopefully very small.
For free-floating and top-level actors this provides a measurable
performance benefit. According to Google Profiler, calls to
`_clutter_stage_maybe_relayout` are now so cheap that they no longer show
up in performance profiles.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/575
The private function `_clutter_input_device_update()` is not currently
exported.
This function calls `_clutter_input_device_set_actor()` which updates
the `ClutterActor` under the pointer, so making that function available
outside of Clutter will allow to make sure the pointer device actor is
updated prior to do picking.
Also, now that the functions is exported to the upper layers, drop the
underscore suffix from the function name.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1026
Right now the CONTENT_SIZE request mode for a ClutterActor is only
respected by `clutter_actor_get_preferred_size()`, but not by
`get_preferred_width()` and `get_preferred_height()`. Those simply try
to ask the layout manager and will return [0, 0] for actors without
children. So be consistent and also return the content size in those two
functions.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1019
As recommended by the docs for `g_settings_schema_source_get_default`:
> The returned source may actually consist of multiple schema sources
> from different directories, depending on which directories were given
> in XDG_DATA_DIRS and GSETTINGS_SCHEMA_DIR. For this reason, all lookups
> performed against the default source should probably be done recursively.
Now it's actually found and works again, including subpixel font smoothing.
Closes: https://gitlab.gnome.org/GNOME/gnome-shell/issues/1447https://gitlab.gnome.org/GNOME/mutter/merge_requests/1017
ClutterActors width and height can be reset to automatically use the
preferred (calculated) value by setting the width or height to -1, so
far this only works by setting it using `clutter_actor_set_width()` or
`clutter_actor_set_height()`, make sure it can also be done using the
"width" and "height" GObject properties.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/1018
Some ClutterOffscreenEffect subclasses, such as ClutterBrightnessContrastEffect,
early-return FALSE in pre-paint before chaining up. It's an important optimization
that avoids creating or updating the offscreen framebuffer.
However, if an offscreen framebuffer already exists by the time pre-paint fails,
it will be used *without* repaint the actor over it. That causes an old picture
of the actor to be displayed.
Fix that by always clearing the offscreen framebuffer when pre-paint fails.
Fixes https://gitlab.gnome.org/GNOME/mutter/issues/810https://gitlab.gnome.org/GNOME/mutter/merge_requests/992
When changing the 'enabled' property and disabling the offscreen effect,
it doesn't make sense to preserve the offscreen framebuffer. It's not
drawing, after all.
Furthermore, because ClutterOffscreenEffect only checks if the offscreen
framebuffer exists to decide whether or not to redraw, keeping the fbo
alive is a waste of resources.
Clear the offscreen framebuffer when the effect is disabled or enabled.
Fixes https://gitlab.gnome.org/GNOME/mutter/issues/810https://gitlab.gnome.org/GNOME/mutter/merge_requests/992
FLT_MIN is the smallest *positive* number above 0 that can be
represented as floating point number. If this is used to initialize the
maximum x/y coordinates of a rectangle, this will always be used if all
x/y coordinates of the rectangle are negative. This means that picking
at 0,0 will always be a hit for such rectangles.
Since mutter creates such a window for server side decorations on X11,
this window will always be picked at 0,0 preventing clicking/hovering
the activities button in gnome-shell at that coordinate.
Fixes https://gitlab.gnome.org/GNOME/mutter/issues/893