Don't update or use last_paint_box when painting inside a clone

The last_paint_box for an actor represents its "normal" position - we
shouldn't update it or use it to cull drawing if we are painting
a clone of the actor. Tracking whether we are painting a clone is
done by adding  _clutter_actor_push/pop_clone_paint() and a global
"clone paint level".

http://bugzilla.clutter-project.org/show_bug.cgi?id=2396
This commit is contained in:
Owen W. Taylor 2010-11-13 11:29:49 -05:00 committed by Robert Bragg
parent c68280556e
commit 8e6fac38fa
3 changed files with 40 additions and 7 deletions

View File

@ -115,6 +115,9 @@ gboolean _clutter_actor_set_default_paint_volume (ClutterActor *self,
G_CONST_RETURN gchar *_clutter_actor_get_debug_name (ClutterActor *self); G_CONST_RETURN gchar *_clutter_actor_get_debug_name (ClutterActor *self);
void _clutter_actor_push_clone_paint (void);
void _clutter_actor_pop_clone_paint (void);
G_END_DECLS G_END_DECLS
#endif /* __CLUTTER_ACTOR_PRIVATE_H__ */ #endif /* __CLUTTER_ACTOR_PRIVATE_H__ */

View File

@ -2465,6 +2465,26 @@ _clutter_actor_draw_paint_volume (ClutterActor *self)
clutter_paint_volume_free (&fake_pv); clutter_paint_volume_free (&fake_pv);
} }
static int clone_paint_level = 0;
void
_clutter_actor_push_clone_paint (void)
{
clone_paint_level++;
}
void
_clutter_actor_pop_clone_paint (void)
{
clone_paint_level--;
}
static gboolean
in_clone_paint (void)
{
return clone_paint_level > 0;
}
/* Returns TRUE if the actor can be ignored */ /* Returns TRUE if the actor can be ignored */
static gboolean static gboolean
cull_actor (ClutterActor *self) cull_actor (ClutterActor *self)
@ -2619,6 +2639,11 @@ clutter_actor_paint (ClutterActor *self)
* We also fetch the current paint box to perform culling so we * We also fetch the current paint box to perform culling so we
* can avoid painting actors outside the current clip region. * can avoid painting actors outside the current clip region.
* *
* If we are painting inside a clone, we should neither update
* the paint box or use it to cull painting, since the paint
* box represents the location of the source actor on the
* screen.
*
* XXX: We are starting to do a lot of vertex transforms on * XXX: We are starting to do a lot of vertex transforms on
* the CPU in a typical paint, so at some point we should * the CPU in a typical paint, so at some point we should
* audit these and consider caching some things. * audit these and consider caching some things.
@ -2636,14 +2661,17 @@ clutter_actor_paint (ClutterActor *self)
* or we'd need to be able to invalidate paint-volumes on * or we'd need to be able to invalidate paint-volumes on
* projection changes. * projection changes.
*/ */
if (G_LIKELY (need_paint_box) && if (!in_clone_paint ())
clutter_actor_get_paint_box (self, &priv->last_paint_box)) {
priv->last_paint_box_valid = TRUE; if (G_LIKELY (need_paint_box) &&
else clutter_actor_get_paint_box (self, &priv->last_paint_box))
priv->last_paint_box_valid = FALSE; priv->last_paint_box_valid = TRUE;
else
priv->last_paint_box_valid = FALSE;
if (cull_actor (self)) if (cull_actor (self))
goto done; goto done;
}
if (priv->effects != NULL) if (priv->effects != NULL)
effect_painted = _clutter_actor_effects_pre_paint (self); effect_painted = _clutter_actor_effects_pre_paint (self);

View File

@ -184,7 +184,9 @@ clutter_clone_paint (ClutterActor *self)
was_unmapped = TRUE; was_unmapped = TRUE;
} }
_clutter_actor_push_clone_paint ();
clutter_actor_paint (priv->clone_source); clutter_actor_paint (priv->clone_source);
_clutter_actor_pop_clone_paint ();
if (was_unmapped) if (was_unmapped)
_clutter_actor_set_enable_paint_unmapped (priv->clone_source, FALSE); _clutter_actor_set_enable_paint_unmapped (priv->clone_source, FALSE);