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

using zx;
using fuchsia.images;
using fuchsia.ui.composition;
using fuchsia.sysmem;

/// Arguments passed into Present2(). Note that every argument is mandatory.
resource table Present2Args {
    /// `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.
    ///
    /// 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. Requested presentation
    /// times must be monotonically increasing.
    ///
    /// Using a `requested_presentation_time` in the future schedules the enqueued
    /// operations to take visible effect as closely as possible to or after
    /// the stated time, but no earlier.
    ///
    /// Each rendered frame has a target presentation time. This is when Scenic
    /// aims to have the frame presented to the user. Before rendering a frame,
    /// the scene manager applies all enqueued operations associated with all
    /// prior calls to Present2 whose `requested_presentation_time` is on or
    /// before the frame's target presentation time.
    1: zx.time requested_presentation_time;

    /// Scenic will wait until all of a session's `acquire_fences` are ready
    /// before it will execute the presented commands.
    2: vector<zx.handle:EVENT> acquire_fences;

    /// `release_fences` is the list of events that will be signalled by Scenic when
    /// the following Present2 call's `acquire_fences` has been signalled, and
    /// the updated session state has been fully committed: future frames will be
    /// rendered using this state, and all frames generated using previous session
    /// states have been fully-rendered and presented to the display.
    3: vector<zx.handle:EVENT> release_fences;

    /// `requested_prediction_span` is the amount of time into the future Scenic
    /// will provide predictions for. A span of 0 is guaranteed to provide at
    /// least one future time.
    4: zx.duration requested_prediction_span;
};

/// Client use Sessions to interact with a Scenic instance by enqueuing commands
/// that create or modify resources.
protocol Session {
    Enqueue(vector<Command> cmds);

    // TODO(jeffbrown): Defining presentation time in terms of `CLOCK_MONOTONIC`
    // simplifies synchronization across subsystems but it might be too simple.
    // We should consider using a synthetic timebase and describing its relation
    // to other clocks separately.  That would make it possible to present
    // content (animations, media, and UI) in "slow mode" simply by varying the
    // timing relation, assuming clients play along.
    // TODO(fxbug.dev/23637): document invariants that apply to `presentation_info`.  Is it
    // strong enough to guarantee that receiving the response means that all
    // previously-enqueued Commands have been applied?  Or does it need to be stronger,
    // e.g. that all frames based on previous presentations are completely done,
    // and subsequent frames will be rendered based on the most recent presented
    // content?
    /// Present all previously enqueued operations.  In order to pipeline the
    /// preparation of the resources required to render the scene, two lists of
    /// fences (implemented as events) are passed.
    ///
    /// SCHEDULING PRESENTATION
    ///
    /// `presentation_time` specifies the time on or after which the
    /// client would like the enqueued operations should take visible effect
    /// (light up pixels on the screen), expressed in nanoseconds in the
    /// `CLOCK_MONOTONIC` timebase.  Desired presentation times must be
    /// monotonically non-decreasing.
    ///
    /// Using a desired 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 desired presentation time in the future schedules the enqueued
    /// operations to take visible effect as closely as possible to or after
    /// the stated time (but no earlier).
    ///
    /// Each rendered frame has a target presentation time.  Before rendering
    /// a frame, the scene manager applies all enqueued operations associated
    /// with all prior calls to `Present()` whose desired presentation time
    /// is on or before the frame's target presentation time.
    ///
    /// The `Present()` method does not return until the scene manager begins
    /// preparing the first frame which includes its presented content.
    /// Upon return, the `PresentationInfo` provides timing information for the
    /// frame which includes the presented content.
    ///
    /// To present new content on each successive frame, wait for `Present()`
    /// to return before calling `Present()` again with content for the next
    /// frame.
    ///
    /// It is also possible to enqueue and present successive frames of content
    /// all at once with increasing desired presentation times, incrementing by
    /// `PresentationInfo.presentation_interval` for each one.
    ///
    /// Animation updates are also coordinated in terms of presentation time.
    ///
    /// SYNCHRONIZATION
    ///
    /// `acquire_fences` are used by Scenic to wait until all of the session's
    /// resources are ready to render (or to allow downstream components, such as
    /// the Vulkan driver, to wait for these resources).
    ///
    /// For example, Fuchsia's Vulkan driver allows an zx::event to be obtained
    /// from a VkSemaphore.  This allows a Scenic client to submit a Vulkan command
    /// buffer to generate images/meshes/etc., and instructing Vulkan to signal a
    /// VkSemaphore when it is done.  By inserting the zx::event corresponding to
    /// this semaphore into `acquire_fences`, the client allows Scenic to submit work
    /// to the Vulkan driver without waiting on the CPU for the event to be
    /// signalled.
    ///
    /// `release_fences` is a list of events that will be signalled by Scenic when
    /// the updated session state has been fully committed: future frames will be
    /// rendered using this state, and all frames generated using previous session
    /// states have been fully-rendered and presented to the display.
    ///
    /// Together, `acquire_fences` and `release_fences` are intended to allow clients
    /// to implement strategies such as double-buffering.  For example, a client
    /// might do the following in the Scenic subsystem:
    ///   1) create two Image with resource IDs #1 and #2.
    ///   2) create two Materials with resource IDs #3 and #4, which respectively
    ///      use Images #1 and #2 as their texture.
    ///   3) create a tree of Nodes and attach them to the scene.
    ///   4) set one of the nodes above, say #5, to use Material #3.
    ///   5) submit a Vulkan command-buffer which renders into Image #1, and
    ///      will signal a VkSemaphore.
    ///   6) call Present() with one acquire-fence (obtained from the VkSemaphore
    ///      above) and one newly-created release-fence.
    ///
    /// After the steps above, Scenic will use the committed session state to render
    /// frames whenever necessary.  When the client wants to display something
    /// different than Image #1, it would do something similar to steps 4) to 6):
    ///   7) set Node #5 to use Material #4.
    ///   8) submit a Vulkan command-buffer which renders into Image #1, and
    ///      will signal a VkSemaphore.
    ///   9) call Present() with one acquire-fence (obtained from the VkSemaphore
    ///      above) and one newly-created release-fence.
    ///
    /// Finally, to continually draw new content, the client could repeat steps
    /// 4) to 9), with one important difference: step 5) must wait on the event
    /// signalled by step 9).  Otherwise, it might render into Image #1 while that
    /// image is still being used by Scenic to render a frame.  Similarly, step 8)
    /// must wait on the event signalled by step 6).
    ///
    /// The scenario described above uses one acquire-fence and one release-fence,
    /// but it is easy to imagine cases that require more.  For example, in addition
    /// to using Vulkan to render into Images #1 and #2, the client might also
    /// upload other resources to Vulkan on a different VkQueue, which would
    /// would signal a separate semaphore, and therefore require an additional
    /// acquire-fence.
    ///
    /// Note: `acquire_fences` and `release_fences` are only necessary to synchronize
    /// access to memory (and other external resources).  Any modification to
    /// resources made via the Session API are automatically synchronized.
    [Transitional]Present(uint64 presentation_time,
              vector<zx.handle:EVENT> acquire_fences, vector<zx.handle:EVENT> release_fences)
          -> (fuchsia.images.PresentationInfo presentation_info);

