clutter/stage: Set viewport without getting the last allocation

When getting the last allocation using
clutter_actor_get_allocation_box(), Clutter will do an immediate
relayout of the stage in case an actor has an invalid allocation. Since
the allocation is always invalid when the allocate() vfunc is called,
clutter_stage_allocate() always forces another allocation cycle.

To fix that, stop comparing the old allocation to the new one to find
out whether the viewport changed, but instead use the existing check in
_clutter_stage_set_viewport() and implement the behavior of rounding the
viewport to the nearest int using roundf() (which should behave just as
CLUTTER_NEARBYINT()) since we're passing around floats anyway.

https://gitlab.gnome.org/GNOME/mutter/-/merge_requests/1247
This commit is contained in:
Jonas Dreßler 2020-05-10 01:23:34 +02:00 committed by Jonas Ådahl
parent 0a37c32a72
commit 7abf0f1e2d

View File

@ -619,7 +619,6 @@ clutter_stage_allocate (ClutterActor *self,
{
ClutterStagePrivate *priv = CLUTTER_STAGE (self)->priv;
ClutterActorBox alloc = CLUTTER_ACTOR_BOX_INIT_ZERO;
float old_width, old_height;
float new_width, new_height;
float width, height;
cairo_rectangle_int_t window_size;
@ -628,10 +627,6 @@ clutter_stage_allocate (ClutterActor *self,
if (priv->impl == NULL)
return;
/* our old allocation */
clutter_actor_get_allocation_box (self, &alloc);
clutter_actor_box_get_size (&alloc, &old_width, &old_height);
/* the current allocation */
clutter_actor_box_get_size (box, &width, &height);
@ -719,27 +714,14 @@ clutter_stage_allocate (ClutterActor *self,
&override);
}
/* reset the viewport if the allocation effectively changed */
/* set the viewport to the new allocation */
clutter_actor_get_allocation_box (self, &alloc);
clutter_actor_box_get_size (&alloc, &new_width, &new_height);
if (CLUTTER_NEARBYINT (old_width) != CLUTTER_NEARBYINT (new_width) ||
CLUTTER_NEARBYINT (old_height) != CLUTTER_NEARBYINT (new_height))
{
int real_width = CLUTTER_NEARBYINT (new_width);
int real_height = CLUTTER_NEARBYINT (new_height);
_clutter_stage_set_viewport (CLUTTER_STAGE (self),
0, 0,
real_width,
real_height);
/* Note: we don't assume that set_viewport will queue a full redraw
* since it may bail-out early if something preemptively set the
* viewport before the stage was really allocated its new size.
*/
queue_full_redraw (CLUTTER_STAGE (self));
}
_clutter_stage_set_viewport (CLUTTER_STAGE (self),
0, 0,
new_width,
new_height);
}
typedef struct _Vector4
@ -2494,6 +2476,8 @@ _clutter_stage_set_viewport (ClutterStage *stage,
priv = stage->priv;
width = roundf (width);
height = roundf (height);
if (x == priv->viewport[0] &&
y == priv->viewport[1] &&