fuchsia.sysmem

Added: 7

PROTOCOLS

Allocator

Defined in fuchsia.sysmem/allocator.fidl

Allocates system memory buffers.

AllocateNonSharedCollection

Allocates a BufferCollection on behalf of a single client (aka initiator) who is also the only participant (from the point of view of sysmem).

This call exists mainly for temp/testing purposes. This call skips the BufferCollectionToken stage, so there's no way to allow another participant to specify its constraints.

Real clients are encouraged to use AllocateSharedCollection() instead, and to let relevant participants directly convey their own constraints to sysmem.

collection_request is the server end of the BufferCollection FIDL channel. The client can call SetConstraints() and then WaitForBuffersAllocated() on the client end of this channel to specify constraints and then determine success/failure and get the BufferCollectionInfo_2 for the BufferCollection. The client should also keep the client end of this channel open while using the BufferCollection, and should notice when this channel closes and stop using the BufferCollection ASAP.

Request

NameType
collection_request server_end<BufferCollection>

AllocateSharedCollection

Creates a logical BufferCollectionToken which can be shared among participants (using BufferCollectionToken.Duplicate()), and then converted into a BufferCollection using BindSharedCollection().

Success/failure to populate the BufferCollection with buffers is determined via the BufferCollection interface.

Request

NameType
token_request server_end<BufferCollectionToken>

BindSharedCollection

Convert a BufferCollectionToken into a connection to the logical BufferCollection. The BufferCollection hasn't yet been populated with buffers - the participant must first also send SetConstraints() via the client end of buffer_collection.

All BufferCollectionToken(s) duplicated from a logical BufferCollectionToken created via AllocateSharedCollection() must be turned in via BindSharedCollection() before the logical BufferCollection will be populated with buffers.

token the client endpoint of a channel whose server end was sent to sysmem using AllocateSharedCollection or whose server end was sent to sysmem using BufferCollectionToken.Duplicate(). The token is being "exchanged" for a channel to the logical BufferCollection.

buffer_collection_request the server end of a BufferCollection channel. The sender retains the client end as usual. The BufferCollection channel is a single participant's connection to the logical BufferCollection. There typically will be other participants with their own BufferCollection channel to the logical BufferCollection.

Request

NameType
token BufferCollectionToken
buffer_collection_request server_end<BufferCollection>

ConnectToSysmem2Allocator

This allows creating a sysmem2 Allocator given a sysmem(1) Allocator.

This is mainly useful in situations where library code is handed a sysmem(1) allocator, but the library code has been updated to use sysmem2. Typically the library will provide a way to pass in a sysmem2 Allocator instead, but client code isn't always in the same repo, so this message allows the library to still accept the sysmem(1) Allocator temporarily.

The info set via SetDebugClientInfo (if any) is copied to the sysmem2 Allocator.

Added: HEAD

Request

NameType
allocator_request handle<channel>

SetDebugClientInfo

Set information about the current client that can be used by sysmem to help debug leaking memory and hangs waiting for constraints. |name| can be an arbitrary string, but the current process name (see fsl::GetCurrentProcessName()) is a good default. |id| can be an arbitrary id, but the current process ID (see fsl::GetCurrentProcessKoid()) is a good default.

This information is propagated to all BufferCollections created using BindSharedCollection() or AllocateNonSharedCollection() from this allocator. It does not affect BufferCollectionTokens, since they are often passed cross-process and should have their names managed manually.

Request

NameType
name string[64]
id uint64

ValidateBufferCollectionToken

Validate that a BufferCollectionToken is known to the sysmem server.

This can be used in cases where BindSharedCollection() won't be called until after BufferCollectionToken.Duplicate() + BufferCollectionToken.Sync(), when the client code wants to know earlier whether an incoming token is valid (so far).

Calling BufferCollectionToken.Sync() on a token that isn't known to sysmem risks the Sync() hanging forever.

Given that an incoming token can become invalid at any time if any participant drops their BufferCollectionToken(s) or BufferCollection(s), authors of client code are encouraged to consider not calling ValidateBufferCollectionToken() and instead dealing with async failure of the BufferCollection.Sync() after all the BufferCollectionToken.Duplicate() and BindSharedCollection() (before sending any duplicate tokens to other processes).

Regardless of the result of this call, this call has no effect on the token with the referenced koid.

A true result from this call doesn't guarantee that the token remains valid for any duration afterwards.

Client code will zx_object_get_info() on the client's token handle, passing ZX_INFO_HANDLE_BASIC and getting back the related_koid which then gets passed to ValidateBufferCollectionToken().

If ValidateBufferCollectionToken() returns true, the token was known at the time the sysmem server processed the call, but may no longer be valid/known by the time the client code receives the response.

If ValidateBufferCollectionToken() returns false, the token wasn't known at the time the sysmem server processed the call, but the token may become known by the time the client code receives the response. However client code is not required to mitigate the possibility that the token may become known late, since the source of the token should have synced the token to sysmem before sending the token to the client code.

If calling ValidateBufferCollectionToken() fails in some way, there will be a zx_status_t from the FIDL layer.

token_server_koid the koid of the server end of a channel that might be a BufferCollectionToken channel. This can be obtained from zx_object_get_info() ZX_INFO_HANDLE_BASIC related_koid.

Request

NameType
token_server_koid zx/Koid

Response

NameType
is_known bool

BufferCollection

Defined in fuchsia.sysmem/collection.fidl

BufferCollection is a connection directly from a participant to sysmem re. a logical BufferCollection; typically the logical BufferCollection is shared with other participants. In other words, an instance of the BufferCollection interface is a view of a "logical buffer collection".

This connection exists to facilitate async indication of when the logical BufferCollection has been populated with buffers.

Also, the channel's closure by the server is an indication to the client that the client should close all VMO handles that were obtained from the BufferCollection ASAP.

Also, this interface may in future allow specifying constraints in other ways, and may allow for back-and-forth negotiation of constraints to some degree.

This interface may in future allow for more than 64 VMO handles per BufferCollection, but currently the limit is 64.

This interface may in future allow for allocating/deallocating single buffers.

Some initiators may wait a short duration until all old logical BufferCollection VMO handles have closed (or until the short duration times out) before allocating a new BufferCollection, to help control physical memory fragmentation and avoid overlap of buffer allocation lifetimes for the old and new collections. Collections can be large enough that it's worth avoiding allocation overlap (in time).

AttachLifetimeTracking

AttachLifetimeTracking:

AttachLifetimeTracking() is intended to allow a client to wait until an old logical buffer collection is fully or mostly deallocated before attempting allocation of a new logical buffer collection.

Attach an eventpair endpoint to the logical buffer collection, so that the server_end will be closed when the number of buffers allocated drops to 'buffers_remaining'. The server_end won't close until after logical allocation has completed.

If logical allocation fails, such as for an attached sub-tree (using AttachToken()), the server_end will close during that failure regardless of the number of buffers potenitally allocated in the overall logical buffer collection.

The lifetime signalled by this event includes asynchronous cleanup of allocated buffers, and this asynchronous cleanup cannot occur until all holders of VMO handles to the buffers have closed those VMO handles. Therefore clients should take care not to become blocked forever waiting for ZX_EVENTPAIR_PEER_CLOSED to be signalled, especially if any of the participants using the logical buffer collection are less trusted or less reliable.

The buffers_remaining parameter allows waiting for all but buffers_remaining buffers to be fully deallocated. This can be useful in situations where a known number of buffers are intentionally not closed so that the data can continue to be used, such as for keeping the last available video picture displayed in the UI even if the video stream was using protected output buffers. It's outside the scope of the BufferCollection interface (at least for now) to determine how many buffers may be held without closing, but it'll typically be in the range 0-2.

This mechanism is meant to be compatible with other protocols providing a similar AttachLifetimeTracking() mechanism, in that duplicates of the same event can be sent to more than one AttachLifetimeTracking(), and the ZX_EVENTPAIR_PEER_CLOSED will be signalled when all the lifetime over conditions are met (all holders of duplicates have closed their handle(s)).

There is no way to cancel an attach. Closing the client end of the eventpair doesn't subtract from the number of pending attach(es).

Closing the client's end doesn't result in any action by the server. If the server listens to events from the client end at all, it is for debug logging only.

The server intentionally doesn't "trust" any bits signalled by the client. This mechanism intentionally uses only ZX_EVENTPAIR_PEER_CLOSED which can't be triggered early, and is only triggered when all handles to server_end are closed. No meaning is associated with any of the other signal bits, and clients should functionally ignore any other signal bits on either end of the eventpair or its peer.

The server_end may lack ZX_RIGHT_SIGNAL or ZX_RIGHT_SIGNAL_PEER, but must have ZX_RIGHT_DUPLICATE (and must have ZX_RIGHT_TRANSFER to transfer without causing CodecFactory channel failure).

Request

NameType
server_end handle<eventpair>
buffers_remaining uint32

AttachToken

Create a new token, for trying to add a new participant to an existing collection, if the existing collection's buffer counts, constraints, and participants allow.

This can be useful in replacing a failed participant, and/or in adding/re-adding a participant after buffers have already been allocated.

Failure of an attached token / collection does not propagate to the parent of the attached token. Failure does propagate from a normal child of a dispensable token to the dispensable token. Failure of a child is blocked from reaching its parent if the child is attached, or if the child is dispensable and the failure occurred after logical allocation.

An initiator may in some scenarios choose to initially use a dispensable token for a given instance of a participant, and then later if the first instance of that participant fails, a new second instance of that participant my be given a token created with AttachToken().

From the point of view of the client end of the BufferCollectionToken channel, the token acts like any other token. The client can Duplicate() the token as needed, and can send the token to a different process. The token should be converted to a BufferCollection channel as normal by calling BindSharedCollection(). SetConstraints() should be called on that BufferCollection channel.

A success result from WaitForBuffersAllocated() means the new participant's constraints were satisfiable using the already-existing buffer collection, the already-established BufferCollectionInfo including image format constraints, and the already-existing other participants and their buffer counts. A failure result means the new participant's constraints cannot be satisfied using the existing buffer collection and its already-logically-allocated participants. Creating a new collection instead may allow all participant's constraints to be satisfied, assuming SetDispensable() is used in place of AttachToken(), or a normal token is used.

A token created with AttachToken() performs constraints aggregation with all constraints currently in effect on the buffer collection, plus the attached token under consideration plus child tokens under the attached token which are not themselves an attached token or under such a token.

Allocation of buffer_count to min_buffer_count_for_camping etc is first-come first-served, but a child can't logically allocate before all its parents have sent SetConstraints().

See also SetDispensable(), which in contrast to AttachToken(), has the created token + children participate in constraints aggregation along with its parent.

The newly created token needs to be Sync()ed to sysmem before the new token can be passed to BindSharedCollection(). The Sync() of the new token can be accomplished with BufferCollection.Sync() on this BufferCollection. Alternately BufferCollectionToken.Sync() on the new token also works. A BufferCollectionToken.Sync() can be started after any BufferCollectionToken.Duplicate() messages have been sent via the newly created token, to also sync those additional tokens to sysmem using a single round-trip.

These values for rights_attenuation_mask result in no attenuation (note that 0 is not on this list; 0 will output an ERROR to the system log to help diagnose the bug in client code):

  • ZX_RIGHT_SAME_RIGHTS (preferred)
  • 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)

Request

NameType
rights_attenuation_mask uint32
token_request server_end<BufferCollectionToken>

CheckBuffersAllocated

This returns the same result code as WaitForBuffersAllocated if the buffer collection has been allocated or failed, or ZX_ERR_UNAVAILABLE if WaitForBuffersAllocated would block.

Request

<EMPTY>

Response

NameType
status zx/Status

Close

On a BufferCollectionToken channel:

Normally a participant will convert a BufferCollectionToken into a BufferCollection view, but a participant is also free to Close() the token (and then close the channel immediately or shortly later in response to server closing its end), which avoids causing logical buffer collection failure.  Normally an unexpected token channel close will cause logical buffer collection failure (the only exceptions being certain cases involving AttachToken() or SetDispensable()).

On a BufferCollection channel:

By default the server handles unexpected failure of a BufferCollection by failing the whole logical buffer collection. Partly this is to expedite closing VMO handles to reclaim memory when any participant fails. If a participant would like to cleanly close a BufferCollection view without causing logical buffer collection failure, the participant can send Close() before closing the client end of the BufferCollection channel. If this is the last BufferCollection view, the logical buffer collection will still go away. The Close() can occur before or after SetConstraints(). If before SetConstraints(), the buffer collection won't require constraints from this node in order to allocate. If after SetConstraints(), the constraints are retained and aggregated along with any subsequent logical allocation(s), despite the lack of channel connection.

