While the layout manager of a ClutterActor does get properly unset when
destroying an actor, we currently forget to disconnect the
"layout-changed" signal from it.
So do that, and while at it, also switch to using the signal id for
disconnecting from the signal instead of
g_signal_handlers_disconnect_by_func(), which caused problems before
because it might traverse the signal handler list.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1281
We currently are confusing g_param_spec_enum and g_param_spec_flags for
the offscreen-redirect property of ClutterActor. Since it's actually a
flag, make it a flag everywhere.
Fun fact: This was already partly done with
d7814cf63eab1cf95625b06face9f914133d7eaa, but that commit missed the
setter.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1292
For actors which don't have needs_allocation set to TRUE and where the
new allocation wouldn't be different from the old one, the allocate()
vfunc doesn't have to be called. We still did this in case a parent
actor was moved though (so the absolute origin changed), because we
needed to propagate the ABSOLUTE_ORIGIN_CHANGED allocation flag down to
all actors.
Since that flag is now removed and got replaced with a private property,
we can simply notify the children about the absolute allocation change
using the existing infrastructure and safely stop allocating children at
this point.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1247
With commit 0eab73dc2e we introduced an optimization of not doing
allocations for actors which are hidden. This broke the propagation of
absolute origin changes to hidden actors, so if an actor is moved while
its child is hidden, the child will not get
priv->needs_compute_resource_scale set to TRUE, which means the resource
scale won't be updated when the child gets mapped and shown again.
Since we now have priv->absolute_origin_changed, we can simply check
whether that is TRUE for our parent before bailing out of
clutter_actor_allocate() and if it is, notify the whole hidden sub-tree
about the absolute origin change.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1247
When manipulating the allocation of a ClutterActor from an allocate()
vfunc override, clutter_actor_set_allocation() is used to let Clutter
know about the changes.
If the actors allocation or its absolute origin did not change before
that, this can also affect the actors absolute_origin_changed property
used by the children to detect changes to their absolute position.
So fix this bug (which luckily didn't seem to affect us so far) and set
priv->absolute_origin_changed to TRUE in case the origin changes inside
clutter_actor_set_allocation_internal(). Since this function is always
called when our allocation changes, we no longer need to update
absolute_origin_changed in clutter_actor_allocate() now.
Since a change to the absolute origin always affects the resource scale,
too, we also need to move that check from clutter_actor_allocate() here
to make sure we update the resource scale.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1247
Since the introduction of the shallow relayout functionality it's
possible to start an allocation cycle at any point in the tree, not only
at the stage. Now when starting an allocation at an actor that's not the
stage, we'd still look at the absolute_origin_changed property of this
actors parent, which might still be set to TRUE from the parents last
allocation.
So avoid using the parents absolute_origin_changed property from the
last allocation in case a shallow relayout is being done and always
reset the absolute_origin_changed property to FALSE after the allocation
cycle.
This broke with the removal of the ABSOLUTE_ORIGIN_CHANGED
ClutterAllocationFlag that was done in commit dc8e5c7f.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1247
All existing users of clutter_actor_has_mapped_clones() actually want to
know whether the actor is being cloned by a visible clone, it doesn't
matter to them if that clone is attached to an actor somewhere else in
the tree or to the actor itself.
So make clutter_actor_has_mapped_clones() a bit more convenient to use
and also check the clones of the parent-actors in that function.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1235
The comment in _clutter_actor_get_allocation_clip() explicitely notices
that it doesn't need the behavior of doing an immediate relayout as
clutter_actor_get_allocation_box() does. The comment is also still valid
since the code calling _clutter_actor_get_allocation_clip() checks for
priv->needs_allocation just before.
So let's just use the allocation directly here instead of going through
that function.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1264
The ABSOLUTE_ORIGIN_CHANGED allocation flag is only really useful to
propagate the information of the absolute origin of an actor having
changed inside Clutter. It wasn't used anywhere else besides for some
debug messages and it probably shouldn't be used in custom layout
implementations anyway since 1) actors shouldn't have to be aware of
absolute allocation changes and 2) it doesn't factor in changes to the
transformation matrix of a parent.
Also the propagation of absolute origin changes using this flag broke
with commit 0eab73dc2e and now hidden actors are no longer notified
about those changes.
Additionally, this flag gets in the way of a few potential optimizations
since it has to be propagated even if the allocation box of the child
hasn't changed, forcing a reallocation of the child.
So replace this flag with a simple new private property of ClutterActor
absolute_origin_changed, but keep the exact same behavior for now.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1245
Since we now only layout the children ourselves in case the actor
implementation doesn't override the allocate vfunc, we can remove
clutter_actor_maybe_layout_children() and move the functionality inside
clutter_actor_real_allocate().
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1245
Now that we no longer have the DELEGATE_LAYOUT we expect all actors
overriding the allocate() vfunc to allocate their children themselves.
Since clutter_actor_set_allocation() is only called from custom
vfunc_allocate() implementations, the condition in
clutter_actor_maybe_layout_children() would always fail, which makes
calling the function useless anyway.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1245
The CLUTTER_DELEGATE_LAYOUT flag is unintuitive and makes the allocation
process inside Clutter unnecessarily complicated. It's very easy for
actors overriding the allocate() vfunc to layout their children
themselves (in fact most of them do this), and it also never made sense
that clutter_actor_set_allocation() does eventually layout children.
There was no ClutterActor implementation in mutter or gnome-shell which
actually used the DELEGATE_LAYOUT flag, but even without it, it's fairly
easy to archive the same behavior now: In the allocate() override,
adjust the allocation as wanted, then chain up to the parent vfunc
without calling clutter_actor_set_allocation().
So remove the CLUTTER_DELEGATE_LAYOUT flag, which will allow making the
relayout code in Clutter a bit easier to follow.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1245
The public API to get the parent actor, clutter_actor_get_parent() does
a type check whether the actor is actually a ClutterActor. In case of
_clutter_actor_apply_relative_transformation_matrix(), which is called
recursively and very often during the paint process, this type check
shows up with almost twice the amount of hits than the actual matrix
multiplication.
So use the parent pointer directly in some code paths that are executed
very often and avoid the expensive type checking there, we can do that
since both places are not public API.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1259
The CLUTTER_ACTOR_IN_REPARENT and the CLUTTER_IN_REPARENT flag are never
set and the logic for skipping unmap, unrealize and the emission of the
"parent-set" signal during reparents has been solved differently by
leaving out the CHECK_STATE and EMIT_PARENT_SET flags when calling
add_child_internal() and remove_child_internal().
The only place where those REPARENT flags are theoretically still useful
is in the clutter_actor_verify_map_state() debugging function, but that
is never called during reparent anyway, so simply leave the comment
regarding reparent there.
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1228
Transitions are used for animating actors when e.g. going from/to
fullscreen, and the like. We need to know such things when deciding
whether to avoid compositing a window actor, so make add API visible to
mutter that checks whether there are any transitions active.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/798
When selecting the pick regions for an actor we were not considering
whether the actor was allocated and that was causing issues where the
preferred width/height of the actor was used when deciding whether
the actor should be considered as a pick target.
Check if the actor has a valid allocation, in addition to being mapped
and being in pick mode, in clutter_actor_should_pick_paint().
https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1169
When calculating the resource scale of a clone source, we might end up
in situations where we fail to do so, even though we're in a paint. A
real world example when this may happen if this happens:
* A client creates a toplevel window
* A client creates a modal dialog for said toplevel window
* Said client commits a buffer to the modal before the toplevel
If GNOME Shell is in overview mode, the window group is hidden, and the
toplevel window actor is hidden. When the clone tries to paint, it fails
to calculate the resource scale, as the parent of the parent (window
group) is not currently mapped. It would have succeeded if only the
clone source was unmapped, as it deals with the unmapped actor painting
by setting intermediate state while painting, but this does not work
when the *parent* of the source is unmapped as well.
Fix this by inheriting the unmapped clone paint even when calculating
the resource scale.
This also adds a test case that mimics the sequence of events otherwise
triggered by a client. We can't add a Wayland client to test this, where
we actually crash is in the offscreen redirect effect used by the window
dimming feature in GNOME Shell.
Fixes: https://gitlab.gnome.org/GNOME/mutter/-/issues/808https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1147
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
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
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
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
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
Instead of using the intermediate stage state "active framebuffer" to
find the framebuffer a paint eventually targets, use the "base
framebuffer" of the paint context, as this more correctly corresponds to
the end point of a paint. It also means we can then later remove this
intermediate state from the stage.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/935
Instead of pushing and popping the Cogl framebuffer stack, use the
framebuffer passed around using the pick context. This removes usage of
the deprecated framebuffer stack when picking.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/935
Rendering off stage we never cull, and previously this was checked by
comparing the "active framebuffer" of the stage, to the current
framebuffer in the cogl stack. Replace this by checking whether the
current paint context is currently drawing on stage or not.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/935
Just as with painting, add a pick context that carries pick related
temporary state when doing actor picking. It is currently unused, and
will at least at first still carry around a framebuffer to deal track
view transforms etc.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/935
When painting, actors rely on semi global state tracked by the state to
get various things needed for painting, such as the current draw
framebuffer. Having state hidden in such ways can be very deceiving as
it's hard to follow changes spread out, and adding more and more state
that should be tracked during a paint gets annoying as they will not
change in isolation but one by one in their own places. To do this
better, introduce a paint context that is passed along in paint calls
that contains the necessary state needed during painting.
The paint context implements a framebuffer stack just as Cogl works,
which is currently needed for offscreen rendering used by clutter.
The same context is passed around for paint nodes, contents and effects
as well.
In this commit, the context is only introduced, but not used. It aims to
replace the Cogl framebuffer stack, and will allow actors to know what
view it is currently painted on.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/935
This is inspired by 98892391d764d1cf where the usage of
`g_signal_handler_disconnect()` without resetting the corresponding
handler id later resulted in a bug. Using `g_clear_signal_handler()`
makes sure we avoid similar bugs and is almost always the better
alternative. We use it for new code, let's clean up the old code to
also use it.
A further benefit is that it can get called even if the passed id is
0, allowing us to remove a lot of now unnessecary checks, and the fact
that `g_clear_signal_handler()` checks for the right type size, forcing us
to clean up all places where we used `guint` instead of `gulong`.
No functional changes intended here and all changes should be trivial,
thus bundled in one big commit.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/940
Clutter has a draw debug mode that allows for painting
paint volumes. Right now, this debug mode uses the old
immediate paint mode.
Switch the painting of paint volumes to use paint nodes,
and sneak a few minor style cleanups.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/890
Now that we unconditionally use ClutterActorNode to
paint ClutterActors, move the PAINT private flag to
the ClutterActorNode. This way, we can run the paint
on the actor anywhere inside the paint tree.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/890
When setting the root node as child of a clip or transform node, we add a
new reference to it, without removing the one that we've previously added
when getting it from the actor node (and that won't ever be unset by the
auto-pointer since the root_node is re-associated).
So, once we add the root node as child and re-define it, unref it.
Fixes https://gitlab.gnome.org/GNOME/mutter/issues/908
A compositor is notably opaque (usually has nothing to be painted on!).
gnome-shell sets this hint, but there's no reason why we wouldn't want
it by default.
Also, the color buffer being cleared messes with stencil clips, as the
clear operation by definition ignores the stencil buffer. We want to
use these more extensively in the future, so just drop this API.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/911
Make ClutterActor paint using ClutterTransformNode, ClutterClip
node, and ClutterActorNode. Essencially, the actor node is a
replacement for clutter_actor_continue_paint().
An interesting aspect of this commit is that the order of the
operations is reversed to be preserved.
Before being able to remove the dummy node hack, we'll need to
make ClutterEffects compatible with paint nodes first -- and
naturally, that's enough content for its own merge request.
https://gitlab.gnome.org/GNOME/mutter/merge_requests/872