| // Copyright 2015 The Chromium Authors. All rights reserved. |
| // Use of this source code is governed by a BSD-style license that can be |
| // found in the LICENSE file. |
| |
| [DartPackage="mojo_services"] |
| module mojo.gfx.composition; |
| |
| import "mojo/services/gfx/composition/interfaces/nodes.mojom"; |
| import "mojo/services/gfx/composition/interfaces/resources.mojom"; |
| import "mojo/services/gfx/composition/interfaces/scene_token.mojom"; |
| import "mojo/services/gfx/composition/interfaces/scheduling.mojom"; |
| |
| // The node id which represents the root of a scene. |
| // |
| // Every scene should have a root node which uses this id unless the scene |
| // has no content at all. |
| const uint32 kSceneRootNodeId = 0; |
| |
| // The scene version used as a placeholder when the version doesn't matter. |
| // |
| // This version code can be used by a consumer of a scene to express that |
| // it would like to consume the latest version of the scene. |
| // |
| // This version code can also be used by a scene itself if it has not |
| // received any other specific indications as to the version it should |
| // report when publishing its content. |
| const uint32 kSceneVersionNone = 0; |
| |
| // A scene component maintains a description of some graphical content which |
| // an application would like to render. This description consists of |
| // resources and nodes. |
| // |
| // LIFECYCLE |
| // |
| // Use |Compositor.CreateScene()| to create a scene. The application |
| // uses the |Scene| interface to manage the scene's content and implements |
| // the |SceneListener| interface to handle events. |
| // |
| // To destroy a scene, simply close the |Scene| message pipe. |
| // |
| // CONTENT |
| // |
| // Resources are references to foreign objects which are being imported into |
| // the scene graph, such as images and other scenes. Each resource must be |
| // given a locally unique identifier when it is bound to the scene. |
| // |
| // Nodes express the geometry and content of the scene, such as images and |
| // references to embedded scenes. Nodes are arranged to form a directed |
| // acyclic graph of drawing commands. |
| // |
| // The root node of the scene has the special id of |kSceneRootNodeId|. |
| // |
| // ATOMICITY |
| // |
| // To ensure atomicity of updates, the evolution of a scene occurs in two |
| // phases: update and publish. Incremental changes to the scene made during |
| // the update phase are not observed until published. |
| // |
| // - Update phase: To construct the next state of a scene, the scene owner |
| // issues any number of scene update requests to add, update, or remove |
| // resources and nodes. |
| // |
| // - Publish phase: When the next state of a scene is fully constructed, the |
| // scene owner issues a request to publish its changes to the scene and |
| // assigns it a version identifier. The version identifer may be used |
| // in scene references to coordinate updates across multiple scenes which |
| // must be synchronized. |
| // |
| // Once the scene has been published, the scene owner may begin to construct |
| // the next state without disrupting the state just published. |
| // |
| // SYNCHRONIZATION |
| // |
| // To ensure synchronization of updates across scenes, some additional work |
| // is needed. |
| // |
| // For example, consider the case of a scene X which embeds two other scenes |
| // A and B. If X changes size, it may need to resize A and B as well to |
| // fit properly within its layout. |
| // |
| // To do so, X sends the owners of A and B each a message indicating the |
| // new size it desires along with new scene version identifiers V(A) and |
| // V(B) which the owners of A and B must use when they publish the new scene |
| // state which incorporates the requested size change. |
| // |
| // Meanwhile, X produces a new scene of its own taking into account its |
| // new size. As part of constructing this new scene, it binds to the V(A) |
| // and V(B) versions of A and B to express its dependence on A and B |
| // having been updated to the new size. |
| // |
| // Propagating version information top-down through the scene graph in |
| // this manner allows for state changes to be synchronized in a purely |
| // feed-forward manner. |
| // |
| // CONCURRENCY |
| // |
| // In the above synchronization example, version numbers were used to |
| // couple the state of one scene with others that it depends on. |
| // What should happen if these dependencies are not satisfied promptly? |
| // |
| // Suppose X and A quickly produce new scenes with the new size but |
| // B is taking longer than anticipated to do so. We have a few choices: |
| // |
| // - Stall: The compositor could continue to show the old state of X, A, and B |
| // until such time as all three have published their new versions. |
| // |
| // - Recover: The compositor could realize that X and A are already up to date |
| // but B is lagging and choose to apply a transformation to B's old content |
| // cover for the lag, such as by scaling, clipping, masking, or discarding |
| // B's old content. |
| // |
| // - Speculate: The compositor could allow X to provide alternate descriptions |
| // of the scene in the case where A or B are not keeping up so that it |
| // can more finely control the recovery policy. |
| // |
| // To maximize concurrency, we adopt the latter approach. |
| // |
| // SCHEDULING |
| // |
| // The scene provides support for scheduling frames via its associated |
| // |FrameScheduler| interface. Use the scheduler to obtain frame timing |
| // information and to throttle updates to match the display refresh rate |
| // (ie. with vsync). |
| interface Scene { |
| // Sets the listener for receiving events from the scene. |
| // |
| // If |listener| is null, then the previously set listener is removed. |
| SetListener(SceneListener? listener); |
| |
| // Applies a batch of incremental updates to the contents of the scene. |
| // |
| // Incremental changes can be split across any number of updates but it is |
| // more efficient to process them in batches. Updates have no visible |
| // effect until the scene owner calls |Publish()| to publish them. |
| // |
| // Updates are buffered and applied when |Publish()| is called. This means |
| // it is safe to issue an update which adds a node that refers to a resource |
| // which is not added until a subsequent update as long as the scene is |
| // not published in between those updates. |
| Update(SceneUpdate update); |
| |
| // Publishes the scene and tags it with the specified version. |
| // |
| // All pending incremental updates are applied atomically when the scene |
| // is published and the new state is labeled with the version indicated |
| // in the associated metadata. |
| // |
| // The |metadata| describes how the published scene should be presented. |
| // If null, this method behaves as if a |SceneMetadata| object initialized |
| // with default values had been supplied. |
| // |
| // Publishing a scene graph applies all pending updates. It is an error |
| // to publish updates which cause the scene state to become inconsistent, |
| // such as by having nodes which refer to non-existent resources or |
| // introducing cycles in the scene's nodes; the connection will be closed. |
| Publish(SceneMetadata? metadata); |
| |
| // Gets a scheduler to receive frame timing information for the scene. |
| GetScheduler(FrameScheduler& scheduler); |
| }; |
| |
| // An interface applications may implement to receive events from a scene. |
| interface SceneListener { |
| // Called when a resource has become unavailable. |
| // |
| // Any nodes which are using the resource will be considered blocked |
| // until the resource is replaced or the nodes using it are removed. |
| OnResourceUnavailable(uint32 resource_id) => (); |
| }; |
| |
| // A batch of incremental changes to be applied to a scene. |
| struct SceneUpdate { |
| // If true, clears all resources before processing the update. |
| bool clear_resources = false; |
| |
| // If true, clears all nodes before processing the update. |
| bool clear_nodes = false; |
| |
| // Resources to be added, updated, or removed, indexed by resource id. |
| // The value replaces the definition of the resource with the given id. |
| // If the value is null, then the resource is removed from the scene. |
| map<uint32, Resource?>? resources; |
| |
| // Nodes to be added, updated, or removed, indexed by node id. |
| // The value replaces the definition of the node with the given id. |
| // If the value is null, then the node is removed from the scene. |
| // |
| // The root node must have an id of 0. |
| map<uint32, Node?>? nodes; |
| }; |
| |
| // Describes how a published scene should be presented. |
| struct SceneMetadata { |
| // The scene's new version number. |
| // |
| // Version numbers are usually associated with requests to change the |
| // state of the scene. For example, the embedder of this scene may send |
| // it a request to resize its content or change its color and provide a |
| // new version number that this scene should apply when it publishes the |
| // first update which addresses this request. |
| // |
| // In general, the version number will be provided to the owner of the |
| // scene by some other party which is in change of synchronizing updates |
| // across multiple scenes including this one. The other party will |
| // frequently be the owner of some other scene which embeds this one. |
| // |
| // In certain cases there might not be a version number provided for |
| // synchronization. When this happens, set |version| to |kSceneVersionNone|. |
| // |
| // Note that version numbers are unordered; there is no need to increment |
| // them monotonically. Values may also be reused at will. |
| uint32 version = 0; // kSceneVersionNone |
| |
| // A timestamp indicating approximately when the published contents of the |
| // scene are to be shown on the display output assuming everything is |
| // fully rendered and submitted by the appropriate deadline. |
| // |
| // Expressed in microseconds in the |MojoTimeTicks| timebase. |
| // |
| // A value of 0 means "as soon as possible". |
| // |
| // See also: |FrameInfo.presentation_time|. |
| int64 presentation_time = 0; |
| }; |