On a BufferCollectionTokenGroup channel:

By default, unexpected failure of a BufferCollectionTokenGroup will trigger failure of the logical BufferCollectionTokenGroup and will propagate failure to its parent. To close a BufferCollectionTokenGroup channel without failing the logical group or propagating failure, send Close() before closing the channel client endpoint.

If Close() occurs before AllChildrenPresent(), the logical buffer collection will still fail despite the Close() (because sysmem can't be sure whether all relevant children were created, so it's ambiguous whether all relevant constraints will be provided to sysmem). If Close() occurs after AllChildrenPresent(), the children and all their constraints remain intact (just as they would if the BufferCollectionTokenGroup channel had remained open), and the close doesn't trigger or propagate failure.

Added: 9

Request

<EMPTY>

DeprecatedClose

Added: 9

Request

<EMPTY>

DeprecatedSetDebugClientInfo

Added: 9

Request

NameType
name string[64]
id uint64

DeprecatedSetName

Added: 9

Request

NameType
priority uint32
name string[64]

DeprecatedSync

Added: 9

Request

<EMPTY>

Response

<EMPTY>

GetNodeRef

This gets an event handle that can be used as a parameter to IsAlternateFor() called on any Node. The client will not be granted the right to signal this event, as this handle should only be used as proof that the client obtained this handle from this Node.

Because this is a get not a set, no Sync() is needed between the GetNodeRef() and the call to IsAlternateFor(), despite the two calls potentially being on different channels.

See also IsAlternateFor().

Added: 9

Request

<EMPTY>

Response

NameType
node_ref handle<event>

IsAlternateFor

This checks whether the calling node is in a subtree rooted at a different child token of a common parent BufferCollectionTokenGroup, in relation to the passed-in node_ref.

This call is for assisting with admission control de-duplication, and with debugging.

The node_ref must be obtained using GetNodeRef() of a BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.

The node_ref can be a duplicated handle; it's not necessary to call GetNodeRef() for every call to IsAlternateFor().

If a calling token may not actually be a valid token at all due to a potentially hostile/untrusted provider of the token, call ValidateBufferCollectionToken() first instead of potentially getting stuck indefinitely if IsAlternateFor() never responds due to a calling token not being a real token (not really talking to sysmem). Another option is to call BindSharedCollection with this token first which also validates the token along with converting it to a BufferCollection, then call BufferCollection IsAlternateFor().

