| // Copyright 2019 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; |
| |
| using fuchsia.sysmem; |
| |
| // A maximum of 16 fences is enough for the current usage of these APIs. |
| const int32 MAX_ACQUIRE_RELEASE_FENCE_COUNT = 16; |
| |
| /// 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 BufferCollections to the image pipe to allow |
| /// consumer to set constraints. |
| /// - 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 memory objects associated with the images in the pipe. |
| /// - Close all BufferCollection resources. |
| /// - 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 ImagePipe2 { |
| /// Adds a BufferCollection resource to the image pipe. |
| /// |
| /// The producer is expected to set constraints on this resource for images added |
| /// via `AddImage()`. The consumer can set its constraints on |
| /// `buffer_collection_token` before or after. Note that the buffers won’t be |
| /// allocated until all BufferCollectionToken instances are used to set |
| /// constraints, on both the producer and consumer side. See collection.fidl for |
| /// details. |
| /// |
| /// The following errors will cause the connection to be closed: |
| /// - `buffer_collection_id` is already registered |
| AddBufferCollection(uint32 buffer_collection_id, |
| fuchsia.sysmem.BufferCollectionToken buffer_collection_token); |
| |
| /// Adds an image resource to image pipe. |
| /// |
| /// `buffer_collection_id` refers to the BufferCollectionToken instance that is |
| /// registered via `AddBufferCollection()`. The underlying memory objects allocated |
| /// are used to address to the image data. `buffer_collection_id` refers to the |
| /// index of the memory object allocated in BufferCollection. |
| /// |
| /// `image_format` specifiies image properties. `coded_width` and `coded_height` are |
| /// used to set image dimensions. |
| /// |
| /// 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 following errors will cause the connection to be closed: |
| /// - `image_id` is already registered |
| /// - `buffer_collection_id` refers to an unregistered BufferCollection. |
| /// - `buffer_collection_index` points to a resource index out of the initialized |
| /// BufferCollection bounds |
| /// - No resource is allocated in the registered BufferCollection. |
| AddImage(uint32 image_id, uint32 buffer_collection_id, uint32 buffer_collection_index, |
| fuchsia.sysmem.ImageFormat_2 image_format); |
| |
| /// Removes a BufferCollection resource from the pipe. |
| /// |
| /// The `buffer_collection_id` resource is detached as well as all Images that are |
| /// associated with that BufferCollection. Leads to the same results as calling |
| /// `RemoveImage()` on all Images for `buffer_collection_id`. |
| /// |
| /// The producer must wait for all release fences associated with the Images 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: |
| /// - `buffer_collection_id` does not reference a currently registered BufferCollection |
| RemoveBufferCollection(uint32 buffer_collection_id); |
| |
| /// 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 producer may decide not to signal `acquire_fences` for an image. |
| /// In that case, if a later image is enqueued and later image’s |
| /// `presentation_time` is reached, the consumer presents the later image when |
| /// later image’s `acquire_fences` are signaled. The consumer also signals |
| /// earlier image’s `release_fences` and removes it from the presentation queue. |
| /// This sequence works as a cancellation mechanism. |
| /// |
| /// 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>>:MAX_ACQUIRE_RELEASE_FENCE_COUNT acquire_fences, |
| vector<handle<event>>:MAX_ACQUIRE_RELEASE_FENCE_COUNT release_fences) |
| -> (PresentationInfo presentation_info); |
| }; |