f5f066df9c
When building actor relative transforms, instead of using the matrix stack to combine transformations and making assumptions about what is currently on the stack we now just explicitly initialize an identity matrix and apply transforms to that. This removes the full_vertex_t typedef for internal transformation code and we just use ClutterVertex. ClutterStage now implements apply_transform like any other actor now and the code we had in _cogl_setup_viewport has been moved to the stage's apply_transform instead. ClutterStage now tracks an explicit projection matrix and viewport geometry. The projection matrix is derived from the perspective whenever that changes, and the viewport is updated when the stage gets a new allocation. The SYNC_MATRICES mechanism has been removed in favour of _clutter_stage_dirty_viewport/projection() APIs that get used when switching between multiple stages to ensure cogl has the latest information about the onscreen framebuffer.
302 lines
11 KiB
Plaintext
302 lines
11 KiB
Plaintext
ClutterActor Invariants
|
|
===============================================================================
|
|
|
|
ClutterActor behaviour has invariants that will be kept with the same API and
|
|
ABI guarantees as the whole Clutter library.
|
|
|
|
This document refers to the 0.8 release of Clutter.
|
|
|
|
Sections:
|
|
|
|
i. Flags
|
|
a. Public ClutterActor Flags
|
|
b. Private ClutterActor Flags
|
|
c. Private Pick Modes
|
|
ii. Invariants
|
|
iii. State changes
|
|
iv. Responsibilities of a ClutterActor
|
|
a. Adding to a container
|
|
b. Removing from a container
|
|
c. Initial state
|
|
|
|
i. Flags
|
|
-------------------------------------------------------------------------------
|
|
|
|
This section describes the various flags and enumerations used by
|
|
ClutterActor.
|
|
|
|
a. Public ClutterActor Flags
|
|
|
|
CLUTTER_ACTOR_REALIZED
|
|
Means: the actor has GPU resources associated to its paint
|
|
cycle. Note however that an actor is allowed to allocate Cogl
|
|
resources before being realized because Clutter only ever uses
|
|
one rendering context which is always current. An actor is
|
|
free to create resources at any time.
|
|
|
|
Set by clutter_actor_realize(), unset by
|
|
clutter_actor_unrealize(). Generally set implicitly when the
|
|
actor becomes MAPPED (see below).
|
|
|
|
May only be set if one of the actor's ancestors is a toplevel.
|
|
May only be set if all of the actor's ancestors are realized.
|
|
|
|
Once realized an actor remains realized until removed from the
|
|
toplevel. Hide, reparent will not unrealize; but unparent or
|
|
destroy will unrealize since they remove the actor from the
|
|
toplevel.
|
|
|
|
CLUTTER_ACTOR_MAPPED
|
|
Means: the actor will be painted if the stage is mapped.
|
|
|
|
On non-toplevels, will be set if all of the following are
|
|
true, and unset otherwise:
|
|
* the actor's VISIBLE flag is set
|
|
* all of the actor's non-toplevel ancestors have the MAPPED
|
|
flag set
|
|
* the actor has a toplevel ancestor
|
|
* the toplevel ancestor's VISIBLE flag is set
|
|
* the toplevel ancestor's REALIZED flag is set
|
|
|
|
On toplevels, MAPPED is set asynchronously when the window
|
|
system notifies Clutter that the toplevel has been made
|
|
visible on the screen.
|
|
|
|
The MAPPED flag requires that an actor is REALIZED. When
|
|
Clutter sets the MAPPED flag, it forces realization; this is
|
|
the "normal" way for realization to occur, though explicit
|
|
realization with clutter_actor_realize() is permitted.
|
|
|
|
CLUTTER_ACTOR_VISIBLE
|
|
Means: the actor's "visible" property was set to true by
|
|
the application programmer.
|
|
|
|
Set by clutter_actor_show(), unset by clutter_actor_hide().
|
|
|
|
This is an application-controlled property, while MAPPED and
|
|
REALIZED are usually managed by Clutter (with the exception
|
|
that applications can "realize early" with
|
|
clutter_actor_realize()).
|
|
|
|
If VISIBLE is unset, the actor (and any children) must
|
|
be immediately unmapped, to maintain the invariants for
|
|
the MAPPED flag.
|
|
|
|
CLUTTER_ACTOR_REACTIVE
|
|
Set and unset by clutter_actor_set_reactive()
|
|
Means: the actor is now reactive to events.
|
|
Notes:
|
|
* If parents need to be reactive for child its up to the
|
|
parent implementation. In the case of ClutterGroup it
|
|
being marked unreactive does not mark all children unreactive.
|
|
* Clutter stage is always reactive.
|
|
|
|
|
|
b. Private ClutterActor flags
|
|
|
|
CLUTTER_ACTOR_IN_DESTRUCTION
|
|
Set internally by clutter_actor_destroy().
|
|
Used to avoid uneeded overhead when freeing GPU resources on unrealize
|
|
|
|
CLUTTER_ACTOR_IS_TOPLEVEL
|
|
Set internally by the initialization of ClutterStage
|
|
|
|
CLUTTER_ACTOR_IN_REPARENT
|
|
Set internally by clutter_actor_reparent(). This flag
|
|
optimizes the reparent process by avoiding the need
|
|
to pass through an unrealized state when the actor is
|
|
removed from the old parent.
|
|
|
|
CLUTTER_ACTOR_ABOUT_TO_UNPARENT
|
|
Set internally during part of clutter_actor_unparent().
|
|
Causes the actor to pretend it has no parent, then
|
|
update invariants; which effectively forces the actor
|
|
to unrealize. The purpose of this is to unrealize _before_ the
|
|
actor is removed from the stage, so unrealize implementations
|
|
can use clutter_actor_get_stage().
|
|
|
|
CLUTTER_ACTOR_IN_PAINT:
|
|
Set internally by clutter_actor_paint()
|
|
|
|
CLUTTER_ACTOR_IN_RELAYOUT
|
|
Set internally by clutter_relayout()
|
|
|
|
c. Private Pick Modes
|
|
|
|
CLUTTER_PICK_NONE
|
|
No pick operation is performed during the paint
|
|
|
|
CLUTTER_PICK_REACTIVE
|
|
Only reactive actors will be picked
|
|
|
|
CLUTTER_PICK_ALL
|
|
All visible actors will be picked
|
|
|
|
ii. Invariants
|
|
-------------------------------------------------------------------------------
|
|
|
|
This section describes the various constraints and invariants on ClutterActor.
|
|
|
|
In the following
|
|
|
|
A => B means if A is true then B is true
|
|
A <=> B means A is true if and only if B is true
|
|
(equivalent to A => B && A <= B)
|
|
|
|
1) CLUTTER_ACTOR_IN_DESTRUCTION => !CLUTTER_ACTOR_IS_MAPPED (actor) &&
|
|
!CLUTTER_ACTOR_IS_REALIZED (actor)
|
|
|
|
clutter_actor_destroy() will cause an actor to be unparented,
|
|
which means the actor must be unmapped and unrealized as
|
|
well.
|
|
|
|
2) CLUTTER_ACTOR_IS_MAPPED (actor) => CLUTTER_ACTOR_IS_REALIZED (actor)
|
|
|
|
when an actor is mapped, it must first be realized.
|
|
|
|
This is the most common way an actor becomes realized.
|
|
|
|
3) if clutter_actor_set_parent (actor, parent):
|
|
((parent_is_not_toplevel && CLUTTER_ACTOR_IS_MAPPED (parent)) ||
|
|
(parent_is_toplevel && CLUTTER_ACTOR_IS_VISIBLE(parent))) &&
|
|
CLUTTER_ACTOR_IS_VISIBLE (actor)
|
|
=> CLUTTER_ACTOR_IS_MAPPED (actor)
|
|
|
|
calling clutter_actor_set_parent() on an actor and a mapped
|
|
parent will map the actor if it has been shown.
|
|
|
|
4) if clutter_actor_unparent (actor):
|
|
CLUTTER_ACTOR_IS_MAPPED (actor) <=> CLUTTER_ACTOR_IN_REPARENT
|
|
|
|
calling clutter_actor_unparent() on an actor will unmap and
|
|
unrealize the actor since it no longer has a toplevel.
|
|
|
|
calling clutter_actor_reparent() on an actor will leave the
|
|
actor mapped and realized (if it was before) until it has a
|
|
new parent, at which point the invariants implied by the new
|
|
parent's state are applied.
|
|
|
|
5) CLUTTER_ACTOR_IS_REALIZED(actor) => CLUTTER_ACTOR_IS_REALIZED(parent)
|
|
|
|
Actors may only be realized if their parent is realized.
|
|
However, they may be unrealized even though their parent
|
|
is realized.
|
|
|
|
This implies that an actor may not be realized unless
|
|
it has a parent, or is a toplevel.
|
|
|
|
Since only toplevels can realize without a parent, no actor
|
|
can be realized unless it either is a toplevel or has a
|
|
toplevel ancestor.
|
|
|
|
As long as they are unmapped, actors may be unrealized. This
|
|
will force all children of the actor to be unrealized, since
|
|
children may not be realized while parents are unrealized.
|
|
|
|
6) CLUTTER_ACTOR_IS_MAPPED(actor) <=>
|
|
( ( (CLUTTER_ACTOR_IS_VISIBLE(toplevel_parent) &&
|
|
CLUTTER_ACTOR_IS_REALIZED(toplevel_parent)) ||
|
|
CLUTTER_ACTOR_IS_MAPPED(non_toplevel_parent) ) ) &&
|
|
CLUTTER_ACTOR_IS_VISIBLE(actor)
|
|
|
|
Actors _must_ be mapped if and only if they are visible and
|
|
their parent is mapped, or they are visible and their
|
|
parent is a toplevel that's realized and visible.
|
|
|
|
This invariant enables us to track whether an actor will
|
|
be painted (whether it's MAPPED) without ever traversing
|
|
the actor graph.
|
|
|
|
iii. State changes
|
|
-------------------------------------------------------------------------------
|
|
|
|
clutter_actor_show:
|
|
1. sets VISIBLE
|
|
2. sets MAPPED if invariants are met; mapping in turn sets
|
|
REALIZED
|
|
|
|
clutter_actor_hide:
|
|
1. sets !VISIBLE
|
|
2. unsets MAPPED if actor was mapped previously
|
|
3. does not affect REALIZED
|
|
|
|
clutter_actor_destroy:
|
|
1. sets CLUTTER_ACTOR_IN_DESTRUCTION
|
|
2. unparents the actor, which in turn implies unmap and unrealize
|
|
|
|
clutter_actor_realize:
|
|
1. attempts to set REALIZED on all parents, failing if
|
|
invariants are not met, e.g. not in a toplevel yet
|
|
2. sets REALIZED on actor if parent was successfully realized
|
|
|
|
clutter_actor_unrealize:
|
|
1. sets !VISIBLE which forces !MAPPED
|
|
2. sets !REALIZED
|
|
3. !MAPPED and !REALIZED forces unmap and unrealize of all
|
|
children
|
|
|
|
clutter_actor_set_parent:
|
|
1. sets actor->parent
|
|
2. if actor->show_on_set_parent is TRUE calls clutter_actor_show
|
|
3. sets MAPPED if all prerequisites are now met for map
|
|
4. if !CLUTTER_ACTOR_IN_REPARENT emits ::parent-set with
|
|
old_parent set to NULL
|
|
|
|
clutter_actor_unparent:
|
|
1. unsets actor->parent
|
|
2. if !CLUTTER_ACTOR_IN_REPARENT, sets !MAPPED and !REALIZED
|
|
since the invariants for those flags are no longer met
|
|
3. if !CLUTTER_ACTOR_IN_REPARENT emits ::parent-set with
|
|
old_parent set to the previous parent
|
|
|
|
clutter_actor_reparent:
|
|
1. sets CLUTTER_ACTOR_IN_REPARENT
|
|
2. emits ::parent-set with old_parent set to the previous parent
|
|
equivalent to:
|
|
clutter_actor_unparent
|
|
clutter_actor_set_parent
|
|
3. updates state of the actor to match invariants
|
|
(may change MAPPED or REALIZED in either direction,
|
|
depending on state of the new parent)
|
|
|
|
|
|
iv. Responsibilities of a ClutterActor
|
|
-------------------------------------------------------------------------------
|
|
|
|
a. Adding to a container
|
|
|
|
When adding an actor to a container, the container must:
|
|
|
|
1. call clutter_actor_set_parent (actor, container)
|
|
2. call clutter_actor_queue_relayout (container) if
|
|
adding the actor changes the container's preferred
|
|
size
|
|
|
|
b. Removing from a container
|
|
|
|
When removing an actor from a container, the container must:
|
|
|
|
1. call clutter_actor_unparent (actor)
|
|
2. call clutter_actor_queue_relayout (container) if removing
|
|
the actor changes the container's preferred size
|
|
|
|
Notes:
|
|
|
|
* here a container actor is any actor that contains children actors; it
|
|
does not imply the implementation of the ClutterContainer interface.
|
|
|
|
* clutter_actor_unparent() will unmap and unrealize the actor except
|
|
in the special case when CLUTTER_ACTOR_IN_REPARENT is set.
|
|
|
|
* 'Composite' Clutter actors need to pass down any allocations to children.
|
|
|
|
c. Initial state
|
|
|
|
When creating an actor, the initial state is:
|
|
|
|
1. !CLUTTER_ACTOR_REALIZED
|
|
2. !CLUTTER_ACTOR_MAPPED
|
|
|
|
===============================================================================
|
|
$LastChangedDate$
|