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

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

    // 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.
    //
    // 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.
    //
    // SYNCHRONIZATION
    //
    // |acquire_fences| are used by Mozart 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 Mozart 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 Mozart 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 Mozart 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, Mozart 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 Mozart 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.
    //
    // TODO(MZ-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?
    2: Present(uint64 presentation_time,
               vector<handle<event>> acquire_fences, vector<handle<event>> release_fences)
           -> (fuchsia.images.PresentationInfo presentation_info);

    // TODO(MZ-422) Remove these methods from the FIDL; they should just be
    // exposed to View Manager directly using a C++ interface.
    3: HitTest(uint32 node_id, fuchsia.ui.gfx.vec3 ray_origin, fuchsia.ui.gfx.vec3 ray_direction)
           -> (vector<fuchsia.ui.gfx.Hit>? hits);
    4: HitTestDeviceRay(fuchsia.ui.gfx.vec3 ray_origin, fuchsia.ui.gfx.vec3 ray_direction)
           -> (vector<fuchsia.ui.gfx.Hit>? hits);

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

// Listens for events which occur within the session.
interface SessionListener {
    // Called when an error has occurred and the session will be torn down.
    1: 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.
    2: OnScenicEvent(vector<Event> events);
};
