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

// ImagePipe is a mechanism for streaming shared images between a producer
// and a consumer which may be running in different processes.
//
// Conceptually, the image pipe maintains a table of image resources supplied
// by the producer into which graphical content may be stored as well as a
// presentation queue containing a sequence of images which the producer has
// asked the consumer to present.
//
// The presentation queue is initially empty.
//
// Each entry in the presentation queue consists of an image together with a
// pair of optional synchronization fences:
// - Acquire fence: signaled by the producer when the image is ready to be consumed
// - Release fence: signaled by the consumer when the image is free to be freed or
//   modified by the producer
//
// The producer performs the following sequence of steps to present content:
// - Allocate and add some number of images (often 2 or 3) to the image pipe
//   to establish a pool using |AddImage()|.
// - Obtain the next available image from the pool.
// - Ask the consumer to enqueue an image for presentation and provide fences
//   using |PresentImage()|.
// - Start rendering the image.
// - Signal the image's acquire fence when rendering is complete.
// - Loop to present more image, listen for signals on release fences to recycle
//   images back into the pool.
//
// The consumer performs the following sequence of steps for each image which
// is enqueued in the presentation queue:
// - Await signals on the image's acquire fence.
// - If the fence wait cannot be satisfied or if some other error is detected,
//   close the image pipe.
//   Otherwise, begin presenting the image's content.
// - Retire the previously presented image (if any) from the presentation queue
//   and signal its release fence when no longer needed.
// - Continue presenting the same image until the next one is ready.  Loop.
//
// If the producer wants to close the image pipe, it should:
// - Close its side of the connection.
// - Wait on all release fences for buffers that it has submitted with
//   |PresentImage()|.
// - Proceed with resource cleanup.
//
// When the consumer detects the image pipe has closed, it should:
// - Stop using/presenting any images from the pipe.
// - Unmap all VMOs associated with the images in the pipe.
// - Close all handles to the VMOs.
// - Signal all release fences for presented and queued buffers.
// - Close all handles to fences.
// - Close its side of the connection.
//
// When either party detects that a fence has been abandoned (remotely closed
// without being signaled) it should assume that the associated image is in
// an indeterminate state.  This will typically happen when the other party
// (or one of its delegates) has crashed.  The safest course of action is to
// close the image pipe, release all resources which were shared with the
// other party, and re-establish the connection to recover.
interface ImagePipe {
    // Adds an image resource to image pipe.
    //
    // The |memory| is the handle of a memory object which contains the image
    // data.  It is valid to create multiple images backed by the same memory
    // object; they may even overlap.  Consumers must detect this and handle
    // it accordingly.  The |offset_bytes| indicates the offset within the
    // memory object at which the image data begins.  The |size_bytes|
    // indicates the amount of memory from |memory| that should be utilized.
    // The type of memory stored in the VMO is |memory_type| (e.g. GPU memory,
    // host memory).
    //
    // The following errors will cause the connection to be closed:
    // - |image_id| is already registered
    // - |image_info| represents a format not supported by the consumer
    // - |memory| is not a handle for a readable VMO
    // - the image data expected at |offset_bytes| according to the |image_info|
    //   exceeds the memory object's bounds
    1: AddImage(uint32 image_id, ImageInfo image_info,
                handle<vmo> memory, uint64 offset_bytes, uint64 size_bytes, MemoryType memory_type);

    // Removes an image resource from the pipe.
    //
    // The |image_id| is detached from the image resource and is free to be
    // reused to add a new image resource.
    //
    // Removing an image from the image pipe does not affect the presentation
    // queue or the currently presented image.
    //
    // The producer must wait for all release fences associated with the image to
    // be signaled before freeing or modifying the underlying memory object since
    // the image may still be in use in the presentation queue.
    //
    // The following errors will cause the connection to be closed:
    // - |image_id| does not reference a currently registered image resource
    2: RemoveImage(uint32 image_id);

    // Enqueues the specified image for presentation by the consumer.
    //
    // The |acquire_fences| are a set of fences which must all be signaled by the
    // producer before the consumer presents the image.
    // The |release_fences| are set of fences which must all be signaled by the
    // consumer before it is safe for the producer to free or modify the image.
    // |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.
    //
    // |presentation_info| returns timing information about the submitted frame
    // and future frames (see presentation_info.fidl).
    //
    // The following errors will cause the connection to be closed:
    // - |image_id| does not reference a currently registered image resource
    3: PresentImage(uint32 image_id, uint64 presentation_time,
                    vector<handle<event>> acquire_fences, vector<handle<event>> release_fences)
           -> (PresentationInfo presentation_info);
};
