// 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 fuchsia.images;

/// 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.
    Present(uint64 presentation_time,
            vector<handle<event>> acquire_fences, vector<handle<event>> release_fences)
        -> (fuchsia.images.PresentationInfo presentation_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);
};
