blob: 7eb31d9eaa8ff317e95db2dba1bc9db4e202d847 [file] [log] [blame]
// 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;
using zx;
// A maximum of 16 fences is enough for the current usage of these APIs.
@available(deprecated=13)
const MAX_ACQUIRE_RELEASE_FENCE_COUNT int32 = 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.
@available(deprecated=13)
closed 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
strict AddBufferCollection(resource struct {
buffer_collection_id uint32;
buffer_collection_token client_end:fuchsia.sysmem.BufferCollectionToken;
});
/// 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_index` 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.
strict AddImage(struct {
image_id uint32;
buffer_collection_id uint32;
buffer_collection_index uint32;
image_format fuchsia.sysmem.ImageFormat_2;
});
/// 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
strict RemoveBufferCollection(struct {
buffer_collection_id uint32;
});
/// 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
strict RemoveImage(struct {
image_id uint32;
});
/// 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 a set of fences which inform the producer that
/// it's safe to free or modify the `image_id` image, and it's safe to
/// re-use the fences in `acquire_fences`. The consumer must signal all the
/// fences in `release_fences` after `image_id` is no longer being
/// presented. The producer may reuse resources after any of the
/// `release_fences` is signaled.
///
/// This design allows a producer to distribute image processing across
/// multiple threads / processes without unnecessary coordination delay.
/// Each thread / process signals its own fence in `acquire_fences` when
/// it's done rendering its piece of `image_id`, and waits on its own fence
/// in `release_fences` to render new content in `image_id`.
///
/// `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
strict PresentImage(resource struct {
image_id uint32;
presentation_time uint64;
acquire_fences vector<zx.Handle:EVENT>:MAX_ACQUIRE_RELEASE_FENCE_COUNT;
release_fences vector<zx.Handle:EVENT>:MAX_ACQUIRE_RELEASE_FENCE_COUNT;
}) -> (struct {
presentation_info PresentationInfo;
});
};