error values:

ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical buffer collection as the calling Node. Before logical allocation and within the same logical allocation sub-tree, this essentially means that the node_ref was never part of this logical buffer collection, since before logical allocation all node_refs that come into existence remain in existence at least until logical allocation (including Node(s) that have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND to be returned, this Node's channel needs to still be connected server side, which won't be the case if the whole logical allocation has failed. After logical allocation or in a different logical allocation sub-tree there are additional potential reasons for this error. For example a different logical allocation (separated from this Node(s) logical allocation by an AttachToken() or SetDispensable()) can fail its sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may exist and may select a different child sub-tree than the sub-tree the node_ref is in causing deletion of the node_ref Node. The only time sysmem keeps a Node around after that Node has no corresponding channel is when Close() is used and the Node's sub-tree has not yet failed. Another reason for this error is if the node_ref is an eventpair handle with sufficient rights, but isn't actually a real node_ref obtained from GetNodeRef().

ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an eventpair handle, or doesn't have the needed rights expected on a real node_ref.

No other failing status codes are returned by this call. However, sysmem may add additional codes in future, so the client should have sensible default handling for any failing status code.

On success, is_alternate has the following meaning:

  • true - The first parent node in common between the calling node and the node_ref Node is a BufferCollectionTokenGroup. This means that the calling Node and the node_ref Node will not have both their constraints apply - rather sysmem will choose one or the other of the constraints - never both. This is because only one child of a BufferCollectionTokenGroup is selected during logical allocation, with only that one child's sub-tree contributing to constraints aggregation.
  • false - The first parent node in common between the calling Node and the node_ref Node is not a BufferCollectionTokenGroup. Currently, this means the first parent node in common is a BufferCollectionToken or BufferCollection (regardless of not Close()ed or Close()ed). This means that the calling Node and the node_ref Node may have both their constraints apply during constraints aggregation of the logical allocation, if both Node(s) are selected by any parent BufferCollectionTokenGroup(s) involved. In this case, there is no BufferCollectionTokenGroup that will directly prevent the two Node(s) from both being selected and their constraints both aggregated, but even when false, one or both Node(s) may still be eliminated from consideration if one or both Node(s) has a direct or indirect parent BufferCollectionTokenGroup which selects a child sub-tree other than the sub-tree containing the calling Node or node_ref Node.
Added: 9

Request

NameType
node_ref handle<event>

Response

NameType
payload Node_IsAlternateFor_Result

SetConstraints

Provide BufferCollectionConstraints to the logical BufferCollection.

A participant may only call SetConstraints() once.

Sometimes the initiator is a participant only in the sense of wanting to keep an eye on success/failure to populate with buffers, and zx.Status on failure. In that case, has_constraints can be false, and constraints will be ignored.

VMO handles will not be provided to the client that sends null constraints - that can be intentional for an initiator that doesn't need VMO handles. Not having VMO handles doesn't prevent the initator from adjusting which portion of a buffer is considered valid and similar, but the initiator can't hold a VMO handle open to prevent the logical BufferCollection from cleaning up if the logical BufferCollection needs to go away regardless of the initiator's degree of involvement for whatever reason.

For population of buffers to be attempted, all holders of a BufferCollection client channel need to call SetConstraints() before sysmem will attempt to allocate buffers.

has_constraints if false, the constraints are effectively null, and constraints are ignored. The sender of null constraints won't get any VMO handles in BufferCollectionInfo, but can still find out how many buffers were allocated and can still refer to buffers by their buffer_index.

constraints are constraints on the buffer collection.

Request

NameType
has_constraints bool
constraints BufferCollectionConstraints

SetDebugClientInfo

Set information about the current client that can be used by sysmem to help debug leaking memory and hangs waiting for constraints. |name| can be an arbitrary string, but the current process name (see fsl::GetCurrentProcessName()) is a good default. |id| can be an arbitrary id, but the current process ID (see fsl::GetCurrentProcessKoid()) is a good default.

Also used when verbose logging is enabled (see SetVerboseLogging()) to indicate which client is closing their channel first, leading to sub-tree failure (which can be normal if the purpose of the sub-tree is over, but if happening earlier than expected, the client-channel-specific name can help diagnose where the failure is first coming from, from sysmem's point of view).

By default (unless overriden by this message or using Allocator.SetDebugClientInfo()), a Node will copy info from its parent Node at the time the child Node is created. While this can be better than nothing, it's often better for each participant to use Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the info directly relevant to the current client. Also, SetVerboseLogging() can be used to help disambiguate if a Node is suspected of having info that was copied from its parent.

Added: 9

Request

NameType
name string[64]
id uint64

SetDebugTimeoutLogDeadline

Sysmem logs a warning if not all clients have set constraints 5 seconds after creating a collection. Clients can call this method to change when the log is printed. If multiple client set the deadline, it's unspecified which deadline will take effect.

Added: 9

Request

NameType
deadline zx/Time

SetName

Set a name for VMOs in this buffer collection. The name may be truncated shorter. The name only affects VMOs allocated after it's set - this call does not rename existing VMOs. If multiple clients set different names then the larger priority value will win.

Added: 9

Request

NameType
priority uint32
name string[64]

SetVerboseLogging

Verbose logging includes constraints set via SetConstraints() from each client along with info set via SetDebugClientInfo() and the structure of the tree of Node(s).

Normally sysmem prints only a single line complaint when aggregation fails, with just the specific detailed reason that aggregation failed, with minimal context. While this is often enough to diagnose a problem if only a small change was made and the system had been working before the small change, it's often not particularly helpful for getting a new buffer collection to work for the first time. Especially with more complex trees of nodes, involving things like AttachToken(), SetDispensable(), BufferCollectionTokenGroup nodes, and associated sub-trees of nodes, verbose logging may help in diagnosing what the tree looks like and why it's failing a logical allocation, or why a tree or sub-tree is failing sooner than expected.

The intent of the extra logging is to be acceptable from a performance point of view, if only enabled on a low number of buffer collections. If we're not tracking down a bug, we shouldn't send this message.

If too many participants leave verbose logging enabled, we may end up needing to require that system-wide sysmem verbose logging be permitted via some other setting, to avoid sysmem spamming the log too much due to this message.

This may be a NOP for some nodes due to intentional policy associated with the node, if we don't trust a node enough to let it turn on verbose logging.

Added: 9

Request

<EMPTY>

Sync

Ensure that previous messages, including Duplicate() messages on a token, collection, or group, have been received server side.

Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a valid sysmem token risks the Sync() hanging forever. See ValidateBufferCollectionToken() for one way to mitigate the possibility of a hostile/fake BufferCollectionToken at the cost of one round trip. Another way is to pass the token to BindSharedCollection(), which also validates the token as part of exchanging it for a BufferCollection channel, and BufferCollection Sync() can then be used.

After a Sync(), it's then safe to send the client end of token_request to another participant knowing the server will recognize the token when it's sent into BindSharedCollection() by the other participant.

Other options include waiting for each token.Duplicate() to complete individually (using separate call to token.Sync() after each), or calling Sync() on BufferCollection after the token has been turned in via BindSharedCollection().

Another way to mitigate is to avoid calling Sync() on the token, and instead later deal with potential failure of BufferCollection.Sync() if the original token was invalid. This option can be preferable from a performance point of view, but requires client code to delay sending tokens duplicated from this token until after client code has converted the duplicating token to a BufferCollection and received successful response from BufferCollection.Sync().

Prefer using BufferCollection.Sync() instead, when feasible (see above). When BufferCollection.Sync() isn't feasible, the caller must already know that this token is/was valid, or BufferCollectionToken.Sync() may hang forever. See ValidateBufferCollectionToken() to check token validity first if the token isn't already known to be (is/was) valid.

Added: 9

Request

<EMPTY>

Response

<EMPTY>

WaitForBuffersAllocated

This request completes when buffers have been allocated, responds with some failure detail if allocation has been attempted but failed.

The following must occur before buffers will be allocated:

  • All BufferCollectionToken(s) of the logical BufferCollectionToken must be turned in via BindSharedCollection().
  • All BufferCollection(s) of the logical BufferCollection must have had SetConstraints() sent to them.

Returns ZX_OK if successful. Returns ZX_ERR_NO_MEMORY if the request is valid but cannot be fulfilled due to resource exhaustion. Returns ZX_ERR_ACCESS_DENIED if the caller is not permitted to obtain the buffers it requested. Returns ZX_ERR_INVALID_ARGS if the request is malformed. Returns ZX_ERR_NOT_SUPPORTED if request is valid but cannot be satisfied, perhaps due to hardware limitations.

buffer_collection_info has the VMO handles and other related info.

Request

<EMPTY>

Response

NameType
status zx/Status
buffer_collection_info BufferCollectionInfo_2

BufferCollectionToken

Defined in fuchsia.sysmem/collection.fidl

A BufferCollectionToken is not a BufferCollection, but rather a way to identify a potential shared BufferCollection prior to the BufferCollection being allocated.

We use a channel for the BufferCollectionToken instead of a single eventpair (pair) because this way we can detect error conditions like a participant dying mid-create.

Close

On a BufferCollectionToken channel:

Normally a participant will convert a BufferCollectionToken into a BufferCollection view, but a participant is also free to Close() the token (and then close the channel immediately or shortly later in response to server closing its end), which avoids causing logical buffer collection failure.  Normally an unexpected token channel close will cause logical buffer collection failure (the only exceptions being certain cases involving AttachToken() or SetDispensable()).

On a BufferCollection channel:

By default the server handles unexpected failure of a BufferCollection by failing the whole logical buffer collection. Partly this is to expedite closing VMO handles to reclaim memory when any participant fails. If a participant would like to cleanly close a BufferCollection view without causing logical buffer collection failure, the participant can send Close() before closing the client end of the BufferCollection channel. If this is the last BufferCollection view, the logical buffer collection will still go away. The Close() can occur before or after SetConstraints(). If before SetConstraints(), the buffer collection won't require constraints from this node in order to allocate. If after SetConstraints(), the constraints are retained and aggregated along with any subsequent logical allocation(s), despite the lack of channel connection.

On a BufferCollectionTokenGroup channel:

By default, unexpected failure of a BufferCollectionTokenGroup will trigger failure of the logical BufferCollectionTokenGroup and will propagate failure to its parent. To close a BufferCollectionTokenGroup channel without failing the logical group or propagating failure, send Close() before closing the channel client endpoint.

If Close() occurs before AllChildrenPresent(), the logical buffer collection will still fail despite the Close() (because sysmem can't be sure whether all relevant children were created, so it's ambiguous whether all relevant constraints will be provided to sysmem). If Close() occurs after AllChildrenPresent(), the children and all their constraints remain intact (just as they would if the BufferCollectionTokenGroup channel had remained open), and the close doesn't trigger or propagate failure.

Added: 9

Request

<EMPTY>

CreateBufferCollectionTokenGroup

Most sysmem clients and many participants don't need to care about this message or about BufferCollectionTokenGroup(s) in general.

A BufferCollectionTokenGroup is used to create a 1 of N OR among N child tokens. The child tokens which are not selected during aggregation will fail (close), which a potential participant should notice when their BufferCollection channel client endpoint sees PEER_CLOSED, allowing the participant to clean up the speculative usage that didn't end up happening (similarly to a normal BufferCollection server end closing on failure of a logical buffer collection).

See comments on protocol BufferCollectionTokenGroup.

Any rights_attenuation_mask or AttachToken()/SetDispensable() to be applied to the whole group can be achieved with a token for this purpose as a direct parent of the group.

group_request - the server end of a BufferCollectionTokenGroup channel to be served by sysmem.

Added: 9

Request

NameType
group_request server_end<BufferCollectionTokenGroup>

DeprecatedClose

Added: 9

Request

<EMPTY>

DeprecatedSetDebugClientInfo

Added: 9

Request

NameType
name string[64]
id uint64

DeprecatedSetDebugTimeoutLogDeadline

Added: 9

Request

NameType
deadline zx/Time

DeprecatedSetName

Added: 9

Request

NameType
priority uint32
name string[64]

DeprecatedSync

Added: 9

Request

<EMPTY>

Response

<EMPTY>

Duplicate

This method can be used to add a participant prior to creating a shared BufferCollection. It should only be used instead of DuplicateSync in performance sensitive cases where it would be undesireable to wait for sysmem to respond as part of each duplicate.

After sending one or more Duplicate() messages, and before sending the created tokens to other participants (or to other Allocator channels), the client should send a Sync() and wait for its response. The Sync() call can be made on the token, or on the BufferCollection obtained by passing this token to BindSharedCollection(). Either will ensure that the server knows about the tokens created via Duplicate() before the other participant sends the token to the server via separate Allocator channel.

All tokens must be turned in via BindSharedCollection() or Close() for a BufferCollection to be successfully created.

When a client calls BindSharedCollection() to turn in a BufferCollectionToken, the server will process all Duplicate() messages before closing down the BufferCollectionToken. This allows the client to Duplicate() and immediately turn in the BufferCollectionToken using BindSharedCollection, then later transfer the client end of token_request to another participant - the server will notice the existence of the token_request before considering this BufferCollectionToken fully closed.

rights_attenuation_mask rights bits that are zero in this mask will be absent in the buffer VMO rights obtainable via the client end of token_request. This allows an initiator or intermediary participant to attenuate the rights available to a participant. This does not allow a participant to gain rights that the participant doesn't already have. The value ZX_RIGHT_SAME_RIGHTS can be used to specify that no attenuation should be applied.

These values for rights_attenuation_mask result in no attenuation:

  • ZX_RIGHT_SAME_RIGHTS (preferred)
  • 0xFFFFFFFF (this is reasonable when an attenuation mask is computed)
  • 0 (deprecated - do not use 0 - an ERROR will go to the log)

token_request is the server end of a BufferCollectionToken channel. The client end of this channel acts as another participant in creating the shared BufferCollection.

Request

NameType
rights_attenuation_mask uint32
token_request server_end<BufferCollectionToken>

DuplicateSync

This method can be used to add more participants prior to creating a shared BufferCollection. A new token will be returned for each entry in the rights_attenuation_masks array. The return value is the client ends of each new participant token.

If the calling token may not actually be a valid token at all due to a potentially hostile/untrusted provider of the token, consider using ValidateBufferCollectionToken() first instead of potentially getting stuck indefinitely if DuplicateSync() never responds due to the calling token not being a real token.

In contrast to Duplicate(), no Sync() (see "protocol Node") is needed after calling this method.

All tokens must be turned in via BindSharedCollection() or Close() for a BufferCollection to be successfully created.

In each entry of rights_attenuation_masks, rights bits that are zero will be absent in the buffer VMO rights obtainable via the corresponding returned token. This allows an initiator or intermediary participant to attenuate the rights available to a participant. This does not allow a participant to gain rights that the participant doesn't already have. The value ZX_RIGHT_SAME_RIGHTS can be used to specify that no attenuation should be applied.

Request

NameType
rights_attenuation_masks vector<zx/Rights>[64]

Response

NameType
tokens vector<BufferCollectionToken>[64]

GetNodeRef

This gets an event handle that can be used as a parameter to IsAlternateFor() called on any Node. The client will not be granted the right to signal this event, as this handle should only be used as proof that the client obtained this handle from this Node.

Because this is a get not a set, no Sync() is needed between the GetNodeRef() and the call to IsAlternateFor(), despite the two calls potentially being on different channels.

See also IsAlternateFor().

Added: 9

Request

<EMPTY>

Response

NameType
node_ref handle<event>

IsAlternateFor

This checks whether the calling node is in a subtree rooted at a different child token of a common parent BufferCollectionTokenGroup, in relation to the passed-in node_ref.

This call is for assisting with admission control de-duplication, and with debugging.

The node_ref must be obtained using GetNodeRef() of a BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.

The node_ref can be a duplicated handle; it's not necessary to call GetNodeRef() for every call to IsAlternateFor().

If a calling token may not actually be a valid token at all due to a potentially hostile/untrusted provider of the token, call ValidateBufferCollectionToken() first instead of potentially getting stuck indefinitely if IsAlternateFor() never responds due to a calling token not being a real token (not really talking to sysmem). Another option is to call BindSharedCollection with this token first which also validates the token along with converting it to a BufferCollection, then call BufferCollection IsAlternateFor().

error values:

ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical buffer collection as the calling Node. Before logical allocation and within the same logical allocation sub-tree, this essentially means that the node_ref was never part of this logical buffer collection, since before logical allocation all node_refs that come into existence remain in existence at least until logical allocation (including Node(s) that have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND to be returned, this Node's channel needs to still be connected server side, which won't be the case if the whole logical allocation has failed. After logical allocation or in a different logical allocation sub-tree there are additional potential reasons for this error. For example a different logical allocation (separated from this Node(s) logical allocation by an AttachToken() or SetDispensable()) can fail its sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may exist and may select a different child sub-tree than the sub-tree the node_ref is in causing deletion of the node_ref Node. The only time sysmem keeps a Node around after that Node has no corresponding channel is when Close() is used and the Node's sub-tree has not yet failed. Another reason for this error is if the node_ref is an eventpair handle with sufficient rights, but isn't actually a real node_ref obtained from GetNodeRef().

ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an eventpair handle, or doesn't have the needed rights expected on a real node_ref.

No other failing status codes are returned by this call. However, sysmem may add additional codes in future, so the client should have sensible default handling for any failing status code.

On success, is_alternate has the following meaning:

  • true - The first parent node in common between the calling node and the node_ref Node is a BufferCollectionTokenGroup. This means that the calling Node and the node_ref Node will not have both their constraints apply - rather sysmem will choose one or the other of the constraints - never both. This is because only one child of a BufferCollectionTokenGroup is selected during logical allocation, with only that one child's sub-tree contributing to constraints aggregation.
  • false - The first parent node in common between the calling Node and the node_ref Node is not a BufferCollectionTokenGroup. Currently, this means the first parent node in common is a BufferCollectionToken or BufferCollection (regardless of not Close()ed or Close()ed). This means that the calling Node and the node_ref Node may have both their constraints apply during constraints aggregation of the logical allocation, if both Node(s) are selected by any parent BufferCollectionTokenGroup(s) involved. In this case, there is no BufferCollectionTokenGroup that will directly prevent the two Node(s) from both being selected and their constraints both aggregated, but even when false, one or both Node(s) may still be eliminated from consideration if one or both Node(s) has a direct or indirect parent BufferCollectionTokenGroup which selects a child sub-tree other than the sub-tree containing the calling Node or node_ref Node.
Added: 9

Request

NameType
node_ref handle<event>

Response

NameType
payload Node_IsAlternateFor_Result

SetDebugClientInfo

Set information about the current client that can be used by sysmem to help debug leaking memory and hangs waiting for constraints. |name| can be an arbitrary string, but the current process name (see fsl::GetCurrentProcessName()) is a good default. |id| can be an arbitrary id, but the current process ID (see fsl::GetCurrentProcessKoid()) is a good default.

Also used when verbose logging is enabled (see SetVerboseLogging()) to indicate which client is closing their channel first, leading to sub-tree failure (which can be normal if the purpose of the sub-tree is over, but if happening earlier than expected, the client-channel-specific name can help diagnose where the failure is first coming from, from sysmem's point of view).

By default (unless overriden by this message or using Allocator.SetDebugClientInfo()), a Node will copy info from its parent Node at the time the child Node is created. While this can be better than nothing, it's often better for each participant to use Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the info directly relevant to the current client. Also, SetVerboseLogging() can be used to help disambiguate if a Node is suspected of having info that was copied from its parent.

Added: 9

Request

NameType
name string[64]
id uint64

SetDebugTimeoutLogDeadline

Sysmem logs a warning if not all clients have set constraints 5 seconds after creating a collection. Clients can call this method to change when the log is printed. If multiple client set the deadline, it's unspecified which deadline will take effect.

Added: 9

Request

NameType
deadline zx/Time

SetDispensable

A dispensable token can fail after buffers are logically allocated without causing failure of its parent (if any).

The dispensable token participates in constraints aggregation along with its parent before logical buffer allocation. If the dispensable token fails before buffers are logically allocated, the failure propagates to the dispensable token's parent.

After buffers are logically allocated, failure of the dispensable token (or any child of the dispensable token) does not propagate to the dispensable token's parent. Failure does propagate from a normal child of a dispensable token to the dispensable token. Failure of a child is blocked from reaching its parent if the child is attached, or if the child is dispensable and the failure occurred after logical allocation.

A dispensable token can be used in cases where a participant needs to provide constraints, but after buffers are allocated, the participant can fail without causing buffer collection failure from the parent's point of view.

In contrast, AttachToken() can be used to create a token which does not participate in constraints aggregation with its parent, and whose failure at any time does not propagate to its parent, and whose delay providing constraints does not prevent the parent from completing its buffer allocation.

An initiator may in some scenarios choose to initially use a dispensable token for a given instance of a participant, and then later if the first instance of that participant fails, a new second instance of that participant my be given a token created with AttachToken().

If a client uses this message, the client should not rely on the client's own BufferCollectionToken or BufferCollection channel to close from the server end due to abrupt failure of any BufferCollectionToken or BufferCollection that the client has SetDispensable() and given out to another process. For this reason, the client should take extra care to notice failure of that other process via other means.

While it is possible (and potentially useful) to SetDispensable() on a direct child of a BufferCollectionTokenGroup, it isn't possible to later replace a failed dispensable token that was a direct child of a group with a new token using AttachToken() (since there's no AttachToken() on a group). Instead, to enable AttachToken() replacement in this case, create an additional non-dispensable token (node) that's a direct child of the group and make the existing dispensable token a child of the additional token (node). This way, the additional token (node) that is a direct child of the group has BufferCollection.AttachToken() which can be used to replace the failed dispensable token.

SetDispensable() on an already-dispensable token is idempotent.

Request

<EMPTY>

SetName

Set a name for VMOs in this buffer collection. The name may be truncated shorter. The name only affects VMOs allocated after it's set - this call does not rename existing VMOs. If multiple clients set different names then the larger priority value will win.

Added: 9

Request

NameType
priority uint32
name string[64]

SetVerboseLogging

Verbose logging includes constraints set via SetConstraints() from each client along with info set via SetDebugClientInfo() and the structure of the tree of Node(s).

Normally sysmem prints only a single line complaint when aggregation fails, with just the specific detailed reason that aggregation failed, with minimal context. While this is often enough to diagnose a problem if only a small change was made and the system had been working before the small change, it's often not particularly helpful for getting a new buffer collection to work for the first time. Especially with more complex trees of nodes, involving things like AttachToken(), SetDispensable(), BufferCollectionTokenGroup nodes, and associated sub-trees of nodes, verbose logging may help in diagnosing what the tree looks like and why it's failing a logical allocation, or why a tree or sub-tree is failing sooner than expected.

The intent of the extra logging is to be acceptable from a performance point of view, if only enabled on a low number of buffer collections. If we're not tracking down a bug, we shouldn't send this message.

If too many participants leave verbose logging enabled, we may end up needing to require that system-wide sysmem verbose logging be permitted via some other setting, to avoid sysmem spamming the log too much due to this message.

This may be a NOP for some nodes due to intentional policy associated with the node, if we don't trust a node enough to let it turn on verbose logging.

Added: 9

Request

<EMPTY>

Sync

Ensure that previous messages, including Duplicate() messages on a token, collection, or group, have been received server side.

Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a valid sysmem token risks the Sync() hanging forever. See ValidateBufferCollectionToken() for one way to mitigate the possibility of a hostile/fake BufferCollectionToken at the cost of one round trip. Another way is to pass the token to BindSharedCollection(), which also validates the token as part of exchanging it for a BufferCollection channel, and BufferCollection Sync() can then be used.

After a Sync(), it's then safe to send the client end of token_request to another participant knowing the server will recognize the token when it's sent into BindSharedCollection() by the other participant.

Other options include waiting for each token.Duplicate() to complete individually (using separate call to token.Sync() after each), or calling Sync() on BufferCollection after the token has been turned in via BindSharedCollection().

Another way to mitigate is to avoid calling Sync() on the token, and instead later deal with potential failure of BufferCollection.Sync() if the original token was invalid. This option can be preferable from a performance point of view, but requires client code to delay sending tokens duplicated from this token until after client code has converted the duplicating token to a BufferCollection and received successful response from BufferCollection.Sync().

Prefer using BufferCollection.Sync() instead, when feasible (see above). When BufferCollection.Sync() isn't feasible, the caller must already know that this token is/was valid, or BufferCollectionToken.Sync() may hang forever. See ValidateBufferCollectionToken() to check token validity first if the token isn't already known to be (is/was) valid.

Added: 9

Request

<EMPTY>

Response

<EMPTY>

BufferCollectionTokenGroup

Defined in fuchsia.sysmem/collection.fidl

The sysmem implementation is guaranteed to be consistent with a logical / conceptual model as follows:

As usual, a logical allocation considers either the root and all nodes with connectivity to the root that don't transit an AttachToken(), or a sub-tree rooted at an AttachToken() token and all nodes with connectivity to that subtree that don't transit another AttachToken(). This is called the logical allocation pruned sub-tree, or pruned sub-tree for short.

During constraints aggregation, each BufferCollectionTokenGroup will select a single child token among its children. The rest of the children will appear to fail the logical allocation, while the selected child may succeed.

When more than one BufferCollectionTokenGroup exists in the overall logical allocation pruned sub-tree, the relative priority between two groups is equivalent to their ordering in a DFS pre-order iteration of the tree, with parents higher priority than children, and left children higher priority than right children.

When a particular child of a group is selected (whether provisionally during a constraints aggregation attempt, or as a final selection), the non-selection of other children of the group can potentially "hide" other groups under those non-selected children.

Within a logical allocation, aggregation is attempted first by provisionally selecting the child 0 of the highest-priority group, and child 0 of the next highest-priority group that isn't hidden by the provisional selections so far, etc.

If that aggregation attempt fails, aggregation will be attempted with the ordinal 0 child of all the same groups except the lowest priority non-hidden group which will provisionally select its ordinal 1 child (and then child 2 and so on). If a new lowest-priority group is un-hidden as provisional selections are updated, that newly un-hidden lowest-priority group has all its children considered in order, before changing the provisional selection in the former lowest-priority group. In terms of result, this is equivalent to systematic enumeration of all possible combinations of choices in a counting-like order updating the lowest-priority group the most often and the highest-priority group the least often. Rather than actually attempting aggregation with all the combinations, we can skip over combinations which are redundant/equivalent due to hiding without any change to the result.

Attempted aggregations of enumerated non-equivalent combinations of choices continue in this manner until either (a) all aggregation attempts fail in which case the overall logical allocation fails, or (b) until an attempted aggregation succeeds, in which case buffer allocation (if needed) is attempted once. If buffer allocation based on the first successful aggregation fails, the overall logical allocation fails (there is no buffer allocation retry / re-attempt). If buffer allocation succeeds (or is not needed), the logical allocation succeeds.

If this prioritization scheme cannot reasonably work for your usage of sysmem, please contact sysmem folks to discuss potentially adding a way to achieve what you need.

Please avoid creating a large number of BufferCollectionTokenGroup(s) per logical allocation, especially with large number of children overall, and especially in cases where aggregation may reasonably be expected to often fail using ordinal 0 children and possibly with later children as well. We anticipate mitigating potentially high time complexity of evaluating too many child combinations/selections across too many groups by simply failing logical allocation beyond a certain (fairly high, but not huge) max number of considered group child combinations/selections. More advanced (and more complicated) mitigation is not anticipated to be practically necessary or worth the added complexity. Please contact sysmem folks if the max limit is getting hit or if you anticipate it getting hit, to discuss potential options.

Prefer to use multiple ImageFormatConstraints in a single BufferCollectionConstraints when feasible (when a participant just needs to express the ability to work with more than a single PixelFormat, with sysmem choosing which PixelFormat to use among those supported by all participants).

Similar to BufferCollectionToken and BufferCollection, closure of the BufferCollectionTokenGroup channel without sending Close() first will cause logical buffer collection failure (or sub-tree failure if using SetDispensable() or AttachToken() and the BufferCollectionTokenGroup is part of a sub-tree under such a node that doesn't propagate failure to its parent).

Added: 9

AllChildrenPresent

AllChildrenPresent()

After creating all children, the client must call AllChildrenPresent() to inform sysmem that no more children will be created, so that sysmem can know when it's ok to start aggregating constraints.

If Close() is to be sent, it should be sent after AllChildrenPresent(), else failure of the group and propagation of the failure to the group's parent will still be triggered.

Request

<EMPTY>

Close

On a BufferCollectionToken channel:

Normally a participant will convert a BufferCollectionToken into a BufferCollection view, but a participant is also free to Close() the token (and then close the channel immediately or shortly later in response to server closing its end), which avoids causing logical buffer collection failure.  Normally an unexpected token channel close will cause logical buffer collection failure (the only exceptions being certain cases involving AttachToken() or SetDispensable()).

On a BufferCollection channel:

By default the server handles unexpected failure of a BufferCollection by failing the whole logical buffer collection. Partly this is to expedite closing VMO handles to reclaim memory when any participant fails. If a participant would like to cleanly close a BufferCollection view without causing logical buffer collection failure, the participant can send Close() before closing the client end of the BufferCollection channel. If this is the last BufferCollection view, the logical buffer collection will still go away. The Close() can occur before or after SetConstraints(). If before SetConstraints(), the buffer collection won't require constraints from this node in order to allocate. If after SetConstraints(), the constraints are retained and aggregated along with any subsequent logical allocation(s), despite the lack of channel connection.

On a BufferCollectionTokenGroup channel:

By default, unexpected failure of a BufferCollectionTokenGroup will trigger failure of the logical BufferCollectionTokenGroup and will propagate failure to its parent. To close a BufferCollectionTokenGroup channel without failing the logical group or propagating failure, send Close() before closing the channel client endpoint.

If Close() occurs before AllChildrenPresent(), the logical buffer collection will still fail despite the Close() (because sysmem can't be sure whether all relevant children were created, so it's ambiguous whether all relevant constraints will be provided to sysmem). If Close() occurs after AllChildrenPresent(), the children and all their constraints remain intact (just as they would if the BufferCollectionTokenGroup channel had remained open), and the close doesn't trigger or propagate failure.

Added: 9

Request

<EMPTY>

CreateChild

Create a child token. Before passing the client end of this token to BindSharedCollection(), completion of Sync() after CreateChild() is required. Or the client can use CreateChildrenSync() which essentially includes the Sync().

token_request - the server end of the new token channel.

rights_attenuation_mask - If ZX_RIGHT_SAME_RIGHTS, the created token allows the holder to get the same rights to buffers as the parent token (of the group) had.

Request

NameType
payload BufferCollectionTokenGroupCreateChildRequest

CreateChildrenSync

Create 1 or more child tokens at once, synchronously. In contrast to CreateChild(), no Sync() completion is required before passing the client end of a returned token to BindSharedCollection().

The size of the rights_attentuation_mask determines the number of created child tokens.

The lower-index child tokens are higher priority (attempted sooner) than higher-index child tokens.

As per all child tokens, successful aggregation will choose exactly one child among all created children (across all children created across potentially multiple calls to CreateChild() and CreateChildrenSync()).

The maximum permissible total number of children per group, and total number of nodes in an overall tree (from the root) are capped to limits which are not configurable via these protocols.

Request

NameType
rights_attenuation_masks vector<zx/Rights>[64]

Response

NameType
tokens vector<BufferCollectionToken>[64]

GetNodeRef

This gets an event handle that can be used as a parameter to IsAlternateFor() called on any Node. The client will not be granted the right to signal this event, as this handle should only be used as proof that the client obtained this handle from this Node.

Because this is a get not a set, no Sync() is needed between the GetNodeRef() and the call to IsAlternateFor(), despite the two calls potentially being on different channels.

See also IsAlternateFor().

Added: 9

Request

<EMPTY>

Response

NameType
node_ref handle<event>

IsAlternateFor

This checks whether the calling node is in a subtree rooted at a different child token of a common parent BufferCollectionTokenGroup, in relation to the passed-in node_ref.

This call is for assisting with admission control de-duplication, and with debugging.

The node_ref must be obtained using GetNodeRef() of a BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.

The node_ref can be a duplicated handle; it's not necessary to call GetNodeRef() for every call to IsAlternateFor().

If a calling token may not actually be a valid token at all due to a potentially hostile/untrusted provider of the token, call ValidateBufferCollectionToken() first instead of potentially getting stuck indefinitely if IsAlternateFor() never responds due to a calling token not being a real token (not really talking to sysmem). Another option is to call BindSharedCollection with this token first which also validates the token along with converting it to a BufferCollection, then call BufferCollection IsAlternateFor().

error values:

ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical buffer collection as the calling Node. Before logical allocation and within the same logical allocation sub-tree, this essentially means that the node_ref was never part of this logical buffer collection, since before logical allocation all node_refs that come into existence remain in existence at least until logical allocation (including Node(s) that have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND to be returned, this Node's channel needs to still be connected server side, which won't be the case if the whole logical allocation has failed. After logical allocation or in a different logical allocation sub-tree there are additional potential reasons for this error. For example a different logical allocation (separated from this Node(s) logical allocation by an AttachToken() or SetDispensable()) can fail its sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may exist and may select a different child sub-tree than the sub-tree the node_ref is in causing deletion of the node_ref Node. The only time sysmem keeps a Node around after that Node has no corresponding channel is when Close() is used and the Node's sub-tree has not yet failed. Another reason for this error is if the node_ref is an eventpair handle with sufficient rights, but isn't actually a real node_ref obtained from GetNodeRef().

ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an eventpair handle, or doesn't have the needed rights expected on a real node_ref.

No other failing status codes are returned by this call. However, sysmem may add additional codes in future, so the client should have sensible default handling for any failing status code.

On success, is_alternate has the following meaning:

  • true - The first parent node in common between the calling node and the node_ref Node is a BufferCollectionTokenGroup. This means that the calling Node and the node_ref Node will not have both their constraints apply - rather sysmem will choose one or the other of the constraints - never both. This is because only one child of a BufferCollectionTokenGroup is selected during logical allocation, with only that one child's sub-tree contributing to constraints aggregation.
  • false - The first parent node in common between the calling Node and the node_ref Node is not a BufferCollectionTokenGroup. Currently, this means the first parent node in common is a BufferCollectionToken or BufferCollection (regardless of not Close()ed or Close()ed). This means that the calling Node and the node_ref Node may have both their constraints apply during constraints aggregation of the logical allocation, if both Node(s) are selected by any parent BufferCollectionTokenGroup(s) involved. In this case, there is no BufferCollectionTokenGroup that will directly prevent the two Node(s) from both being selected and their constraints both aggregated, but even when false, one or both Node(s) may still be eliminated from consideration if one or both Node(s) has a direct or indirect parent BufferCollectionTokenGroup which selects a child sub-tree other than the sub-tree containing the calling Node or node_ref Node.
Added: 9

Request

NameType
node_ref handle<event>

Response

NameType
payload Node_IsAlternateFor_Result

SetDebugClientInfo

Set information about the current client that can be used by sysmem to help debug leaking memory and hangs waiting for constraints. |name| can be an arbitrary string, but the current process name (see fsl::GetCurrentProcessName()) is a good default. |id| can be an arbitrary id, but the current process ID (see fsl::GetCurrentProcessKoid()) is a good default.

Also used when verbose logging is enabled (see SetVerboseLogging()) to indicate which client is closing their channel first, leading to sub-tree failure (which can be normal if the purpose of the sub-tree is over, but if happening earlier than expected, the client-channel-specific name can help diagnose where the failure is first coming from, from sysmem's point of view).

By default (unless overriden by this message or using Allocator.SetDebugClientInfo()), a Node will copy info from its parent Node at the time the child Node is created. While this can be better than nothing, it's often better for each participant to use Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the info directly relevant to the current client. Also, SetVerboseLogging() can be used to help disambiguate if a Node is suspected of having info that was copied from its parent.

Added: 9

Request

NameType
name string[64]
id uint64

SetDebugTimeoutLogDeadline

Sysmem logs a warning if not all clients have set constraints 5 seconds after creating a collection. Clients can call this method to change when the log is printed. If multiple client set the deadline, it's unspecified which deadline will take effect.

Added: 9

Request

NameType
deadline zx/Time

SetName

Set a name for VMOs in this buffer collection. The name may be truncated shorter. The name only affects VMOs allocated after it's set - this call does not rename existing VMOs. If multiple clients set different names then the larger priority value will win.

Added: 9

Request

NameType
priority uint32
name string[64]

SetVerboseLogging

Verbose logging includes constraints set via SetConstraints() from each client along with info set via SetDebugClientInfo() and the structure of the tree of Node(s).

Normally sysmem prints only a single line complaint when aggregation fails, with just the specific detailed reason that aggregation failed, with minimal context. While this is often enough to diagnose a problem if only a small change was made and the system had been working before the small change, it's often not particularly helpful for getting a new buffer collection to work for the first time. Especially with more complex trees of nodes, involving things like AttachToken(), SetDispensable(), BufferCollectionTokenGroup nodes, and associated sub-trees of nodes, verbose logging may help in diagnosing what the tree looks like and why it's failing a logical allocation, or why a tree or sub-tree is failing sooner than expected.

The intent of the extra logging is to be acceptable from a performance point of view, if only enabled on a low number of buffer collections. If we're not tracking down a bug, we shouldn't send this message.

If too many participants leave verbose logging enabled, we may end up needing to require that system-wide sysmem verbose logging be permitted via some other setting, to avoid sysmem spamming the log too much due to this message.

This may be a NOP for some nodes due to intentional policy associated with the node, if we don't trust a node enough to let it turn on verbose logging.

Added: 9

Request

<EMPTY>

Sync

Ensure that previous messages, including Duplicate() messages on a token, collection, or group, have been received server side.

Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a valid sysmem token risks the Sync() hanging forever. See ValidateBufferCollectionToken() for one way to mitigate the possibility of a hostile/fake BufferCollectionToken at the cost of one round trip. Another way is to pass the token to BindSharedCollection(), which also validates the token as part of exchanging it for a BufferCollection channel, and BufferCollection Sync() can then be used.

After a Sync(), it's then safe to send the client end of token_request to another participant knowing the server will recognize the token when it's sent into BindSharedCollection() by the other participant.

Other options include waiting for each token.Duplicate() to complete individually (using separate call to token.Sync() after each), or calling Sync() on BufferCollection after the token has been turned in via BindSharedCollection().

Another way to mitigate is to avoid calling Sync() on the token, and instead later deal with potential failure of BufferCollection.Sync() if the original token was invalid. This option can be preferable from a performance point of view, but requires client code to delay sending tokens duplicated from this token until after client code has converted the duplicating token to a BufferCollection and received successful response from BufferCollection.Sync().

Prefer using BufferCollection.Sync() instead, when feasible (see above). When BufferCollection.Sync() isn't feasible, the caller must already know that this token is/was valid, or BufferCollectionToken.Sync() may hang forever. See ValidateBufferCollectionToken() to check token validity first if the token isn't already known to be (is/was) valid.

Added: 9

Request

<EMPTY>

Response

<EMPTY>

Node

Defined in fuchsia.sysmem/collection.fidl

Added: 9

Close

On a BufferCollectionToken channel:

Normally a participant will convert a BufferCollectionToken into a BufferCollection view, but a participant is also free to Close() the token (and then close the channel immediately or shortly later in response to server closing its end), which avoids causing logical buffer collection failure.  Normally an unexpected token channel close will cause logical buffer collection failure (the only exceptions being certain cases involving AttachToken() or SetDispensable()).

On a BufferCollection channel:

By default the server handles unexpected failure of a BufferCollection by failing the whole logical buffer collection. Partly this is to expedite closing VMO handles to reclaim memory when any participant fails. If a participant would like to cleanly close a BufferCollection view without causing logical buffer collection failure, the participant can send Close() before closing the client end of the BufferCollection channel. If this is the last BufferCollection view, the logical buffer collection will still go away. The Close() can occur before or after SetConstraints(). If before SetConstraints(), the buffer collection won't require constraints from this node in order to allocate. If after SetConstraints(), the constraints are retained and aggregated along with any subsequent logical allocation(s), despite the lack of channel connection.

On a BufferCollectionTokenGroup channel:

By default, unexpected failure of a BufferCollectionTokenGroup will trigger failure of the logical BufferCollectionTokenGroup and will propagate failure to its parent. To close a BufferCollectionTokenGroup channel without failing the logical group or propagating failure, send Close() before closing the channel client endpoint.

If Close() occurs before AllChildrenPresent(), the logical buffer collection will still fail despite the Close() (because sysmem can't be sure whether all relevant children were created, so it's ambiguous whether all relevant constraints will be provided to sysmem). If Close() occurs after AllChildrenPresent(), the children and all their constraints remain intact (just as they would if the BufferCollectionTokenGroup channel had remained open), and the close doesn't trigger or propagate failure.

Added: 9

Request

<EMPTY>

GetNodeRef

This gets an event handle that can be used as a parameter to IsAlternateFor() called on any Node. The client will not be granted the right to signal this event, as this handle should only be used as proof that the client obtained this handle from this Node.

Because this is a get not a set, no Sync() is needed between the GetNodeRef() and the call to IsAlternateFor(), despite the two calls potentially being on different channels.

See also IsAlternateFor().

Added: 9

Request

<EMPTY>

Response

NameType
node_ref handle<event>

IsAlternateFor

This checks whether the calling node is in a subtree rooted at a different child token of a common parent BufferCollectionTokenGroup, in relation to the passed-in node_ref.

This call is for assisting with admission control de-duplication, and with debugging.

The node_ref must be obtained using GetNodeRef() of a BufferCollectionToken, BufferCollection, or BufferCollectionTokenGroup.

The node_ref can be a duplicated handle; it's not necessary to call GetNodeRef() for every call to IsAlternateFor().

If a calling token may not actually be a valid token at all due to a potentially hostile/untrusted provider of the token, call ValidateBufferCollectionToken() first instead of potentially getting stuck indefinitely if IsAlternateFor() never responds due to a calling token not being a real token (not really talking to sysmem). Another option is to call BindSharedCollection with this token first which also validates the token along with converting it to a BufferCollection, then call BufferCollection IsAlternateFor().

error values:

ZX_ERR_NOT_FOUND means the node_ref wasn't found within the same logical buffer collection as the calling Node. Before logical allocation and within the same logical allocation sub-tree, this essentially means that the node_ref was never part of this logical buffer collection, since before logical allocation all node_refs that come into existence remain in existence at least until logical allocation (including Node(s) that have done a Close() and closed their channel), and for ZX_ERR_NOT_FOUND to be returned, this Node's channel needs to still be connected server side, which won't be the case if the whole logical allocation has failed. After logical allocation or in a different logical allocation sub-tree there are additional potential reasons for this error. For example a different logical allocation (separated from this Node(s) logical allocation by an AttachToken() or SetDispensable()) can fail its sub-tree deleting those Node(s), or a BufferCollectionTokenGroup may exist and may select a different child sub-tree than the sub-tree the node_ref is in causing deletion of the node_ref Node. The only time sysmem keeps a Node around after that Node has no corresponding channel is when Close() is used and the Node's sub-tree has not yet failed. Another reason for this error is if the node_ref is an eventpair handle with sufficient rights, but isn't actually a real node_ref obtained from GetNodeRef().

ZX_ERR_INVALID_ARGS means the caller passed a node_ref that isn't an eventpair handle, or doesn't have the needed rights expected on a real node_ref.

No other failing status codes are returned by this call. However, sysmem may add additional codes in future, so the client should have sensible default handling for any failing status code.

On success, is_alternate has the following meaning:

  • true - The first parent node in common between the calling node and the node_ref Node is a BufferCollectionTokenGroup. This means that the calling Node and the node_ref Node will not have both their constraints apply - rather sysmem will choose one or the other of the constraints - never both. This is because only one child of a BufferCollectionTokenGroup is selected during logical allocation, with only that one child's sub-tree contributing to constraints aggregation.
  • false - The first parent node in common between the calling Node and the node_ref Node is not a BufferCollectionTokenGroup. Currently, this means the first parent node in common is a BufferCollectionToken or BufferCollection (regardless of not Close()ed or Close()ed). This means that the calling Node and the node_ref Node may have both their constraints apply during constraints aggregation of the logical allocation, if both Node(s) are selected by any parent BufferCollectionTokenGroup(s) involved. In this case, there is no BufferCollectionTokenGroup that will directly prevent the two Node(s) from both being selected and their constraints both aggregated, but even when false, one or both Node(s) may still be eliminated from consideration if one or both Node(s) has a direct or indirect parent BufferCollectionTokenGroup which selects a child sub-tree other than the sub-tree containing the calling Node or node_ref Node.
Added: 9

Request

NameType
node_ref handle<event>

Response

NameType
payload Node_IsAlternateFor_Result

SetDebugClientInfo

Set information about the current client that can be used by sysmem to help debug leaking memory and hangs waiting for constraints. |name| can be an arbitrary string, but the current process name (see fsl::GetCurrentProcessName()) is a good default. |id| can be an arbitrary id, but the current process ID (see fsl::GetCurrentProcessKoid()) is a good default.

Also used when verbose logging is enabled (see SetVerboseLogging()) to indicate which client is closing their channel first, leading to sub-tree failure (which can be normal if the purpose of the sub-tree is over, but if happening earlier than expected, the client-channel-specific name can help diagnose where the failure is first coming from, from sysmem's point of view).

By default (unless overriden by this message or using Allocator.SetDebugClientInfo()), a Node will copy info from its parent Node at the time the child Node is created. While this can be better than nothing, it's often better for each participant to use Node.SetDebugClientInfo() or Allocator.SetDebugClientInfo() to keep the info directly relevant to the current client. Also, SetVerboseLogging() can be used to help disambiguate if a Node is suspected of having info that was copied from its parent.

Added: 9

Request

NameType
name string[64]
id uint64

SetDebugTimeoutLogDeadline

Sysmem logs a warning if not all clients have set constraints 5 seconds after creating a collection. Clients can call this method to change when the log is printed. If multiple client set the deadline, it's unspecified which deadline will take effect.

Added: 9

Request

NameType
deadline zx/Time

SetName

Set a name for VMOs in this buffer collection. The name may be truncated shorter. The name only affects VMOs allocated after it's set - this call does not rename existing VMOs. If multiple clients set different names then the larger priority value will win.

Added: 9

Request

NameType
priority uint32
name string[64]

SetVerboseLogging

Verbose logging includes constraints set via SetConstraints() from each client along with info set via SetDebugClientInfo() and the structure of the tree of Node(s).

Normally sysmem prints only a single line complaint when aggregation fails, with just the specific detailed reason that aggregation failed, with minimal context. While this is often enough to diagnose a problem if only a small change was made and the system had been working before the small change, it's often not particularly helpful for getting a new buffer collection to work for the first time. Especially with more complex trees of nodes, involving things like AttachToken(), SetDispensable(), BufferCollectionTokenGroup nodes, and associated sub-trees of nodes, verbose logging may help in diagnosing what the tree looks like and why it's failing a logical allocation, or why a tree or sub-tree is failing sooner than expected.

The intent of the extra logging is to be acceptable from a performance point of view, if only enabled on a low number of buffer collections. If we're not tracking down a bug, we shouldn't send this message.

If too many participants leave verbose logging enabled, we may end up needing to require that system-wide sysmem verbose logging be permitted via some other setting, to avoid sysmem spamming the log too much due to this message.

This may be a NOP for some nodes due to intentional policy associated with the node, if we don't trust a node enough to let it turn on verbose logging.

Added: 9

Request

<EMPTY>

Sync

Ensure that previous messages, including Duplicate() messages on a token, collection, or group, have been received server side.

Calling BufferCollectionToken.Sync() on a token that isn't/wasn't a valid sysmem token risks the Sync() hanging forever. See ValidateBufferCollectionToken() for one way to mitigate the possibility of a hostile/fake BufferCollectionToken at the cost of one round trip. Another way is to pass the token to BindSharedCollection(), which also validates the token as part of exchanging it for a BufferCollection channel, and BufferCollection Sync() can then be used.

After a Sync(), it's then safe to send the client end of token_request to another participant knowing the server will recognize the token when it's sent into BindSharedCollection() by the other participant.

Other options include waiting for each token.Duplicate() to complete individually (using separate call to token.Sync() after each), or calling Sync() on BufferCollection after the token has been turned in via BindSharedCollection().

Another way to mitigate is to avoid calling Sync() on the token, and instead later deal with potential failure of BufferCollection.Sync() if the original token was invalid. This option can be preferable from a performance point of view, but requires client code to delay sending tokens duplicated from this token until after client code has converted the duplicating token to a BufferCollection and received successful response from BufferCollection.Sync().

Prefer using BufferCollection.Sync() instead, when feasible (see above). When BufferCollection.Sync() isn't feasible, the caller must already know that this token is/was valid, or BufferCollectionToken.Sync() may hang forever. See ValidateBufferCollectionToken() to check token validity first if the token isn't already known to be (is/was) valid.

Added: 9

Request

<EMPTY>

Response

<EMPTY>

SecureMem

Defined in fuchsia.sysmem/secure_mem.fidl

SecureMem

The client is sysmem. The server is securemem driver.

TEE - Trusted Execution Environment.

REE - Rich Execution Environment.

Enables sysmem to call the securemem driver to get any secure heaps configured via the TEE (or via the securemem driver), and set any physical secure heaps configured via sysmem.

Presently, dynamically-allocated secure heaps are configured via sysmem, as it starts quite early during boot and can successfully reserve contiguous physical memory. Presently, fixed-location secure heaps are configured via TEE, as the plumbing goes from the bootloader to the TEE. However, this protocol intentionally doesn't care which heaps are dynamically-allocated and which are fixed-location.

AddSecureHeapPhysicalRange

This request from sysmem to the securemem driver conveys a physical range to add, for a heap whose physical range(s) are set up via sysmem.

Only sysmem can call this because only sysmem is handed the client end of a FIDL channel serving this protocol, via RegisterSecureMem(). The securemem driver is the server end of this protocol.

The securemem driver must configure all the covered offsets as protected before responding to this message with success.

On failure, the securemem driver must ensure the protected range was not created.

Sysmem must only call this up to once if dynamic_protection_ranges false.

If dynamic_protection_ranges is true, sysmem can call this multiple times as long as the current number of ranges never exceeds max_protected_range_count.

The caller must not attempt to add a range that matches an already-existing range. Added ranges can overlap each other as long as no two ranges match exactly.

Errors:

  • ZX_ERR_BAD_STATE - called more than once when !dynamic_protection_ranges. Adding a heap that would cause overall heap count to exceed max_protected_range_count.
  • ZX_ERR_INVALID_ARGS - unexpected heap, or range that doesn't conform to protected_range_granularity.
  • ZX_ERR_INTERNAL - generic internal error (such as in communication with TEE which doesn't generate zx_status_t errors).
  • other errors are possible, such as from communication failures or server propagation of zx_status_t failures.

Request

NameType
heap_range SecureHeapAndRange

Response

NameType
payload SecureMem_AddSecureHeapPhysicalRange_Result

DeleteSecureHeapPhysicalRange

This request from sysmem to the securemem driver conveys a physical range to delete, for a heap whose physical range(s) are set up via sysmem.

Only sysmem can call this because only sysmem is handed the client end of a FIDL channel serving this protocol, via RegisterSecureMem(). The securemem driver is the server end of this protocol.

The securemem driver must configure all the covered offsets as not protected before responding to this message with success.

On failure, the securemem driver must ensure the protected range was not deleted.

Sysmem must not call this if dynamic_protection_ranges false.

If dynamic_protection_ranges is true, sysmem can call this repeatedly, on various ranges that exist at the time of the call.

If any portion of the range being deleted is not also covered by another protected range, then any ongoing DMA to any part of the entire range may be interrupted / may fail, potentially in a way that's disruptive to the entire system (bus lockup or similar, depending on device details). Therefore, the caller must ensure that no ongoing DMA is occurring to any portion of the range being deleted, unless the caller has other active ranges covering every block of the range being deleted. Ongoing DMA to/from blocks outside the range being deleted is never impacted by the deletion.

Errors:

  • ZX_ERR_BAD_STATE - called when !dynamic_protection_ranges.
  • ZX_ERR_INVALID_ARGS - unexpected heap, or range that doesn't conform to protected_range_granularity.
  • ZX_ERR_INTERNAL - generic internal error (such as in communication with TEE which doesn't generate zx_status_t errors).
  • ZX_ERR_NOT_FOUND - the specified range is not found.
  • other errors are possible, such as from communication failures or server propagation of zx_status_t failures.

Request

NameType
heap_range SecureHeapAndRange

Response

NameType
payload SecureMem_DeleteSecureHeapPhysicalRange_Result

GetPhysicalSecureHeapProperties

This request from sysmem to the securemem driver gets the properties of a protected/secure heap.

This only handles heaps with a single contiguous physical extent.

The heap's entire physical range is indicated in case this request needs some physical space to auto-detect how many ranges are REE-usable. Any temporary HW protection ranges will be deleted before this request completes.

Added: 9

Request

NameType
entire_heap SecureHeapAndRange

Response

NameType
payload SecureMem_GetPhysicalSecureHeapProperties_Result

GetPhysicalSecureHeaps

Gets the physical address and length of any secure heap whose physical range is configured via the TEE.

Presently, these will be fixed physical addresses and lengths, with the location plumbed via the TEE.

This is preferred over RegisterHeap() when there isn't any special heap-specific per-VMO setup or teardown required.

The physical range must be secured/protected by the TEE before the securemem driver responds to this request with success.

Sysmem should only call this once. Returning zero heaps is not a failure.

Errors:

  • ZX_ERR_BAD_STATE - called more than once.
  • ZX_ERR_INTERNAL - generic internal error (such as in communication with TEE which doesn't generate zx_status_t errors).
  • other errors are possible, such as from communication failures or server propagation of zx_status_t failures

Request

<EMPTY>

Response

NameType
payload SecureMem_GetPhysicalSecureHeaps_Result

ModifySecureHeapPhysicalRange

This request from sysmem to the securemem driver conveys a physical range to modify and its new base and length, for a heap whose physical range(s) are set up via sysmem.

Only sysmem can call this because only sysmem is handed the client end of a FIDL channel serving this protocol, via RegisterSecureMem(). The securemem driver is the server end of this protocol.

The securemem driver must configure the range to cover only the new offsets before responding to this message with success.

On failure, the securemem driver must ensure the range was not changed.

Sysmem must not call this if dynamic_protection_ranges false. Sysmem must not call this if !is_mod_protected_range_available.

If dynamic_protection_ranges is true, sysmem can call this repeatedly, on various ranges that exist at the time of the call.

The range must only be modified at one end or the other, but not both. If the range is getting shorter, and the un-covered blocks are not covered by other active ranges, any ongoing DMA to the entire range that's geting shorter may fail in a way that disrupts the entire system (bus lockup or similar), so the caller must ensure that no DMA is ongoing to any portion of a range that is getting shorter, unless the blocks being un-covered by the modification to this range are all covered by other active ranges, in which case no disruption to ongoing DMA will occur.

If a range is modified to become <= zero length, the range is deleted.

Errors:

  • ZX_ERR_BAD_STATE - called when !dynamic_protection_ranges.
  • ZX_ERR_INVALID_ARGS - unexpected heap, or old_range or new_range that doesn't conform to protected_range_granularity, or old_range and new_range differ in both begin and end (disallowed).
  • ZX_ERR_INTERNAL - generic internal error (such as in communication with TEE which doesn't generate zx_status_t errors).
  • ZX_ERR_NOT_FOUND - the specified range is not found.
  • other errors are possible, such as from communication failures or server propagation of zx_status_t failures.

Request

NameType
range_modification SecureHeapAndRangeModification

Response

NameType
payload SecureMem_ModifySecureHeapPhysicalRange_Result

ZeroSubRange

Zero a sub-range of a currently-existing physical range added via AddSecureHeapPhysicalRange(). The sub-range must be fully covered by exactly one physical range, and must not overlap with any other physical range.

is_covering_range_explicit - When true, the covering range must be one of the ranges explicitly created via AddSecureHeapPhysicalRange(), possibly modified since. When false, the covering range must not be one of the ranges explicitly created via AddSecureHeapPhysicalRange(), but the covering range must exist as a covering range not created via AddSecureHeapPhysicalRange(). The covering range is typically the entire physical range (or a range which covers even more) of a heap configured by the TEE and whose configuration is conveyed to sysmem via GetPhysicalSecureHeaps().

Ongoing DMA is not disrupted by this request.

Request

NameType
is_covering_range_explicit bool
heap_range SecureHeapAndRange

Response

NameType
payload SecureMem_ZeroSubRange_Result

STRUCTS

BufferCollectionConstraints

Defined in fuchsia.sysmem/constraints.fidl

Constraints on BufferCollection parameters. These constraints can be specified per-participant. The sysmem service implements aggregation of constraints from multiple participants.

FieldTypeDescriptionDefault
usage BufferUsage

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.

No default
min_buffer_count_for_camping uint32

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.

No default
min_buffer_count_for_dedicated_slack 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.

No default
min_buffer_count_for_shared_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.

No default
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 above.

No default
max_buffer_count uint32

0 is treated as 0xFFFFFFFF.

No default
has_buffer_memory_constraints bool

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.

No default
buffer_memory_constraints BufferMemoryConstraints No default
image_format_constraints_count uint32

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 participants with non-zero image_format_constraints_count (and non-Null) BufferCollectionConstraints) are retained.

No default
image_format_constraints [32] No default

BufferCollectionInfo resource

Defined in fuchsia.sysmem/collections_deprecated.fidl

Information about a buffer collection and its buffers.

FieldTypeDescriptionDefault
buffer_count uint32

The number of buffers in the collection.

No default
format BufferFormat

Describes how the contents of buffers are represented. All buffers within the collection have the same format.

No default
vmos vmo[64]

VMO handles for each buffer in the collection. The VMOs are only present when the buffers are backed by VMOs.

If present, all the VMOs after buffer_count are invalid handles. All buffer VMO handles have identical size and access rights. 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.

No default
vmo_size uint64

The size of each VMO provided. This property is only present when the buffers are backed by VMOs.

0

BufferCollectionInfo_2 resource

Defined in fuchsia.sysmem/constraints.fidl

Information about a buffer collection and its buffers.

FieldTypeDescriptionDefault
buffer_count uint32

The total number of buffers.

No default
settings SingleBufferSettings

These settings apply to all the buffers in the initial buffer allocation.

No default
buffers [64]

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.

No default

BufferFormat

Defined in fuchsia.sysmem/formats_deprecated.fidl

Describes how the contents of buffers are represented. Buffers of each type are described by their own tables.

FieldTypeDescriptionDefault
tag uint32

Since this struct used to be a single member union, we kept the tag to avoid any wire format changes. The tag must be set to 0, no other value is correct.

0
image ImageFormat No default

BufferMemoryConstraints

Defined in fuchsia.sysmem/constraints.fidl

FieldTypeDescriptionDefault
min_size_bytes uint32 0
max_size_bytes uint32

0 is treated as 0xFFFFFFFF.

4294967295
physically_contiguous_required bool false
secure_required bool

If true, at least one participant requires secure memory.

When aggregating BufferCollectionConstraints, these values boolean-OR.

false
ram_domain_supported 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)

false
cpu_domain_supported bool true
inaccessible_domain_supported bool false
heap_permitted_count uint32

Optional heap constraints. Participants that don't care which heap memory is allocated on should leave this field 0.

No default
heap_permitted [32] No default

BufferMemorySettings

Defined in fuchsia.sysmem/constraints.fidl

FieldTypeDescriptionDefault
size_bytes uint32 No default
is_physically_contiguous bool No default
is_secure bool No default
coherency_domain CoherencyDomain No default
heap HeapType

The specific heap from which buffers are allocated. See above in this file for heap identifier values.

No default

BufferUsage

Defined in fuchsia.sysmem/usages.fidl

FieldTypeDescriptionDefault
none uint32 No default
cpu uint32 No default
vulkan uint32 No default
display uint32 No default
video uint32 No default

ColorSpace

Defined in fuchsia.sysmem/image_formats.fidl

Describes how the pixels within an image are meant to be presented. Simple color spaces need only a type. Parametric color spaces may require additional properties.

FieldTypeDescriptionDefault
type ColorSpaceType No default

FormatModifier

Defined in fuchsia.sysmem/format_modifier.fidl

FieldTypeDescriptionDefault
value uint64

The upper 8 bits are a vendor code as allocated in FormatModifierVendor enum. The lower 56 bits are vendor-defined.

This field and the values that go in this field are defined this way for compatibility reasons.

No default

ImageFormat

Defined in fuchsia.sysmem/image_formats_deprecated.fidl

Describes how an image is represented.

FieldTypeDescriptionDefault
width uint32

Row width in pixels.

No default
height uint32

Number of rows.

No default
layers uint32

Number of layers within a multi-layered image. Defaults to 1 if not specified.

1
pixel_format PixelFormat

Pixel format.

No default
color_space ColorSpace

Color space.

No default
planes [4] No default

ImageFormatConstraints

Defined in fuchsia.sysmem/constraints.fidl

Describes constraints on layout of image data in buffers.

FieldTypeDescriptionDefault
pixel_format PixelFormat

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.

No default
color_spaces_count uint32

Empty is an error. Redundant entries are an error. Arbitrary ordering is not an error.

No default
color_space [32] No default
min_coded_width 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.

No default
max_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.

No default
min_coded_height uint32

Minimum height in pixels. For example a video decoder participant may set this field to the coded_height specified by a stream.

No default
max_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.

No default
min_bytes_per_row uint32

Must be >= the value implied by min_coded_width for plane 0.

No default
max_bytes_per_row uint32

Must be >= the value implied by max_coded_width for plane 0. 0 is treated as 0xFFFFFFFF.

No default
max_coded_width_times_coded_height 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.

4294967295
layers uint32

Number of layers within a multi-layered image. 0 is treated as 1.

1
coded_width_divisor uint32

coded_width % width_divisor must be 0. 0 is treated as 1.

1
coded_height_divisor uint32

coded_height % height_divisor must be 0. 0 is treated as 1.

1
bytes_per_row_divisor uint32

bytes_per_row % bytes_per_row_divisor must be 0. 0 is treated as 1.

1
start_offset_divisor uint32

vmo_usable_start % start_offset_divisor must be 0. 0 is treated as 1.

1
display_width_divisor uint32

display_width % display_width_divisor must be 0. 0 is treated as 1.

1
display_height_divisor uint32

display_height % display_height_divisor must be 0. 0 is treated as 1.

1
required_min_coded_width uint32

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.

No default
required_max_coded_width uint32 No default
required_min_coded_height uint32

0 is treated as 0xFFFFFFFF.

No default
required_max_coded_height uint32 No default
required_min_bytes_per_row uint32

0 is treated as 0xFFFFFFFF.

No default
required_max_bytes_per_row uint32 No default

ImageFormat_2

Defined in fuchsia.sysmem/constraints.fidl

Describes how an image is represented.

FieldTypeDescriptionDefault
pixel_format PixelFormat

Pixel format.

No default
coded_width uint32

Row width in pixels that exist in the buffer. Must be >= display_width. Can be < the width implied by stride_bytes.

No default
coded_height uint32

Number of rows. Must be >= display_height.

No default
bytes_per_row 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.

No default
display_width 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).

No default
display_height uint32

Number of rows to be displayed. This can be <= coded_height, with any cropping on the bottom (not top).

No default
layers uint32

Number of layers within a multi-layered image.

1
color_space ColorSpace

Color space.

No default
has_pixel_aspect_ratio bool

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.

false
pixel_aspect_ratio_width uint32 1
pixel_aspect_ratio_height uint32 1

ImagePlane

Defined in fuchsia.sysmem/image_formats_deprecated.fidl

FieldTypeDescriptionDefault
byte_offset uint32

Byte offset of the start of the plane from the beginning of the image.

No default
bytes_per_row uint32

Stride in bytes per row. Only meaningful for linear buffer formats.

No default

ImageSpec

Defined in fuchsia.sysmem/image_formats_deprecated.fidl

Describes constraints for allocating images of some desired form.

FieldTypeDescriptionDefault
min_width uint32

Minimum width in pixels.

No default
min_height uint32

Minimum height in pixels.

No default
layers uint32

Number of layers within a multi-layered image. Defaults to 1 if not specified.

1
pixel_format PixelFormat

Pixel format.

No default
color_space ColorSpace

Color space.

No default

Node_IsAlternateFor_Response

Defined in fuchsia.sysmem/collection.fidl

FieldTypeDescriptionDefault
is_alternate bool No default

PixelFormat

Defined in fuchsia.sysmem/image_formats.fidl

Describes how the pixels within an image are represented. Simple formats need only a type. Parametric pixel formats may require additional properties.

FieldTypeDescriptionDefault
type PixelFormatType No default
has_format_modifier bool

This bool effectively makes format_modifier optional, to satisfy 'ForDeprecatedCBindings', to satisfy "FIDL Simple C Bindings".

No default
format_modifier FormatModifier No default

SecureMem_AddSecureHeapPhysicalRange_Response

Defined in fuchsia.sysmem/secure_mem.fidl

<EMPTY>

SecureMem_DeleteSecureHeapPhysicalRange_Response

Defined in fuchsia.sysmem/secure_mem.fidl

<EMPTY>

SecureMem_GetPhysicalSecureHeapProperties_Response

Defined in fuchsia.sysmem/secure_mem.fidl

FieldTypeDescriptionDefault
properties SecureHeapProperties No default

SecureMem_GetPhysicalSecureHeaps_Response

Defined in fuchsia.sysmem/secure_mem.fidl

FieldTypeDescriptionDefault
heaps SecureHeapsAndRanges No default

SecureMem_ModifySecureHeapPhysicalRange_Response

Defined in fuchsia.sysmem/secure_mem.fidl

<EMPTY>

SecureMem_ZeroSubRange_Response

Defined in fuchsia.sysmem/secure_mem.fidl

<EMPTY>

SingleBufferInfo resource

Defined in fuchsia.sysmem/constraints.fidl

FieldTypeDescriptionDefault
settings SingleBufferSettings No default
buffer VmoBuffer No default

SingleBufferSettings

Defined in fuchsia.sysmem/constraints.fidl

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:

FieldTypeDescriptionDefault
buffer_settings BufferMemorySettings No default
has_image_format_constraints bool

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.

No default
image_format_constraints ImageFormatConstraints No default

VmoBuffer resource

Defined in fuchsia.sysmem/constraints.fidl

FieldTypeDescriptionDefault
vmo handle<vmo>?

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.

No default
vmo_usable_start uint64

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.

No default

ENUMS

CoherencyDomain strict

Type: uint32

Defined in fuchsia.sysmem/constraints.fidl

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.

NameValueDescription
0
1
2

ColorSpaceType strict

Type: uint32

Defined in fuchsia.sysmem/image_formats.fidl

This list has a separate entry for each variant of a color space standard.

For this reason, should we ever add support for the RGB variant of 709, for example, we'd add a separate entry to this list for that variant. Similarly for the RGB variants of 2020 or 2100. Similarly for the YcCbcCrc variant of 2020. Similarly for the ICtCp variant of 2100.

A given ColorSpaceType may permit usage with a PixelFormatType(s) that provides a bits-per-sample that's compatible with the ColorSpaceType's official spec. Not all spec-valid combinations are necessarily supported. See ImageFormatIsSupportedColorSpaceForPixelFormat() for the best-case degree of support, but a "true" from that function doesn't guarantee that any given combination of participants will all support the desired combination of ColorSpaceType and PixelFormatType.

The sysmem service helps find a mutually supported combination and allocate suitable buffers.

A ColorSpaceType's spec is not implicitly extended to support outside-the-standard bits-per-sample (R, G, B, or Y sample). For example, for 2020 and 2100, 8 bits-per-Y-sample is not supported (by sysmem), because 8 bits-per-Y-sample is not in the spec for 2020 or 2100. A sysmem participant that attempts to advertise support for a PixelFormat + ColorSpace that's non-standard will cause sysmem to reject the combo and fail to allocate (intentionally, to strongly discourage specifying insufficiently-defined combos).

NameValueDescription
0

Not a valid color space type.

1

sRGB

2

601 NTSC ("525 line") YCbCr primaries, narrow

3

601 NTSC ("525 line") YCbCr primaries, wide

4

601 PAL ("625 line") YCbCr primaries, narrow

5

601 PAL ("625 line") YCbCr primaries, wide

6

709 YCbCr (not RGB)

7

2020 YCbCr (not RGB, not YcCbcCrc)

8

2100 YCbCr (not RGB, not ICtCp)

9

Either the pixel format doesn't represent a color, or it's in an application-specific colorspace that isn't describable by another entry in this enum.

4294967294

The sysmem client is explicitly indicating that the sysmem client does not care which color space is chosen / used.

Added: 10

HeapType strict

Type: uint64

Defined in fuchsia.sysmem/constraints.fidl

Known heap types. Device specific types should have bit 60 set. Top order bit is reserved and should not be set.

NameValueDescription
0
1152921504606912512

Heap used for amlogic protected memory.

1152921504606912513

Heap used for amlogic protected memory between decrypt and video decode.

1152921504606978048

Heap used by goldfish vulkan for device-local memory.

1152921504606978049

Heap used by goldfish vulkan for host-visible memory.

1152921504607043585

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.

PixelFormatType strict

Type: uint32

Defined in fuchsia.sysmem/image_formats.fidl

The ordering of the channels in the format name reflects how the actual layout of the channel.

Each of these values is opinionated re. the color spaces that can be contained within (in contrast with Vulkan).

This should be kept in sync with fuchsia.sysmem2.PixelFormatType.

NameValueDescription
0
1

RGB only, 8 bits per each of R/G/B/A sample Compatible with VK_FORMAT_R8G8B8A8_UNORM.

101

32bpp BGRA, 1 plane. RGB only, 8 bits per each of B/G/R/A sample. Compatible with VK_FORMAT_B8G8R8A8_UNORM.

102

YUV only, 8 bits per Y sample Compatible with VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM.

103

YUV only, 8 bits per Y sample Not compatible with any vulkan format.

104

YUV only, 8 bits per Y sample Compatible with VK_FORMAT_G8_B8R8_2PLANE_420_UNORM.

105

YUV only, 8 bits per Y sample Compatible with VK_FORMAT_G8B8G8R8_422_UNORM.

106
107

YUV only, 8 bits per Y sample Compatible with VK_FORMAT_G8_B8_R8_3PLANE_420_UNORM with B and R swizzled.

108

24bpp BGR, 1 plane. RGB only, 8 bits per each of B/G/R sample Compatible with VK_FORMAT_B8G8R8_UNORM.

109

16bpp RGB, 1 plane. 5 bits R, 6 bits G, 5 bits B Compatible with VK_FORMAT_R5G6B5_UNORM_PACK16.

110

8bpp RGB, 1 plane. 3 bits R, 3 bits G, 2 bits B Not compatible with any vulkan format.

111

8bpp RGB, 1 plane. 2 bits R, 2 bits G, 2 bits B Not compatible with any vulkan format.

112

8bpp, Luminance-only (red, green and blue have identical values.) Compatible with VK_FORMAT_R8_UNORM.

113

8bpp, Red-only (Green and Blue are to be interpreted as 0). Compatible with VK_FORMAT_R8_UNORM.

114

16bpp RG, 1 plane. 8 bits R, 8 bits G. Compatible with VK_FORMAT_R8G8_UNORM.

115

32bpp RGBA, 1 plane. 2 bits A, 10 bits R/G/B. Compatible with VK_FORMAT_A2R10G10B10_UNORM_PACK32.

116

32bpp BGRA, 1 plane. 2 bits A, 10 bits R/G/B. Compatible with VK_FORMAT_A2B10G10R10_UNORM_PACK32.

4294967294

The sysmem client is explicitly indicating that the sysmem client does not care which pixel format is chosen / used. When setting this value, the sysmem client must not set format_modifier_value.

Added: 10

TABLES

BufferCollectionTokenGroupCreateChildRequest resource

Defined in fuchsia.sysmem/collection.fidl

OrdinalFieldTypeDescription
token_request server_end<BufferCollectionToken>

Must be set.

rights_attenuation_mask uint32

If not set, the default is ZX_RIGHT_SAME_RIGHTS.

SecureHeapAndRange

Defined in fuchsia.sysmem/secure_mem.fidl

OrdinalFieldTypeDescription
heap HeapType
range SecureHeapRange

SecureHeapAndRangeModification

Defined in fuchsia.sysmem/secure_mem.fidl

OrdinalFieldTypeDescription
heap HeapType
old_range SecureHeapRange
new_range SecureHeapRange

SecureHeapAndRanges

Defined in fuchsia.sysmem/secure_mem.fidl

OrdinalFieldTypeDescription
heap HeapType

This is which secure/protected heap.

ranges vector<SecureHeapRange>[128]

The list of physical ranges. This list must be sorted by physical_address (lower first), and must not have any overlapping ranges. Ranges that are directly adjacent are allowed (not overlapping).

SecureHeapProperties

Defined in fuchsia.sysmem/secure_mem.fidl

OrdinalFieldTypeDescription
heap HeapType

The HeapType is repeated here for convenience.

dynamic_protection_ranges bool

If true, more than one call to SetPhysicalSecureHeap() for the same heap is allowed. If false, only one SetPhyscialSecureHeap() call is allowed, and no calls to DeleteSecureHeapPhysicalRange() or ModifySecureHeapPhysicalRange() are allowed. Even when this is false, the SecureMem server (driver) is still responsible for de-protecting just before warm reboot if protected ranges would not otherwise be cleaned up during a warm reboot.

protected_range_granularity uint32

The granularity of protection ranges. If the granularity of start is different than granularity of end or length, then this is the max granularity value among those values.

This must be a power of 2. The client must not request ranges that specify smaller granularity.

This must be at least zx_system_page_size() even if the HW can do smaller granularity.

max_protected_range_count uint64

The SecureMem server should not count reserved ranges that the SecureMem server uses internally to get from range set A to range set B, if the SecureMem server needs to do any emulation of that sort. Normally such emulation by the SecureMem server is unnecessary. If any ranges are reserved by the SecureMem server, those reserved ranges are not available for use by the SecureMem client.

If the number of ranges is limited only by available memory, it's ok for the SecureMem server to report 0xFFFFFFFFFFFFFFFF for this value. The field must still be set. As usual, the SecureMem server should ensure that SetPhysicalSecureHeapRanges() succeeds or fails atomically (either fully updates or rolls back before completing).

is_mod_protected_range_available bool

Iff true, ModifySecureHeapPhysicalRange() is implemented. Calling ModifySecureHeapPhysicalRange() when is_mod_protected_range_available is false is prohibited. Don't attempt to detect availability of ModifySecureHeapPhysicalRange() by calling it to see if it fails; it may ZX_PANIC().

SecureHeapRange

Defined in fuchsia.sysmem/secure_mem.fidl

OrdinalFieldTypeDescription
physical_address uint64

Must be aligned to at least heap_range_granularity.

size_bytes uint64

Must be aligned to at least heap_range_granularity.

SecureHeapsAndRanges

Defined in fuchsia.sysmem/secure_mem.fidl

OrdinalFieldTypeDescription
heaps vector<SecureHeapAndRanges>[32]

UNIONS

Node_IsAlternateFor_Result strict

Defined in fuchsia.sysmem/collection.fidl

OrdinalVariantTypeDescription
response Node_IsAlternateFor_Response
err zx/Status

SecureMem_AddSecureHeapPhysicalRange_Result strict

Defined in fuchsia.sysmem/secure_mem.fidl

OrdinalVariantTypeDescription
response SecureMem_AddSecureHeapPhysicalRange_Response
err zx/Status

SecureMem_DeleteSecureHeapPhysicalRange_Result strict

Defined in fuchsia.sysmem/secure_mem.fidl

OrdinalVariantTypeDescription
response SecureMem_DeleteSecureHeapPhysicalRange_Response
err zx/Status

SecureMem_GetPhysicalSecureHeapProperties_Result strict

Defined in fuchsia.sysmem/secure_mem.fidl

OrdinalVariantTypeDescription
response SecureMem_GetPhysicalSecureHeapProperties_Response
err zx/Status

SecureMem_GetPhysicalSecureHeaps_Result strict

Defined in fuchsia.sysmem/secure_mem.fidl

OrdinalVariantTypeDescription
response SecureMem_GetPhysicalSecureHeaps_Response
err zx/Status

SecureMem_ModifySecureHeapPhysicalRange_Result strict

Defined in fuchsia.sysmem/secure_mem.fidl

OrdinalVariantTypeDescription
response SecureMem_ModifySecureHeapPhysicalRange_Response
err zx/Status

SecureMem_ZeroSubRange_Result strict

Defined in fuchsia.sysmem/secure_mem.fidl

OrdinalVariantTypeDescription
response SecureMem_ZeroSubRange_Response
err zx/Status

CONSTANTS

NameValueTypeDescription
FORMAT_MODIFIER_ARM_AFBC_16X16 576460752303423489 uint64
FORMAT_MODIFIER_ARM_AFBC_16X16_SPLIT_BLOCK_SPARSE_YUV 576460752303423601 uint64
FORMAT_MODIFIER_ARM_AFBC_16X16_SPLIT_BLOCK_SPARSE_YUV_TE 576460752303427697 uint64
FORMAT_MODIFIER_ARM_AFBC_16X16_SPLIT_BLOCK_SPARSE_YUV_TE_TILED_HEADER 576460752303435889 uint64
FORMAT_MODIFIER_ARM_AFBC_16X16_SPLIT_BLOCK_SPARSE_YUV_TILED_HEADER 576460752303431793 uint64
FORMAT_MODIFIER_ARM_AFBC_16X16_TE 576460752303427585 uint64
FORMAT_MODIFIER_ARM_AFBC_16X16_YUV_TILED_HEADER 576460752303431697 uint64
FORMAT_MODIFIER_ARM_AFBC_32X8 576460752303423490 uint64
FORMAT_MODIFIER_ARM_AFBC_32X8_TE 576460752303427586 uint64
FORMAT_MODIFIER_ARM_BCH_BIT 2048 uint64
FORMAT_MODIFIER_ARM_LINEAR_TE 576460752303427584 uint64
FORMAT_MODIFIER_ARM_SPARSE_BIT 64 uint64
FORMAT_MODIFIER_ARM_SPLIT_BLOCK_BIT 32 uint64
FORMAT_MODIFIER_ARM_TE_BIT 4096 uint64
FORMAT_MODIFIER_ARM_TILED_HEADER_BIT 8192 uint64
FORMAT_MODIFIER_ARM_YUV_BIT 16 uint64
FORMAT_MODIFIER_DO_NOT_CARE 72057594037927934 uint64
Added: HEAD
FORMAT_MODIFIER_GOOGLE_GOLDFISH_OPTIMAL 648518346341351425 uint64
FORMAT_MODIFIER_INTEL_CCS_BIT 16777216 uint64
FORMAT_MODIFIER_INTEL_I915_X_TILED 72057594037927937 uint64
FORMAT_MODIFIER_INTEL_I915_YF_TILED 72057594037927939 uint64
FORMAT_MODIFIER_INTEL_I915_YF_TILED_CCS 72057594054705155 uint64
FORMAT_MODIFIER_INTEL_I915_Y_TILED 72057594037927938 uint64
FORMAT_MODIFIER_INTEL_I915_Y_TILED_CCS 72057594054705154 uint64
FORMAT_MODIFIER_INVALID FORMAT_MODIFIER_VALUE_RESERVED uint64
FORMAT_MODIFIER_LINEAR 0 uint64
FORMAT_MODIFIER_NONE 0 uint64
FORMAT_MODIFIER_VALUE_RESERVED 72057594037927935 uint64
FORMAT_MODIFIER_VENDOR_AMD 144115188075855872 uint64
FORMAT_MODIFIER_VENDOR_ARM 576460752303423488 uint64
FORMAT_MODIFIER_VENDOR_BROADCOM 504403158265495552 uint64
FORMAT_MODIFIER_VENDOR_GOOGLE 648518346341351424 uint64
FORMAT_MODIFIER_VENDOR_INTEL 72057594037927936 uint64
FORMAT_MODIFIER_VENDOR_NONE 0 uint64
FORMAT_MODIFIER_VENDOR_NVIDIA 216172782113783808 uint64
FORMAT_MODIFIER_VENDOR_QCOM 360287970189639680 uint64
FORMAT_MODIFIER_VENDOR_SAMSUNG 288230376151711744 uint64
FORMAT_MODIFIER_VENDOR_VIVANTE 432345564227567616 uint64
MAX_COUNT_BUFFER_COLLECTION_CONSTRAINTS_IMAGE_FORMAT_CONSTRAINTS 32 uint32
MAX_COUNT_BUFFER_COLLECTION_INFO_BUFFERS 64 uint32
MAX_COUNT_BUFFER_MEMORY_CONSTRAINTS_HEAP_PERMITTED 32 uint32
MAX_COUNT_CREATE_CHILDREN 64 int32

Actually creating this many children isn't recommended in most typical scenarios, but isn't prevented, for testing reasons, and just in case an unusual scenario needs it. Mitigation of potentially high time complexity in sysmem will limit the actual number of group child combinations considered in aggregation attempts to a separate maximum that is not settable via these protocols. The maximum number of total nodes in a sysmem token tree is limited to a separate maximum that is not settable via these protocols.

Added: 9
MAX_COUNT_DUPLICATES 64 uint32
MAX_COUNT_IMAGE_FORMAT_CONSTRAINTS_COLOR_SPACES 32 uint32
MAX_HEAPS_COUNT 32 uint32
MAX_RANGES_COUNT 128 uint32
VULKAN_BUFFER_USAGE_INDEX_BUFFER 4194304 uint32
VULKAN_BUFFER_USAGE_INDIRECT_BUFFER 16777216 uint32
VULKAN_BUFFER_USAGE_STORAGE_BUFFER 2097152 uint32
VULKAN_BUFFER_USAGE_STORAGE_TEXEL_BUFFER 524288 uint32
VULKAN_BUFFER_USAGE_TRANSFER_DST 131072 uint32
VULKAN_BUFFER_USAGE_TRANSFER_SRC 65536 uint32
VULKAN_BUFFER_USAGE_UNIFORM_BUFFER 1048576 uint32
VULKAN_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER 262144 uint32
VULKAN_BUFFER_USAGE_VERTEX_BUFFER 8388608 uint32
VULKAN_IMAGE_USAGE_COLOR_ATTACHMENT 16 uint32
VULKAN_IMAGE_USAGE_INPUT_ATTACHMENT 128 uint32
VULKAN_IMAGE_USAGE_SAMPLED 4 uint32
VULKAN_IMAGE_USAGE_STENCIL_ATTACHMENT 32 uint32
VULKAN_IMAGE_USAGE_STORAGE 8 uint32
VULKAN_IMAGE_USAGE_TRANSFER_DST 2 uint32
VULKAN_IMAGE_USAGE_TRANSFER_SRC 1 uint32
VULKAN_IMAGE_USAGE_TRANSIENT_ATTACHMENT 64 uint32
cpuUsageRead 1 uint32
cpuUsageReadOften 2 uint32
cpuUsageWrite 4 uint32
cpuUsageWriteOften 8 uint32
displayUsageCursor 2 uint32
displayUsageLayer 1 uint32
noneUsage 1 uint32
videoUsageCapture 8 uint32
videoUsageDecryptorOutput 16 uint32
videoUsageHwDecoder 1 uint32
videoUsageHwDecoderInternal 32 uint32
videoUsageHwEncoder 2 uint32
videoUsageHwProtected 4 uint32
vulkanUsageColorAttachment 16 uint32
vulkanUsageInputAttachment 128 uint32
vulkanUsageSampled 4 uint32
vulkanUsageStencilAttachment 32 uint32
vulkanUsageStorage 8 uint32
vulkanUsageTransferDst 2 uint32
vulkanUsageTransferSrc 1 uint32
vulkanUsageTransientAttachment 64 uint32