// 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.
protocol 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
    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
    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
    PresentImage(uint32 image_id, uint64 presentation_time,
                 vector<handle<event>> acquire_fences, vector<handle<event>> release_fences)
        -> (PresentationInfo presentation_info);
};
