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

/// Arguments passed into Present2(). Note that every argument is mandatory.
type Present2Args = resource table {
    /// `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: requested_presentation_time zx.time;

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

    /// `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: release_fences vector<zx.handle:EVENT>;

    /// `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: requested_prediction_span zx.duration;
};

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

    // 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(resource struct {
        presentation_time uint64;
        acquire_fences vector<zx.handle:EVENT>;
        release_fences vector<zx.handle:EVENT>;
    }) -> (struct {
        presentation_info fuchsia.images.PresentationInfo;
    });

    /// 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(resource struct {
        args Present2Args;
    }) -> (struct {
        request_presentation_times_info fuchsia.scenic.scheduling.FuturePresentationTimes;
    });

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

    /// 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(struct {
        requested_prediction_span zx.duration;
    }) -> (struct {
        request_presentation_times_info fuchsia.scenic.scheduling.FuturePresentationTimes;
    });

    /// 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(resource struct {
        buffer_id uint32;
        token client_end:fuchsia.sysmem.BufferCollectionToken;
    });

    /// 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(struct {
        buffer_id uint32;
    });

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

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

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