// 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); };