|  | // Copyright 2019 The Fuchsia Authors. All rights reserved. | 
|  | // Use of this source code is governed by a BSD-style license that can be | 
|  | // found in the LICENSE file. | 
|  |  | 
|  | library fuchsia.ui.scenic.internal; | 
|  |  | 
|  | using fuchsia.scenic.scheduling; | 
|  | using fuchsia.sysmem; | 
|  | using zx; | 
|  |  | 
|  | // The set of error codes returned by Flatland::Present(). | 
|  | enum Error { | 
|  | BAD_OPERATION = 0; | 
|  | NO_PRESENTS_REMAINING = 1; | 
|  | }; | 
|  |  | 
|  | // TODO(fxbug.dev/36766): Unify with math types for other APIs. | 
|  | struct Vec2 { | 
|  | float32 x; | 
|  | float32 y; | 
|  | }; | 
|  |  | 
|  | enum Orientation { | 
|  | CCW_0_DEGREES = 0; | 
|  | CCW_90_DEGREES = 1; | 
|  | CCW_180_DEGREES = 2; | 
|  | CCW_270_DEGREES = 3; | 
|  | }; | 
|  |  | 
|  | /// The return type of GraphLink::GetLayout(). This table contains most of the information necessary | 
|  | /// for a client to decide how to layout their content in a Flatland instance. This data may be | 
|  | /// provided to the client before the command that creates the Link is presented, so that the client | 
|  | /// may lay out content properly before their first call to Present(). | 
|  | table LayoutInfo { | 
|  | /// The layout size of a Graph in logical pixels, defined by the parent's call to | 
|  | /// SetLinkProperties(). Clients should re-layout their content when this value changes. | 
|  | 1: Vec2 logical_size; | 
|  | /// The ratio from physical display pixels to logical pixels, defined by the sizes and scale | 
|  | /// transforms of the parent. Clients should not necessarily re-layout their content when this | 
|  | /// value changes. | 
|  | 2: Vec2 pixel_scale; | 
|  | }; | 
|  |  | 
|  | /// GraphLinks will be informed when they are actively attached to a output display (either | 
|  | /// directly, or through a chain of parent links) and when they are not. Until they are connected to | 
|  | /// a display, some pieces of information (such as pixel scale) may be unavailable. | 
|  | enum GraphLinkStatus { | 
|  | CONNECTED_TO_DISPLAY = 0; | 
|  | DISCONNECTED_FROM_DISPLAY = 1; | 
|  | }; | 
|  |  | 
|  | /// A protocol that provides information about a particular Link to the child client. Each Flatland | 
|  | /// instance may only specify a single root transform, so other objects in the graph can only be | 
|  | /// children of a single GraphLink. However, more than one GraphLink protocol may be active at a | 
|  | /// time for a particular Flatland instance. Specifically, when a Flatland instance is transitioning | 
|  | /// from using one Link to another, each Link will have a separate protocol instance, and more than | 
|  | /// one protocol may receive certain updates. | 
|  | protocol GraphLink { | 
|  | /// A hanging get for receiving layout information. Clients may receive layout information | 
|  | /// before the GraphLink operation has been presented. This allows children to layout their | 
|  | /// content before their first call to Present(). In transition cases where two GraphLink | 
|  | /// channels exist at the same time, both protocol instances will be receiving different layout | 
|  | /// information. | 
|  | /// | 
|  | /// This hanging get will only fire when the LayoutInfo is different than the previously | 
|  | /// returned LayoutInfo. Note that, since LayoutInfo is a table, only some fields may have | 
|  | /// changed. | 
|  | GetLayout() -> (LayoutInfo info); | 
|  |  | 
|  | /// A hanging get for receiving the status of the Link. This provides global connectivity | 
|  | /// information to the child. | 
|  | /// | 
|  | /// This hanging get will only fire when the GraphLinkStatus is different than the previously | 
|  | /// returned GraphLinkStatus. | 
|  | GetStatus() -> (GraphLinkStatus status); | 
|  | }; | 
|  |  | 
|  | enum ContentLinkStatus { | 
|  | /// The underlying Graph has connected its Link, called Present(), and the acquisition fences | 
|  | /// of the Present() call have all be reached, indicating that it has some content ready to be | 
|  | /// displayed. | 
|  | CONTENT_HAS_PRESENTED = 0; | 
|  | }; | 
|  |  | 
|  | /// A protocol that provides information about a particular Link to the parent client. Flatland | 
|  | /// instances may contain any number of ContentLinks, each of which may or may not be attached to | 
|  | /// the Root Transform. Each ContentLink has its own protocol instance. | 
|  | protocol ContentLink { | 
|  | /// A hanging get for receiving the status of a Link. This provides information to the parent, | 
|  | /// such as whether or not the child has successfully presented content through this Link. | 
|  | /// | 
|  | /// This hanging get will only fire when the ContentLinkStatus is different than the previously | 
|  | /// returned ContentLinkStatus. | 
|  | GetStatus() -> (ContentLinkStatus status); | 
|  | }; | 
|  |  | 
|  | /// A typed wrapper for an eventpair, representing the child endpoint of a Link. | 
|  | resource struct GraphLinkToken { | 
|  | zx.handle:EVENTPAIR value; | 
|  | }; | 
|  |  | 
|  | /// A typed wrapper for an eventpair, representing the parent endpoint of a Link. | 
|  | resource struct ContentLinkToken { | 
|  | zx.handle:EVENTPAIR value; | 
|  | }; | 
|  |  | 
|  | /// The properties of a Link as defined by the parent. This data, along with the set of attached | 
|  | /// Transforms, will be used to compute the LayoutInfo for the child of the Link. | 
|  | table LinkProperties { | 
|  | /// The size of the Link in logical pixels. This maps directly to the logical_size field in | 
|  | /// LayoutInfo. | 
|  | 1: Vec2 logical_size; | 
|  | }; | 
|  |  | 
|  | /// The properties of an Image as defined by the client. These properties determine how an Image | 
|  | /// uses the backing BufferCollection. See CreateImage() for more information. | 
|  | table ImageProperties { | 
|  | /// The width of the Image in pixels. | 
|  | 1: uint32 width; | 
|  | /// The height of the Image in pixels. | 
|  | 2: uint32 height; | 
|  | }; | 
|  |  | 
|  | /// A user-defined identifier for a particular transform. See CreateTransform() and | 
|  | /// ReleaseTransform() for more information. | 
|  | alias TransformId = uint64; | 
|  |  | 
|  | /// A user-defined identifier for a particular BufferCollection. See RegisterBufferCollection() | 
|  | /// for more information. | 
|  | alias BufferCollectionId = uint64; | 
|  |  | 
|  | /// A user-defined identifier for a particular piece of Content. See Content creation functions | 
|  | /// (e.g. CreateLink(), CreateImage()) for more information. | 
|  | alias ContentId = uint64; | 
|  |  | 
|  | // A maximum of 16 fences is enough for the current usage of these APIs. | 
|  | const int32 MAX_ACQUIRE_RELEASE_FENCE_COUNT = 16; | 
|  |  | 
|  | /// Arguments passed into Present(). All arguments are optional, and if an | 
|  | /// argument is omitted Flatland will use a reasonable default, specified below. | 
|  | resource table PresentArgs { | 
|  | /// `requested_presentation_time` specifies the time on or after which the client would like the | 
|  | /// enqueued operations to take visible effect (light up pixels on the screen), expressed in | 
|  | /// nanoseconds in the `CLOCK_MONOTONIC` timebase. | 
|  | /// | 
|  | /// The default `requested_presentation_time` is 0. | 
|  | /// | 
|  | /// Using a `requested_presentation_time` in the present or past (such as 0) schedules enqueued | 
|  | /// operations to take visible effect as soon as possible, during the next frame to be prepared. | 
|  | /// | 
|  | /// Using a `requested_presentation_time` in the future schedules the enqueued operations to | 
|  | /// take visible effect on or as closely as possible after the stated time, but no earlier. | 
|  | /// | 
|  | /// Each rendered frame has a target presentation time. This is when Flatland aims to have the | 
|  | /// frame presented to the user. Before rendering a frame, Flatland applies all | 
|  | /// enqueued operations associated with all squashable calls to Present() whose | 
|  | /// `requested_presentation_time` is on or before the frame's target presentation time. | 
|  | 1: zx.time requested_presentation_time; | 
|  |  | 
|  | /// Flatland will wait until all of a session's `acquire_fences` are ready before it will | 
|  | /// execute the presented commands. | 
|  | /// | 
|  | /// The default `acquire_fences` value is the empty vector. | 
|  | 2: vector<zx.handle:EVENT>:MAX_ACQUIRE_RELEASE_FENCE_COUNT acquire_fences; | 
|  |  | 
|  | /// Flatland will signal all `release_fences` when the resources and shared buffers from this | 
|  | /// Present() are no longer in use. Callers should not modify shared resources, such as | 
|  | /// BufferCollections, until after these fences are signaled. | 
|  | /// | 
|  | /// If an error occurrs, release fences are not necessarily fired as Flatland can close the | 
|  | /// client's instance at any point. | 
|  | /// | 
|  | /// The default `release_fences` value is the empty vector. | 
|  | 3: vector<zx.handle:EVENT>:MAX_ACQUIRE_RELEASE_FENCE_COUNT release_fences; | 
|  |  | 
|  | /// If `squashable` is true, then an update can be combined with those that | 
|  | /// come after it. If `squashable` is false, then the update is guaranteed | 
|  | /// to be shown for at least one vsync interval. | 
|  | /// | 
|  | /// The default `squashable` value is true. | 
|  | 4: bool squashable; | 
|  | }; | 
|  |  | 
|  | /// Each Flatland instance contains a Graph, which consists of a set of objects, and the | 
|  | /// relationships between those objects. The client can specify a subset of those objects | 
|  | /// (specifically, the directed acyclic graph starting at the root transform) to be presented as | 
|  | /// content to some kind of output -- usually, a display. | 
|  | /// | 
|  | /// Flatland Graphs are both hierarchical, and distributed. Graphs from different Flatland instances | 
|  | /// may be linked together, allowing multiple processes to be involved in authoring content for a | 
|  | /// particular output. | 
|  | /// | 
|  | /// All functions in this protocol are feed-forward. The operations they represent are not fully | 
|  | /// executed until Present() is called. | 
|  | [Discoverable] | 
|  | protocol Flatland { | 
|  | /// Complete execution of all feed-forward operations. | 
|  | /// | 
|  | /// If executing an operation produces an error (e.g., CreateTransform(0)), Present() will | 
|  | /// return an error. Operations that produce errors are ignored. Future operations are still | 
|  | /// executed. | 
|  | /// | 
|  | /// The client may only call Present() when they have a non-zero number of "present tokens", | 
|  | /// which are tracked by the server. The server may increment the counter when it fires the | 
|  | /// OnPresentTokensReturned() event, which informs the client when it receives additional | 
|  | /// tokens. Each Present() call uses one "present token" and decrements the server count by | 
|  | /// one. If the client calls Present() when no tokens remain, it will return | 
|  | /// `NO_PRESENTS_REMAINING`. | 
|  | /// | 
|  | /// The client should assume that prior to receiving any OnPresentTokensReturned() events, they | 
|  | /// have one present token. | 
|  | /// | 
|  | /// Every Present() call results in one OnPresentTokensReturned() event, and one | 
|  | /// OnFramePresented() event, typically in that order. | 
|  | /// | 
|  | /// When the commands flushed by Present() make it to display, an `OnFramePresented` | 
|  | /// event is fired. This event includes information pertaining to all Present()s that had content | 
|  | /// that were part of that frame. | 
|  | /// | 
|  | /// See `PresentArgs` documentation above for more detailed information on what arguments are | 
|  | /// passed in and their role. | 
|  | /// | 
|  | /// TODO(fxbug.dev/36166): Present should stop execution, and kill the channel, when irrecoverable | 
|  | /// errors are detected. | 
|  | Present(PresentArgs args) -> () error Error; | 
|  |  | 
|  | /// Clients may use the timing of this event to begin their rendering work. | 
|  | /// | 
|  | /// This event is fired to give the client additional present tokens, indicating that the | 
|  | /// client can call Present() additional times. | 
|  | -> OnPresentTokensReturned(uint32 present_tokens); | 
|  |  | 
|  | /// This event is fired whenever a set of one or more Present()s are presented simultaneously, | 
|  | /// and are therefore no longer in flight. | 
|  | /// TODO(fxbug.dev/63305): remove `num_presents_allowed` from this event. | 
|  | -> OnFramePresented(fuchsia.scenic.scheduling.FramePresentedInfo frame_presented_info); | 
|  |  | 
|  | // ***** Graph management ***** | 
|  |  | 
|  | /// A Link is a connection between the objects authored in this Graph, and the objects in | 
|  | /// the Graph of another process. The parent process has control over how the linked content is | 
|  | /// integrated into their Graph. | 
|  | /// | 
|  | /// A link is formed by creating an event pair, passing one end to the parent (which calls | 
|  | /// CreateLink()) and the other end to the child (which calls LinkToParent()). | 
|  | /// | 
|  | /// Only nodes connected to the Root Transform in this Flatland instance will be rendered as | 
|  | /// part of the parent's Graph. | 
|  | /// | 
|  | /// Calling LinkToParent() a second time will disconnect the Root Transform from the existing | 
|  | /// parent's Graph, and attach it to a new parent's Graph. | 
|  | /// | 
|  | /// This function is feed-forward, meaning that the Root Transform will not be attached to the | 
|  | /// parent Graph until Present() is called. However, Clients will receive information through | 
|  | /// their GraphLinkListener (e.g., LayoutInfo) immediately after calling this function, even if | 
|  | /// they have not called Present() or SetRoot(). This allows clients to wait for layout | 
|  | /// information from their parent before calling Present(), if they wish. | 
|  | LinkToParent(GraphLinkToken token, request<GraphLink> graph_link); | 
|  |  | 
|  | /// Disconnects this Graph from its parent Graph and returns the GraphLinkToken used to | 
|  | /// establish the link. This token can then be used to establish a new link with the Parent | 
|  | /// graph. | 
|  | /// | 
|  | /// To clear the existing content from the screen without unlinking the current Graph, use | 
|  | /// SetRootTransform(0) instead. | 
|  | /// | 
|  | /// Despite having a return type, this function is still feed-forward Like LinkToParent() and | 
|  | /// requires a call to Present() to be executed. The GraphLinkToken will be returned after the | 
|  | /// presented operations have been executed. | 
|  | UnlinkFromParent() -> (GraphLinkToken token); | 
|  |  | 
|  | /// This function will reset all state on this interface. This includes destroying all existing | 
|  | /// Links without returning the associated Token to the caller. | 
|  | ClearGraph(); | 
|  |  | 
|  | // ***** Transforms ***** | 
|  |  | 
|  | // Transform constructors. | 
|  |  | 
|  | /// Creates a new Transform node. Transforms are a hierarchical piece of a Flatland graph. They | 
|  | /// can have children, and can reference Content. A sub-graph represented by a Transform and its | 
|  | /// descendants can be rendered to a display. | 
|  | /// | 
|  | /// Transforms are kept alive, even when released, as long as they are children of either an | 
|  | /// unreleased Transform, or the Root Transform. | 
|  | /// | 
|  | /// Each Transform can have a single piece of attached Content. Common types of Content include | 
|  | /// bitmaps, asynchronous streams of images, and links to Transforms in other processes. | 
|  | /// | 
|  | /// Transforms have attributes. Child Transforms inherit the combined attributes of their | 
|  | /// parents. Content attached to a Transform is also affected by that Transform's attributes. | 
|  | /// | 
|  | /// When a sub-graph of Transforms is rendered, Content will be rendered back-to-front, starting | 
|  | /// with the Content on the root transform, and continuing recursively through all of its child | 
|  | /// Transforms in the order the children were added. See AddChild() for more information. | 
|  | /// | 
|  | /// Zero is not a valid transform id. All other values are valid, assuming they are not already | 
|  | /// in use (see ReleaseTransform() for more details). | 
|  | CreateTransform(TransformId transform_id); | 
|  |  | 
|  | // ***** Attributes ***** | 
|  |  | 
|  | /// All Transform objects support all attributes. | 
|  | /// | 
|  | /// Geometric attributes are applied in the following order: | 
|  | /// 1. Translation (relative to the parent's coordinate space) | 
|  | /// 2. Orientation (around the new origin as defined by the translation) | 
|  | /// 3. Scale (relative to the new rotated origin) | 
|  | /// 4. Crop (in the scaled coordinate space) | 
|  | /// | 
|  | /// Sets the translation on a Transform. The order of geometric attribute application is | 
|  | /// addressed above. | 
|  | SetTranslation(TransformId transform_id, Vec2 translation); | 
|  |  | 
|  | /// Sets the orientation on a Transform. The order of geometric attribute application is | 
|  | /// addressed in the documentation for SetTranslation(). | 
|  | SetOrientation(TransformId transform_id, Orientation orientation); | 
|  |  | 
|  | /// Sets the scale on a Transform. The order of geometric attribute application is addressed | 
|  | /// in the documentation for SetTranslation(). | 
|  | SetScale(TransformId transform_id, Vec2 scale); | 
|  |  | 
|  | // Transform management | 
|  |  | 
|  | /// Adds a child Transform to a parent Transform. The new child Transform, and any Content | 
|  | /// attached to it or its children, will be rendered on top of the parent's Content, as well as | 
|  | /// any previously added children. | 
|  | AddChild(TransformId parent_transform_id, TransformId child_transform_id); | 
|  |  | 
|  | /// Removes a child Transform from a parent Transform. | 
|  | RemoveChild(TransformId parent_transform_id, TransformId child_transform_id); | 
|  |  | 
|  | /// Sets the Root Transform for the graph. | 
|  | /// | 
|  | /// The sub-graph defined by the Root Transform and its children will be rendered as Content | 
|  | /// in the linked parent Graph (see LinkToParent()). Any parents of the Root Transform in this | 
|  | /// Graph will be ignored. | 
|  | /// | 
|  | /// The Root Transform, and all children of the Root Transform, are kept alive if they are | 
|  | /// released (see ReleaseTransform() for more details). | 
|  | /// | 
|  | /// There is only ever one Root. Since 0 is not a valid transform id (see CreateTransform()), | 
|  | /// calling SetRootTransform(0) clears the current Root, destroying any previously released | 
|  | /// objects that are not referenced by the new root. | 
|  | SetRootTransform(TransformId transform_id); | 
|  |  | 
|  | // ***** Content ***** | 
|  |  | 
|  | // Content comes in many forms, but most content can be treated conceptually as a bitmap. | 
|  | // Content is attached to Transforms. Each Transform can have, at most, one piece of attached | 
|  | // Content. Content will inherit all of the attributes from its attached Transform (which | 
|  | // inherits the attributes of its parent Transform, and so on). | 
|  |  | 
|  | // Content is contained within a unit rectangle, with the top-left corner at the origin of the | 
|  | // coordinate space defined by the attached Transform. Content can be resized using either | 
|  | // scale attributes on transforms, or the appropriate Content mutators. | 
|  |  | 
|  | // Content constructors | 
|  |  | 
|  | /// A Link is a connection between the objects authored in this Graph, and the objects in | 
|  | /// another process. The parent process has control over how the linked Content is integrated | 
|  | /// into their Graph through this Link object, and the object's associated Link properties. | 
|  | /// | 
|  | /// `LinkProperties` must have logical_size set. This is the initial size that will drive the | 
|  | /// layout of the child. The logical_size is also used as the default Content size, but | 
|  | /// subsequent changes to the logical_size will have no effect on the Content size. | 
|  | /// | 
|  | /// The logical_size must have positive X and Y components. | 
|  | /// | 
|  | /// Zero is not a valid Link id. All other values are valid, assuming they are not already | 
|  | /// in use for another piece of Content (see ReleaseLink() for more details). | 
|  | CreateLink(ContentId link_id, ContentLinkToken token, LinkProperties properties, | 
|  | request<ContentLink> content_link); | 
|  |  | 
|  | /// A BufferCollection is a set of VMOs created by Sysmem and shared by a number of | 
|  | /// participants, one of which is the Flatland Renderer. Some content, such as Images, use a | 
|  | /// BufferCollection as their backing memory. | 
|  | /// | 
|  | /// Flatland participates in the allocation of buffers by setting constraints on the | 
|  | /// BufferCollection referenced by the token. It will not block on buffers being allocated | 
|  | /// until the client creates content using the BufferCollection. | 
|  | /// | 
|  | /// Zero is not a valid buffer collection id. All other values are valid, assuming they are not | 
|  | /// already in use (see UnregisterBufferCollection() for more details). | 
|  | RegisterBufferCollection(BufferCollectionId buffer_id, | 
|  | fuchsia.sysmem.BufferCollectionToken token); | 
|  |  | 
|  | /// An Image is a bitmap backed by a specific VMO in a BufferCollection. | 
|  | /// | 
|  | /// Image creation requires an allocated BufferCollection. This function will fail unless all | 
|  | /// clients of the specified BufferCollection have set their constraints. | 
|  | /// | 
|  | /// The Image must reference a valid VMO index and must have ImageProperties that fall within | 
|  | /// the constraints specified by the backing BufferCollection (i.e. width and height within a | 
|  | /// valid range, accepted pixel format, etc.) | 
|  | /// | 
|  | /// Zero is not a valid Image id. All other values are valid, assuming they are not already in | 
|  | /// use for another piece of Content (see ReleaseImage() for more details). | 
|  | CreateImage(ContentId image_id, BufferCollectionId buffer_id, uint32 vmo_index, | 
|  | ImageProperties properties); | 
|  |  | 
|  | // Content management | 
|  |  | 
|  | /// Setting a piece of Content on a Transform makes that Content visible in the render tree as | 
|  | /// long as the Transform is visible from the root Transform. The Content will be rendered | 
|  | /// before, and therefore "behind", any Content attached to the descendants of the Transform. | 
|  | /// | 
|  | /// Because each Transform can have, at most, a single piece of Content on it, calling this | 
|  | /// function on a Transform that already has Content will replace that Content. | 
|  | /// | 
|  | /// Calling this function with a Content id of 0 will remove any Content currently on the | 
|  | /// Transform. | 
|  | SetContentOnTransform(ContentId content_id, TransformId transform_id); | 
|  |  | 
|  | // Content mutators | 
|  |  | 
|  | /// Transforms are usually sufficient to change how Content is presented. Links, however, have | 
|  | /// special properties that are not part of the Transform hierarchy. Those properties can be set | 
|  | /// using this function. | 
|  | /// | 
|  | /// The logical_size must have positive X and Y components. | 
|  | SetLinkProperties(ContentId link_id, LinkProperties properties); | 
|  |  | 
|  | /// The Content size for a Link is the size of the rectangle in the parent's space that the | 
|  | /// Link occupies. This effectively applies a scale to the Link Content equal to the ratio from | 
|  | /// its Content size to its logical_size. | 
|  | /// | 
|  | /// The Link Content size must have positive X and Y components. | 
|  | SetLinkSize(ContentId link_id, Vec2 size); | 
|  |  | 
|  | // ***** Cleanup operations ***** | 
|  |  | 
|  | /// Released Transforms will be garbage collected by the system once they are no longer | 
|  | /// necessary for rendering. For Transforms, this means there is no path from any unreleased | 
|  | /// Transform to the newly-released Transform. | 
|  | /// | 
|  | /// Once released, the id immediately goes out of scope for future function calls and can be | 
|  | /// reused when creating new Transforms. | 
|  | /// | 
|  | /// It is an error to call functions with a released id (unless that id has been reused to | 
|  | /// construct a new Transform). | 
|  | ReleaseTransform(TransformId transform_id); | 
|  |  | 
|  | /// Releasing a Link removes the attached sub-Graph from the scene, even if the Link is still | 
|  | /// connected to a Transform. Unlike other resources, Links are garbage collected by the system | 
|  | /// during the next Present() because a released Link is guaranteed to provide no renderable | 
|  | /// content. | 
|  | /// | 
|  | /// Use SetLinkOnTransform(transform_id, 0) to clean up references to deleted Links. | 
|  | /// | 
|  | /// Despite having a return type, this function is still feed-forward like LinkToParent() and | 
|  | /// requires a call to Present() to be executed. The ContentLinkToken will be returned after the | 
|  | /// presented operations have been executed. | 
|  | ReleaseLink(ContentId link_id) -> (ContentLinkToken token); | 
|  |  | 
|  | /// Deregistered buffer collections will be garbage collected by the system when they are no | 
|  | /// longer referenced by any Images, and thus no longer necessary for rendering. This includes | 
|  | /// references from released Images that have not yet been fully garbage collected, such as | 
|  | /// Images still referenced by a Transform or Images involved in a current or pending render. | 
|  | /// | 
|  | /// Once released, the id immediately goes out of scope for future function calls and can be | 
|  | /// reused when creating new BufferCollections. | 
|  | /// | 
|  | /// It is an error to call functions with a released id (unless that id has been reused to | 
|  | /// construct a new buffer collection). | 
|  | DeregisterBufferCollection(BufferCollectionId id); | 
|  |  | 
|  | /// Released Images will be garbage collected by the system once they are no longer necessary | 
|  | /// for rendering. For Images, this means the Image is no longer attached to any Transform and | 
|  | /// any pending rendering that references the Image is complete. | 
|  | /// | 
|  | /// Use SetImageOnTransform(transform_id, 0) to clean up references to released Images. | 
|  | /// | 
|  | /// Once released, the id immediately goes out of scope for future function calls and can be | 
|  | /// reused when creating new Images. | 
|  | /// | 
|  | /// It is an error to call functions with a released id (unless that id has been reused to | 
|  | /// construct a new Image). | 
|  | ReleaseImage(ContentId image_id); | 
|  | }; |