| // 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; |
| |
| /// The maximum size of |
| /// [`fuchsia.sysmem2/BufferCollectionConstraints.image_format_constraints`]. |
| @available(added=19) |
| const MAX_COUNT_BUFFER_COLLECTION_CONSTRAINTS_IMAGE_FORMAT_CONSTRAINTS uint32 = 64; |
| |
| /// The maximum size of |
| /// [`fuchsia.sysmem2/BufferMemoryConstraints.permitted_heaps`]. |
| @available(added=19) |
| const MAX_COUNT_BUFFER_MEMORY_CONSTRAINTS_PERMITTED_HEAPS uint32 = 64; |
| |
| /// The maximum size of [`fuchsia.sysmem2/ImageFormatConstraints.color_spaces`]. |
| const MAX_COUNT_IMAGE_FORMAT_CONSTRAINTS_COLOR_SPACES uint32 = 32; |
| |
| /// The maximum size of |
| /// [`fuchsia.sysmem2/ImageFormatConstraints.pixel_format_and_modifiers`]. |
| const MAX_COUNT_PIXEL_FORMAT_AND_MODIFIERS uint32 = 64; |
| |
| /// Constraints on allocated buffers and, optionally, constraints on images |
| /// stored in the buffers. These constraints can be specified per-participant. |
| /// The sysmem service implements aggregation of constraints from multiple |
| /// participants. |
| @available(added=19) |
| type BufferCollectionConstraints = table { |
| /// The `usage` is a hint to sysmem to potentially help choose a more |
| /// optimal [`fuchsia.images2/PixelFormat`] and/or `pixel_format_modifier` |
| /// when multiple compatible options exist. |
| /// |
| /// When aggregating [`fuchsia.sysmem2/BufferCollectionConstraints`], these |
| /// values bitwise-OR. |
| /// |
| /// At least one `usage` bit must be specified (however, it's permitted for |
| /// a [`fuchsia.sysmem2/BufferCollection.SetConstraints`] request to have |
| /// the request `constraints` field not set, in which case `kNoneUsage` is |
| /// the default, along with no constraints from the participant). |
| /// |
| /// When `kNoneUsage` is specified it must be the only set bit, and no VMOs |
| /// will be sent in response to |
| /// [`fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated`]. |
| 1: usage BufferUsage; |
| |
| /// Per-participant number of buffers that the participant may concurrently |
| /// hold for its exclusive use for more than a transient duration (camp on). |
| /// In this context, a "transient" duration is the time it takes to finish |
| /// running a small amount of non-blocking code that finishes transfering |
| /// away ownership of the buffer. Things like reading from storage, waiting |
| /// on hardware that isn't already known to be done, or doing things like |
| /// frame encode or decode are not considered transient durations, even if |
| /// they might sometimes complete quickly. |
| /// |
| /// For example, a video decoder would specify (at least) the maximum number |
| /// of reference frames + 1 frame currently being decoded into. But not 1 |
| /// more for the code that runs async and quickly to deliver a previously |
| /// decoded frame, even though that frame can potentially be owned for a |
| /// transient duration concurrent with decode of the next frame. |
| /// |
| /// A participant must not camp on more buffers than specified here (except |
| /// for a transient duration) else processing may get stuck. |
| /// |
| /// When aggregating BufferCollectionConstraints, these values add. |
| /// |
| /// In testing scenarios, camping on more buffers than this for any |
| /// significant duration (one screen refresh period is "significant" in this |
| /// context) 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.buffer_count`. Any such |
| /// participant should still fill out the min_buffer_count_for_* fields as |
| /// appropriate. |
| /// |
| /// If this field is un-set, the logical `min_buffer_count` is 0. |
| 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.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 set `image_format_constraints` 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 collection. This includes |
| /// [`fuchsia.images2/PixelFormat`] and `pixel_format_modifier` (for tiling |
| /// and the like). These constraints can be specified separately per |
| /// `pixel_format` `pixel_format_modifier` pair. Duplicated `pixel_format` |
| /// `pixel_format_modifier` pairs aren't permitted. |
| /// |
| /// When aggregating, only `pixel_format` `pixel_format_modifier` pairs that |
| /// are specified by all participants with non-zero |
| /// `image_format_constraints` size (and non-null) |
| /// BufferCollectionConstraints) are retained. |
| /// |
| /// A participant can specify `pixel_format` |
| /// [`fuchsia.images2/PixelFormat.DO_NOT_CARE`] and/or |
| /// `pixel_format_modifier` [`fuchsia.images2/FORMAT_MODIFIER_DO_NOT_CARE`] |
| /// to permit any value to be selected, but at least one participant must |
| /// specify a specific format for overall allocation to succeed. |
| /// |
| /// In a SetConstraints message, un-set or zero length means no image format |
| /// constraints; a raw buffer can be allocated if no other participants |
| /// specify any `image_format_constraints` entries. |
| 8: image_format_constraints |
| vector<ImageFormatConstraints>:MAX_COUNT_BUFFER_COLLECTION_CONSTRAINTS_IMAGE_FORMAT_CONSTRAINTS; |
| }; |
| |
| /// A reference to a heap instance. |
| /// |
| /// A given heap instance can have more than one `Heap` which can be used to |
| /// refer to the heap instance. Comparing `Heap` tables without knowledge of |
| /// these `Heap` aliases is not a reliable way to determine if two `Heap` tables |
| /// refer to the same heap (matching means yes, but not matching means maybe). |
| /// Allowing heap aliases makes renaming `Heap.type`(s) easier. |
| @available(added=19) |
| type Heap = table { |
| /// The type of the heap, specified using a bind string defined per the |
| /// schema and mechanism described in comments in the |
| /// fuchsia.sysmem.heap.bind file. |
| /// |
| /// Examples: |
| /// * "fuchsia.sysmem.heap.HEAP_TYPE.SYSTEM_RAM" |
| /// * "fuchsia.goldfish.platform.sysmem.heap.HEAP_TYPE.HOST_VISIBLE" |
| // |
| // The word "heap" is repeated here because "type" is a keyword or reserved |
| // keyword in at least one relevant language (rust), and this naming also |
| // lines up with the bind enum(s) named `HEAP_TYPE` which provide the known |
| // meaningful/valid strings for this field. |
| 1: heap_type string:128; |
| |
| /// The uint64 id of the heap. This is only required to be unique per (type, |
| /// boot) tuple. In other words, a given heap id is only meaningful within |
| /// the current boot of the machine (not across boots), and only within the |
| /// `Heap.type`. |
| /// |
| /// For `Heap.type`(s) that refer to a singleton heap, a participant |
| /// specifying the singleton heap in |
| /// [`fuchsia.sysmem2.BufferMemoryConstraints.permitted_heaps`] can leave |
| /// this field un-set, or set it to zero. Sysmem will always fill out this |
| /// field for the heap indicated in |
| /// [`fuchsia.sysmem2.BufferMemmorySettings.heap`] (for a singleton heap the |
| /// `id` field will be set to 0 by sysmem). |
| 2: id uint64; |
| }; |
| |
| @available(added=19) |
| type BufferMemoryConstraints = table { |
| /// un-set is treated as 1 |
| 1: min_size_bytes uint64; |
| /// un-set is treated as 0xFFFFFFFFFFFFFFFF. |
| 2: max_size_bytes uint64; |
| |
| /// When false, physical pages of a buffer VMO can be non-contiguous. When |
| /// true, physical pages of a buffer VMO must be sequentially contiguous. A |
| /// client that doesn't require physically contiguous VMOs must still accept |
| /// physically contiguous VMOs or "physical" VMOs. |
| 3: physically_contiguous_required bool; |
| |
| /// If true, the participant requires secure memory. |
| /// |
| /// When aggregating `BufferCollectionConstraints`, these values boolean-OR. |
| 4: secure_required bool; |
| |
| /// When true (or when `BufferMemoryConstraints` is not present), the |
| /// participant is ok with sysmem selecting the CPU domain. |
| /// |
| /// If the CPU domain is selected, participants must ensure the CPU can read |
| /// or write data to the buffer without cache operations outside of the |
| /// participant. |
| 5: cpu_domain_supported bool; |
| /// When true, the participant is ok with sysmem selecting the RAM domain. |
| /// |
| /// If the RAM domain is selected, producer 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) |
| 6: ram_domain_supported bool; |
| /// When true, the participant is ok with sysmem selecting the INACCESSIBLE |
| /// domain. |
| /// |
| /// If the INACCESSIBLE domain is selected, CPU reads and writes of the data |
| /// are prevented. Attempts to read/write the data with the CPU may result |
| /// in UB and/or process termination. |
| /// |
| /// If the INACCESSIBLE domain is selected, participants must only operate |
| /// on the data using DMAs performed by HW, or platform-specific DMA-like |
| /// requests to a secure environment. |
| /// |
| /// Secure heaps only support INACCESSIBLE domain, and will fail allocation |
| /// if any participant with `BufferUsage` other than `NONE_USAGE` does not |
| /// set inaccessible_domain_supported to true. |
| 7: inaccessible_domain_supported bool; |
| |
| /// Which heaps are acceptable to the participant. Participants that don't |
| /// care which heap memory is allocated on should leave this field un-set. A |
| /// secure heap is only selected if all participants explicitly indicate |
| /// that the secure heap is acceptable via `heap_permitted`, or specify |
| /// `NONE_USAGE`. |
| 8: permitted_heaps vector<Heap>:MAX_COUNT_BUFFER_MEMORY_CONSTRAINTS_PERMITTED_HEAPS; |
| }; |
| |
| /// `INACCESSIBLE` is only for cases where there is no CPU access to the |
| /// buffers. |
| /// |
| /// 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. In other words, INACCESSIBLE does not imply secure, |
| /// but secure implies INACCESSIBLE. |
| /// |
| /// `CPU` means producers must ensure that a consumer can read the produced data |
| /// with the CPU without the consumer needing to do additional cache ops not |
| /// already performed (as needed) by the producer. |
| /// |
| /// `RAM` means producers must ensure that the produced data is entirely present |
| /// in RAM, without any dirty CPU cache lines, and a consumer must invalidate |
| /// (or flush and invalidate, typically) the CPU cache before reading data with |
| /// the CPU. The `RAM` domain can be faster than the `CPU` domain when all |
| /// access is via HW DMA, since in that case no CPU cache ops are required, |
| /// since no participant is actually reading/writing using the CPU. |
| @available(added=19) |
| type CoherencyDomain = flexible enum { |
| CPU = 0; |
| RAM = 1; |
| INACCESSIBLE = 2; |
| }; |
| |
| type PixelFormatAndModifier = struct { |
| /// When specified by a participant in a message to sysmem, this can be any |
| /// `PixelFormat` value that's acceptable to the participant. Specifying |
| /// `kInvalid` is not permitted. |
| /// |
| /// The participant can specify [`fuchsia.images2/PixelFormat.DO_NOT_CARE`] |
| /// if the participant needs to specify `ImageFormatConstraints` without |
| /// constraining the `pixel_format`. |
| pixel_format fuchsia.images2.PixelFormat; |
| /// Specific modifier (not just flags), or `FORMAT_MODIFIER_DO_NOT_CARE`, |
| /// from set of values defined in `fuchsia.images2` format_modifier.fidl. |
| // |
| // Re. changing the type, in this particular case we'll change any impacted |
| // client code that needs to compile with < 19 and >= 19 SDK to make sure it |
| // compiles either way. The old/new types are wire compatible and there's no |
| // change to any defined/permitted values. |
| pixel_format_modifier fuchsia.images2.PixelFormatModifier; |
| }; |
| |
| /// Describes constraints on layout of image data in buffers. |
| type ImageFormatConstraints = table { |
| /// The [`fuchsia.images2/PixelFormat`] for which the following constraints |
| /// apply. |
| /// |
| /// The `pixel_format` and `pixel_format_modifier` fields together are |
| /// treated by the server as one additional `pixel_format_and_modifiers` |
| /// entry. |
| /// |
| /// A participant may have more than one |
| /// [`fuchsia.sysmem2/PixelFormatAndModifier`] that's supported. |
| /// |
| /// * If image constraints are the same for different |
| /// `PixelFormatAndModifier`s, the participant may list additional |
| /// `PixelFormatAndModifier`s for which the constraints apply in the |
| /// `pixel_format_and_modifiers` field. This reduces the overall number of |
| /// `ImageFormatConstraints` that need to be sent, without changing the |
| /// meaning (vs for example sending a bunch of separate |
| /// `ImageFormatConstraints` that only differ by the `pixel_format` and |
| /// `pixel_format_modifier` which overall specify the same list of |
| /// `PixelFormatAndModifier`s). |
| /// * If image constraints differ for different `PixelFormatAndModifier`s, |
| /// the participant can convey this using a separate |
| /// `ImageFormatConstraints` entry in `image_format_constraints` for each |
| /// set of `PixelFormatAndModifier`s that have different image |
| /// constraints. |
| /// * It's ok for a participant to have two `image_format_constraints` |
| /// entries that only differ in their pixel_format_and_modifiers, but this |
| /// is isn't the most compact way to represent that situation since the |
| /// two entries could be combined by specifying two |
| /// `PixelFormatAndModifier`s within a single `ImageFormatConstraints`. |
| /// |
| /// It's not uncommon for the other fields of `ImageFormatConstraints` to |
| /// vary by `pixel_format` or by `pixel_format_modifier` - for example for a |
| /// linear format to support smaller max size than a tiled format. |
| /// |
| /// See also |
| /// [`fuchsia.sysmem2/ImageFormatConstraints.pixel_format_and_modifiers`]. |
| /// |
| /// Thie field must be set to a value other than |
| /// [`fuchsia.images2/PixelFormat.INVALID`] unless |
| /// `pixel_format_and_modifiers` is non-empty. In other words, there must be |
| /// at least one `PixelFormatAndModifier` per `ImageFormatConstraints`. If |
| /// `pixel_format_modifier` is set, this field must also be set. |
| /// |
| /// The participant can specify [`fuchsia.images2/PixelFormat.DO_NOT_CARE`] |
| /// if the participant needs to specify `ImageFormatConstraints` without |
| /// constraining the `pixel_format`. |
| 1: pixel_format fuchsia.images2.PixelFormat; |
| |
| /// The pixel format modifier for which the following constraints apply. |
| /// |
| /// The `pixel_format` and `pixel_format_modifier` fields together are |
| /// treated by the server as one additional `pixel_format_and_modifiers` |
| /// entry. |
| /// |
| /// This is a value from `fuchsia.images2` format_modifier.fidl that's |
| /// acceptable to the participant in combination with the `pixel_format`. |
| /// |
| /// See also `pixel_format_and_modifiers`. |
| /// |
| /// If `pixel_format` is set but `pixel_format_modifier` is un-set, the |
| /// default depends on other fields: |
| /// |
| /// * If `pixel_format` is `DO_NOT_CARE`, the pixel format modifier is |
| /// implicitly `FORMAT_MODIFIER_DO_NOT_CARE`. |
| /// * else if `BufferCollectionConstraints.usage` isn't `NONE`, the pixel |
| /// format modifier is implicitly `FORMAT_MODIFIER_LINEAR`. |
| /// * else the pixel format modifier is implicitly |
| /// `FORMAT_MODIFIER_DO_NOT_CARE`. |
| /// |
| /// When set, this value is a specific modifier (not just flags), or |
| /// `FORMAT_MODIFIER_DO_NOT_CARE`, from set of values defined in |
| /// `fuchsia.images2` format_modifier.fidl. |
| // |
| // Re. changing the type, in this particular case we'll change any impacted |
| // client code that needs to compile with < 19 and >= 19 SDK to make sure it |
| // compiles either way. The old/new types are wire compatible and there's no |
| // change to any defined/permitted values. |
| 2: pixel_format_modifier fuchsia.images2.PixelFormatModifier; |
| |
| /// The (additional) [`fuchsia.sysmem2/PixelFormatAndModifier`]s for which |
| /// the following constraints apply. |
| /// |
| /// As a non-limiting example, if a participant only wants to set a single |
| /// `PixelFormatAndModifier` for this |
| /// [`fuchsia.sysmem2/ImageFormatConstraints`], the participant can either |
| /// (a) use `pixel_format` and `pixel_format_modifier` fields to specify the |
| /// fields of the one `PixelFormatAndModifier` and leave |
| /// `pixel_format_and_modifiers` un-set, or (b) leave `pixel_format` and |
| /// `pixel_format_modifier` fields un-set and put the one |
| /// `PixelFormatAndModifier` in `pixel_format_and_modifiers`. |
| /// |
| /// If `pixel_format` is set, the server will take pixel_format and |
| /// pixel_format_modifier fields (un-setting them in the process), pack them |
| /// into a `PixelFormatAndModifier`, and move it into this vector as one |
| /// additional entry, with an overall size limit of |
| /// `MAX_COUNT_PIXEL_FORMAT_AND_MODIFIERS + 1`. |
| /// |
| /// After the server moves `pixel_format`, `pixel_format_modifier` into one |
| /// additional entry in this vector, this vector must not be empty. When the |
| /// resulting list has more than 1 item, the entries in this vector are |
| /// equivalent to (shorthand for) listing (size) separate |
| /// `ImageFormatConstraints` entries, one per `pixel_format_and_modifiers` |
| /// entry, each with one `PixelFormatAndModifier`, where all the separate |
| /// `ImageFormatConstraints` entries have the same constraints (compared |
| /// field by field, not including `pixel_format`, `pixel_format_modifier`, |
| /// or `pixel_format_and_modifiers` fields). |
| /// |
| /// In `SetConstraints` message, each entry specifies a |
| /// `PixelFormatAndModifier` which is acceptable to the participant |
| /// (assuming the following constraints fields are also satisfied). |
| /// |
| /// In the response to `WaitForAllBuffersAllocated`, this field will be |
| /// un-set and the one chosen `PixelFormatAndModifier` will be indicated |
| /// using the `pixel_format` and `pixel_format_modifier` fields. |
| /// |
| /// All the `PixelFormatAndModifiers` in a `SetConstraints` message from a |
| /// participant must be unique across all the entries under |
| /// `image_format_constraints`. If `fuchsia.images2.PixelFormat.DO_NOT_CARE` |
| /// is used in an entry, there must not be any other entry (considering all |
| /// the entries under `image_format_constraints`) with matching |
| /// `pixel_format_modifier`. If `FORMAT_MODIFIER_DO_NOT_CARE` is used, there |
| /// must not be any other entry (considering all the entries under |
| /// `image_format_constraints`) with matching `pixel_format`. |
| /// |
| /// A `PixelFormatAndModifier` value with either `DO_NOT_CARE` or |
| /// `FORMAT_MODIFIER_DO_NOT_CARE` (but not both, for purposes of this |
| /// example) can be combined with a `PixelFormatAndModifier` from a separate |
| /// participant with the other field indicating "do not care", resulting in |
| /// a complete `PixelFormatAndModifier` that can succeed allocation. |
| /// However, at least for now, it's not permitted for a single participant |
| /// to specify two separate `PixelFormatAndModifier` values which have "do |
| /// not care" in different fields. This does not prohibit a single |
| /// `PixelFormatAndModifier` with both DO_NOT_CARE and |
| /// PIXEL_FORMAT_DO_NOT_CARE (which is only a single |
| /// `PixelFormatAndModifier` value). If a client really needs to specify |
| /// some constraints relevant to `pixel_format`(s) with |
| /// `pixel_format_modifier` FORMAT_MODIFIER_DO_NOT_CARE, and other |
| /// constraints relevant to `pixel_format_modifier`(s) with `pixel_format` |
| /// DO_NOT_CARE, the client can do so by duplicating the token and |
| /// using/driving two separate participants. |
| /// |
| /// See also `pixel_format` for more comments relevant to multiple |
| /// `PixelFormatAndModifier`s in a single `ImageFormatConstraints`. |
| 15: pixel_format_and_modifiers |
| vector<PixelFormatAndModifier>:MAX_COUNT_PIXEL_FORMAT_AND_MODIFIERS; |
| |
| /// Empty is an error. Duplicate entries are an error. Arbitrary ordering is |
| /// not an error. |
| /// |
| /// The client can specify a single entry |
| /// [fuchsia.sysmem2/ColorSpace.DO_NOT_CARE`] if the client doesn't want to |
| /// constrain which `ColorSpace` is chosen. At least one participant must |
| /// specify at least one `ColorSpace` value other than |
| /// `ColorSpace.DO_NOT_CARE`, or allocation will fail. |
| 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. |
| /// |
| /// See also `required_max_size`. |
| 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 in bytes" 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`. However, 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. |
| /// |
| /// Sending to sysmem, un-set is treated as 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 maximum number of pixels. |
| /// |
| /// The max image area in pixels is limited indirectly via |
| /// [`fuchsia.sysmem/BufferMemoryConstraints.max_size_bytes`] and the |
| /// resulting [`fuchsia.sysmem/BufferSettings.size_bytes`], and can also be |
| /// enforced directly via this field. |
| /// |
| /// In contrast to the [`fuchsia.sysmem2/ImageFormatConstraints.max_size`] |
| /// field which limits width and height separately, this field limits the |
| /// total number of pixels. |
| /// |
| /// In contrast to |
| /// [`fuchsia.sysmem/BufferMemoryConstraints.max_size_bytes`], this field |
| /// doesn't limit the number of non-pixel padding bytes after each row of |
| /// pixels, and doesn't limit the number of non-pixel bytes in the case of |
| /// tiled `pixel_format_modifier`. |
| /// |
| /// Very narrow or very short image aspect ratios can have worse performance |
| /// per pixel in comparison to more typical aspect ratios. Padding and/or |
| /// memory bandwidth overheads tend to increase for extreme aspect ratios. |
| /// Participants can indicate lack of support for very narrow or very short |
| /// dimensions using ['fuchsia.sysmem/ImageFormatConstraints.min_size`]. |
| /// |
| /// 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_width_times_height uint64; |
| |
| /// Alignment requirements on the image `size`. |
| /// |
| /// * `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; |
| |
| /// Alignment requirements on `display_rect`. |
| /// |
| /// * `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 that satisfies alignment |
| /// requirements) 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. |
| /// |
| /// This field aggregates by taking the min per component, and |
| /// required_max_size aggregates by taking the max per component. |
| /// |
| /// 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. |
| /// |
| /// Prefer to use `require_bytes_per_row_at_pixel_boundary` when the intent |
| /// is to ensure that `bytes_per_row' will be a multiple of the pixel size |
| /// in bytes. |
| /// |
| /// 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 in bytes" (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 can |
| /// also result 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; |
| |
| /// Iff set and true, bytes_per_row_divisor in the resulting |
| /// ImageFormatConstraints is guaranteed to be a value which requires |
| /// bytes_per_row to be an integral number of pixels. This can result in |
| /// more padding at the end of each row than when this field is not set to |
| /// true, but ensures that the stride can be expressed as an integral number |
| /// of pixels. |
| /// |
| /// For example, if the chosen `PixelFormat` is `B8G8R8`, if this field is |
| /// set to true, the resulting bytes_per_row_divisor will be a multiple of |
| /// 3. In this example, if another participant sets `bytes_per_row_divisor` |
| /// to 4, the resulting `bytes_per_row_divisor` will be a multiple of 12. |
| 16: require_bytes_per_row_at_pixel_boundary bool; |
| }; |