blob: f651b9aa95e3f98b244cfeaafeb5f755791ccc29 [file] [log] [blame] [edit]
// Copyright 2020 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.sysmem2;
using fuchsia.images2;
using fuchsia.math;
const MAX_COUNT_BUFFER_COLLECTION_CONSTRAINTS_IMAGE_FORMAT_CONSTRAINTS uint32 = 64;
const MAX_COUNT_BUFFER_MEMORY_CONSTRAINTS_HEAP_PERMITTED uint32 = 64;
const MAX_COUNT_IMAGE_FORMAT_CONSTRAINTS_COLOR_SPACES uint32 = 32;
// The contents of this file are not final. Incompatible changes are still
// being made to this file. Do not rely on the contents of this file to provide
// backward compatibility (yet).
//
// TODO(fxbug.dev/34192): Sysmem should use llcpp and FIDL tables. The
// fuchsia.sysmem2.BufferCollectionConstraints defined here are part of that
// transition, but the definitions here are not final. For now, the definition
// here is only used internally to sysmem (not between processes), and therefore
// this definition can change for now. Later after we're happy with this
// representation, we'll create
// fuchsia.sysmem2.BufferCollection.SetConstraints() which will accept
// constraints as defined here.
/// Constraints on BufferCollection parameters. These constraints can be
/// specified per-participant. The sysmem service implements aggregation of
/// constraints from multiple participants.
type BufferCollectionConstraints = table {
/// The usage is only meant as a hint to help sysmem choose a more optimal
/// PixelFormat or similar when multiple compatible options exist.
///
/// When aggregating BufferCollectionConstraints, these values bitwise-OR.
///
/// At least one usage bit must be specified unless the whole
/// BufferCollectionConstraints is logically null (no fields set).
1: usage BufferUsage;
/// Per-participant number of buffers that the participant may concurrently
/// hold for its exclusive use for a non-transient period of time (camp on).
///
/// For example, a video decoder would specify (at least) the maximum number
/// of reference frames + 1 frame currently being decoded into.
///
/// A participant must not camp on more buffers than specified here (except
/// very transiently) else processing may get stuck.
///
/// When aggregating BufferCollectionConstraints, these values add.
///
/// In testing scenarios, camping on more buffers than this for any
/// significant duration may (ideally will) be flagged as a failure. In
/// testing scenarios, the participant may not be provided with more buffers
/// than this concurrently.
2: min_buffer_count_for_camping uint32;
/// Per-participant minimum number of buffers that are needed for slack
/// reasons, for better overlap of processing / better performance.
///
/// When aggregating BufferCollectionConstraints, these values add.
///
/// A participant should typically specify 0 or 1 here - typically 0 is
/// appropriate if min_buffer_count_for_camping is already enough to keep
/// the participant busy 100% of the time when the participant is slightly
/// behind, while 1 can be appropriate if 1 more buffer than strictly needed
/// for min-camping reasons gives enough slack to stay busy 100% of the time
/// (when slightly behind, vs. lower % without the extra buffer).
///
/// In testing scenarios, this field may be forced to 0, and all
/// participants are expected to continue to work without getting stuck. If
/// a buffer is needed for forward progress reasons, that buffer should be
/// accounted for in min_buffer_count_for_camping.
3: min_buffer_count_for_dedicated_slack uint32;
/// Similar to min_buffer_count_for_dedicated_slack, except when aggregating
/// these values max (instead of add). The value here is not shared with
/// any participant's min_buffer_count_for_dedicated_slack.
///
/// A participant can specify > 0 here if a participant would like to ensure
/// there's some slack overall, but doesn't need that slack to be dedicated.
///
/// The choice whether to use min_buffer_count_for_dedicated_slack or
/// min_buffer_count_for_shared_slack (or both) will typically be about the
/// degree to which the extra slack improves performance.
///
/// In testing scenarios, this field may be forced to 0, and all
/// participants are expected to continue to work without getting stuck. If
/// a buffer is needed for forward progress reasons, that buffer should be
/// accounted for in min_buffer_count_for_camping.
4: min_buffer_count_for_shared_slack uint32;
/// A particularly-picky participant may unfortunately need to demand a
/// tight range of buffer_count, or even a specific buffer_count. This
/// field should remain 0 unless a participant really must set this field to
/// constrain the overall BufferCollectionInfo_2.buffer_count. Any such
/// participant should still fill out the min_buffer_count_for_* fields.
///
/// If this field is un-set, the logical min_buffer_count is 1.
5: min_buffer_count uint32;
/// A particularly-picky participant may unfortunately need to demand a
/// tight range of buffer_count, or even a specific buffer_count. This
/// field should remain 0 unless a participant really must set this field to
/// constrain the overall BufferCollectionInfo_2.buffer_count. Any such
/// participant should still fill out the min_buffer_count_for_* fields.
///
/// If this field is un-set, the logical max_buffer_count is 0xFFFFFFFF.
6: max_buffer_count uint32;
/// Optional constraints on BufferCollectionSettings.buffer_settings.
///
/// A participant that intends to specify image_format_constraints_count > 1
/// will typically specify the minimum buffer size implicitly via
/// image_format_constraints, and possibly specify only the max buffer size
/// via buffer_memory_constraints.
///
/// If un-set, the client is specifying "don't care" re. any buffer memory
/// constraints.
7: buffer_memory_constraints BufferMemoryConstraints;
/// Optional constraints on the image format parameters of an image stored
/// in a buffer of the BufferCollection. This includes pixel format and
/// image layout. These constraints are per-pixel-format, so more than one
/// is permitted. Entries in the list must have unique pixel_formats.
///
/// When aggregating, only pixel formats that are specified by all
/// particpants with non-zero image_format_constraints_count (and non-Null)
/// BufferCollectionConstraints) are retained.
///
/// Un-set means no image format constraints. set but zero length is an
/// error.
8: image_format_constraints
vector<ImageFormatConstraints>:MAX_COUNT_BUFFER_COLLECTION_CONSTRAINTS_IMAGE_FORMAT_CONSTRAINTS;
/// If true, a secure heap may only be selected if all participants with
/// BufferMemoryConstraints specify allow_clear_aux_buffers_for_secure. If
/// "need" is true, "allow" must also be true.
///
/// If false (or unset), the participant can still work, potentially even
/// with secure memory (depending on supported heaps), without clear aux
/// buffers.
9: need_clear_aux_buffers_for_secure bool;
/// If true, the participant will use clear aux buffers, if they are
/// allocated, as appropriate to the participant's role. If the participant
/// is a writer, then the participant writer will populate the clear aux
/// buffers with the clear (not-encrypted, not-DRM-protected) bytes, and
/// fill protected bytes with data that does not emulate start codes, such
/// as 0xFF.
///
/// If un-set, then allow_clear_aux_buffers_for_secure is true iff the
/// participant specifies usage which is read-only.
///
/// If un-set from a participant with write usage, or false, the buffer
/// collection won't be able to allocate if any participant specifies
/// need_clear_aux_buffers_for_secure true.
10: allow_clear_aux_buffers_for_secure bool;
};
/// Known heap types.
/// Device specific types should have bit 60 set. Top order bit is reserved
/// and should not be set.
type HeapType = flexible enum : uint64 {
SYSTEM_RAM = 0x0000000000000000;
/// Heap used for amlogic protected memory.
AMLOGIC_SECURE = 0x1000000000010000;
/// Heap used for amlogic protected memory between decrypt and video decode.
AMLOGIC_SECURE_VDEC = 0x1000000000010001;
/// Heap used by goldfish vulkan for device-local memory.
GOLDFISH_DEVICE_LOCAL = 0x1000000000020000;
/// Heap used by goldfish vulkan for host-visible memory.
GOLDFISH_HOST_VISIBLE = 0x1000000000020001;
/// Heap used for display framebuffer. This is used by display drivers
/// limited to a single framebuffer located at a specific physical address.
/// The framebuffer heap makes it possible to create buffer collections
/// for the framebuffer and enables sysmem support in these drivers.
FRAMEBUFFER = 0x1000000000030001;
};
type BufferMemoryConstraints = table {
1: min_size_bytes uint32;
/// un-set is treated as 0xFFFFFFFF.
2: max_size_bytes uint32;
3: physically_contiguous_required bool;
/// If true, at least one participant requires secure memory.
///
/// When aggregating BufferCollectionConstraints, these values boolean-OR.
4: secure_required bool;
/// By default, participants must ensure the CPU can read or write data to
/// the buffer without cache operations. If they support using the RAM
/// domain, data must be available in RAM (with CPU cache state such that
/// the RAM data won't get corrupted by a dirty CPU cache line writing
/// incorrect data to RAM), and a consumer reading using the CPU must
/// invalidate CPU cache before reading (the producer doesn't guarantee
/// zero stale "clean" cache lines)
5: cpu_domain_supported bool;
6: ram_domain_supported bool;
7: inaccessible_domain_supported bool;
/// Optional heap constraints. Participants that don't care which heap
/// memory is allocated on should leave this field un-set.
8: heap_permitted vector<HeapType>:MAX_COUNT_BUFFER_MEMORY_CONSTRAINTS_HEAP_PERMITTED;
};
/// Inaccessible is only for cases where there is no CPU-based access to the
/// buffers. A secure_required buffer can still have CoherencyDomain Cpu or
/// Ram even if the secure_required buffer can only be accessed by the CPU when
/// the CPU is running in secure mode (or similar). In contrast, device-local
/// memory that isn't reachable from the CPU is CoherencyDomain Inaccessible,
/// even if it's possible to cause a device (physical or virtual) to copy the
/// data from the Inaccessible buffers to buffers that are visible to the CPU.
type CoherencyDomain = flexible enum {
CPU = 0;
RAM = 1;
INACCESSIBLE = 2;
};
/// Describes constraints on layout of image data in buffers.
// TODO(fxbug.dev/32119): change struct to table
type ImageFormatConstraints = table {
/// The PixelFormat for which the following constraints apply. A
/// participant may have more than one PixelFormat that's supported, in
/// which case that participant can use a list of ImageFormatConstraints
/// with an entry per PixelFormat. It's not uncommon for the other fields
/// of ImageFormatConstraints to vary by PixelFormat - for example for a
/// linear format to support smaller max size than a tiled format.
///
/// If not set, these ImageFormatConstraints apply to all PixelFormat(s),
/// and this ImageFormatConstraints does not constrain which PixelFormat is
/// chosen. For example this can be used to set required_max_coded_width
/// and required_max_coded_height fields to force allocating large-enough
/// buffers to hold particular video dimensions, without needing to list
/// every PixelFormat.
1: pixel_format fuchsia.images2.PixelFormat;
2: pixel_format_modifier uint64;
/// Empty is an error. Redundant entries are an error. Arbitrary ordering
/// is not an error.
3: color_spaces
vector<fuchsia.images2.ColorSpace>:MAX_COUNT_IMAGE_FORMAT_CONSTRAINTS_COLOR_SPACES;
/// Minimum permitted size in pixels.
///
/// For example a video decoder participant may set this field to the
/// minimum size that might potentially be specified by a stream. In
/// contrast, `required_min_size` would be set to the current size specified
/// by the stream. While `min_size` aggregates by taking the max,
/// `required_min_size` aggregates by taking the min.
///
/// When sending to sysmem, this field can be un-set if the participant is
/// prepared to deal with the smallest possible non-zero image layout
/// limited only by the constraints implicitly imposed by the `pixel_format`
/// and `pixel_format_modifier`. Or this field can be set to the actual
/// minimum size the participant can handle.
///
/// Producers should set min_size and set both width and height to the
/// actual non-zero smallest width and height that the producer might
/// generate. For example, a video decoder can set the size of a single
/// macroblock here.
///
/// When receiving from sysmem, this field will always be set, and neither
/// width nor height will be 0, because at least one participant must
/// specify a non-zero minimum size (where both width and height aren't
/// zero).
///
/// See also `required_min_size`.
4: min_size fuchsia.math.SizeU;
/// Maximum size in pixels. For example Scenic may set this field (directly
/// or via sub-participants) to the maximum size that can be composited.
///
/// Sending to sysmem, un-set is treated as 0xFFFFFFFF, 0xFFFFFFFF.
///
/// Receiving from sysmem, this field will always be set. For width and
/// height separately, if there is no enforced max, that sub-field will be
/// 0xFFFFFFFF.
5: max_size fuchsia.math.SizeU;
/// The minimum number of bytes per row, including any padding beyond the
/// last image data in a row.
///
/// This is sometimes called the "stride" or the "line to line offset". For
/// single-plane formats, this is the number of bytes per row of pixels. For
/// multi-plane formats, this is the number of bytes per row of samples in
/// plane 0 (for example, the number of bytes per row of luma samples in the
/// case of a multi-plane YUV format). For multi-plane formats, the bytes
/// per row in planes other than plane 0 is format specific but always a
/// specific relationship to the plane 0 bytes per row.
///
/// When sending `ImageFormatConstraints` to sysmem, setting this field is
/// optional. Not setting this field is recommended unless the participant
/// needs to force the `bytes_per_row` to be larger than the minimum value
/// implied by min_size.width, the "stride bytes per width pixel" of the
/// `pixel_format` plus `pixel_format_modifier` (see also
/// `ImageFormatStrideBytesPerWidthPixel`), and `bytes_per_row_divisor`.
///
/// When this structure is received from sysmem, this field will always be
/// set (when the parent structure is present), and will always be at least
/// the value implied by min_size.width, the "stride bytes per width pixel"
/// of the `pixel_format` plus `pixel_format_modifier`, and
/// `bytes_per_row_divisor`. Some producer participants may prefer to simply
/// set `ImageFormat.bytes_per_row` to
/// `ImageFormatConstraints.min_bytes_per_row` since sysmem is guaranteeing
/// that `min_bytes_per_row` is compatible with an image of width
/// min_size.width. Producer participants that need to have `size.width` >
/// `min_size.width` can get a corresponding `min_bytes_per_row` from
/// ImageFormatMinimumRowBytes (in C++), or can just calculate the
/// `bytes_per_row` directly.
6: min_bytes_per_row uint32;
/// The maximum number of bytes per row, including any padding beyond the
/// last image data in a row.
///
/// When sent to sysmem, must be >= the value implied by `max_size.width`,
/// "stride bytes per width pixel", and `bytes_per_row_divisor`, or
/// constraints aggregation will fail. Un-set means the participant doesn't
/// need/want to set a strict max.
///
/// When a participant wants to not specify any maximum, the participant can
/// either not set this field, or set this field to 0xFFFFFFFF.
///
/// When received from sysmem, this field will always be set. If the max is
/// effectively infinite, the value will be 0xFFFFFFFF (not zero).
7: max_bytes_per_row uint32;
/// The max image area in pixels is limited indirectly via
/// `BufferSettings.size_bytes`, and can also be enforced directly via this
/// field.
///
/// Sending to sysmem, un-set is treated as 0xFFFFFFFF.
///
/// Receiving from sysmem, this field will always be set, and can be set to
/// 0xFFFFFFFF.
8: max_surface_width_times_surface_height uint32;
/// * `size.width % size_alignment.width` must be 0.
/// * `size.height % size_alignment.height` must be 0. Un-set is treated as
/// 1, 1.
9: size_alignment fuchsia.math.SizeU;
/// * `display_rect.x % display_rect_alignment.width` must be 0.
/// * `display_rect.y % display_rect_alignment.height` must be 0.
/// * `display_rect.width % display_rect_alignment.width` must be 0.
/// * `display_rect.height % display_rect_alignment.height` must be 0.
/// Un-set is treated as 1, 1.
10: display_rect_alignment fuchsia.math.SizeU;
/// These fields can be used to ensure the aggregated constraints have
/// min_size and max_size such that both required_min_size and
/// required_max_size (and anything in between) are permitted values of
/// ImageFormat.size.
///
/// For example, a producer video decoder doesn't want to constrain the
/// allowed ImageFormat.size, as a compressed stream can change dimensions
/// mid-stream, but the producer video decoder needs to ensure that the
/// aggregated constraints allow for at least the current dimensions of
/// uncompressed frames at the current position in the stream.
///
/// As another example, an initiator that's intending to decode video may
/// know what the maximum expected size of frames in the stream(s) can be,
/// so by setting `required_max_size`, can ensure that the allocated buffers
/// are large enough to support that max `size`. In addition on successful
/// allocation the initiator also knows that the consumer participants are
/// ok with receiving up to that max `size`.
///
/// It's much more common for a producer or initiator to set these fields
/// than for a consumer to set these fields.
///
/// While `min_size` and `max_size` aggregate by effectively taking the
/// intersection, the `required_min_size` and `required_max_size` aggregate
/// by effectively taking the union.
///
/// TODO(fxbug.dev/34192): Make it easier to allocate buffers of minimal
/// size that can (optionally) also handle 90 degree rotated version of the
/// max dimensions / alternate required bounds for another main aspect
/// ratio. Un-set is treated as 0xFFFFFFFF, 0xFFFFFFFF.
11: required_min_size fuchsia.math.SizeU;
/// See also required_min_size. Un-set is treated as 0, 0.
12: required_max_size fuchsia.math.SizeU;
/// `fuchsia_images2.ImageFormat.bytes_per_row % bytes_per_row_divisor` must
/// be 0. un-set is treated as 1. When set, this must be a power of 2.
///
/// Prefer to use `size_alignment.width` when the intent is to ensure that
/// the width in pixels is aligned. In contrast, this field can specify that
/// the "stride" (byte offset from start of image to start of row n minus
/// byte offset from start of image to start of row n-1, with result in
/// bytes) needs to be aligned to the specified number of bytes. For
/// example, when `PixelFormat.BGR24` (24 bit color; 3 bytes per pixel) is
/// used, it's not uncommon for a participant to need each row of pixels to
/// start at a 4 byte aligned offset from the start of the image, which can
/// imply some padding bytes at the end of each row of pixels, before the
/// start of the next row of pixels.
///
/// While any value of `bytes_per_row_divisor` could instead be enforced by
/// setting `size_alignment.width` to the least-common-multiple of the
/// "stride bytes per width pixel" and the stride alignment requirement,
/// enforcing the stride alignment requirement that way can lead to more
/// padding than necessary (implying larger buffer than necessary), and also
/// results in a "fake" `size.width`; this field exists to avoid that
/// situation. Instead, the stride alignment requirement in bytes is
/// specified directly here.
13: bytes_per_row_divisor uint32;
/// `vmo_usable_start % start_offset_divisor` must be 0. Un-set is treated
/// as 1.
///
/// Producer participants are discouraged from setting non-zero image start
/// offset (from the buffer base) unless actually required, as not all
/// participants correctly handle non-zero image start offset.
14: start_offset_divisor uint32;
};