blob: 075389a820951b4a0a4842121a8cd0166d16084d [file] [log] [blame]
// 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.sysmem;
using zx;
// TODO(dustingreen): FIDL C generated code doesn't implement field defaults, so
// either move to FIDL C++ generated code (for this reason among several others;
// preferred), or make 0 values be aliases for the intended default value. For
// now, the field defaults don't take effect and the field ends up having value
// 0 if not explicitly initialized, despite having a default value in the FIDL.
/// Constraints on BufferCollection parameters. These constraints can be
/// specified per-participant. The sysmem service implements aggregation of
/// constraints from multiple participants.
type BufferCollectionConstraints = struct {
/// 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 due to !has_constraints.
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.
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.
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.
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
/// above.
min_buffer_count uint32;
/// 0 is treated as 0xFFFFFFFF.
max_buffer_count uint32;
/// 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.
has_buffer_memory_constraints bool;
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.
image_format_constraints_count uint32;
type BufferCollectionConstraintsAuxBuffers = struct {
/// 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, the participant can still work, potentially even with secure
/// memory (depending on supported heaps), without clear aux buffers.
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 producer, then the participant producer 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 BufferCollectionConstraintsAuxBuffers is never sent by a
/// participant, then "allow" is true iff the participant specifies usage
/// which is read only.
/// If unspecified by 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.
allow_clear_aux_buffers_for_secure bool;
type VmoBuffer = resource struct {
/// The same VMO can be used by more than one CodecBuffer (only of the same
/// buffer_lifetime_ordinal), but each vmo handle must be a separate handle.
/// The vmo field can be 0 if this is a VmoBuffer in BufferCollectionInfo_2
/// that's at or beyond BufferCollectionInfo_2.buffer_count.
vmo zx.handle:<VMO, optional>;
/// Offset within the VMO of the first usable byte. Must be < the VMO's
/// size in bytes, and leave sufficient room for
/// BufferMemorySettings.size_bytes before the end of the VMO.
vmo_usable_start uint64;
// TODO( change struct to table
/// Information about a buffer collection and its buffers.
type BufferCollectionInfo_2 = resource struct {
/// The total number of buffers.
buffer_count uint32;
/// These settings apply to all the buffers in the initial buffer allocation.
settings SingleBufferSettings;
/// VMO handles (and vmo_usable_start offset) for each buffer in the
/// collection.
/// If present, all the VMOs at or after index `buffer_count` are invalid
/// (0) handles.
/// All buffer VMO handles have identical size and access rights. The size
/// is in settings.buffer_settings.size_bytes.
/// The VMO access rights are determined based on the usages which the
/// client specified when allocating the buffer collection. For example,
/// a client which expressed a read-only usage will receive VMOs without
/// write rights. In addition, the rights can be attenuated by the
/// parameter to BufferCollectionToken.Duplicate() calls.
type SingleBufferInfo = resource struct {
settings SingleBufferSettings;
buffer VmoBuffer;
/// After the initial buffer allocation, it's allowed to close old buffers and
/// allocate new buffers. When a new buffer is allocated its settings can
/// differ from the rest of the buffers in the collection, and the single
/// buffer's settings are delivered via OnSingleBufferAllocated() using this
/// struct:
type SingleBufferSettings = struct {
buffer_settings BufferMemorySettings;
/// Buffers holding data that is not uncompressed image data will not have
/// this field set. Buffers holding data that is uncompressed image data
/// _may_ have this field set.
/// At least for now, changing the PixelFormat requires re-allocating
/// buffers.
has_image_format_constraints bool;
image_format_constraints ImageFormatConstraints;
/// Known heap types.
/// Device specific types should have bit 60 set. Top order bit is reserved
/// and should not be set.
type HeapType = strict 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 = struct {
min_size_bytes uint32 = 0;
/// 0 is treated as 0xFFFFFFFF.
max_size_bytes uint32 = 0xFFFFFFFF;
physically_contiguous_required bool = false;
/// If true, at least one participant requires secure memory.
/// When aggregating BufferCollectionConstraints, these values boolean-OR.
secure_required bool = false;
/// 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)
ram_domain_supported bool = false;
cpu_domain_supported bool = true;
inaccessible_domain_supported bool = false;
/// Optional heap constraints. Participants that don't care which heap
/// memory is allocated on should leave this field 0.
heap_permitted_count uint32;
/// 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 = strict enum {
CPU = 0;
RAM = 1;
type BufferMemorySettings = struct {
size_bytes uint32;
is_physically_contiguous bool;
is_secure bool;
coherency_domain CoherencyDomain;
/// The specific heap from which buffers are allocated.
/// See above in this file for heap identifier values.
heap HeapType;
// TODO( change struct to table
/// Describes constraints on layout of image data in buffers.
type ImageFormatConstraints = struct {
/// 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.
pixel_format PixelFormat;
/// Empty is an error. Redundant entries are an error. Arbitrary ordering
/// is not an error.
color_spaces_count uint32;
/// Minimum permitted width in pixels.
/// For example a video decoder participant may set this field to the
/// minimum coded_width that might potentially be specified by a stream. In
/// contrast, required_min_coded_width would be set to the current
/// coded_width specified by the stream. While min_coded_width aggregates
/// by taking the max, required_min_coded_width aggregates by taking the
/// min.
/// See also required_min_coded_width.
min_coded_width uint32;
/// Maximum width in pixels. For example Scenic may set this field
/// (directly or via sub-participants) to the maximum width that can be
/// composited.
/// 0 is treated as 0xFFFFFFFF.
max_coded_width uint32;
/// Minimum height in pixels. For example a video decoder participant may
/// set this field to the coded_height specified by a stream.
min_coded_height uint32;
/// Maximum height in pixels. For example Scenic may set this field
/// (directly or via sub-participants) to the maximum height that can be
/// composited.
/// 0 is treated as 0xFFFFFFFF.
max_coded_height uint32;
/// Must be >= the value implied by min_coded_width for plane 0.
min_bytes_per_row uint32;
/// Must be >= the value implied by max_coded_width for plane 0.
/// 0 is treated as 0xFFFFFFFF.
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.
/// 0 is treated as 0xFFFFFFFF.
max_coded_width_times_coded_height uint32 = 0xFFFFFFFF;
/// Number of layers within a multi-layered image.
/// 0 is treated as 1.
layers uint32 = 1;
/// coded_width % width_divisor must be 0.
/// 0 is treated as 1.
coded_width_divisor uint32 = 1;
/// coded_height % height_divisor must be 0.
/// 0 is treated as 1.
coded_height_divisor uint32 = 1;
/// bytes_per_row % bytes_per_row_divisor must be 0.
/// 0 is treated as 1.
bytes_per_row_divisor uint32 = 1;
/// vmo_usable_start % start_offset_divisor must be 0.
/// 0 is treated as 1.
start_offset_divisor uint32 = 1;
/// display_width % display_width_divisor must be 0.
/// 0 is treated as 1.
display_width_divisor uint32 = 1;
/// display_height % display_height_divisor must be 0.
/// 0 is treated as 1.
display_height_divisor uint32 = 1;
/// required_ dimension bounds.
/// In contrast to the corresponding fields without "required_" at the
/// start, these fields (when set to non-zero values) express a requirement
/// that the resulting aggregated non-required_ fields specify a space that
/// fully contain the space expressed by each participant's required_
/// fields.
/// For example, a producer video decoder is perfectly happy for the
/// consumer to be willing to accept anything, and the video decoder doesn't
/// really want to constrain the potential space of dimensions that might be
/// seen in a stream and may be acceptable to the consumer, but the video
/// decoder needs to ensure that the resulting dimension ranges contain
/// at least the current dimensions decoded from the stream.
/// Similarly, an initiator with a particular dynamic-dimension scenario in
/// mind may wish to require up front that participants agree to handle at
/// least the range of dimensions expected by the initiator in that
/// scenario (else fail earlier rather than later, maybe trying again with
/// smaller required_ space).
/// It's much more common for a producer or initiator to set these fields
/// than for a consumer to set these fields.
/// While the non-required_ fields aggregate by taking the intersection, the
/// required_ fields aggregate by taking the union.
/// If set, the required_max_coded_width and required_max_coded_height will
/// cause the allocated buffers to be large enough to hold an image that is
/// required_max_coded_width * required_max_coded_height.
/// TODO(dustingreen): 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.
/// 0 is treated as 0xFFFFFFFF.
required_min_coded_width uint32;
required_max_coded_width uint32;
/// 0 is treated as 0xFFFFFFFF.
required_min_coded_height uint32;
required_max_coded_height uint32;
/// 0 is treated as 0xFFFFFFFF.
required_min_bytes_per_row uint32;
required_max_bytes_per_row uint32;
// TODO( change struct to table
/// Describes how an image is represented.
type ImageFormat_2 = struct {
/// Pixel format.
pixel_format PixelFormat;
/// Row width in pixels that exist in the buffer. Must be >= display_width.
/// Can be < the width implied by stride_bytes.
coded_width uint32;
/// Number of rows. Must be >= display_height.
coded_height uint32;
/// Stride in bytes of plane 0. Planes beyond plane 0 (if any, depending on
/// pixel_format) have a known fixed relationship with plane 0's stride.
/// For Intel tiled textures, the stride is for the linearized version of the texture.
bytes_per_row uint32;
/// Row width in pixels that are to be displayed. This can be <=
/// coded_width. Any cropping occurs on the right of the image (not left).
display_width uint32;
/// Number of rows to be displayed. This can be <= coded_height, with any
/// cropping on the bottom (not top).
display_height uint32;
/// Number of layers within a multi-layered image.
layers uint32 = 1;
/// Color space.
color_space ColorSpace;
/// The pixel_aspect_ratio_width : pixel_aspect_ratio_height is the
/// pixel aspect ratio (AKA sample aspect ratio aka SAR) for the luma
/// (AKA Y) samples. A pixel_aspect_ratio of 1:1 mean square pixels. A
/// pixel_aspect_ratio of 2:1 would mean pixels that are displayed twice
/// as wide as they are tall. Codec implementation should ensure these
/// two values are relatively prime by reducing the fraction (dividing
/// both by GCF) if necessary.
/// When has_pixel_aspect_ratio == false, the pixel_aspect_ratio is unknown.
/// A default of 1:1 can be appropriate in some cases, but as always, a
/// consumer may determine the actual pixel_aspect_ratio by OOB means.
has_pixel_aspect_ratio bool = false;
pixel_aspect_ratio_width uint32 = 1;
pixel_aspect_ratio_height uint32 = 1;