mirror of
https://github.com/brl/mutter.git
synced 2024-12-25 12:32:05 +00:00
stage: make it possible to queue a relayout only
This adds a private ->relayout_pending boolean similar in spirit to redraw_pending. This will allow us to queue a relayout without implicitly queueing a redraw; instead we can depend on the actions of a relayout to queue any necessary redraw.
This commit is contained in:
parent
f8a6e36f1b
commit
6d5f6449dd
@ -225,47 +225,6 @@ clutter_get_accessibility_enabled (void)
|
|||||||
return cally_get_cally_initialized ();
|
return cally_get_cally_initialized ();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void
|
|
||||||
_clutter_stage_maybe_relayout (ClutterActor *stage)
|
|
||||||
{
|
|
||||||
gfloat natural_width, natural_height;
|
|
||||||
ClutterActorBox box = { 0, };
|
|
||||||
CLUTTER_STATIC_TIMER (relayout_timer,
|
|
||||||
"Mainloop", /* no parent */
|
|
||||||
"Layouting",
|
|
||||||
"The time spent reallocating the stage",
|
|
||||||
0 /* no application private data */);
|
|
||||||
|
|
||||||
/* avoid reentrancy */
|
|
||||||
if (!CLUTTER_ACTOR_IN_RELAYOUT (stage))
|
|
||||||
{
|
|
||||||
CLUTTER_TIMER_START (_clutter_uprof_context, relayout_timer);
|
|
||||||
CLUTTER_NOTE (ACTOR, "Recomputing layout");
|
|
||||||
|
|
||||||
CLUTTER_SET_PRIVATE_FLAGS (stage, CLUTTER_IN_RELAYOUT);
|
|
||||||
|
|
||||||
natural_width = natural_height = 0;
|
|
||||||
clutter_actor_get_preferred_size (stage,
|
|
||||||
NULL, NULL,
|
|
||||||
&natural_width, &natural_height);
|
|
||||||
|
|
||||||
box.x1 = 0;
|
|
||||||
box.y1 = 0;
|
|
||||||
box.x2 = natural_width;
|
|
||||||
box.y2 = natural_height;
|
|
||||||
|
|
||||||
CLUTTER_NOTE (ACTOR, "Allocating (0, 0 - %d, %d) for the stage",
|
|
||||||
(int) natural_width,
|
|
||||||
(int) natural_height);
|
|
||||||
|
|
||||||
clutter_actor_allocate (stage, &box, CLUTTER_ALLOCATION_NONE);
|
|
||||||
|
|
||||||
CLUTTER_UNSET_PRIVATE_FLAGS (stage, CLUTTER_IN_RELAYOUT);
|
|
||||||
CLUTTER_TIMER_STOP (_clutter_uprof_context, relayout_timer);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void
|
void
|
||||||
_clutter_do_redraw (ClutterStage *stage)
|
_clutter_do_redraw (ClutterStage *stage)
|
||||||
{
|
{
|
||||||
@ -278,9 +237,6 @@ _clutter_do_redraw (ClutterStage *stage)
|
|||||||
_clutter_stage_set_pick_buffer_valid (stage, FALSE);
|
_clutter_stage_set_pick_buffer_valid (stage, FALSE);
|
||||||
_clutter_stage_reset_picks_per_frame_counter (stage);
|
_clutter_stage_reset_picks_per_frame_counter (stage);
|
||||||
|
|
||||||
/* Before we can paint, we have to be sure we have the latest layout */
|
|
||||||
_clutter_stage_maybe_relayout (CLUTTER_ACTOR (stage));
|
|
||||||
|
|
||||||
_clutter_backend_ensure_context (ctx->backend, stage);
|
_clutter_backend_ensure_context (ctx->backend, stage);
|
||||||
|
|
||||||
/* Setup FPS count - not currently across *all* stages rather than per */
|
/* Setup FPS count - not currently across *all* stages rather than per */
|
||||||
|
@ -120,6 +120,7 @@ struct _ClutterStagePrivate
|
|||||||
|
|
||||||
GArray *paint_volume_stack;
|
GArray *paint_volume_stack;
|
||||||
|
|
||||||
|
guint relayout_pending : 1;
|
||||||
guint redraw_pending : 1;
|
guint redraw_pending : 1;
|
||||||
guint is_fullscreen : 1;
|
guint is_fullscreen : 1;
|
||||||
guint is_cursor_visible : 1;
|
guint is_cursor_visible : 1;
|
||||||
@ -673,7 +674,54 @@ _clutter_stage_needs_update (ClutterStage *stage)
|
|||||||
|
|
||||||
priv = stage->priv;
|
priv = stage->priv;
|
||||||
|
|
||||||
return priv->redraw_pending;
|
return priv->relayout_pending || priv->redraw_pending;
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
_clutter_stage_maybe_relayout (ClutterActor *actor)
|
||||||
|
{
|
||||||
|
ClutterStage *stage = CLUTTER_STAGE (actor);
|
||||||
|
ClutterStagePrivate *priv = stage->priv;
|
||||||
|
gfloat natural_width, natural_height;
|
||||||
|
ClutterActorBox box = { 0, };
|
||||||
|
CLUTTER_STATIC_TIMER (relayout_timer,
|
||||||
|
"Mainloop", /* no parent */
|
||||||
|
"Layouting",
|
||||||
|
"The time spent reallocating the stage",
|
||||||
|
0 /* no application private data */);
|
||||||
|
|
||||||
|
if (!priv->relayout_pending)
|
||||||
|
return;
|
||||||
|
priv->relayout_pending = FALSE;
|
||||||
|
|
||||||
|
/* avoid reentrancy */
|
||||||
|
if (!CLUTTER_ACTOR_IN_RELAYOUT (stage))
|
||||||
|
{
|
||||||
|
CLUTTER_TIMER_START (_clutter_uprof_context, relayout_timer);
|
||||||
|
CLUTTER_NOTE (ACTOR, "Recomputing layout");
|
||||||
|
|
||||||
|
CLUTTER_SET_PRIVATE_FLAGS (stage, CLUTTER_IN_RELAYOUT);
|
||||||
|
|
||||||
|
natural_width = natural_height = 0;
|
||||||
|
clutter_actor_get_preferred_size (CLUTTER_ACTOR (stage),
|
||||||
|
NULL, NULL,
|
||||||
|
&natural_width, &natural_height);
|
||||||
|
|
||||||
|
box.x1 = 0;
|
||||||
|
box.y1 = 0;
|
||||||
|
box.x2 = natural_width;
|
||||||
|
box.y2 = natural_height;
|
||||||
|
|
||||||
|
CLUTTER_NOTE (ACTOR, "Allocating (0, 0 - %d, %d) for the stage",
|
||||||
|
(int) natural_width,
|
||||||
|
(int) natural_height);
|
||||||
|
|
||||||
|
clutter_actor_allocate (CLUTTER_ACTOR (stage),
|
||||||
|
&box, CLUTTER_ALLOCATION_NONE);
|
||||||
|
|
||||||
|
CLUTTER_UNSET_PRIVATE_FLAGS (stage, CLUTTER_IN_RELAYOUT);
|
||||||
|
CLUTTER_TIMER_STOP (_clutter_uprof_context, relayout_timer);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -693,17 +741,15 @@ _clutter_stage_do_update (ClutterStage *stage)
|
|||||||
|
|
||||||
priv = stage->priv;
|
priv = stage->priv;
|
||||||
|
|
||||||
if (!priv->redraw_pending)
|
/* NB: We need to ensure we have an up to date layout *before* we
|
||||||
return FALSE;
|
* check or clear the pending redraws flag since a relayout may
|
||||||
|
* queue a redraw.
|
||||||
/* clutter_do_redraw() will also call maybe_relayout(), but since a relayout
|
|
||||||
* can queue a redraw, we want to do the relayout before we clear the
|
|
||||||
* update_idle to avoid painting the stage twice. Calling maybe_relayout()
|
|
||||||
* twice in a row is cheap because of caching of requested and allocated
|
|
||||||
* size.
|
|
||||||
*/
|
*/
|
||||||
_clutter_stage_maybe_relayout (CLUTTER_ACTOR (stage));
|
_clutter_stage_maybe_relayout (CLUTTER_ACTOR (stage));
|
||||||
|
|
||||||
|
if (!priv->redraw_pending)
|
||||||
|
return FALSE;
|
||||||
|
|
||||||
CLUTTER_NOTE (PAINT, "redrawing via idle for stage[%p]", stage);
|
CLUTTER_NOTE (PAINT, "redrawing via idle for stage[%p]", stage);
|
||||||
_clutter_do_redraw (stage);
|
_clutter_do_redraw (stage);
|
||||||
|
|
||||||
@ -721,6 +767,20 @@ _clutter_stage_do_update (ClutterStage *stage)
|
|||||||
return TRUE;
|
return TRUE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static void
|
||||||
|
clutter_stage_real_queue_relayout (ClutterActor *self)
|
||||||
|
{
|
||||||
|
ClutterStage *stage = CLUTTER_STAGE (self);
|
||||||
|
ClutterStagePrivate *priv = stage->priv;
|
||||||
|
ClutterActorClass *parent_class;
|
||||||
|
|
||||||
|
priv->relayout_pending = TRUE;
|
||||||
|
|
||||||
|
/* chain up */
|
||||||
|
parent_class = CLUTTER_ACTOR_CLASS (clutter_stage_parent_class);
|
||||||
|
parent_class->queue_relayout (self);
|
||||||
|
}
|
||||||
|
|
||||||
static void
|
static void
|
||||||
clutter_stage_real_queue_redraw (ClutterActor *actor,
|
clutter_stage_real_queue_redraw (ClutterActor *actor,
|
||||||
ClutterActor *leaf)
|
ClutterActor *leaf)
|
||||||
@ -1112,6 +1172,7 @@ clutter_stage_class_init (ClutterStageClass *klass)
|
|||||||
actor_class->unrealize = clutter_stage_unrealize;
|
actor_class->unrealize = clutter_stage_unrealize;
|
||||||
actor_class->show = clutter_stage_show;
|
actor_class->show = clutter_stage_show;
|
||||||
actor_class->hide = clutter_stage_hide;
|
actor_class->hide = clutter_stage_hide;
|
||||||
|
actor_class->queue_relayout = clutter_stage_real_queue_relayout;
|
||||||
actor_class->queue_redraw = clutter_stage_real_queue_redraw;
|
actor_class->queue_redraw = clutter_stage_real_queue_redraw;
|
||||||
actor_class->apply_transform = clutter_stage_real_apply_transform;
|
actor_class->apply_transform = clutter_stage_real_apply_transform;
|
||||||
|
|
||||||
@ -1471,6 +1532,8 @@ clutter_stage_init (ClutterStage *self)
|
|||||||
priv->fog.z_near = 1.0;
|
priv->fog.z_near = 1.0;
|
||||||
priv->fog.z_far = 2.0;
|
priv->fog.z_far = 2.0;
|
||||||
|
|
||||||
|
priv->relayout_pending = TRUE;
|
||||||
|
|
||||||
clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE);
|
clutter_actor_set_reactive (CLUTTER_ACTOR (self), TRUE);
|
||||||
clutter_stage_set_title (self, g_get_prgname ());
|
clutter_stage_set_title (self, g_get_prgname ());
|
||||||
clutter_stage_set_key_focus (self, NULL);
|
clutter_stage_set_key_focus (self, NULL);
|
||||||
@ -2617,6 +2680,7 @@ clutter_stage_ensure_redraw (ClutterStage *stage)
|
|||||||
g_return_if_fail (CLUTTER_IS_STAGE (stage));
|
g_return_if_fail (CLUTTER_IS_STAGE (stage));
|
||||||
|
|
||||||
priv = stage->priv;
|
priv = stage->priv;
|
||||||
|
priv->relayout_pending = TRUE;
|
||||||
priv->redraw_pending = TRUE;
|
priv->redraw_pending = TRUE;
|
||||||
|
|
||||||
master_clock = _clutter_master_clock_get_default ();
|
master_clock = _clutter_master_clock_get_default ();
|
||||||
|
Loading…
Reference in New Issue
Block a user