// 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;

/// 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.
    ///
    /// `requested_presentation_time` specifies the time on or after which the results of the
    /// Present() should take visible effect, expressed in nanoseconds in the `CLOCK_MONOTONIC`
    /// timebase. A `requested_presentation_time` in the present or past (such as 0) schedules the
    /// Present() to take visible effect as soon as possible (i.e. during the next frame). A
    /// `requested_presentation_time` in the future schedules the Present() to take visible effect
    /// as closely as possible to or after the stated time, but no earlier. Times must be
    /// monotonically increasing.
    ///
    /// Flatland will not access any content or shared buffers created since the previous
    /// Present() until the caller signals all `acquire_fences`. As a result, the updates
    /// associated with a Present() will not be visible to the user until the caller signals all
    /// `acquire_fences`. If the `acquire_fences` are not signalled before the
    /// `requested_presentation_time` is reached, the Present() will be delayed.
    ///
    /// 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.
    ///
    /// TODO(fxbug.dev/36166): Present should stop execution, and kill the channel, when irrecoverable errors
    /// are detected.
    ///
    /// The client may only call Present() when they have a non-zero number of "present tokens",
    /// which are tracked by the server. The server increments 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.
    Present(zx.time requested_presentation_time, vector<zx.handle:EVENT>:16 acquire_fences,
            vector<zx.handle:EVENT>:16 release_fences) -> () error Error;

    /// This event is fired to give the client additional present tokens, indicating that the
    /// client can call Present() additional times. `present_tokens` will always be greater than
    /// zero.
    -> 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);
};
