blob: c2326ce0b125fc5a462984cf725b55fff9b75637 [file] [log] [blame]
Jeff Brown751f4d32016-01-26 15:51:01 -08001// Copyright 2015 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5// Primitives express the geometry of the scene, such as quads and references
6// to embedded scenes. Primitives are arranged hierarchically as nodes,
7// each with an associated transformation matrix.
8
9[DartPackage="mojo_services"]
10module mojo.gfx.composition;
11
12import "mojo/services/geometry/interfaces/geometry.mojom";
13import "mojo/services/gfx/composition/interfaces/hit_tests.mojom";
14
15// Nodes express the geometry and content of the scene, such as images and
16// references to embedded scenes. Nodes are arranged to form a directed
17// acyclic graph of drawing commands.
18//
Jeff Brown33eb7732016-03-02 11:17:31 -080019// RENDERING
20//
21// The node graph is renderer in pre-order traversal. Starting from the
Jeff Brown8e372232016-02-24 14:11:56 -080022// root, the compositor applies the transformation, clip, applies the
23// node's operation (if any), then recursively processes the node's children
24// according to the node's combinator rule.
Jeff Brown751f4d32016-01-26 15:51:01 -080025//
26// BLOCKED NODES
27//
28// Due to the asynchronous nature of the system, it may happen that some
29// nodes cannot be processed immediately at drawing time because they require
30// access to certain resources which are not available, such as a specific
31// version of a scene which has yet to be produced by some other application.
32//
33// When a node cannot be drawn due to an unsatisfied dependency, it is
34// said to be "blocked". Blocked nodes prevent rendering of the entire
35// subgraph below them.
36//
37// NODE COMBINATORS
38//
39// Node combinator rules describe what should happen when a node which is
40// otherwise unblocked has one or more blocked children.
41//
42// With the |MERGE| combinator, the children of a node are all drawn in
43// sequence if none of them are blocked, otherwise the node itself is
44// blocked. This is the default.
45//
46// With the |PRUNE| combinator, the children of a node are all drawn in
47// sequence while skipping over any of them which are blocked. Blocked
48// children will not appear in the output.
49//
50// With the |FALLBACK| combinator, the first unblocked child of a node is
51// drawn and the remaining nodes are ignored. If the node has children
52// and all of them are blocked then the node itself is blocked.
53//
54// Combinators make it possible to express complex rules such as substituting
55// missing content for an earlier version of that content or for a placeholder
56// if not available.
57//
Jeff Brownc1287c12016-03-02 11:17:58 -080058// HIT TESTING
59//
60// Hit testing is the process of determining which nodes within a scene graph
61// should be responsible for handling events which occur within their visual
62// space on the screen.
63//
64// For example, when the user touches objects on a touch screen, the input
65// system asks the compositor to performs a hit test at the contact point to
66// find the nodes which represent the objects the user wants to interact with.
67// The result of the hit test is a list of nodes, in dispatch order, which
68// have asked to participate in handling events related to the contact point.
69//
70// Nodes may be opaque, translucent, or invisible to the hit testing
71// process depending on whether they prevent or allow targets visually
72// behind them from being hit and whether they can actually be hit,
73// as specified by |HitTestBehavior.visibility|.
74//
75// Nodes are added to the hit test result whenever one of their opaque children
76// is hit. This is useful for scrolling containers which may need to intercept
77// certain gestures within the space of their children and therefore need to
78// be added to the hit test result themselves.
79//
80// Nodes can also request to prune hit testing for their children, which
81// prevents their children from being hit.
82//
83// Hit testing proceeds recursively in post-order traversal (the reverse of
84// the drawing order). Intuitively, this means that the most specific
85// (deepest) nodes of the tree are tested before their ancestors.
86//
87// Starting from the root, the compositor transforms the point of interest
88// into the node's coordinate system, rejects the node if the point is
89// outside of the node's clip region, otherwise recursively tests the
90// node's children (those which were selected by the combinator rule)
91// until the first opaque target hit is found, then evaluates the node's
92// |HitTestBehavior| to determine whether the node was hit. Nodes are
93// accumulated into a hit test result in the order in which they were
94// determined to have been hit.
95//
96// See |HitTestBehavior| for more details.
97//
Jeff Brown33eb7732016-03-02 11:17:31 -080098// INSTANCING
99//
100// The compositor allows nodes to be referenced and reused multiple times
101// within a scene (this is known as instancing). Instancing makes it easier
102// to take advantage of combinators for interleaving placeholder content
103// when certain nodes are blocked from rendering (see above). It also allows
104// common elements to be reused if desired.
105//
106// Likewise, the compositor allows scenes to be multiply referenced so that
107// the same content can be presented simultaneously in several places.
108//
109// CYCLES
110//
111// The compositor forbids cycles among nodes within scenes and will
112// reject scene updates which introduce node cycles by closing the client's
113// connection.
114//
115// Likewise, the compositor forbids cycles across scenes and will respond
116// to them by considering any scene within a cycle to be blocked from
117// rendering.
118//
119// For example, if there are scenes A, B, and C linked such that rendering
120// would traverse a path A -> B -> C -> B, the compositor will consider both
121// scenes B and C to be blocked and will apply A's combinator rules as required
122// to resolve the problem at the point where it would have entered the cycle.
123// This may cause A itself to be blocked if there are no applicable |PRUNE|
124// or |FALLBACK| predicated alternatives.
125//
126// This policy protects clients from cross-scene cycles which may have been
127// introduced downstream in the graph without their knowledge or which may
128// occur transiently, so long as they are not within the cycle themselves.
129// It also ensures that cycles are resolved deterministically regardless of
130// where they are encountered during traversal; all scenes within the cycle
131// are suppressed.
132//
Jeff Brown751f4d32016-01-26 15:51:01 -0800133// TIPS
134//
135// 1. Reuse nodes when possible to reduce the size of the graph. Consider
136// using LayerNodeOps to flatten common elements to a texture which can
137// be redrawn efficiently in many places.
138//
Jeff Brown33eb7732016-03-02 11:17:31 -0800139// 2. Insert |PRUNE| or |FALLBACK| nodes in places where blocking is likely to
Jeff Brown751f4d32016-01-26 15:51:01 -0800140// occur, such as when embedding scenes produced by other applications.
Jeff Brown33eb7732016-03-02 11:17:31 -0800141// Provide alternate content where possible to avoid stalling the
142// rendering pipeline at these points.
Jeff Brown751f4d32016-01-26 15:51:01 -0800143//
144struct Node {
145 // The combinator specifies how child nodes are processed.
146 enum Combinator {
147 // All children are drawn in sequence, blocking if any are blocked.
148 MERGE,
149 // All children are drawn in sequence, skipping any that are blocked.
150 PRUNE,
151 // The first unblocked node is drawn, blocking if there are children
152 // and all of them are blocked.
153 FALLBACK,
154 };
155
156 // The forward transformation from the node's content space to its
157 // containing node's content space. If null, an identity transformation
158 // is assumed.
159 //
160 // For example, if you want to translate the content of the node so that
161 // it is drawn at X = 100 relative to its containing node's origin, simply
162 // set a transformation matrix with the X translation component equal to 100.
163 // Take care not to specify the inverse transform by mistake.
164 mojo.Transform? content_transform;
165
166 // The clip rectangle to apply to this node's content and to its children
167 // in content space in addition to any clipping performed by the container.
168 // If null, the node does not apply any clipping of its own.
Jeff Brown563af9f2016-03-10 08:24:46 -0800169 mojo.RectF? content_clip;
Jeff Brown751f4d32016-01-26 15:51:01 -0800170
Jeff Brown751f4d32016-01-26 15:51:01 -0800171 // The Combinator to apply when processing the children of this node.
172 Combinator combinator = Combinator.MERGE;
173
Jeff Brownc1287c12016-03-02 11:17:58 -0800174 // The hit testing behavior of the node.
175 // If null, the node is considered invisible for hit testing.
176 HitTestBehavior? hit_test_behavior;
177
Jeff Brown751f4d32016-01-26 15:51:01 -0800178 // The ids of the children of this node.
179 // It is an error to specify a node id that does not refer to a valid
Jeff Brown33eb7732016-03-02 11:17:31 -0800180 // node or which creates a cycle in the graph; the compositor will close
181 // the connection when the scene is published.
Jeff Brown751f4d32016-01-26 15:51:01 -0800182 array<uint32>? child_node_ids;
183
184 // The drawing operation to apply when processing this node.
185 // If null, no drawing operation occurs at this node.
186 NodeOp? op;
187};
188
189// A drawing operation to apply when processing the node.
190union NodeOp {
191 RectNodeOp rect;
192 ImageNodeOp image;
193 SceneNodeOp scene;
194 LayerNodeOp layer;
195 // TODO(jeffbrown): Color filters.
196};
197
198// Fills a rectangle with a solid color.
199struct RectNodeOp {
200 // The rectangle to fill in content space.
Jeff Brown563af9f2016-03-10 08:24:46 -0800201 mojo.RectF content_rect;
Jeff Brown751f4d32016-01-26 15:51:01 -0800202
203 // The rectangle's color.
204 Color color;
205};
206
207// Draws an image at the specified location.
208//
209// The node containing this operation will be blocked if the image resource
210// is not ready for use at draw time.
211struct ImageNodeOp {
212 // The rectangle in which to draw the image in content space.
Jeff Brown563af9f2016-03-10 08:24:46 -0800213 mojo.RectF content_rect;
Jeff Brown751f4d32016-01-26 15:51:01 -0800214
215 // The portion of the image to draw.
216 // If null, draws the entire image.
Jeff Brown563af9f2016-03-10 08:24:46 -0800217 mojo.RectF? image_rect;
Jeff Brown751f4d32016-01-26 15:51:01 -0800218
219 // The resource id of a valid |MailboxTextureResource| to draw.
220 // It is an error to specify a resource id that does not refer to an image
221 // resource; the compositor will close the connection when the scene
222 // is published.
223 uint32 image_resource_id;
224
225 // The blending parameters. If null, uses the default values specified
226 // in the |Blend| structure declaration.
227 Blend? blend;
228};
229
230// Draws a scene.
231//
232// A scene operation embeds another scene at this point in the scene graph.
233// It has essentially the same effect as drawing the root node of the
234// referenced scene and drawing it as if it were a child of this node.
235//
236// The node containing this operation will be blocked if the specified
237// version of the scene is not ready for use at draw time or if it too
238// is blocked.
239//
240// It is often useful to wrap this node with a |LayerNodeOp| when blending
241// the scene with other content.
242struct SceneNodeOp {
243 // The resource id of a valid |SceneResource| to link into the scene.
244 // It is an error to specify a resource id that does not refer to a scene
245 // resource; the compositor will close the connection when the scene
246 // is published.
Jeff Brown33eb7732016-03-02 11:17:31 -0800247 // If a cycle is introduced then the scene will be substituted with
248 // placeholder content by the compositor.
Jeff Brown751f4d32016-01-26 15:51:01 -0800249 uint32 scene_resource_id;
250
251 // The version of the scene that we would like to reference.
252 // Use |kSceneVersionNone| to request the most recently published
253 // version of the scene if synchronization is unimportant.
Alexandre Zanid26dd212016-03-24 13:24:48 -0700254 uint32 scene_version = 0; // kSceneVersionNone
Jeff Brown751f4d32016-01-26 15:51:01 -0800255};
256
257// Draws a layer.
258//
259// Conceptually, this operation has the effect of drawing the children of
Jeff Brown563af9f2016-03-10 08:24:46 -0800260// the node to a temporary buffer which is then composited in place like an
261// image. This is useful for ensuring correct blending of layered content.
Jeff Brown751f4d32016-01-26 15:51:01 -0800262struct LayerNodeOp {
Jeff Brown563af9f2016-03-10 08:24:46 -0800263 // The region of the node's content space to render to a layer.
264 // Drawing within this region will be included in the layer.
265 mojo.RectF layer_rect;
Jeff Brown751f4d32016-01-26 15:51:01 -0800266
267 // The blending parameters. If null, uses the default values specified
268 // in the |Blend| structure declaration.
269 Blend? blend;
270};
271
272// Specifies a color to draw.
273// TODO(jeffbrown): This is silly but unambiguous for prototyping.
274// Make it less silly.
275struct Color {
276 uint8 red;
277 uint8 green;
278 uint8 blue;
279 uint8 alpha;
280};
281
282// Specifies how blending should take place.
283struct Blend {
284 // The opacity for composition in a range from 0 (fully transparent)
285 // to 255 (fully opaque).
286 uint8 alpha = 255;
287
288 // TODO(jeffbrown): Blend modes and texture filtering.
289};