    /// Present all previously enqueued operations. In order to pipeline the
    /// preparation of the resources required to render the scene, two lists of
    /// fences, implemented as events, are passed.
    ///
    /// When a client calls Present2, they receive an immediate callback
    /// consisting of the same information they would get as if they had called
    /// `RequestPresentationTimes` with the equivalent
    /// `requested_prediction_span`. See its documentation below for more
    /// information, as Present2's functionality is a superset of it.
    ///
    /// Then, when the commands flushed by Present2 make it to display, an
    /// `OnFramePresented` event is fired. This event includes information
    /// pertaining to all Present2s that had content that were part of that
    /// frame.
    ///
    /// Clients may only use one of Present/Present2 per Session.
    /// Switching between both is an error that will result in the Session being
    /// closed.
    ///
    /// See `Present2Args` documentation above for more detailed information on
    /// what arguments are passed in and their role.
    Present2(Present2Args args)
        -> (fuchsia.ui.composition.FuturePresentationTimes request_presentation_times_info);

    /// This event is fired whenever a set of one or more Present2s are
    /// presented simultaenously, and are therefore no longer in flight.
    -> OnFramePresented(fuchsia.ui.composition.FramePresentedInfo frame_presented_info);

    /// Returns information about future presentation times, and their
    /// respective latch points. Clients can use the returned information to
    /// make informed scheduling decisions: if a client wants their frame to be
    /// displayed at a given `presentation_time`, they should aim to have all
    /// `acquire_fences` fired before the associated `latch_point`.
    ///
    /// Scenic will attempt to return predictions that span a duration equal to
    /// `requested_prediction_span`, up to a limit.
    ///
    /// A value of 0 is guaranteed to give at least one future presentation info.
    RequestPresentationTimes(zx.duration requested_prediction_span)
        -> (fuchsia.ui.composition.FuturePresentationTimes request_presentation_times_info);

    /// Registers BufferCollection referenced by the `token` and sets contraints on it.
    /// It does not block on the buffers being allocated until content backed by one of the
    /// collection's VMOs is created, e.g. an Image2.
    ///
    /// A value of 0 for the `buffer_id` is invalid. All other values are valid as long as they
    /// are not currently in use.
    RegisterBufferCollection(uint32 buffer_id, fuchsia.sysmem.BufferCollectionToken token);

    /// Deregisters the BufferCollection previously registered with the `buffer_id` and sets it
    /// to be garbage collected as soon as it is no longer referenced by any resources.
    ///
    /// Only `buffer_id` that have been previously registered and not yet deregistered are valid.
    DeregisterBufferCollection(uint32 buffer_id);

    /// Set an optional debug name for the session. The debug name will be
    /// output in things such as logging and trace events.
    SetDebugName(string debug_name);
};

/// Listens for events which occur within the session.
protocol SessionListener {
    /// Called when an error has occurred and the session will be torn down.
    OnScenicError(string error);

    /// Called to deliver a batch of one or more events to the listener.
    /// Use `SetEventMaskCmd` to enable event delivery for a resource.
    OnScenicEvent(vector<Event> events);
};
