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

/// 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.
    ///
    /// SCHEDULING PRESENTATIONS
    ///
    /// |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.
    ///
    /// SYNCHRONIZATION
    ///
    /// Scenic will wait until all of a session's |acquire_fences| are ready
    /// before it will execute the presented commands.
    ///
    /// |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.
    Present2(zx.time requested_presentation_time,
             vector<handle<event>> acquire_fences, vector<handle<event>> release_fences,
             zx.duration requested_prediction_span)
        -> (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);
};
