// 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.scenic.scheduling;

/// Arguments passed into Present2(). Note that every argument is mandatory.
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<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<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(SCN-400): 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<handle<event>> acquire_fences, vector<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.scenic.scheduling.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.scenic.scheduling.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.scenic.scheduling.FuturePresentationTimes request_presentation_times_info);

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