fuchsia.sysmem2

添加数量:12

协议

分配器

fuchsia.sysmem2/allocator.fidl 中定义

分配系统内存缓冲区。

此协议中不使用墓碑。

添加数量:19

AllocateNonSharedCollection

代表同时是唯一参与者的单个客户端(从 sysmem 的角度来看)分配缓冲区收集。

此调用主要用于临时/测试目的。此调用会跳过 fuchsia.sysmem2/BufferCollectionToken 阶段,因此无法允许其他参与者指定其约束条件。

我们建议实际客户端改用 fuchsia.sysmem2/Allocator.AllocateSharedCollection,并让相关参与者通过向系统参与者发送 BufferCollectionToken 来直接将他们自己的约束传达给系统。

请求

名称类型
payload AllocatorAllocateNonSharedCollectionRequest

AllocateSharedCollection

创建根 fuchsia.sysmem2/BufferCollectionToken

可以使用 fuchsia.sysmem2/BufferCollectionToken.Duplicate“复制”BufferCollectionToken 以便分发给参与者。可以使用 fuchsia.sysmem2/Allocator.BindSharedCollection 将每个 BufferCollectionToken 转换为 fuchsia.sysmem2.BufferCollection

可通过 fuchsia.sysmem2/BufferCollection.SetConstraints 设置缓冲区约束条件。

可以使用缓冲区填充缓冲区集合的成功/失败可通过 fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated 确定。

关闭 BufferCollectionTokenBufferCollection 的客户端端(不先关闭 Release)会使所有客户端都无法在同一故障网域中结束,该网域默认为缓冲区集合的所有客户端端。如需了解如何在缓冲区集合中创建单独的故障域,请参阅 fuchsia.sysmem2/BufferCollection.SetDispensablefuchsia.sysmem2/BufferCollection.AttachToken

请求

名称类型
payload AllocatorAllocateSharedCollectionRequest

BindSharedCollection

fuchsia.sysmem2/BufferCollectionToken 转换为 fuchsia.sysmem2/BufferCollection

在发送此消息时,缓冲区集合尚未填充缓冲区。参与者还必须通过 BufferCollection 客户端发送 fuchsia.sysmem2/BufferCollection.SetConstraints

从根 BufferCollectionToken(通过 AllocateSharedCollection 创建)复制的所有 BufferCollectionToken 都必须通过 BindSharedCollection(或 Release)“上交”,并且所有现有 BufferCollection 客户端结束都必须发送 SetConstraints,然后逻辑 BufferCollection 才会填充缓冲区(如果无法满足整体约束条件,则将失败)。

请求

名称类型
payload AllocatorBindSharedCollectionRequest

GetVmoInfo

给定 sysmem 提供的 VMO 的句柄后,它会返回有关相应 sysmem 逻辑缓冲区的其他信息。

大多数调用方都会先复制 VMO 句柄,然后将副本发送到此调用。

如果客户端创建了系统内存提供的 VMO 的子 VMO,则出于此调用目的,该子 VMO 不会被视为“sysmem VMO”。

  • 请求 vmo 系统提供的 VMO 的句柄(或查看错误)。
  • 响应 buffer_collection_id 缓冲区集合 ID,每次启动时每个逻辑缓冲区集合都是唯一的。
  • 响应 buffer_index 缓冲区集合中缓冲区的缓冲区索引。它与 fuchsia.sysmem2/BufferCollectionInfo.buffers 中缓冲区的索引相同。对于与同一逻辑缓冲区对应的所有由系统内存提供的 VMO,buffer_index 都是相同的,即使 VMO KID 不同也是如此。buffer_index 仅在相应缓冲区集合的缓冲区中是唯一的。对于给定的缓冲区,buffer_collection_idbuffer_index 的组合在每次启动时是唯一的。
  • 响应 close_weak_asap 如果 vmo 是安全系数低的系统 VMO 的句柄,则系统会在响应中设置 close_weak_asap 字段。当应该尽快关闭缓冲区的所有弱 VMO 句柄时,此句柄将发出 ZX_EVENTPAIR_PEER_CLOSED 信号。关闭缓冲区的所有强系统 VMO 后(包括通过强 BufferCollectionToken 或强 BufferCollection 间接保留的任何系统 VMO)后,系统会立即发出信号。如果在 ZX_EVENTPAIR_PEER_CLOSED 时未能快速关闭所有弱系统 VMO 对缓冲区的处理,此行为会被视为 VMO 泄露,如果客户端仍持有较弱的系统 VMO 句柄,并且会导致系统向日志发出大量投诉,集合的缓冲区可以相互独立地释放。在响应到达客户端之前,ZX_EVENTPAIR_PEER_CLOSED 可能已经收到信号。看到此字段集后,未准备好处理弱系统内存 VMO 的客户端可能会关闭缓冲区的所有句柄,并使所有关联的请求失败。
  • 错误 [fuchsia.sysmem2/Error.NOT_FOUND] - vmo 不是系统内存 VMO。强和弱系统 VMO 都可以传递给此调用,而传入此调用本身的 VMO 句柄会使 VMO 的信息保持活跃状态,以便响应此调用。因此,ZX_ERR_NOT_FOUND 错误是明确的(即使调用时没有 VMO 的其他句柄,即使在 GetVmoInfo 响应到达客户端之前其他句柄已关闭),也是如此。
  • 错误 [fuchsia.sysmem2/Error.HANDLE_ACCESS_DENIED] 由于权限/功能衰减,vmo 无法与 GetVmoInfo 一起使用。VMO 需要可与主题为 ZX_INFO_HANDLE_BASICzx_vmo_get_info 一起使用。
  • 错误 [fuchsia.sysmem2/Error.UNSPECIFIED] 请求失败,原因不明。如需了解详情,请参阅日志。
  • 错误 [fuchsia.sysmem2/Error.PROTOCOL_DEVIATION] 未设置 vmo 字段,或者请求字段存在其他问题。

请求

名称类型
payload AllocatorGetVmoInfoRequest

响应

名称类型
payload Allocator_GetVmoInfo_Result

SetDebugClientInfo

设置有关当前客户端的信息,sysmem 可以使用这些信息来帮助诊断泄漏内存以及等待参与者发送 fuchsia.sysmem2/BufferCollection.SetConstraints 的分配暂停问题。

这将在此 fuchsia.sysmem2/分配器随后创建的所有 fuchsia.sysmem2/Node(fuchsia.sysmem2Allocator.BindSharedCollectionfuchsia.sysmem2Allocator.SetDebugClientInfoBufferCollectionBufferCollection

之后可以通过发送 fuchsia.sysmem2/Node.SetDebugClientInfo,按 Node 替换此信息。

针对每个 Allocator 发送一次 fuchsia.sysmem2/Allocator.SetDebugClientInfo,是确保所有 fuchsia.sysmem2/Node 至少已设置一些调试客户端信息的最有效方式。此外,与通过 fuchsia.sysmem2/{6.sysm2/提供相同的调试客户端信息更加高效。Node.SetDebugClientInfofuchsia.sysmem2

  • request name 它可以是任意字符串,但最好使用当前进程名称(请参阅 fsl::GetCurrentProcessName)。
  • 请求 id。它可以是任意 ID,但最好使用当前进程 ID(请参阅 fsl::GetCurrentProcessKoid)。

请求

名称类型
payload AllocatorSetDebugClientInfoRequest

ValidateBufferCollectionToken

检查 sysmem 服务器是否知道 fuchsia.sysmem2/BufferCollectionToken

通过此调用,客户端可以确定传入令牌是否为 sysmem 服务器已知的真实 sysmem 令牌,而不会永远卡在潜在的虚假令牌上以完成 fuchsia.sysmem2/BufferCollectionToken.DuplicateSyncfuchsia.sysmem2/BufferCollectionToken.Sync(或任何其他两个消息)。如果客户端信任令牌的来源来提供真实令牌,则在调试之外通常不需要此调用。

如果验证有时会失败,但其他时间成功,则令牌来源本身可能不在创建/复制令牌之后、将令牌发送到当前客户端之前调用 fuchsia.sysmem2/BufferCollectionToken.Syncfuchsia.sysmem2/BufferCollection.Sync。来源使用 fuchsia.sysmem2/BufferCollectionToken.DuplicateSync 来复制令牌可能更方便,因为该调用内置了同步步骤。或者,缓冲区收集可能在 sysmem 服务器处理此调用之前失败,因为缓冲区收集失败可以清理 sysmem 对关联令牌的跟踪。

此调用对任何令牌都没有影响。

  • 请求token_server_koid:通道(可能是 BufferCollectionToken 通道)的服务器端的 koid。这可以通过 zx_object_get_info ZX_INFO_HANDLE_BASIC related_koid 获取。
  • 响应 is_known true 表示 sysmem 在处理请求时便知道该令牌,但不保证在客户端收到回复时令牌仍然有效。它能保证该令牌至少是一个真实的令牌,因此对令牌的双向调用不会永远停止(将会很快失败或成功,而不会停滞)。如果令牌的来源可以信任以提供真实令牌,则已经隐式知道这一点。false 值表示 sysmem 处理此调用时 sysmem 不知道该令牌,但该令牌之前可能有效,或者可能已经生效。或者,如果令牌的发送者不可信,无法提供真实令牌,则令牌可能是虚假的。在将令牌发送给其他参与者之前,发送者有责任与 sysmem 同步,以确保 sysmem 知道之前创建/复制的令牌。

请求

名称类型
payload AllocatorValidateBufferCollectionTokenRequest

响应

名称类型
payload Allocator_ValidateBufferCollectionToken_Result

BufferCollection

fuchsia.sysmem2/collection.fidl 中定义

fuchsia.sysmem2/BufferCollection 是参与者与系统 mem 之间的直接连接,用于缓冲区集合;通常,缓冲区集合会与其他参与者共享,这些参与者有自己的 BufferCollection 客户端与同一缓冲区集合相关联。也就是说,BufferCollection 接口的实例是缓冲区集合的视图,而不是缓冲区集合本身。

BufferCollection 连接是为了帮助异步指示何时已填充缓冲区集合。

此外,sysmem 服务器关闭该频道表示客户端应尽快关闭从 BufferCollection 获取的所有 VMO 句柄。

某些缓冲区集合可以使用足够的内存,通过 fuchsia.sysmem2/BufferCollection.AttachLifetimeTracking 方法,使用足够的内存来避免分配重叠(及时),以便发起程序可以在启动器分配新的缓冲区集合之前了解何时完全取消分配缓冲区集合中足够的缓冲区已经完全取消分配。

此协议中不使用墓碑。

添加数量:19

AttachLifetimeTracking

将事件对设置为在分配缓冲区后收到信号 (ZX_EVENTPAIR_PEER_CLOSED),并且缓冲区集合中仅保留指定数量的缓冲区(或更少数量)。

fuchsia.sysmem2/BufferCollection.AttachLifetimeTracking 允许客户端等待,直到旧缓冲区收集完全或大体取消分配完后再尝试分配新的缓冲区收集。仅当其他缓冲区已完全取消分配(不仅仅是客户端未引用,这些缓冲区使用的所有内存已被完全回收/回收),或包括此 fuchsia.sysmem2/BufferCollection 的树或子树的分配或逻辑分配失败时,事件对才会发出信号。

在分配或逻辑分配完成之前,事件对不会发出信号;在此之前,集合的当前缓冲区计数会被忽略。

如果附加的子树的逻辑分配失败(使用 fuchsia.sysmem2/BufferCollection.AttachToken),则无论整个缓冲区集合中可能分配的缓冲区数是多少,事件对的服务器端都将在失败期间关闭。这是为了实现逻辑分配与正常分配的逻辑分配一致性。

此事件发出的生命周期包括对已分配缓冲区的异步清理,并且此异步清理必须等到所有缓冲区的 VMO 句柄都关闭这些 VMO 句柄后才会发生。因此,如果任何使用逻辑缓冲区收集的参与者可信度较低或可靠性较低,客户端应注意不要等到 ZX_EVENTPAIR_PEER_CLOSED 发出信号后被永久阻止。如果没有分配新的/替换缓冲区集合,要比永远卡住要好得多。

此机制旨在与具有类似 AttachLifetimeTracking 消息的其他协议兼容;同一 eventpair 句柄(服务器端)的重复项可通过多条 AttachLifetimeTracking 消息发送到不同的协议,并且当所有条件都满足时(所有副本持有者均已关闭其服务器端句柄),系统会向客户端发送 ZX_EVENTPAIR_PEER_CLOSED 信号。此外,由于事件对端点的工作原理,可以在不阻止 ZX_EVENTPAIR_PEER_CLOSED 信号的情况下复制客户端。

服务器有意并不“信任”server_end 上的任何信号,此机制有意仅使用 ZX_EVENTPAIR_PEER_CLOSED 无法“提前”设置,并且仅在服务器端事件对的所有句柄均关闭时设置。没有任何含义与任何其他信号相关联,客户端应忽略 eventpair 任一端的其他任何信号位。

server_end 可能缺少 ZX_RIGHT_SIGNALZX_RIGHT_SIGNAL_PEER,但必须具有 ZX_RIGHT_DUPLICATE(并且必须具有 ZX_RIGHT_TRANSFER 才能进行传输,且不会导致 BufferCollection 信道故障)。

目前,所有表字段均为必填字段。

  • 请求 server_end。如果最初分配了缓冲区,但缓冲区数小于或等于 buffers_remaining,则系统服务器会关闭此事件对句柄。
  • 请求 buffers_remaining 等待除 buffers_remaining(或更少)之外的所有缓冲区完全取消分配。大于零的数字会在以下情况下很有用:有意不关闭已知数量的缓冲区,以便继续使用数据,例如,即使视频流使用的是受保护的输出缓冲区,也保留界面中显示的最后一个可用视频帧。它不在 BufferCollection 接口的范围之内(至少目前为止),无法确定可在不关闭的情况下保留多少缓冲区,但通常范围介于 0-2 之间。

请求

名称类型
payload BufferCollectionAttachLifetimeTrackingRequest

AttachToken

如果现有集合的缓冲区计数、限制和参与者允许,请创建一个新令牌,将新参与者添加到现有逻辑缓冲区集合。

这对于替换失败的参与者和/或在分配缓冲区后添加/重新添加参与者时很有用。

使用 fuchsia.sysmem2/BufferCollection.AttachToken 时,位于附加的 fuchsia.sysmem2/BufferCollectionToken 根部的子树会执行常规过程:设置约束条件或关闭 fuchsia.sysmem2/Node,尽管之前分配的视图可能性地重新分配了客户端的缓冲区。此过程称为“逻辑分配”。文档中有关其他消息的大多数“分配”实例也可被解读为“分配或逻辑分配”,同时保持有效状态,但我们在大多数地方只说“分配”,以确保说明简洁明了,并提供了有关 AttachToken 上文档的“逻辑分配”的详细信息。

附加的 Node 失败不会传播到所附加 Node 的父项。更笼统地说,如果子项 Node 已附加,或者子项可分配且故障发生在逻辑分配之后(请参阅 fuchsia.sysmem2/BufferCollectionToken.SetDispensable),则子项 Node 的故障将无法到达其父项 Node

在某些情况下,参与者可以选择最初为受托参与者的指定实例使用可分发令牌,之后,如果该受托参与者的第一个实例失败,该受托参与者的第二个实例将获得使用 AttachToken 创建的令牌。

fuchsia.sysmem2/BufferCollectionToken 客户端的角度来看,该令牌的作用与任何其他令牌类似。客户端可以根据需要 fuchsia.sysmem2/BufferCollectionToken.Duplicate 令牌,并且可以将令牌发送给其他进程/参与者。BufferCollectionToken Node 应通过发送 fuchsia.sysmem2/Allocator.BindSharedCollection 照常转换为 BufferCollection Node,也可以通过发送 fuchsia.sysmem2/BufferCollectionToken.Release 关闭,而不会导致子树故障。假设前者,应将 fuchsia.sysmem2/BufferCollection.SetConstraints 消息或 fuchsia.sysmem2/BufferCollection.Release 消息发送到 BufferCollection

在子树中,fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated失败结果意味着,无法使用现有缓冲区收集及其已添加的参与者来满足新参与者的约束条件。创建新的集合可以满足所有参与者的约束条件(假设使用 SetDispensable 代替 AttachToken 或使用普通令牌)。

使用 AttachToken 创建的令牌会执行约束聚合,其中当前对缓冲区集合应用的所有约束条件,加上正在考虑的附加令牌,以及附加令牌下本身不是附加令牌或此类令牌下的子令牌。仅当该子树完成逻辑分配之后,该子树下的其他子树才会被视为逻辑分配。

将现有缓冲区分配给参与者的 fuchsia.sysmem2/BufferCollectionConstraints.min_buffer_count_for_camping 等的缓冲区为先到先得,但子节点无法在其所有父项都发送 SetConstraints 之前进行逻辑分配。

另请参阅 fuchsia.sysmem2/BufferCollectionToken.SetDispensable,与 AttachToken 相比,该令牌在父项的分配或逻辑分配期间,其创建的令牌 Node + 子项 Node(位于创建的子树中,但不在此子树下的任何子树中)与其父项一起参与约束聚合。

fuchsia.sysmem2/BufferCollectionToken.Duplicate 类似,新创建的令牌需要先 fuchsia.sysmem2/Node.Sync 同步到 Sysmem,然后才能将新令牌传递到 BindSharedCollection。将创建的 BufferCollectionToken 转换为 BufferCollection 后,可以使用 fuchsia.sysmem2/BufferCollection.Sync 实现新令牌的 Sync。或者,也可以使用新令牌上的 fuchsia.sysmem2/BufferCollectionToken.Sync。或者,也可以使用 fuchsia.sysmem2/BufferCollectionToken.DuplicateSync。像往常一样,BufferCollectionToken.Sync 可在通过新创建的令牌发送任何 BufferCollectionToken.Duplicate 消息后启动,以便通过单次往返将这些额外的令牌同步到 sysmem。

目前,所有表字段均为必填字段。

  • 请求 rights_attentuation_mask - 这样可削减子树的 VMO 权限。rights_attenuation_mask 的这些值不会衰减(请注意,0 不在此列表中):
    • ZX_RIGHT_SAME_RIGHTS(首选)
    • 0xFFFFFFFF(计算衰减掩码时是合理的)
  • request token_request BufferCollectionToken 通道的服务器端。客户端保留客户端。

请求

名称类型
payload BufferCollectionAttachTokenRequest

CheckAllBuffersAllocated

以轮询的方式检查是否已分配所有缓冲区。

添加了:HEAD

请求

<EMPTY>

响应

名称类型
payload BufferCollection_CheckAllBuffersAllocated_Result

GetBufferCollectionId

获取缓冲区集合 ID。此 ID 也可以通过 fuchsia.sysmem2/Allocator.GetVmoInfo(以及集合中的 buffer_index)获得。

此调用主要适用于以下情况:我们无法直接传递 fuchsia.sysmem2/BufferCollectionTokenfuchsia.sysmem2/BufferCollection,但只能传达一个 VMO 句柄,该 VMO 句柄可以与通过其他路径创建的 BufferCollection 客户端端合并。如有可能,最好直接传达 BufferCollectionTokenBufferCollection

信任来自 sysmem 以外的来源的 buffer_collection_id 值类似于信任来自 zircon 以外的来源的 koid 值。除非确实有必要,否则应尽量避免使用这两种方法,而且两者都需要谨慎。在某些情况下,出于效率原因,通过 buffer_collection_id 引用预先确定的 BufferCollection 可能是合理的,但声称是 buffer_collection_id 的传入值并不足以证明向 buffer_collection_id 的发送者授予任何功能。发送方必须先向接收方证明发送者具有 VMO 或具有对同一集合的 BufferCollectionToken,方法是发送一个由系统进程确认是有效系统进程句柄的句柄,以及哪个系统进程映射到 buffer_collection_id 值。如果发送者仅证明发送者具有 VMO,接收者应格外小心,不要假设发送者有 BufferCollectionToken

  • 响应 buffer_collection_id。每次启动后,此 ID 在每个缓冲区集合中都是唯一的。每个缓冲区都由 buffer_collection_idbuffer_index 共同进行唯一标识。

请求

<EMPTY>

响应

名称类型
payload Node_GetBufferCollectionId_Result

GetNodeRef

这会获得一个句柄,可用作在任何 fuchsia.sysmem2/Node 上调用的 fuchsia.sysmem2/Node.IsAlternateFor 的参数。此句柄仅用于证明客户端已从此 Node 获取此句柄。

由于这是一个未设置的集合,因此 GetNodeRef 和对 IsAlternateFor 的调用之间无需 fuchsia.sysmem2/Node.Sync,尽管这两个调用通常位于不同的通道上。

另请参阅 fuchsia.sysmem2/Node.IsAlternateFor

目前,所有表字段均为必填字段。

  • 响应 node_ref 可通过其他 Node 通道上的 IsAlternateFor 发送此句柄,以证明客户端从此 Node 获得了此句柄。

请求

<EMPTY>

响应

名称类型
payload Node_GetNodeRef_Result

IsAlternateFor

检查调用 fuchsia.sysmem2/Node 是否位于与传入的 node_ref 相关的通用父 fuchsia.sysmem2/BufferCollectionTokenGroup 的不同子树的根位置。

此调用旨在协助准入控制去重和调试。

必须使用 fuchsia.sysmem2/Node.GetNodeRef 获取 node_ref

node_ref 可以是重复的句柄;无需在每次调用 fuchsia.sysmem2/Node.IsAlternateFor 时都调用 GetNodeRef

如果由于某个可能的恶意/不可信令牌提供者而导致某个调用令牌实际上根本不是有效令牌,请先调用 fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken,而不是在 IsAlternateFor 从不响应(并非真正与 sysmem 通信)时无限期地卡住。另一种方法是先使用此令牌调用 fuchsia.sysmem2/Allocator.BindSharedCollection,这样也会验证令牌并将其转换为 fuchsia.sysmem2/BufferCollection,然后调用 IsAlternateFor

目前,所有表字段均为必填字段。

  • 响应 is_alternate
    • true:调用节点与 node_ref Node 之间的第一个共同父节点是 BufferCollectionTokenGroup。这意味着,调用 Nodenode_ref Node 不会同时应用其两个约束条件,而 sysmem 只会选择其中一个约束条件,绝不会同时应用两者。这是因为在逻辑分配期间只选择 BufferCollectionTokenGroup 的一个子项,而该子项的子树对约束聚合有贡献。
    • false:调用 Nodenode_ref Node 之间的第一个共同父节点不是 BufferCollectionTokenGroup。目前,这意味着第一个共同的父节点是 BufferCollectionTokenBufferCollection(无论是否经过 Release)。这意味着,如果所涉及的任何父级 BufferCollectionTokenGroup 同时选择了这两个 Node,则调用 Nodenode_ref Node 可能会在逻辑分配的约束聚合期间应用它们的约束条件。在这种情况下,没有 BufferCollectionTokenGroup 会直接阻止选择两个 Node 及其约束条件进行汇总,但即使为 false,如果一个或两个 Node 具有直接或间接父 BufferCollectionTokenGroup,并且其选择除包含调用 Nodenode_ref Node 的子树之外的子子树,那么即使为 false,也可能忽略其中一个或两个 Node
  • 错误 [fuchsia.sysmem2/Error.NOT_FOUND] node_ref 与调用 Node 所关联的缓冲区集合未关联。出现此错误的另一个原因是,node_ref 是具有足够权限的 zx.Handle.EVENT 句柄,但实际上并不是从 GetNodeRef 获取的真实 node_ref
  • 错误 [fuchsia.sysmem2/Error.PROTOCOL_DEVIATION] 调用方传递的 node_ref 不是 zx.Handle:EVENT 句柄,或者在真实的 node_ref 上没有所需的权限。
  • 此调用不会返回其他失败的状态代码。不过,sysmem 将来可能会添加其他代码,以便客户端应对所有失败的状态代码进行合理的默认处理。

请求

名称类型
payload NodeIsAlternateForRequest

响应

名称类型
payload Node_IsAlternateFor_Result

发布

fuchsia.sysmem2/BufferCollectionToken 通道上:

通常,参与者会将 BufferCollectionToken 转换为 fuchsia.sysmem2/BufferCollection,但参与者可以通过令牌发送 Release(然后立即或稍后关闭该通道,以响应服务器关闭服务器端时),从而避免缓冲区收集失败。如果没有事先设置 Release,关闭 BufferCollectionToken 客户端会导致缓冲区收集失败。

fuchsia.sysmem2/BufferCollection 通道上:

默认情况下,服务器通过缓冲区收集失败来处理 fuchsia.sysmem2/BufferCollection 客户端端的意外关闭(没有先使用 Release)。部分原因在于在任何参与者失败时加快关闭 VMO 句柄以回收内存。如果参与者想要彻底关闭 BufferCollection,而不会导致缓冲区收集失败,则可以先发送 Release,然后再关闭 BufferCollection 客户端。Release 可以发生在 SetConstraints 之前或之后。如果位于 SetConstraints 之前,则缓冲区集合不需要此节点的约束条件即可分配。如果在 SetConstraints 之后,约束条件会保留并聚合,尽管在约束条件聚合时缺少 BufferCollection 连接。

fuchsia.sysmem2/BufferCollectionTokenGroup 通道上:

默认情况下,意外关闭 BufferCollectionTokenGroup 客户端(未先添加 Release)将触发缓冲区收集失败。如需关闭 BufferCollectionTokenGroup 通道而不让缓冲区收集失败,请确保已发送 AllChildrenPresent(),并在关闭 BufferCollectionTokenGroup 客户端之前发送 Release

如果 Release 发生在 [fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent], the buffer collection will fail (triggered by reception of Releasewithout priorAllChildrenPresent). This is intentionally not analogous to how <a class='link' href='../fuchsia.sysmem2/'>fuchsia.sysmem2</a>/<a class='link' href='../fuchsia.sysmem2/#BufferCollection.Release'>BufferCollection.Release</a> without <a class='link' href='../fuchsia.sysmem2/'>fuchsia.sysmem2</a>/<a class='link' href='../fuchsia.sysmem2/#BufferCollection.SetConstraints'>BufferCollection.SetConstraints</a> first doesn't cause buffer collection failure. For a BufferCollectionTokenGroup, clean close requires AllChildrenPresent(if not already sent), then Release` 之前,则关闭客户端。

如果 Release 发生在 AllChildrenPresent 之后,则子项及其所有约束条件均保持不变(就像 BufferCollectionTokenGroup 通道保持开启状态时的情况一样),并且客户端关闭不会触发缓冲区收集失败。

在所有 fuchsia.sysmem2/Node 通道(上述任一通道)上:

为简洁起见,上述基于通道协议的段落忽略了由 fuchsia.sysmem2/BufferCollectionToken.SetDispensablefuchsia.sysmem2/BufferCollection.AttachToken 创建的单独故障域。当客户端意外关闭(没有先添加 Release)且该客户端位于故障网域下时,故障网域不会使整个缓冲区收集失败,而是会失败,但缓冲区集合本身会与故障网域的故障隔离开来。此类故障网域可以嵌套,在这种情况下,只有 Node 所在的最内层故障网域会发生故障。

请求

<EMPTY>

SetConstraints

向缓冲区集合提供 fuchsia.sysmem2/BufferCollectionConstraints

对于每个 fuchsia.sysmem2/BufferCollection,参与者最多只能调用 fuchsia.sysmem2/BufferCollection.SetConstraints 一次。

如需尝试分配缓冲区,BufferCollection 客户端的所有容器都需要调用 SetConstraints,然后系统 mem 会尝试分配缓冲区。

  • request constraints。这些是发送客户端/参与者对缓冲区收集施加的限制。constraints 字段无需设置。如果未设置,则客户端不会设置任何实际限制条件,但表示客户端没有要设置的约束条件。未设置 constraints 字段的客户端不会收到任何 VMO 句柄,但仍可以看到分配的缓冲区数量,并且仍然可以通过其 buffer_index 引用缓冲区。

请求

名称类型
payload BufferCollectionSetConstraintsRequest

SetDebugClientInfo

设置有关当前客户端的信息,sysmem 可以使用这些信息来帮助诊断泄漏内存以及等待参与者发送 fuchsia.sysmem2/BufferCollection.SetConstraints 的分配暂停问题。

这会在此 fuchsia.sysmem2/Node 以及派生自此 Node 的所有 Node 上设置调试客户端信息,除非被 fuchsia.sysmem2/Allocator.SetDebugClientInfo 或更新版本的 fuchsia.sysmem2/Node.SetDebugClientInfo 替换。

针对每个 Allocator 发送一次 fuchsia.sysmem2/Allocator.SetDebugClientInfo,是确保所有 fuchsia.sysmem2/Node 至少已设置一些调试客户端信息的最有效方式。此外,与通过 fuchsia.sysmem2/{6.sysm2/提供相同的调试客户端信息更加高效。Node.SetDebugClientInfofuchsia.sysmem2

此外,在启用详细日志记录功能的情况下,也会用于(请参阅 SetVerboseLogging)来指示哪个客户端首先关闭其通道,从而导致子树故障(如果子树的用途结束,这可能是正常的,但如果发生的时间早于预期,客户端渠道专用的名称有助于从 sysmem 的角度诊断故障首先来自何处)。

目前,所有表字段均为必填字段。

  • request name 它可以是任意字符串,但最好使用当前进程名称(请参阅 fsl::GetCurrentProcessName)。
  • 请求 id。它可以是任意 ID,但最好使用当前进程 ID(请参阅 fsl::GetCurrentProcessKoid)。

请求

名称类型
payload NodeSetDebugClientInfoRequest

SetDebugTimeoutLogDeadline

如果 sysmem 在创建新集合后的 5 秒内未从所有客户端看到 fuchsia.sysmem2/BufferCollection.SetConstraints,则 Sysmem 会记录一条警告。

客户端可以调用此方法在日志输出时进行更改。如果多个客户端设置了截止期限,则无法确定哪个截止期限将生效。

在大多数情况下,默认设置的效果很好。

目前,所有表字段均为必填字段。

  • request deadline:表示 sysmem 开始尝试记录警告的时间,除非届时所有限制条件都已使用 sysmem。

请求

名称类型
payload NodeSetDebugTimeoutLogDeadlineRequest

SetName

设置此缓冲区集合中的 VMO 的名称。

如果名称在 ZX_MAX_NAME_LEN 中不适合,vmo 本身的名称将被截断以适应这一要求。vmo 的名称以集合中的缓冲区索引作为后缀(如果后缀符合 ZX_MAX_NAME_LEN)。此处指定的名称(不截断)将在检查数据中列出。

该名称只会影响在设置名称后分配的 VMO;此调用不会重命名现有的 VMO。如果多个客户端设置了不同的名称,则优先级值越大,优先级越高。设置与之前的名称具有相同优先级的新名称不会更改名称。

目前,所有表字段均为必填字段。

  • 请求 priority 仅当这是第一个 SetNamepriority 大于此缓冲区集合的所有 Node 之前 SetName 调用中的任何先前 priority 值时,才会设置名称。
  • 请求 name:在此缓冲区集合下创建的 VMO 的名称。

请求

名称类型
payload NodeSetNameRequest

SetVerboseLogging

这样可以为缓冲区收集启用详细日志记录功能。

详细日志记录包括通过每个客户端通过 fuchsia.sysmem2/BufferCollection.SetConstraints 设置的约束,以及通过 fuchsia.sysmem2/Node.SetDebugClientInfo(或 fuchsia.sysmem2/Allocator.SetDebugClientInfo)设置的信息,以及 {12 theNode

通常,当聚合失败时,sysmem 仅输出一行投诉,并且仅显示聚合失败的具体详细原因,并且没有太多上下文。虽然这通常足以诊断出问题:如果仅进行了细微更改,并且所有功能在进行细微更改之前都正常运行,则对于首次获取新的缓冲区集合来说,这通常不是特别有帮助。尤其是对于更复杂的节点树,涉及 fuchsia.sysmem2/BufferCollection.AttachTokenfuchsia.sysmem2/BufferCollectionToken.SetDispensablefuchsia.sysmem2/BufferCollectionTokenGroup 等节点的子树分配失败的原因,以及可能的节点子树中的关联子树失败的原因;

额外日志记录的目的在于,从性能的角度来看,这是可以接受的,假设只对少量缓冲区集合启用详细日志记录。如果我们没有跟踪某个 bug,就不应发送此消息。

请求

<EMPTY>

SetWeak

将当前的 fuchsia.sysmem2/Node 和在此消息之后创建的所有子 Node 设置为弱,这意味着客户端的 Node 客户端(或在此消息后创建的子节点)并不足以使已分配的 VMO 保持活跃状态。

从弱 Node 获取的所有 VMO 都是弱系统 VMO。另请参阅 close_weak_asap

只有在 Node 准备好进行分配之前,才允许显示此消息(否则服务器会使用 ZX_ERR_BAD_STATE 关闭通道):

  • BufferCollectionToken:时间不限
  • BufferCollectionSetConstraints 之前
  • BufferCollectionTokenGroupAllChildrenPresent 之前

目前,系统未提供从强 Node 到弱 Node 的转换,但客户端可以在分配前创建一个额外的 Node,并将该额外的 Node 设置为弱 Node,然后在稍后的某个时间点发送 Release 并关闭客户端强 Node 的客户端端,但保留客户端的弱 Node

Node 数和强 VMO 句柄为零会导致缓冲区收集失败(所有 Node 客户端都会看到 ZX_CHANNEL_PEER_CLOSED,所有 close_weak_asap client_end 会看到 ZX_EVENTPAIR_PEER_CLOSED),但系统(有意)不会注意到这种情况,直到所有 Node 都准备好进行分配为止。要使初始分配成功,在分配时至少需要存在一个强 Node,但在该客户端收到 VMO 句柄后,该客户端可以执行 BufferCollection.Release 操作并关闭客户端,而不会导致此类失败。

这也隐含 fuchsia.sysmem2/Node.SetWeakOk,但不隐含 for_children_also 为 true 的 SetWeakOk(可根据情况单独发送)。

请求

<EMPTY>

SetWeakOk

这向 sysmem 表明,客户端已准备好关注 close_weak_asap

如果发送此消息,则此消息必须在 fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated 之前发送。

使用弱 fuchsia.sysmem2/BufferCollection 的所有参与者必须在 WaitForAllBuffersAllocated 之前发送此消息,否则父级 Node 必须发送 fuchsia.sysmem2/Node.SetWeakOkfor_child_nodes_also 为 true,否则 WaitForAllBuffersAllocated 将触发缓冲区收集失败。

这条消息很有必要,因为系统显然较弱的 VMO 并非一直存在,因此较旧的客户端不知道需要关注 close_weak_asap ZX_EVENTPAIR_PEER_CLOSED,并尽快关闭所有剩余系统内存弱 VMO 句柄。通过收到此消息并要求参与者表明其接受整个协议的这一方面,我们可避免以下情况:较旧客户端传递了较弱的 VMO,而 sysmem 无法使该 VMO 稍后(并基于每个缓冲区)快速关闭。

不处理 close_weak_asap 且未通过 WaitForAllBuffersAllocated 检索任何 VMO 句柄的参与者不需要发送 SetWeakOk(也不需要让父级 Node 发送 for_child_nodes_also 为 true 的 SetWeakOk)。但是,如果同一参与者有一个可以检索 VMO 的子节点/委托,该子节点/委托需要在 WaitForAllBuffersAllocated 之前发送 SetWeakOk

  • 请求 for_child_nodes_also 如果存在且值为 true,这意味着在此消息之后创建的此节点的直接子节点以及这些节点的所有后代都将表现得就像在这些节点上发送了 SetWeakOk 一样。在此节点之前创建的任何子节点不包括在内。此设置是“粘性的”,因为后面的 SetWeakOk 如果未将此布尔值设为 true,则不会重置服务器端布尔值。如果这给参与者带来了问题,解决方法是视情况在子令牌上改用 SetWeakOk 并将 for_child_nodes_also 设为 true。仅当参与者确实能够承诺对其自身的弱 VMO 句柄以及持有相应子级 Node 的参与者持有的所有弱 VMO 句柄时都遵守 close_weak_asap,才应将 for_child_nodes_also 设为 true。设置 for_child_nodes_also 后,使用 sysmem(1) 的后代 Node 的性能可能较弱,尽管这些 sysmem1 Node 的客户端无法直接访问 SetWeakOk 或无法通过任何直接方式找到 close_weak_asap。这仅适用于此 Node 使用 sysmem(1) 的后代,而不是在直接从 sysmem2 令牌转换为 sysmem(1) 令牌时转换为此 Node,因为除非此 Node 的祖先将 for_child_nodes_also 指定为 true,否则分配将失败。

请求

名称类型
payload NodeSetWeakOkRequest

同步

确保已在服务器端收到之前的消息。这在之前创建了新令牌的消息之后特别有用,因为在将令牌发送给其他参与者之前,sysmem 服务器必须知道令牌。

对无效令牌调用 fuchsia.sysmem2/BufferCollectionToken.Sync 可能会导致 Sync 永久停止。如需降低因一次往返而降低恶意/虚假 fuchsia.sysmem2/BufferCollectionToken 的可能性,请参阅 fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken。另一种方法是将令牌传递给 fuchsia.sysmem2/Allocator/BindSharedCollection,后者还会在将令牌交换为 fuchsia.sysmem2/BufferCollection 通道时对令牌进行验证,然后就可以使用 fuchsia.sysmem2/BufferCollection.Sync

在创建一个或多个 fuchsia.sysmem2/BufferCollectionToken,然后开始并完成 Sync 后,就可以安全地将 BufferCollectionToken 客户端结束发送给其他参与者,而当其他参与者通过 fuchsia.sysmem2/Allocator.BindSharedCollection这是一种创建令牌的高效方法,可避免不必要的往返。

其他选项包括等待每个 fuchsia.sysmem2/BufferCollectionToken.Duplicate 分别完成(在每个 fuchsia.sysmem2 单独调用 Sync 之后进行调用),或者在通过 fuchsia.sysmem2/Allocator.BindSharedCollectionfuchsia.sysmem2BufferCollectionToken.DuplicateSync

请求

<EMPTY>

响应

名称类型
payload Node_Sync_Result

WaitForAllBuffersAllocated

等待分配所有缓冲区。

此 FIDL 调用会在缓冲区分配完成时完成,或者如果尝试分配失败,则会完成并显示一些失败详细信息。

在分配缓冲区之前必须发生以下情况:

  • 结果 buffer_collection_info VMO 处理和其他相关信息。
  • 错误 [fuchsia.sysmem2/Error.NO_MEMORY] 请求有效,但因资源耗尽而无法完成。
  • 错误 [fuchsia.sysmem2/Error.PROTOCOL_DEVIATION] 请求格式不正确。
  • error [fuchsia.sysmem2/Error.CONSTRAINTS_INTERSECTION_EMPTY] 请求有效但无法满足,可能是由于硬件限制。如果参与者存在不兼容的约束条件(大致来说是空交集),就会发生这种情况。如需了解详情,请参阅日志。如果参与者可能被视为可选项,请参阅 BufferCollectionTokenGroup。使用 fuchsia.sysmem2/BufferCollection.AttachToken 时,如果现有集合中没有足够的缓冲区,满足对附加令牌和从附加令牌派生的令牌子树设置的约束,此错误代码将为错误代码。

请求

<EMPTY>

响应

名称类型
payload BufferCollection_WaitForAllBuffersAllocated_Result

BufferCollectionToken

fuchsia.sysmem2/collection.fidl 中定义

fuchsia.sysmem2/BufferCollectionToken 不是缓冲区集合,而是标识特定潜在的共享缓冲区集合的方法,并是一种在缓冲区集合分配任何缓冲区之前将该潜在共享缓冲区集合分发给其他参与者的方法。

此协议中不使用墓碑。

我们为 BufferCollectionToken 使用一个通道,而不是单个 eventpair(对),因为这样就可以检测参与者在创作过程中失败等错误情况。

添加数量:19

CreateBufferCollectionTokenGroup

在一组令牌之间创建逻辑“或”(OR),称为 fuchsia.sysmem2/BufferCollectionTokenGroup

大多数 sysmem 客户端和许多参与者不需要关注此消息或 BufferCollectionTokenGroup。然而,在某些情况下,参与者希望包含一组委托参与者,但如果限制条件未能以这种方式成功合并,则回退到另一组(可能重叠)的委托参与者,并且/或者回退到要求不太苛刻的策略(就 fuchisa.sysmem2/BufferCollectionConstraints 的所有参与者的严格程度而言),在这种情况下,BufferCollectionTokenGroup 会很有用。

BufferCollectionTokenGroup 用于在 N 个子 fuchsia.sysmem2/BufferCollectionToken 中创建 1 或 N OR 的值。汇总期间未选择的子令牌将失败(关闭),潜在参与者应会在其 BufferCollection 通道客户端端点看到 PEER_CLOSED 时注意到这种情况,从而允许参与者清理最终未发生的推测性使用(这与正常的 BufferCollection 服务器端在分配逻辑缓冲区收集失败或之后发生异步缓冲区收集失败时关闭的情况类似)。

请参阅关于协议 BufferCollectionTokenGroup 的注释。

为此,要应用于整个组的任何 rights_attenuation_maskAttachToken/SetDispensable 都可以作为 BufferCollectionTokenGroup 的直接父项使用 BufferCollectionToken 来实现。

目前,所有表字段均为必填字段。

  • 请求 group_request sysmem 传送的 BufferCollectionTokenGroup 通道的服务器端。

请求

名称类型
payload BufferCollectionTokenCreateBufferCollectionTokenGroupRequest

复制

根据该令牌再创建一个 fuchsia.sysmem2/BufferCollectionToken,并引用相同的缓冲区集合。

创建的令牌是此令牌在 fuchsia.sysmem2/Node 层次结构中的子级。

通过将新创建的令牌转移给其他参与者,可以使用此方法添加参与者。

在性能敏感的情况下,可采用这种单向消息来代替双向 fuchsia.sysmem2/BufferCollectionToken.DuplicateSync FIDL 调用;在此类情况下,无需等待系统响应 fuchsia.sysmem2/BufferCollectionToken.DuplicateSync,或者当客户端代码未全部结构化时,无需将所有令牌都变得简单。

发送一条或多条 Duplicate 消息之后,在将新创建的子令牌发送给其他参与者(或其他 fuchsia.sysmem2/分配器通道之前),客户端必须发送 fuchsia.sysmem2/Node.Sync 并等待 Sync 响应。您可以对该令牌进行 Sync 调用,也可以对通过将此令牌传递给 BindSharedCollection 所获得的 BufferCollection 进行调用。这两种方式均可确保服务器在另一个参与者通过单独的 Allocator 通道将令牌发送到服务器之前,先了解通过 Duplicate 创建的令牌。

所有令牌必须通过 fuchsia.sysmem2/Allocator.BindSharedCollectionfuchsia.sysmem2/Node.Release 上交,BufferCollection 才能成功分配缓冲区。

目前,所有表字段均为必填字段。

  • 请求 rights_attenuation_mask 此掩码中为零的权限位将不存在于可通过 token_request 客户端获取的缓冲区 VMO 权限中。这样,发起者或中间参与者就可以缩小委托参与者可用的权限。但这并不会让参与者获得自己尚未拥有的权利。值 ZX_RIGHT_SAME_RIGHTS 可用于指定不应应用衰减。
    • Rights_attenuation_mask 值不会导致衰减:
      • ZX_RIGHT_SAME_RIGHTS(首选)
      • 0xFFFFFFFF(在计算衰减掩码时是合理的)
      • 0(已弃用 - 请勿使用 0 - ERROR 会写入日志)
  • 请求 token_requestBufferCollectionToken 通道的服务器端。此通道的客户端充当共享缓冲区集合中的另一个参与者。

请求

名称类型
payload BufferCollectionTokenDuplicateRequest

DuplicateSync

根据此令牌创建额外的 fuchsia.sysmem2/BufferCollectionToken,并引用相同的缓冲区集合。

创建的令牌是此令牌在 fuchsia.sysmem2/Node 层次结构中的子令牌。

通过将新创建的令牌转移给其他参与者,可以使用此方法添加更多参与者。

系统将为 rights_attenuation_masks 数组中的每个条目返回一个新令牌。

如果由于调用的令牌可能具有恶意/不受信任的令牌提供方而实际上可能并非有效令牌,请考虑先使用 fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken,而不是在 fuchsia.sysmem2/BufferCollectionToken.DuplicateSync 从未响应(因为调用令牌不是真实令牌)的情况下,无限期地卡住。

fuchsia.sysmem2/BufferCollectionToken.Duplicate 相反,调用此方法后不需要单独的 fuchsia.sysmem2/Node.Sync,因为同步步骤会包含在此调用中,但会导致在此调用期间进行往返。

所有令牌必须通过 fuchsia.sysmem2/Allocator.BindSharedCollectionfuchsia.sysmem2/Node.Release 上交到系统内存,以便 BufferCollection 成功分配缓冲区(或者,在涉及 fuchsia.sysmem2BufferCollectionToken.AttachToken

目前,所有表字段均为必填字段。

  • 请求 rights_attenuation_maskrights_attenuation_masks 的每个条目中,可通过相应返回的令牌获取的缓冲区 VMO 权限位中不存在为零的权限位。这样,发起者或中间参与者就可以减少参与者享有的权利。但这并不会让参与者获得自己尚未拥有的权利。值 ZX_RIGHT_SAME_RIGHTS 可用于指定不应应用衰减。
  • 响应 tokens 每个新创建的令牌的客户端结束。

请求

名称类型
payload BufferCollectionTokenDuplicateSyncRequest

响应

名称类型
payload BufferCollectionToken_DuplicateSync_Result

GetBufferCollectionId

获取缓冲区集合 ID。此 ID 也可以通过 fuchsia.sysmem2/Allocator.GetVmoInfo(以及集合中的 buffer_index)获得。

此调用主要适用于以下情况:我们无法直接传递 fuchsia.sysmem2/BufferCollectionTokenfuchsia.sysmem2/BufferCollection,但只能传达一个 VMO 句柄,该 VMO 句柄可以与通过其他路径创建的 BufferCollection 客户端端合并。如有可能,最好直接传达 BufferCollectionTokenBufferCollection

信任来自 sysmem 以外的来源的 buffer_collection_id 值类似于信任来自 zircon 以外的来源的 koid 值。除非确实有必要,否则应尽量避免使用这两种方法,而且两者都需要谨慎。在某些情况下,出于效率原因,通过 buffer_collection_id 引用预先确定的 BufferCollection 可能是合理的,但声称是 buffer_collection_id 的传入值并不足以证明向 buffer_collection_id 的发送者授予任何功能。发送方必须先向接收方证明发送者具有 VMO 或具有对同一集合的 BufferCollectionToken,方法是发送一个由系统进程确认是有效系统进程句柄的句柄,以及哪个系统进程映射到 buffer_collection_id 值。如果发送者仅证明发送者具有 VMO,接收者应格外小心,不要假设发送者有 BufferCollectionToken

  • 响应 buffer_collection_id。每次启动后,此 ID 在每个缓冲区集合中都是唯一的。每个缓冲区都由 buffer_collection_idbuffer_index 共同进行唯一标识。

请求

<EMPTY>

响应

名称类型
payload Node_GetBufferCollectionId_Result

GetNodeRef

这会获得一个句柄,可用作在任何 fuchsia.sysmem2/Node 上调用的 fuchsia.sysmem2/Node.IsAlternateFor 的参数。此句柄仅用于证明客户端已从此 Node 获取此句柄。

由于这是一个未设置的集合,因此 GetNodeRef 和对 IsAlternateFor 的调用之间无需 fuchsia.sysmem2/Node.Sync,尽管这两个调用通常位于不同的通道上。

另请参阅 fuchsia.sysmem2/Node.IsAlternateFor

目前,所有表字段均为必填字段。

  • 响应 node_ref 可通过其他 Node 通道上的 IsAlternateFor 发送此句柄,以证明客户端从此 Node 获得了此句柄。

请求

<EMPTY>

响应

名称类型
payload Node_GetNodeRef_Result

IsAlternateFor

检查调用 fuchsia.sysmem2/Node 是否位于与传入的 node_ref 相关的通用父 fuchsia.sysmem2/BufferCollectionTokenGroup 的不同子树的根位置。

此调用旨在协助准入控制去重和调试。

必须使用 fuchsia.sysmem2/Node.GetNodeRef 获取 node_ref

node_ref 可以是重复的句柄;无需在每次调用 fuchsia.sysmem2/Node.IsAlternateFor 时都调用 GetNodeRef

如果由于某个可能的恶意/不可信令牌提供者而导致某个调用令牌实际上根本不是有效令牌,请先调用 fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken,而不是在 IsAlternateFor 从不响应(并非真正与 sysmem 通信)时无限期地卡住。另一种方法是先使用此令牌调用 fuchsia.sysmem2/Allocator.BindSharedCollection,这样也会验证令牌并将其转换为 fuchsia.sysmem2/BufferCollection,然后调用 IsAlternateFor

目前,所有表字段均为必填字段。

  • 响应 is_alternate
    • true:调用节点与 node_ref Node 之间的第一个共同父节点是 BufferCollectionTokenGroup。这意味着,调用 Nodenode_ref Node 不会同时应用其两个约束条件,而 sysmem 只会选择其中一个约束条件,绝不会同时应用两者。这是因为在逻辑分配期间只选择 BufferCollectionTokenGroup 的一个子项,而该子项的子树对约束聚合有贡献。
    • false:调用 Nodenode_ref Node 之间的第一个共同父节点不是 BufferCollectionTokenGroup。目前,这意味着第一个共同的父节点是 BufferCollectionTokenBufferCollection(无论是否经过 Release)。这意味着,如果所涉及的任何父级 BufferCollectionTokenGroup 同时选择了这两个 Node,则调用 Nodenode_ref Node 可能会在逻辑分配的约束聚合期间应用它们的约束条件。在这种情况下,没有 BufferCollectionTokenGroup 会直接阻止选择两个 Node 及其约束条件进行汇总,但即使为 false,如果一个或两个 Node 具有直接或间接父 BufferCollectionTokenGroup,并且其选择除包含调用 Nodenode_ref Node 的子树之外的子子树,那么即使为 false,也可能忽略其中一个或两个 Node
  • 错误 [fuchsia.sysmem2/Error.NOT_FOUND] node_ref 与调用 Node 所关联的缓冲区集合未关联。出现此错误的另一个原因是,node_ref 是具有足够权限的 zx.Handle.EVENT 句柄,但实际上并不是从 GetNodeRef 获取的真实 node_ref
  • 错误 [fuchsia.sysmem2/Error.PROTOCOL_DEVIATION] 调用方传递的 node_ref 不是 zx.Handle:EVENT 句柄,或者在真实的 node_ref 上没有所需的权限。
  • 此调用不会返回其他失败的状态代码。不过,sysmem 将来可能会添加其他代码,以便客户端应对所有失败的状态代码进行合理的默认处理。

请求

名称类型
payload NodeIsAlternateForRequest

响应

名称类型
payload Node_IsAlternateFor_Result

发布

fuchsia.sysmem2/BufferCollectionToken 通道上:

通常,参与者会将 BufferCollectionToken 转换为 fuchsia.sysmem2/BufferCollection,但参与者可以通过令牌发送 Release(然后立即或稍后关闭该通道,以响应服务器关闭服务器端时),从而避免缓冲区收集失败。如果没有事先设置 Release,关闭 BufferCollectionToken 客户端会导致缓冲区收集失败。

fuchsia.sysmem2/BufferCollection 通道上:

默认情况下,服务器通过缓冲区收集失败来处理 fuchsia.sysmem2/BufferCollection 客户端端的意外关闭(没有先使用 Release)。部分原因在于在任何参与者失败时加快关闭 VMO 句柄以回收内存。如果参与者想要彻底关闭 BufferCollection,而不会导致缓冲区收集失败,则可以先发送 Release,然后再关闭 BufferCollection 客户端。Release 可以发生在 SetConstraints 之前或之后。如果位于 SetConstraints 之前,则缓冲区集合不需要此节点的约束条件即可分配。如果在 SetConstraints 之后,约束条件会保留并聚合,尽管在约束条件聚合时缺少 BufferCollection 连接。

fuchsia.sysmem2/BufferCollectionTokenGroup 通道上:

默认情况下,意外关闭 BufferCollectionTokenGroup 客户端(未先添加 Release)将触发缓冲区收集失败。如需关闭 BufferCollectionTokenGroup 通道而不让缓冲区收集失败,请确保已发送 AllChildrenPresent(),并在关闭 BufferCollectionTokenGroup 客户端之前发送 Release

如果 Release 发生在 [fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent], the buffer collection will fail (triggered by reception of Releasewithout priorAllChildrenPresent). This is intentionally not analogous to how <a class='link' href='../fuchsia.sysmem2/'>fuchsia.sysmem2</a>/<a class='link' href='../fuchsia.sysmem2/#BufferCollection.Release'>BufferCollection.Release</a> without <a class='link' href='../fuchsia.sysmem2/'>fuchsia.sysmem2</a>/<a class='link' href='../fuchsia.sysmem2/#BufferCollection.SetConstraints'>BufferCollection.SetConstraints</a> first doesn't cause buffer collection failure. For a BufferCollectionTokenGroup, clean close requires AllChildrenPresent(if not already sent), then Release` 之前,则关闭客户端。

如果 Release 发生在 AllChildrenPresent 之后,则子项及其所有约束条件均保持不变(就像 BufferCollectionTokenGroup 通道保持开启状态时的情况一样),并且客户端关闭不会触发缓冲区收集失败。

在所有 fuchsia.sysmem2/Node 通道(上述任一通道)上:

为简洁起见,上述基于通道协议的段落忽略了由 fuchsia.sysmem2/BufferCollectionToken.SetDispensablefuchsia.sysmem2/BufferCollection.AttachToken 创建的单独故障域。当客户端意外关闭(没有先添加 Release)且该客户端位于故障网域下时,故障网域不会使整个缓冲区收集失败,而是会失败,但缓冲区集合本身会与故障网域的故障隔离开来。此类故障网域可以嵌套,在这种情况下,只有 Node 所在的最内层故障网域会发生故障。

请求

<EMPTY>

SetDebugClientInfo

设置有关当前客户端的信息,sysmem 可以使用这些信息来帮助诊断泄漏内存以及等待参与者发送 fuchsia.sysmem2/BufferCollection.SetConstraints 的分配暂停问题。

这会在此 fuchsia.sysmem2/Node 以及派生自此 Node 的所有 Node 上设置调试客户端信息,除非被 fuchsia.sysmem2/Allocator.SetDebugClientInfo 或更新版本的 fuchsia.sysmem2/Node.SetDebugClientInfo 替换。

针对每个 Allocator 发送一次 fuchsia.sysmem2/Allocator.SetDebugClientInfo,是确保所有 fuchsia.sysmem2/Node 至少已设置一些调试客户端信息的最有效方式。此外,与通过 fuchsia.sysmem2/{6.sysm2/提供相同的调试客户端信息更加高效。Node.SetDebugClientInfofuchsia.sysmem2

此外,在启用详细日志记录功能的情况下,也会用于(请参阅 SetVerboseLogging)来指示哪个客户端首先关闭其通道,从而导致子树故障(如果子树的用途结束,这可能是正常的,但如果发生的时间早于预期,客户端渠道专用的名称有助于从 sysmem 的角度诊断故障首先来自何处)。

目前,所有表字段均为必填字段。

  • request name 它可以是任意字符串,但最好使用当前进程名称(请参阅 fsl::GetCurrentProcessName)。
  • 请求 id。它可以是任意 ID,但最好使用当前进程 ID(请参阅 fsl::GetCurrentProcessKoid)。

请求

名称类型
payload NodeSetDebugClientInfoRequest

SetDebugTimeoutLogDeadline

如果 sysmem 在创建新集合后的 5 秒内未从所有客户端看到 fuchsia.sysmem2/BufferCollection.SetConstraints,则 Sysmem 会记录一条警告。

客户端可以调用此方法在日志输出时进行更改。如果多个客户端设置了截止期限,则无法确定哪个截止期限将生效。

在大多数情况下,默认设置的效果很好。

目前,所有表字段均为必填字段。

  • request deadline:表示 sysmem 开始尝试记录警告的时间,除非届时所有限制条件都已使用 sysmem。

请求

名称类型
payload NodeSetDebugTimeoutLogDeadlineRequest

SetDispensable

将此 fuchsia.sysmem2/BufferCollectionToken 设置为可分发。

BufferCollectionToken 转换为 fuchsia.sysmem2/BufferCollection 时,可分配状态也适用于 BufferCollection

通常,如果客户端在没有先发送 fuchsia.sysmem2/BufferCollection.Release 的情况下关闭 fuchsia.sysmem2/BufferCollection 客户端,则BufferCollection fuchisa.sysmem2/Node 将发生故障,而这也会导致相应操作失败,并将相应操作在 Node 中发生故障,从而向根 集合失败。fuchsia.sysmem2Node相比之下,可分配 Node 在分配缓冲区后可能会失败,而不会导致其父项在 fuchsia.sysmem2/Node 层次结构中发生故障。

在缓冲区分配之前,可分配的 Node 会与其父级一起参与约束汇总。如果可用 Node 在分配缓冲区之前失败,则失败会传播到可用 Node 的父级。

分配缓冲区后,可分配 Node(或可分配 Node 的任何子项)的故障都不会传播到可分配 Node 的父级。失败会从可分发 Node 的常规子项传播到可分发 Node。如果使用 fuchsia.sysmem2/BufferCollection.AttachToken 附加子项,或者子项可以判别且在分配后发生故障,系统将阻止子项故障到达其父项。

如果参与者需要提供约束条件,但在分配缓冲区后,参与者可以失败,且不会从父级 Node 的角度导致缓冲区收集失败,则可以使用可消耗的 Node

相比之下,BufferCollection.AttachToken 可用于创建不与其父级 Node 参与约束汇总的 BufferCollectionToken,其在任何时间的失败都不会传播到其父级 Node,并且其潜在延迟提供约束条件不会阻止父级 Node 完成其缓冲区分配。

在某些情况下,发起者(使用 fuchsia.sysmem2/Allocator.AllocateSharedCollection 的根 Node 的创建者)可能会选择最初为参与者的第一个实例使用可分发的 Node,之后,如果该参与者的第一个实例失败,我会为该参与者的新第二个实例获得使用 AttachToken 创建的 BufferCollectionToken

通常,在将可分配的 BufferCollectionToken 发送给委托参与者之前,客户端很快就会对 BufferCollectionToken 执行 SetDispensable。由于 SetDispensable 可防止子级 Node 失败情况传播到父级 Node,因此如果客户端是通过客户端保留的父级 Node 的故障来获悉子级故障,则客户端可能需要通过其他方式注意到失败情况。 如果其他方法不可用/方便,客户端可以改为保留可分发的 Node,并在其下面创建一个子项 Node 将其发送给代理参与者,同时保留此 Node,以便通过此 Node 的 ZX_CHANNEL_PEER_CLOSED 信号发现根位置处的子树故障,并执行任何合适的操作(例如,使用 Buffer2 进行适当的操作,然后使用 Buffer2 进行特定操作,例如在 Buffer2 中向 Buffer2 进行特定操作并执行 Buffer2 附加操作失败,或执行任何合适的操作,例如执行 Buffer2 类中的操作,或执行任何合适的操作,例如执行 BufferCollection.AttachToken

虽然可以在 BufferCollectionTokenGroup Node 的直接子项上 SetDispensable(并且可能有用),但之后无法使用 AttachToken 将失败的可分配 Node(是 BufferCollectionTokenGroup 的直接子项)替换为新令牌(因为组上没有 AttachToken)。如需在这种情况下启用 AttachToken 替换,请另外创建一个不可分配令牌作为该组的直接子级,并将现有的可分配令牌设为这个额外令牌的子级。这样,作为该组的直接子项的额外令牌具有 BufferCollection.AttachToken,可用于替换失败的可分配令牌。

已分发令牌上的 SetDispensable 具有幂等性。

请求

<EMPTY>

SetName

设置此缓冲区集合中的 VMO 的名称。

如果名称在 ZX_MAX_NAME_LEN 中不适合,vmo 本身的名称将被截断以适应这一要求。vmo 的名称以集合中的缓冲区索引作为后缀(如果后缀符合 ZX_MAX_NAME_LEN)。此处指定的名称(不截断)将在检查数据中列出。

该名称只会影响在设置名称后分配的 VMO;此调用不会重命名现有的 VMO。如果多个客户端设置了不同的名称,则优先级值越大,优先级越高。设置与之前的名称具有相同优先级的新名称不会更改名称。

目前,所有表字段均为必填字段。

  • 请求 priority 仅当这是第一个 SetNamepriority 大于此缓冲区集合的所有 Node 之前 SetName 调用中的任何先前 priority 值时,才会设置名称。
  • 请求 name:在此缓冲区集合下创建的 VMO 的名称。

请求

名称类型
payload NodeSetNameRequest

SetVerboseLogging

这样可以为缓冲区收集启用详细日志记录功能。

详细日志记录包括通过每个客户端通过 fuchsia.sysmem2/BufferCollection.SetConstraints 设置的约束,以及通过 fuchsia.sysmem2/Node.SetDebugClientInfo(或 fuchsia.sysmem2/Allocator.SetDebugClientInfo)设置的信息,以及 {12 theNode

通常,当聚合失败时,sysmem 仅输出一行投诉,并且仅显示聚合失败的具体详细原因,并且没有太多上下文。虽然这通常足以诊断出问题:如果仅进行了细微更改,并且所有功能在进行细微更改之前都正常运行,则对于首次获取新的缓冲区集合来说,这通常不是特别有帮助。尤其是对于更复杂的节点树,涉及 fuchsia.sysmem2/BufferCollection.AttachTokenfuchsia.sysmem2/BufferCollectionToken.SetDispensablefuchsia.sysmem2/BufferCollectionTokenGroup 等节点的子树分配失败的原因,以及可能的节点子树中的关联子树失败的原因;

额外日志记录的目的在于,从性能的角度来看,这是可以接受的,假设只对少量缓冲区集合启用详细日志记录。如果我们没有跟踪某个 bug,就不应发送此消息。

请求

<EMPTY>

SetWeak

将当前的 fuchsia.sysmem2/Node 和在此消息之后创建的所有子 Node 设置为弱,这意味着客户端的 Node 客户端(或在此消息后创建的子节点)并不足以使已分配的 VMO 保持活跃状态。

从弱 Node 获取的所有 VMO 都是弱系统 VMO。另请参阅 close_weak_asap

只有在 Node 准备好进行分配之前,才允许显示此消息(否则服务器会使用 ZX_ERR_BAD_STATE 关闭通道):

  • BufferCollectionToken:时间不限
  • BufferCollectionSetConstraints 之前
  • BufferCollectionTokenGroupAllChildrenPresent 之前

目前,系统未提供从强 Node 到弱 Node 的转换,但客户端可以在分配前创建一个额外的 Node,并将该额外的 Node 设置为弱 Node,然后在稍后的某个时间点发送 Release 并关闭客户端强 Node 的客户端端,但保留客户端的弱 Node

Node 数和强 VMO 句柄为零会导致缓冲区收集失败(所有 Node 客户端都会看到 ZX_CHANNEL_PEER_CLOSED,所有 close_weak_asap client_end 会看到 ZX_EVENTPAIR_PEER_CLOSED),但系统(有意)不会注意到这种情况,直到所有 Node 都准备好进行分配为止。要使初始分配成功,在分配时至少需要存在一个强 Node,但在该客户端收到 VMO 句柄后,该客户端可以执行 BufferCollection.Release 操作并关闭客户端,而不会导致此类失败。

这也隐含 fuchsia.sysmem2/Node.SetWeakOk,但不隐含 for_children_also 为 true 的 SetWeakOk(可根据情况单独发送)。

请求

<EMPTY>

SetWeakOk

这向 sysmem 表明,客户端已准备好关注 close_weak_asap

如果发送此消息,则此消息必须在 fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated 之前发送。

使用弱 fuchsia.sysmem2/BufferCollection 的所有参与者必须在 WaitForAllBuffersAllocated 之前发送此消息,否则父级 Node 必须发送 fuchsia.sysmem2/Node.SetWeakOkfor_child_nodes_also 为 true,否则 WaitForAllBuffersAllocated 将触发缓冲区收集失败。

这条消息很有必要,因为系统显然较弱的 VMO 并非一直存在,因此较旧的客户端不知道需要关注 close_weak_asap ZX_EVENTPAIR_PEER_CLOSED,并尽快关闭所有剩余系统内存弱 VMO 句柄。通过收到此消息并要求参与者表明其接受整个协议的这一方面,我们可避免以下情况:较旧客户端传递了较弱的 VMO,而 sysmem 无法使该 VMO 稍后(并基于每个缓冲区)快速关闭。

不处理 close_weak_asap 且未通过 WaitForAllBuffersAllocated 检索任何 VMO 句柄的参与者不需要发送 SetWeakOk(也不需要让父级 Node 发送 for_child_nodes_also 为 true 的 SetWeakOk)。但是,如果同一参与者有一个可以检索 VMO 的子节点/委托,该子节点/委托需要在 WaitForAllBuffersAllocated 之前发送 SetWeakOk

  • 请求 for_child_nodes_also 如果存在且值为 true,这意味着在此消息之后创建的此节点的直接子节点以及这些节点的所有后代都将表现得就像在这些节点上发送了 SetWeakOk 一样。在此节点之前创建的任何子节点不包括在内。此设置是“粘性的”,因为后面的 SetWeakOk 如果未将此布尔值设为 true,则不会重置服务器端布尔值。如果这给参与者带来了问题,解决方法是视情况在子令牌上改用 SetWeakOk 并将 for_child_nodes_also 设为 true。仅当参与者确实能够承诺对其自身的弱 VMO 句柄以及持有相应子级 Node 的参与者持有的所有弱 VMO 句柄时都遵守 close_weak_asap,才应将 for_child_nodes_also 设为 true。设置 for_child_nodes_also 后,使用 sysmem(1) 的后代 Node 的性能可能较弱,尽管这些 sysmem1 Node 的客户端无法直接访问 SetWeakOk 或无法通过任何直接方式找到 close_weak_asap。这仅适用于此 Node 使用 sysmem(1) 的后代,而不是在直接从 sysmem2 令牌转换为 sysmem(1) 令牌时转换为此 Node,因为除非此 Node 的祖先将 for_child_nodes_also 指定为 true,否则分配将失败。

请求

名称类型
payload NodeSetWeakOkRequest

同步

确保已在服务器端收到之前的消息。这在之前创建了新令牌的消息之后特别有用,因为在将令牌发送给其他参与者之前,sysmem 服务器必须知道令牌。

对无效令牌调用 fuchsia.sysmem2/BufferCollectionToken.Sync 可能会导致 Sync 永久停止。如需降低因一次往返而降低恶意/虚假 fuchsia.sysmem2/BufferCollectionToken 的可能性,请参阅 fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken。另一种方法是将令牌传递给 fuchsia.sysmem2/Allocator/BindSharedCollection,后者还会在将令牌交换为 fuchsia.sysmem2/BufferCollection 通道时对令牌进行验证,然后就可以使用 fuchsia.sysmem2/BufferCollection.Sync

在创建一个或多个 fuchsia.sysmem2/BufferCollectionToken,然后开始并完成 Sync 后,就可以安全地将 BufferCollectionToken 客户端结束发送给其他参与者,而当其他参与者通过 fuchsia.sysmem2/Allocator.BindSharedCollection这是一种创建令牌的高效方法,可避免不必要的往返。

其他选项包括等待每个 fuchsia.sysmem2/BufferCollectionToken.Duplicate 分别完成(在每个 fuchsia.sysmem2 单独调用 Sync 之后进行调用),或者在通过 fuchsia.sysmem2/Allocator.BindSharedCollectionfuchsia.sysmem2BufferCollectionToken.DuplicateSync

请求

<EMPTY>

响应

名称类型
payload Node_Sync_Result

BufferCollectionTokenGroup

fuchsia.sysmem2/collection.fidl 中定义

系统实现与分配 / 逻辑分配的逻辑 / 概念模型一致,如下所示:

与往常一样,逻辑分配会考虑根及连接到该根且不传输使用 fuchsia.sysmem2/BufferCollection.AttachToken 创建的 fuchsia.sysmem2/Node 的根及所有节点,或者根位置为 AttachToken Node 的子树和连接到该子树且不传输其他 AttachToken 的所有 Node。这称为逻辑分配剪除的子树,简称为剪枝子树。

在约束条件聚合期间,每个 fuchsia.sysmem2/BufferCollectionTokenGroup 都将在其直接子项中选择单个子 Node。其余子项似乎未通过逻辑分配,而所选子项可能会成功。

当在整体逻辑分配剪除的子树中存在多个 BufferCollectionTokenGroup 时,两个组之间的相对优先级等同于其在树的 DFS 预订迭代中的排序,其中父项的优先级高于子项,左侧子项的优先级高于右侧子项。

选择某个组的特定子项(无论是在约束汇总尝试期间临时选择,还是作为最终选择)时,如果未选择该组的其他子项,则会在这些未选择的子项下“隐藏”任何其他组。

在逻辑分配中,首先尝试通过以下方式进行聚合:临时选择优先级最高的组的子项 0,以及尚未被临时选择目前隐藏的下一个最高优先级组的子项 0,等等。

如果该汇总尝试失败,系统将尝试对所有相同组的序数 0 子组进行汇总,但优先级最低的非隐藏组将暂时选择其序数 1 个子组(然后选择子组 2,依此类推)。如果更新优先级最低的新组时已取消隐藏,在更改之前优先级最低的组中的临时选择之前,新取消隐藏的最低优先级组会按顺序考虑其所有子组。就结果而言,这相当于按照计数类顺序对所有可能的选项组合进行系统枚举,以最高频率更新优先级最低的群组,以最低频率更新优先级最高的群组。我们可以跳过由于隐藏而不对结果进行任何更改而冗余/等效的组合,而不是实际尝试使用所有组合进行汇总。

尝试对枚举的非等效选择组合进行约束汇总,直到:(a) 所有汇总尝试失败(在这种情况下,整体逻辑分配失败)或 (b) 直到尝试的汇总成功(在这种情况下,缓冲区分配,在这种情况下,如果这是位于整个根 Node 根的已剪除子树)尝试一次。如果基于第一个成功约束条件汇总的缓冲区分配失败,则整个逻辑分配失败(没有缓冲区分配重试 / 重试)。如果缓冲区分配成功(或者由于作为不含根的剪枝子树而不需要),逻辑分配会成功。

如果此优先级方案无法满足您对 Sysmem 的使用需求,请随时与系统人员联系,讨论是否增加一种方式来实现您所需的功能。

请避免为每个逻辑分配创建大量的 BufferCollectionTokenGroup,尤其是在总共有大量子节点时,尤其是在合理预期汇总操作经常会失败的情况下,使用序数为 0 的子节点(可能也会使用后续子节点)会失败。Sysmem 通过在考虑的组子组合/选择数量上限(相当高但并不庞大)超出某个上限(相当高但并不庞大)的情况下,仅仅让逻辑分配失败,即可降低在过多组中评估过多子组合/选择时可能较高的时间复杂性。更高级(且更复杂的)缓解措施预计没有实际必要,也不值得增加复杂性。如果达到上限或您预计即将达到上限,请与系统相关人员联系,讨论可能的方案。

在可行的情况下,最好在单个 fuchsia.sysmem2/BufferCollectionConstraints 中使用多个 fuchsia.sysmem2/ImageFormatConstraints(当参与者只需表达使用不止一个 fuchsia.images2/PixelFormat 的能力时,所有参与者都能够选择其中支持的 {12/PixelFormat)。PixelFormat

fuchsia.sysmem2/BufferCollectionTokenfuchsia.sysmem2/BufferCollection 类似,如果不先发送 fuchsia.sysmem2/Node.Release,则关闭 BufferCollectionTokenGroup 通道将会导致缓冲区收集失败(如果使用 fuchsia.sysmem2BufferCollectionToken.SetDispensablefuchsia.sysmem2BufferCollection.AttachToken

此协议中不使用墓碑。

添加数量:19

AllChildrenPresent

表示不再创建子级。

创建所有子项后,客户端应发送 fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent 以告知系统将不会再创建任何子项,以便系统可以知道何时可以开始聚合约束条件。

不允许在 AllChildrenPresent 之后发送 CreateChild;这会导致群组的子树失败并断开连接。

如果要发送 fuchsia.sysmem2/Node.Release,应在 AllChildrenPresent 之后发送,否则会触发组的子树故障。我们特意不类似于没有先前的 fuchsia.sysmem2/BufferCollection.SetConstraintsRelease 不会造成子树故障的情况。

请求

<EMPTY>

CreateChild

创建一个子项 fuchsia.sysmem2/BufferCollectionToken。在分配(或逻辑分配)期间,只会选择一个子节点(包括其子节点)。

将此令牌的客户端端传递给 fuchsia.sysmem2/Allocator.BindSharedCollection 之前,需要在 fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChild 之后完成 fuchsia.sysmem2/Node.Sync。或者,客户端可以使用 fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChildrenSync,其中基本上包含 Sync

不允许在 AllChildrenPresent 之后发送 CreateChild;这会导致群组的子树失败并断开连接。

创建完所有子级后,发送 AllChildrenPresent。

  • 请求 token_request 新令牌通道的服务器端。
  • 请求 rights_attenuation_mask 如果为 ZX_RIGHT_SAME_RIGHTS,则创建的令牌将允许持有者获取与(组的)父令牌相同的缓冲区权限。当值不是 ZX_RIGHT_SAME_RIGHTS 时,系统会将其解释为具有 0 位的位掩码,以确保这些权利被衰减,因此 0xFFFFFFFF 就是 ZX_RIGHT_SAME_RIGHTS 的同义词。不允许值 0 是有意导致子树故障的。

请求

名称类型
payload BufferCollectionTokenGroupCreateChildRequest

CreateChildrenSync

同步创建 1 个或多个子令牌。与 fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChild 不同,在将返回令牌的客户端端传递到 fuchsia.sysmem2/Allocator/BindSharedCollection 之前,不需要使用 fuchsia.sysmem2/Node.Sync

索引较低子令牌的优先级高于(尝试较快)的子令牌。

根据所有子令牌,成功聚合将从所有已创建的子令牌中仅选择一个子项(在可能对 fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChildfuchsia.sysmem2/BufferCollectionTokenGroup.CreateChildrenSync 创建的所有子项中仅选择一个子项。

每个组允许的子项总数上限以及整个树中的节点总数(从根开始)均受限于无法通过这些协议配置的限制。

不允许在 AllChildrenPresent 之后发送 CreateChildrenSync;这会导致群组的子树失败并断开连接。

创建完所有子级后,发送 AllChildrenPresent。

  • 请求 rights_attentuation_masks rights_attentuation_masks 的大小决定了创建的子令牌的数量。值 ZX_RIGHT_SAME_RIGHTS 不会削弱任何权利。 值 0xFFFFFFFF 是 ZX_RIGHT_SAME_RIGHTS 的同义词。对于任何其他值,掩码中的每个 0 位都会在右侧衰减。
  • 响应 tokens 已创建的子令牌。

请求

名称类型
payload BufferCollectionTokenGroupCreateChildrenSyncRequest

响应

名称类型
payload BufferCollectionTokenGroup_CreateChildrenSync_Result

GetBufferCollectionId

获取缓冲区集合 ID。此 ID 也可以通过 fuchsia.sysmem2/Allocator.GetVmoInfo(以及集合中的 buffer_index)获得。

此调用主要适用于以下情况:我们无法直接传递 fuchsia.sysmem2/BufferCollectionTokenfuchsia.sysmem2/BufferCollection,但只能传达一个 VMO 句柄,该 VMO 句柄可以与通过其他路径创建的 BufferCollection 客户端端合并。如有可能,最好直接传达 BufferCollectionTokenBufferCollection

信任来自 sysmem 以外的来源的 buffer_collection_id 值类似于信任来自 zircon 以外的来源的 koid 值。除非确实有必要,否则应尽量避免使用这两种方法,而且两者都需要谨慎。在某些情况下,出于效率原因,通过 buffer_collection_id 引用预先确定的 BufferCollection 可能是合理的,但声称是 buffer_collection_id 的传入值并不足以证明向 buffer_collection_id 的发送者授予任何功能。发送方必须先向接收方证明发送者具有 VMO 或具有对同一集合的 BufferCollectionToken,方法是发送一个由系统进程确认是有效系统进程句柄的句柄,以及哪个系统进程映射到 buffer_collection_id 值。如果发送者仅证明发送者具有 VMO,接收者应格外小心,不要假设发送者有 BufferCollectionToken

  • 响应 buffer_collection_id。每次启动后,此 ID 在每个缓冲区集合中都是唯一的。每个缓冲区都由 buffer_collection_idbuffer_index 共同进行唯一标识。

请求

<EMPTY>

响应

名称类型
payload Node_GetBufferCollectionId_Result

GetNodeRef

这会获得一个句柄,可用作在任何 fuchsia.sysmem2/Node 上调用的 fuchsia.sysmem2/Node.IsAlternateFor 的参数。此句柄仅用于证明客户端已从此 Node 获取此句柄。

由于这是一个未设置的集合,因此 GetNodeRef 和对 IsAlternateFor 的调用之间无需 fuchsia.sysmem2/Node.Sync,尽管这两个调用通常位于不同的通道上。

另请参阅 fuchsia.sysmem2/Node.IsAlternateFor

目前,所有表字段均为必填字段。

  • 响应 node_ref 可通过其他 Node 通道上的 IsAlternateFor 发送此句柄,以证明客户端从此 Node 获得了此句柄。

请求

<EMPTY>

响应

名称类型
payload Node_GetNodeRef_Result

IsAlternateFor

检查调用 fuchsia.sysmem2/Node 是否位于与传入的 node_ref 相关的通用父 fuchsia.sysmem2/BufferCollectionTokenGroup 的不同子树的根位置。

此调用旨在协助准入控制去重和调试。

必须使用 fuchsia.sysmem2/Node.GetNodeRef 获取 node_ref

node_ref 可以是重复的句柄;无需在每次调用 fuchsia.sysmem2/Node.IsAlternateFor 时都调用 GetNodeRef

如果由于某个可能的恶意/不可信令牌提供者而导致某个调用令牌实际上根本不是有效令牌,请先调用 fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken,而不是在 IsAlternateFor 从不响应(并非真正与 sysmem 通信)时无限期地卡住。另一种方法是先使用此令牌调用 fuchsia.sysmem2/Allocator.BindSharedCollection,这样也会验证令牌并将其转换为 fuchsia.sysmem2/BufferCollection,然后调用 IsAlternateFor

目前,所有表字段均为必填字段。

  • 响应 is_alternate
    • true:调用节点与 node_ref Node 之间的第一个共同父节点是 BufferCollectionTokenGroup。这意味着,调用 Nodenode_ref Node 不会同时应用其两个约束条件,而 sysmem 只会选择其中一个约束条件,绝不会同时应用两者。这是因为在逻辑分配期间只选择 BufferCollectionTokenGroup 的一个子项,而该子项的子树对约束聚合有贡献。
    • false:调用 Nodenode_ref Node 之间的第一个共同父节点不是 BufferCollectionTokenGroup。目前,这意味着第一个共同的父节点是 BufferCollectionTokenBufferCollection(无论是否经过 Release)。这意味着,如果所涉及的任何父级 BufferCollectionTokenGroup 同时选择了这两个 Node,则调用 Nodenode_ref Node 可能会在逻辑分配的约束聚合期间应用它们的约束条件。在这种情况下,没有 BufferCollectionTokenGroup 会直接阻止选择两个 Node 及其约束条件进行汇总,但即使为 false,如果一个或两个 Node 具有直接或间接父 BufferCollectionTokenGroup,并且其选择除包含调用 Nodenode_ref Node 的子树之外的子子树,那么即使为 false,也可能忽略其中一个或两个 Node
  • 错误 [fuchsia.sysmem2/Error.NOT_FOUND] node_ref 与调用 Node 所关联的缓冲区集合未关联。出现此错误的另一个原因是,node_ref 是具有足够权限的 zx.Handle.EVENT 句柄,但实际上并不是从 GetNodeRef 获取的真实 node_ref
  • 错误 [fuchsia.sysmem2/Error.PROTOCOL_DEVIATION] 调用方传递的 node_ref 不是 zx.Handle:EVENT 句柄,或者在真实的 node_ref 上没有所需的权限。
  • 此调用不会返回其他失败的状态代码。不过,sysmem 将来可能会添加其他代码,以便客户端应对所有失败的状态代码进行合理的默认处理。

请求

名称类型
payload NodeIsAlternateForRequest

响应

名称类型
payload Node_IsAlternateFor_Result

发布

fuchsia.sysmem2/BufferCollectionToken 通道上:

通常,参与者会将 BufferCollectionToken 转换为 fuchsia.sysmem2/BufferCollection,但参与者可以通过令牌发送 Release(然后立即或稍后关闭该通道,以响应服务器关闭服务器端时),从而避免缓冲区收集失败。如果没有事先设置 Release,关闭 BufferCollectionToken 客户端会导致缓冲区收集失败。

fuchsia.sysmem2/BufferCollection 通道上:

默认情况下,服务器通过缓冲区收集失败来处理 fuchsia.sysmem2/BufferCollection 客户端端的意外关闭(没有先使用 Release)。部分原因在于在任何参与者失败时加快关闭 VMO 句柄以回收内存。如果参与者想要彻底关闭 BufferCollection,而不会导致缓冲区收集失败,则可以先发送 Release,然后再关闭 BufferCollection 客户端。Release 可以发生在 SetConstraints 之前或之后。如果位于 SetConstraints 之前,则缓冲区集合不需要此节点的约束条件即可分配。如果在 SetConstraints 之后,约束条件会保留并聚合,尽管在约束条件聚合时缺少 BufferCollection 连接。

fuchsia.sysmem2/BufferCollectionTokenGroup 通道上:

默认情况下,意外关闭 BufferCollectionTokenGroup 客户端(未先添加 Release)将触发缓冲区收集失败。如需关闭 BufferCollectionTokenGroup 通道而不让缓冲区收集失败,请确保已发送 AllChildrenPresent(),并在关闭 BufferCollectionTokenGroup 客户端之前发送 Release

如果 Release 发生在 [fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent], the buffer collection will fail (triggered by reception of Releasewithout priorAllChildrenPresent). This is intentionally not analogous to how <a class='link' href='../fuchsia.sysmem2/'>fuchsia.sysmem2</a>/<a class='link' href='../fuchsia.sysmem2/#BufferCollection.Release'>BufferCollection.Release</a> without <a class='link' href='../fuchsia.sysmem2/'>fuchsia.sysmem2</a>/<a class='link' href='../fuchsia.sysmem2/#BufferCollection.SetConstraints'>BufferCollection.SetConstraints</a> first doesn't cause buffer collection failure. For a BufferCollectionTokenGroup, clean close requires AllChildrenPresent(if not already sent), then Release` 之前,则关闭客户端。

如果 Release 发生在 AllChildrenPresent 之后,则子项及其所有约束条件均保持不变(就像 BufferCollectionTokenGroup 通道保持开启状态时的情况一样),并且客户端关闭不会触发缓冲区收集失败。

在所有 fuchsia.sysmem2/Node 通道(上述任一通道)上:

为简洁起见,上述基于通道协议的段落忽略了由 fuchsia.sysmem2/BufferCollectionToken.SetDispensablefuchsia.sysmem2/BufferCollection.AttachToken 创建的单独故障域。当客户端意外关闭(没有先添加 Release)且该客户端位于故障网域下时,故障网域不会使整个缓冲区收集失败,而是会失败,但缓冲区集合本身会与故障网域的故障隔离开来。此类故障网域可以嵌套,在这种情况下,只有 Node 所在的最内层故障网域会发生故障。

请求

<EMPTY>

SetDebugClientInfo

设置有关当前客户端的信息,sysmem 可以使用这些信息来帮助诊断泄漏内存以及等待参与者发送 fuchsia.sysmem2/BufferCollection.SetConstraints 的分配暂停问题。

这会在此 fuchsia.sysmem2/Node 以及派生自此 Node 的所有 Node 上设置调试客户端信息,除非被 fuchsia.sysmem2/Allocator.SetDebugClientInfo 或更新版本的 fuchsia.sysmem2/Node.SetDebugClientInfo 替换。

针对每个 Allocator 发送一次 fuchsia.sysmem2/Allocator.SetDebugClientInfo,是确保所有 fuchsia.sysmem2/Node 至少已设置一些调试客户端信息的最有效方式。此外,与通过 fuchsia.sysmem2/{6.sysm2/提供相同的调试客户端信息更加高效。Node.SetDebugClientInfofuchsia.sysmem2

此外,在启用详细日志记录功能的情况下,也会用于(请参阅 SetVerboseLogging)来指示哪个客户端首先关闭其通道,从而导致子树故障(如果子树的用途结束,这可能是正常的,但如果发生的时间早于预期,客户端渠道专用的名称有助于从 sysmem 的角度诊断故障首先来自何处)。

目前,所有表字段均为必填字段。

  • request name 它可以是任意字符串,但最好使用当前进程名称(请参阅 fsl::GetCurrentProcessName)。
  • 请求 id。它可以是任意 ID,但最好使用当前进程 ID(请参阅 fsl::GetCurrentProcessKoid)。

请求

名称类型
payload NodeSetDebugClientInfoRequest

SetDebugTimeoutLogDeadline

如果 sysmem 在创建新集合后的 5 秒内未从所有客户端看到 fuchsia.sysmem2/BufferCollection.SetConstraints,则 Sysmem 会记录一条警告。

客户端可以调用此方法在日志输出时进行更改。如果多个客户端设置了截止期限,则无法确定哪个截止期限将生效。

在大多数情况下,默认设置的效果很好。

目前,所有表字段均为必填字段。

  • request deadline:表示 sysmem 开始尝试记录警告的时间,除非届时所有限制条件都已使用 sysmem。

请求

名称类型
payload NodeSetDebugTimeoutLogDeadlineRequest

SetName

设置此缓冲区集合中的 VMO 的名称。

如果名称在 ZX_MAX_NAME_LEN 中不适合,vmo 本身的名称将被截断以适应这一要求。vmo 的名称以集合中的缓冲区索引作为后缀(如果后缀符合 ZX_MAX_NAME_LEN)。此处指定的名称(不截断)将在检查数据中列出。

该名称只会影响在设置名称后分配的 VMO;此调用不会重命名现有的 VMO。如果多个客户端设置了不同的名称,则优先级值越大,优先级越高。设置与之前的名称具有相同优先级的新名称不会更改名称。

目前,所有表字段均为必填字段。

  • 请求 priority 仅当这是第一个 SetNamepriority 大于此缓冲区集合的所有 Node 之前 SetName 调用中的任何先前 priority 值时,才会设置名称。
  • 请求 name:在此缓冲区集合下创建的 VMO 的名称。

请求

名称类型
payload NodeSetNameRequest

SetVerboseLogging

这样可以为缓冲区收集启用详细日志记录功能。

详细日志记录包括通过每个客户端通过 fuchsia.sysmem2/BufferCollection.SetConstraints 设置的约束,以及通过 fuchsia.sysmem2/Node.SetDebugClientInfo(或 fuchsia.sysmem2/Allocator.SetDebugClientInfo)设置的信息,以及 {12 theNode

通常,当聚合失败时,sysmem 仅输出一行投诉,并且仅显示聚合失败的具体详细原因,并且没有太多上下文。虽然这通常足以诊断出问题:如果仅进行了细微更改,并且所有功能在进行细微更改之前都正常运行,则对于首次获取新的缓冲区集合来说,这通常不是特别有帮助。尤其是对于更复杂的节点树,涉及 fuchsia.sysmem2/BufferCollection.AttachTokenfuchsia.sysmem2/BufferCollectionToken.SetDispensablefuchsia.sysmem2/BufferCollectionTokenGroup 等节点的子树分配失败的原因,以及可能的节点子树中的关联子树失败的原因;

额外日志记录的目的在于,从性能的角度来看,这是可以接受的,假设只对少量缓冲区集合启用详细日志记录。如果我们没有跟踪某个 bug,就不应发送此消息。

请求

<EMPTY>

SetWeak

将当前的 fuchsia.sysmem2/Node 和在此消息之后创建的所有子 Node 设置为弱,这意味着客户端的 Node 客户端(或在此消息后创建的子节点)并不足以使已分配的 VMO 保持活跃状态。

从弱 Node 获取的所有 VMO 都是弱系统 VMO。另请参阅 close_weak_asap

只有在 Node 准备好进行分配之前,才允许显示此消息(否则服务器会使用 ZX_ERR_BAD_STATE 关闭通道):

  • BufferCollectionToken:时间不限
  • BufferCollectionSetConstraints 之前
  • BufferCollectionTokenGroupAllChildrenPresent 之前

目前,系统未提供从强 Node 到弱 Node 的转换,但客户端可以在分配前创建一个额外的 Node,并将该额外的 Node 设置为弱 Node,然后在稍后的某个时间点发送 Release 并关闭客户端强 Node 的客户端端,但保留客户端的弱 Node

Node 数和强 VMO 句柄为零会导致缓冲区收集失败(所有 Node 客户端都会看到 ZX_CHANNEL_PEER_CLOSED,所有 close_weak_asap client_end 会看到 ZX_EVENTPAIR_PEER_CLOSED),但系统(有意)不会注意到这种情况,直到所有 Node 都准备好进行分配为止。要使初始分配成功,在分配时至少需要存在一个强 Node,但在该客户端收到 VMO 句柄后,该客户端可以执行 BufferCollection.Release 操作并关闭客户端,而不会导致此类失败。

这也隐含 fuchsia.sysmem2/Node.SetWeakOk,但不隐含 for_children_also 为 true 的 SetWeakOk(可根据情况单独发送)。

请求

<EMPTY>

SetWeakOk

这向 sysmem 表明,客户端已准备好关注 close_weak_asap

如果发送此消息,则此消息必须在 fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated 之前发送。

使用弱 fuchsia.sysmem2/BufferCollection 的所有参与者必须在 WaitForAllBuffersAllocated 之前发送此消息,否则父级 Node 必须发送 fuchsia.sysmem2/Node.SetWeakOkfor_child_nodes_also 为 true,否则 WaitForAllBuffersAllocated 将触发缓冲区收集失败。

这条消息很有必要,因为系统显然较弱的 VMO 并非一直存在,因此较旧的客户端不知道需要关注 close_weak_asap ZX_EVENTPAIR_PEER_CLOSED,并尽快关闭所有剩余系统内存弱 VMO 句柄。通过收到此消息并要求参与者表明其接受整个协议的这一方面,我们可避免以下情况:较旧客户端传递了较弱的 VMO,而 sysmem 无法使该 VMO 稍后(并基于每个缓冲区)快速关闭。

不处理 close_weak_asap 且未通过 WaitForAllBuffersAllocated 检索任何 VMO 句柄的参与者不需要发送 SetWeakOk(也不需要让父级 Node 发送 for_child_nodes_also 为 true 的 SetWeakOk)。但是,如果同一参与者有一个可以检索 VMO 的子节点/委托,该子节点/委托需要在 WaitForAllBuffersAllocated 之前发送 SetWeakOk

  • 请求 for_child_nodes_also 如果存在且值为 true,这意味着在此消息之后创建的此节点的直接子节点以及这些节点的所有后代都将表现得就像在这些节点上发送了 SetWeakOk 一样。在此节点之前创建的任何子节点不包括在内。此设置是“粘性的”,因为后面的 SetWeakOk 如果未将此布尔值设为 true,则不会重置服务器端布尔值。如果这给参与者带来了问题,解决方法是视情况在子令牌上改用 SetWeakOk 并将 for_child_nodes_also 设为 true。仅当参与者确实能够承诺对其自身的弱 VMO 句柄以及持有相应子级 Node 的参与者持有的所有弱 VMO 句柄时都遵守 close_weak_asap,才应将 for_child_nodes_also 设为 true。设置 for_child_nodes_also 后,使用 sysmem(1) 的后代 Node 的性能可能较弱,尽管这些 sysmem1 Node 的客户端无法直接访问 SetWeakOk 或无法通过任何直接方式找到 close_weak_asap。这仅适用于此 Node 使用 sysmem(1) 的后代,而不是在直接从 sysmem2 令牌转换为 sysmem(1) 令牌时转换为此 Node,因为除非此 Node 的祖先将 for_child_nodes_also 指定为 true,否则分配将失败。

请求

名称类型
payload NodeSetWeakOkRequest

同步

确保已在服务器端收到之前的消息。这在之前创建了新令牌的消息之后特别有用,因为在将令牌发送给其他参与者之前,sysmem 服务器必须知道令牌。

对无效令牌调用 fuchsia.sysmem2/BufferCollectionToken.Sync 可能会导致 Sync 永久停止。如需降低因一次往返而降低恶意/虚假 fuchsia.sysmem2/BufferCollectionToken 的可能性,请参阅 fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken。另一种方法是将令牌传递给 fuchsia.sysmem2/Allocator/BindSharedCollection,后者还会在将令牌交换为 fuchsia.sysmem2/BufferCollection 通道时对令牌进行验证,然后就可以使用 fuchsia.sysmem2/BufferCollection.Sync

在创建一个或多个 fuchsia.sysmem2/BufferCollectionToken,然后开始并完成 Sync 后,就可以安全地将 BufferCollectionToken 客户端结束发送给其他参与者,而当其他参与者通过 fuchsia.sysmem2/Allocator.BindSharedCollection这是一种创建令牌的高效方法,可避免不必要的往返。

其他选项包括等待每个 fuchsia.sysmem2/BufferCollectionToken.Duplicate 分别完成(在每个 fuchsia.sysmem2 单独调用 Sync 之后进行调用),或者在通过 fuchsia.sysmem2/Allocator.BindSharedCollectionfuchsia.sysmem2BufferCollectionToken.DuplicateSync

请求

<EMPTY>

响应

名称类型
payload Node_Sync_Result

节点

fuchsia.sysmem2/collection.fidl 中定义

此协议是通过创建 fuchsia.sysmem2/BufferCollectionToken 以及创建 fuchsia.sysmem2/BufferCollectionTokenGroup 而建立的所有节点的父协议,包括自 fuchsia.sysmem2/BufferCollectionToken(已转换为 fuchsia.sysmem2BufferCollection

此协议中不使用墓碑。

添加数量:19

GetBufferCollectionId

获取缓冲区集合 ID。此 ID 也可以通过 fuchsia.sysmem2/Allocator.GetVmoInfo(以及集合中的 buffer_index)获得。

此调用主要适用于以下情况:我们无法直接传递 fuchsia.sysmem2/BufferCollectionTokenfuchsia.sysmem2/BufferCollection,但只能传达一个 VMO 句柄,该 VMO 句柄可以与通过其他路径创建的 BufferCollection 客户端端合并。如有可能,最好直接传达 BufferCollectionTokenBufferCollection

信任来自 sysmem 以外的来源的 buffer_collection_id 值类似于信任来自 zircon 以外的来源的 koid 值。除非确实有必要,否则应尽量避免使用这两种方法,而且两者都需要谨慎。在某些情况下,出于效率原因,通过 buffer_collection_id 引用预先确定的 BufferCollection 可能是合理的,但声称是 buffer_collection_id 的传入值并不足以证明向 buffer_collection_id 的发送者授予任何功能。发送方必须先向接收方证明发送者具有 VMO 或具有对同一集合的 BufferCollectionToken,方法是发送一个由系统进程确认是有效系统进程句柄的句柄,以及哪个系统进程映射到 buffer_collection_id 值。如果发送者仅证明发送者具有 VMO,接收者应格外小心,不要假设发送者有 BufferCollectionToken

  • 响应 buffer_collection_id。每次启动后,此 ID 在每个缓冲区集合中都是唯一的。每个缓冲区都由 buffer_collection_idbuffer_index 共同进行唯一标识。

请求

<EMPTY>

响应

名称类型
payload Node_GetBufferCollectionId_Result

GetNodeRef

这会获得一个句柄,可用作在任何 fuchsia.sysmem2/Node 上调用的 fuchsia.sysmem2/Node.IsAlternateFor 的参数。此句柄仅用于证明客户端已从此 Node 获取此句柄。

由于这是一个未设置的集合,因此 GetNodeRef 和对 IsAlternateFor 的调用之间无需 fuchsia.sysmem2/Node.Sync,尽管这两个调用通常位于不同的通道上。

另请参阅 fuchsia.sysmem2/Node.IsAlternateFor

目前,所有表字段均为必填字段。

  • 响应 node_ref 可通过其他 Node 通道上的 IsAlternateFor 发送此句柄,以证明客户端从此 Node 获得了此句柄。

请求

<EMPTY>

响应

名称类型
payload Node_GetNodeRef_Result

IsAlternateFor

检查调用 fuchsia.sysmem2/Node 是否位于与传入的 node_ref 相关的通用父 fuchsia.sysmem2/BufferCollectionTokenGroup 的不同子树的根位置。

此调用旨在协助准入控制去重和调试。

必须使用 fuchsia.sysmem2/Node.GetNodeRef 获取 node_ref

node_ref 可以是重复的句柄;无需在每次调用 fuchsia.sysmem2/Node.IsAlternateFor 时都调用 GetNodeRef

如果由于某个可能的恶意/不可信令牌提供者而导致某个调用令牌实际上根本不是有效令牌,请先调用 fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken,而不是在 IsAlternateFor 从不响应(并非真正与 sysmem 通信)时无限期地卡住。另一种方法是先使用此令牌调用 fuchsia.sysmem2/Allocator.BindSharedCollection,这样也会验证令牌并将其转换为 fuchsia.sysmem2/BufferCollection,然后调用 IsAlternateFor

目前,所有表字段均为必填字段。

  • 响应 is_alternate
    • true:调用节点与 node_ref Node 之间的第一个共同父节点是 BufferCollectionTokenGroup。这意味着,调用 Nodenode_ref Node 不会同时应用其两个约束条件,而 sysmem 只会选择其中一个约束条件,绝不会同时应用两者。这是因为在逻辑分配期间只选择 BufferCollectionTokenGroup 的一个子项,而该子项的子树对约束聚合有贡献。
    • false:调用 Nodenode_ref Node 之间的第一个共同父节点不是 BufferCollectionTokenGroup。目前,这意味着第一个共同的父节点是 BufferCollectionTokenBufferCollection(无论是否经过 Release)。这意味着,如果所涉及的任何父级 BufferCollectionTokenGroup 同时选择了这两个 Node,则调用 Nodenode_ref Node 可能会在逻辑分配的约束聚合期间应用它们的约束条件。在这种情况下,没有 BufferCollectionTokenGroup 会直接阻止选择两个 Node 及其约束条件进行汇总,但即使为 false,如果一个或两个 Node 具有直接或间接父 BufferCollectionTokenGroup,并且其选择除包含调用 Nodenode_ref Node 的子树之外的子子树,那么即使为 false,也可能忽略其中一个或两个 Node
  • 错误 [fuchsia.sysmem2/Error.NOT_FOUND] node_ref 与调用 Node 所关联的缓冲区集合未关联。出现此错误的另一个原因是,node_ref 是具有足够权限的 zx.Handle.EVENT 句柄,但实际上并不是从 GetNodeRef 获取的真实 node_ref
  • 错误 [fuchsia.sysmem2/Error.PROTOCOL_DEVIATION] 调用方传递的 node_ref 不是 zx.Handle:EVENT 句柄,或者在真实的 node_ref 上没有所需的权限。
  • 此调用不会返回其他失败的状态代码。不过,sysmem 将来可能会添加其他代码,以便客户端应对所有失败的状态代码进行合理的默认处理。

请求

名称类型
payload NodeIsAlternateForRequest

响应

名称类型
payload Node_IsAlternateFor_Result

发布

fuchsia.sysmem2/BufferCollectionToken 通道上:

通常,参与者会将 BufferCollectionToken 转换为 fuchsia.sysmem2/BufferCollection,但参与者可以通过令牌发送 Release(然后立即或稍后关闭该通道,以响应服务器关闭服务器端时),从而避免缓冲区收集失败。如果没有事先设置 Release,关闭 BufferCollectionToken 客户端会导致缓冲区收集失败。

fuchsia.sysmem2/BufferCollection 通道上:

默认情况下,服务器通过缓冲区收集失败来处理 fuchsia.sysmem2/BufferCollection 客户端端的意外关闭(没有先使用 Release)。部分原因在于在任何参与者失败时加快关闭 VMO 句柄以回收内存。如果参与者想要彻底关闭 BufferCollection,而不会导致缓冲区收集失败,则可以先发送 Release,然后再关闭 BufferCollection 客户端。Release 可以发生在 SetConstraints 之前或之后。如果位于 SetConstraints 之前,则缓冲区集合不需要此节点的约束条件即可分配。如果在 SetConstraints 之后,约束条件会保留并聚合,尽管在约束条件聚合时缺少 BufferCollection 连接。

fuchsia.sysmem2/BufferCollectionTokenGroup 通道上:

默认情况下,意外关闭 BufferCollectionTokenGroup 客户端(未先添加 Release)将触发缓冲区收集失败。如需关闭 BufferCollectionTokenGroup 通道而不让缓冲区收集失败,请确保已发送 AllChildrenPresent(),并在关闭 BufferCollectionTokenGroup 客户端之前发送 Release

如果 Release 发生在 [fuchsia.sysmem2/BufferCollectionTokenGroup.AllChildrenPresent], the buffer collection will fail (triggered by reception of Releasewithout priorAllChildrenPresent). This is intentionally not analogous to how <a class='link' href='../fuchsia.sysmem2/'>fuchsia.sysmem2</a>/<a class='link' href='../fuchsia.sysmem2/#BufferCollection.Release'>BufferCollection.Release</a> without <a class='link' href='../fuchsia.sysmem2/'>fuchsia.sysmem2</a>/<a class='link' href='../fuchsia.sysmem2/#BufferCollection.SetConstraints'>BufferCollection.SetConstraints</a> first doesn't cause buffer collection failure. For a BufferCollectionTokenGroup, clean close requires AllChildrenPresent(if not already sent), then Release` 之前,则关闭客户端。

如果 Release 发生在 AllChildrenPresent 之后,则子项及其所有约束条件均保持不变(就像 BufferCollectionTokenGroup 通道保持开启状态时的情况一样),并且客户端关闭不会触发缓冲区收集失败。

在所有 fuchsia.sysmem2/Node 通道(上述任一通道)上:

为简洁起见,上述基于通道协议的段落忽略了由 fuchsia.sysmem2/BufferCollectionToken.SetDispensablefuchsia.sysmem2/BufferCollection.AttachToken 创建的单独故障域。当客户端意外关闭(没有先添加 Release)且该客户端位于故障网域下时,故障网域不会使整个缓冲区收集失败,而是会失败,但缓冲区集合本身会与故障网域的故障隔离开来。此类故障网域可以嵌套,在这种情况下,只有 Node 所在的最内层故障网域会发生故障。

请求

<EMPTY>

SetDebugClientInfo

设置有关当前客户端的信息,sysmem 可以使用这些信息来帮助诊断泄漏内存以及等待参与者发送 fuchsia.sysmem2/BufferCollection.SetConstraints 的分配暂停问题。

这会在此 fuchsia.sysmem2/Node 以及派生自此 Node 的所有 Node 上设置调试客户端信息,除非被 fuchsia.sysmem2/Allocator.SetDebugClientInfo 或更新版本的 fuchsia.sysmem2/Node.SetDebugClientInfo 替换。

针对每个 Allocator 发送一次 fuchsia.sysmem2/Allocator.SetDebugClientInfo,是确保所有 fuchsia.sysmem2/Node 至少已设置一些调试客户端信息的最有效方式。此外,与通过 fuchsia.sysmem2/{6.sysm2/提供相同的调试客户端信息更加高效。Node.SetDebugClientInfofuchsia.sysmem2

此外,在启用详细日志记录功能的情况下,也会用于(请参阅 SetVerboseLogging)来指示哪个客户端首先关闭其通道,从而导致子树故障(如果子树的用途结束,这可能是正常的,但如果发生的时间早于预期,客户端渠道专用的名称有助于从 sysmem 的角度诊断故障首先来自何处)。

目前,所有表字段均为必填字段。

  • request name 它可以是任意字符串,但最好使用当前进程名称(请参阅 fsl::GetCurrentProcessName)。
  • 请求 id。它可以是任意 ID,但最好使用当前进程 ID(请参阅 fsl::GetCurrentProcessKoid)。

请求

名称类型
payload NodeSetDebugClientInfoRequest

SetDebugTimeoutLogDeadline

如果 sysmem 在创建新集合后的 5 秒内未从所有客户端看到 fuchsia.sysmem2/BufferCollection.SetConstraints,则 Sysmem 会记录一条警告。

客户端可以调用此方法在日志输出时进行更改。如果多个客户端设置了截止期限,则无法确定哪个截止期限将生效。

在大多数情况下,默认设置的效果很好。

目前,所有表字段均为必填字段。

  • request deadline:表示 sysmem 开始尝试记录警告的时间,除非届时所有限制条件都已使用 sysmem。

请求

名称类型
payload NodeSetDebugTimeoutLogDeadlineRequest

SetName

设置此缓冲区集合中的 VMO 的名称。

如果名称在 ZX_MAX_NAME_LEN 中不适合,vmo 本身的名称将被截断以适应这一要求。vmo 的名称以集合中的缓冲区索引作为后缀(如果后缀符合 ZX_MAX_NAME_LEN)。此处指定的名称(不截断)将在检查数据中列出。

该名称只会影响在设置名称后分配的 VMO;此调用不会重命名现有的 VMO。如果多个客户端设置了不同的名称,则优先级值越大,优先级越高。设置与之前的名称具有相同优先级的新名称不会更改名称。

目前,所有表字段均为必填字段。

  • 请求 priority 仅当这是第一个 SetNamepriority 大于此缓冲区集合的所有 Node 之前 SetName 调用中的任何先前 priority 值时,才会设置名称。
  • 请求 name:在此缓冲区集合下创建的 VMO 的名称。

请求

名称类型
payload NodeSetNameRequest

SetVerboseLogging

这样可以为缓冲区收集启用详细日志记录功能。

详细日志记录包括通过每个客户端通过 fuchsia.sysmem2/BufferCollection.SetConstraints 设置的约束,以及通过 fuchsia.sysmem2/Node.SetDebugClientInfo(或 fuchsia.sysmem2/Allocator.SetDebugClientInfo)设置的信息,以及 {12 theNode

通常,当聚合失败时,sysmem 仅输出一行投诉,并且仅显示聚合失败的具体详细原因,并且没有太多上下文。虽然这通常足以诊断出问题:如果仅进行了细微更改,并且所有功能在进行细微更改之前都正常运行,则对于首次获取新的缓冲区集合来说,这通常不是特别有帮助。尤其是对于更复杂的节点树,涉及 fuchsia.sysmem2/BufferCollection.AttachTokenfuchsia.sysmem2/BufferCollectionToken.SetDispensablefuchsia.sysmem2/BufferCollectionTokenGroup 等节点的子树分配失败的原因,以及可能的节点子树中的关联子树失败的原因;

额外日志记录的目的在于,从性能的角度来看,这是可以接受的,假设只对少量缓冲区集合启用详细日志记录。如果我们没有跟踪某个 bug,就不应发送此消息。

请求

<EMPTY>

SetWeak

将当前的 fuchsia.sysmem2/Node 和在此消息之后创建的所有子 Node 设置为弱,这意味着客户端的 Node 客户端(或在此消息后创建的子节点)并不足以使已分配的 VMO 保持活跃状态。

从弱 Node 获取的所有 VMO 都是弱系统 VMO。另请参阅 close_weak_asap

只有在 Node 准备好进行分配之前,才允许显示此消息(否则服务器会使用 ZX_ERR_BAD_STATE 关闭通道):

  • BufferCollectionToken:时间不限
  • BufferCollectionSetConstraints 之前
  • BufferCollectionTokenGroupAllChildrenPresent 之前

目前,系统未提供从强 Node 到弱 Node 的转换,但客户端可以在分配前创建一个额外的 Node,并将该额外的 Node 设置为弱 Node,然后在稍后的某个时间点发送 Release 并关闭客户端强 Node 的客户端端,但保留客户端的弱 Node

Node 数和强 VMO 句柄为零会导致缓冲区收集失败(所有 Node 客户端都会看到 ZX_CHANNEL_PEER_CLOSED,所有 close_weak_asap client_end 会看到 ZX_EVENTPAIR_PEER_CLOSED),但系统(有意)不会注意到这种情况,直到所有 Node 都准备好进行分配为止。要使初始分配成功,在分配时至少需要存在一个强 Node,但在该客户端收到 VMO 句柄后,该客户端可以执行 BufferCollection.Release 操作并关闭客户端,而不会导致此类失败。

这也隐含 fuchsia.sysmem2/Node.SetWeakOk,但不隐含 for_children_also 为 true 的 SetWeakOk(可根据情况单独发送)。

请求

<EMPTY>

SetWeakOk

这向 sysmem 表明,客户端已准备好关注 close_weak_asap

如果发送此消息,则此消息必须在 fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated 之前发送。

使用弱 fuchsia.sysmem2/BufferCollection 的所有参与者必须在 WaitForAllBuffersAllocated 之前发送此消息,否则父级 Node 必须发送 fuchsia.sysmem2/Node.SetWeakOkfor_child_nodes_also 为 true,否则 WaitForAllBuffersAllocated 将触发缓冲区收集失败。

这条消息很有必要,因为系统显然较弱的 VMO 并非一直存在,因此较旧的客户端不知道需要关注 close_weak_asap ZX_EVENTPAIR_PEER_CLOSED,并尽快关闭所有剩余系统内存弱 VMO 句柄。通过收到此消息并要求参与者表明其接受整个协议的这一方面,我们可避免以下情况:较旧客户端传递了较弱的 VMO,而 sysmem 无法使该 VMO 稍后(并基于每个缓冲区)快速关闭。

不处理 close_weak_asap 且未通过 WaitForAllBuffersAllocated 检索任何 VMO 句柄的参与者不需要发送 SetWeakOk(也不需要让父级 Node 发送 for_child_nodes_also 为 true 的 SetWeakOk)。但是,如果同一参与者有一个可以检索 VMO 的子节点/委托,该子节点/委托需要在 WaitForAllBuffersAllocated 之前发送 SetWeakOk

  • 请求 for_child_nodes_also 如果存在且值为 true,这意味着在此消息之后创建的此节点的直接子节点以及这些节点的所有后代都将表现得就像在这些节点上发送了 SetWeakOk 一样。在此节点之前创建的任何子节点不包括在内。此设置是“粘性的”,因为后面的 SetWeakOk 如果未将此布尔值设为 true,则不会重置服务器端布尔值。如果这给参与者带来了问题,解决方法是视情况在子令牌上改用 SetWeakOk 并将 for_child_nodes_also 设为 true。仅当参与者确实能够承诺对其自身的弱 VMO 句柄以及持有相应子级 Node 的参与者持有的所有弱 VMO 句柄时都遵守 close_weak_asap,才应将 for_child_nodes_also 设为 true。设置 for_child_nodes_also 后,使用 sysmem(1) 的后代 Node 的性能可能较弱,尽管这些 sysmem1 Node 的客户端无法直接访问 SetWeakOk 或无法通过任何直接方式找到 close_weak_asap。这仅适用于此 Node 使用 sysmem(1) 的后代,而不是在直接从 sysmem2 令牌转换为 sysmem(1) 令牌时转换为此 Node,因为除非此 Node 的祖先将 for_child_nodes_also 指定为 true,否则分配将失败。

请求

名称类型
payload NodeSetWeakOkRequest

同步

确保已在服务器端收到之前的消息。这在之前创建了新令牌的消息之后特别有用,因为在将令牌发送给其他参与者之前,sysmem 服务器必须知道令牌。

对无效令牌调用 fuchsia.sysmem2/BufferCollectionToken.Sync 可能会导致 Sync 永久停止。如需降低因一次往返而降低恶意/虚假 fuchsia.sysmem2/BufferCollectionToken 的可能性,请参阅 fuchsia.sysmem2/Allocator.ValidateBufferCollectionToken。另一种方法是将令牌传递给 fuchsia.sysmem2/Allocator/BindSharedCollection,后者还会在将令牌交换为 fuchsia.sysmem2/BufferCollection 通道时对令牌进行验证,然后就可以使用 fuchsia.sysmem2/BufferCollection.Sync

在创建一个或多个 fuchsia.sysmem2/BufferCollectionToken,然后开始并完成 Sync 后,就可以安全地将 BufferCollectionToken 客户端结束发送给其他参与者,而当其他参与者通过 fuchsia.sysmem2/Allocator.BindSharedCollection这是一种创建令牌的高效方法,可避免不必要的往返。

其他选项包括等待每个 fuchsia.sysmem2/BufferCollectionToken.Duplicate 分别完成(在每个 fuchsia.sysmem2 单独调用 Sync 之后进行调用),或者在通过 fuchsia.sysmem2/Allocator.BindSharedCollectionfuchsia.sysmem2BufferCollectionToken.DuplicateSync

请求

<EMPTY>

响应

名称类型
payload Node_Sync_Result

结构

BufferCollection_CheckAllBuffersAllocated_Response

fuchsia.sysmem2/collection.fidl 中定义

<EMPTY>

Node_Sync_Response

fuchsia.sysmem2/collection.fidl 中定义

<EMPTY>

PixelFormatAndModifier

fuchsia.sysmem2/constraints.fidl 中定义

字段类型说明默认
pixel_format fuchsia.images2/PixelFormat

如果参与者在发送至 sysmem 的消息中指定,则此值可以是参与者可以接受的任何 PixelFormat 值。不允许指定 kInvalid

如果参与者需要在不限制 pixel_format 的情况下指定 ImageFormatConstraints,则参与者可以指定 fuchsia.images2/PixelFormat.DO_NOT_CARE

无默认取景方式
pixel_format_modifier fuchsia.images2/PixelFormatModifier

特定修饰符(不只是标志)或 FORMAT_MODIFIER_DO_NOT_CARE,来自在 fuchsia.images2 format_modifier.fidl 中定义的一组值。

无默认取景方式

枚举

CoherencyDomain 灵活

类型:uint32

fuchsia.sysmem2/constraints.fidl 中定义

INACCESSIBLE 仅适用于 CPU 无法访问缓冲区的情况。

无法从 CPU 访问的设备本地内存为 CoherencyDomain INACCESSIBLE,即使可能会使设备(物理或虚拟设备)将数据从 INACCESSIBLE 缓冲区复制到对 CPU 可见的缓冲区也是如此。换句话说,INACCESSIBLE 并不意味着安全,但安全则意味着“无法访问”。

CPU 意味着生产方必须确保使用方能够使用 CPU 读取生成的数据,而使用方无需执行提供方尚未(根据需要)执行的额外缓存操作。

RAM 意味着生产方必须确保生成的数据完全存在于 RAM 中,且不包含任何脏 CPU 缓存行,并且消耗方必须在使用 CPU 读取数据之前使 CPU 缓存失效(通常是刷新和失效)。当所有访问都通过硬件 DMA 进行时,RAM 域可能比 CPU 域更快,因为在这种情况下不需要 CPU 缓存操作,因为实际上没有参与者使用 CPU 读取/写入。

添加数量:19

名称说明
0
1
2

错误:柔性环境

类型:uint32

fuchsia.sysmem2/error.fidl 中定义

无论错误代码是哪个,客户端重试的次数(如果有)都应该非常有限。

Error 值不应存储在 zx_status_t 中,因为 zx_status_t 中的正值已弃用。

添加数量:19

名称说明
0

这在此错误枚举中不是有效的错误值。服务器绝不会将此值作为失败代码发送。此值不被视为“成功”。在某些语言中,本地默认初始化的 Error 实例将具有此值,直到使用有效的正错误代码对其进行初始化。

1

未指明的错误。

如果没有其他错误代码适用,则使用此错误代码,并且错误可能不是由通过传递此错误的渠道发送到服务器的消息导致的。

此错误应作为一般错误由客户端处理。

例如,当其他客户端渠道从客户端意外关闭(没有先发送 fuchsia.sysmem2/Node.Release)时,就会出现此错误,从而导致同一树或子树中的任何节点发生故障。在此用法中,主要问题不是接收客户端的“故障”,因为接收客户端可能没有办法对错误执行更具体的操作,至少不能直接进行处理。

再举一个例子,如果正常预期会成功的系统调用意外失败,并且没有明确的原因“归咎于”客户端,则可以使用此错误。

客户端绝不应要求 / 依赖某个错误原因而导致继续导致 UNSPECIFIED,因为任何特定错误原因都可能会导致将来出现更具体的错误代码。

2

某个必填字段未设置,或者指定值无效。如需了解详情,请参阅日志。

如果以错误顺序或从客户端接收消息的方式与协议规则不一致,也使用此方法。

3

未找到客户端指定的对象或 ID。

4

对象句柄权限不足,无法执行该请求。

5

由于缺少可用内存,无法满足分配要求。

内存耗尽可能特定于在约束汇总期间选择的堆,因此在某些情况下,即使正常系统 RAM 并不耗尽,也可能会发生此错误,具体取决于已配置和选定的堆。

6

请求有效,但无法满足,可能是由于硬件限制。如果参与此分配的各个参与者具有不兼容的约束条件(大致上讲,交集为空),就会发生这种情况。如需了解详情,请参阅日志。如果参与者可能被视为可选项,请参阅 BufferCollectionTokenGroup

如果现有集合中没有足够的缓冲区来满足使用 fuchsia.sysmem2/BufferCollection.AttachToken 创建的附加令牌(包括派生令牌的子树),也可能会发生这种情况。

如果客户端的节点位于某个组下,但选择了其他组的子节点,也可能会发生这种情况。

7

尚未尝试分配。调用 fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated,它可能会阻塞。

8

存在并被考虑的 BufferCollectionTokenGroup 子令牌选择组合过多,导致 sysmem 放弃分配,而非枚举其余组合。

AllocatorAllocateNonSharedCollectionRequest 资源

fuchsia.sysmem2/allocator.fidl 中定义

序数字段类型说明
collection_request server_end<BufferCollection>

AllocatorAllocateSharedCollectionRequest 资源

fuchsia.sysmem2/allocator.fidl 中定义

序数字段类型说明
token_request server_end<BufferCollectionToken>

AllocatorBindSharedCollectionRequest 资源

fuchsia.sysmem2/allocator.fidl 中定义

序数字段类型说明
token BufferCollectionToken
buffer_collection_request server_end<BufferCollection>

AllocatorGetVmoInfoRequest 资源

fuchsia.sysmem2/allocator.fidl 中定义

序数字段类型说明
vmo handle<vmo>

需要设置 vmo;所有权会转移给服务器,因此在大多数情况下,客户端将复制标识名并通过此字段转移重复的标识。

AllocatorSetDebugClientInfoRequest

fuchsia.sysmem2/allocator.fidl 中定义

序数字段类型说明
name string[256]
id uint64

AllocatorValidateBufferCollectionTokenRequest

fuchsia.sysmem2/allocator.fidl 中定义

序数字段类型说明
token_server_koid zx/Koid

Allocator_GetVmoInfo_Response 资源

fuchsia.sysmem2/allocator.fidl 中定义

序数字段类型说明
buffer_collection_id uint64
buffer_index uint64
close_weak_asap handle<eventpair>

Allocator_ValidateBufferCollectionToken_Response

fuchsia.sysmem2/allocator.fidl 中定义

序数字段类型说明
is_known bool

BufferCollectionAttachLifetimeTrackingRequest 资源

fuchsia.sysmem2/collection.fidl 中定义

序数字段类型说明
server_end handle<eventpair>
buffers_remaining uint32

BufferCollectionAttachTokenRequest 资源

fuchsia.sysmem2/collection.fidl 中定义

序数字段类型说明
rights_attenuation_mask zx/Rights
token_request server_end<BufferCollectionToken>

BufferCollectionConstraints

fuchsia.sysmem2/constraints.fidl 中定义

对分配的缓冲区的限制,以及(可选)对存储在缓冲区中的图片的限制。您可以为每个参与者指定这些限制。Sysmem 服务实现了来自多个参与者的约束汇总。

添加数量:19

序数字段类型说明
usage BufferUsage

usage 会提示系统内存在存在多个兼容选项时可能帮助选择更优化的 fuchsia.images2/PixelFormat 和/或 pixel_format_modifier

聚合 fuchsia.sysmem2/BufferCollectionConstraints 时,这些值按位或运算。

必须至少指定一个 usage 位(不过,fuchsia.sysmem2/BufferCollection.SetConstraints 请求可以不设置请求 constraints 字段,在这种情况下,kNoneUsage 是默认值,并且参与者没有施加任何约束。

如果指定 kNoneUsage,它必须是唯一的设置位,并且在响应 fuchsia.sysmem2/BufferCollection.WaitForAllBuffersAllocated时,不会发送任何 VMO。

min_buffer_count_for_camping uint32

每个参与者可以同时保留的缓冲区(暂时不止一个临时持续时间)同时保留。在这种情况下,“暂时”时长是指完成运行少量非阻塞代码(完成缓冲区所有权转移)所需的时间。从存储空间读取数据、等待尚未完成的硬件或执行帧编码或解码等操作的操作都不属于瞬时时长,即使有时可能会快速完成也是如此。

例如,视频解码器会指定(至少)最大参考帧数量 + 当前被解码的帧的最大数量。但对于以异步方式快速运行以传送之前解码的帧的代码而言,就不是 1 个。即使该帧可能会在与下一帧解码的同时获得一个瞬时时长,也是如此。

参与者驻留的缓冲区不得超出此处指定的缓冲区(临时时长除外),否则处理可能会卡住。

聚合 BufferCollectionConstraints 时,这些值会相加。

在测试场景中,如果驻留在超过此值的缓冲区中任何较长的时长(在这种情况下,一个屏幕刷新周期即是“很长时间”),则可能会(理想情况下)被标记为失败。在测试场景中,为参与者同时提供的缓冲区不得多于此数量。

min_buffer_count_for_dedicated_slack uint32

每个参与者因 Slack 而需要的最小缓冲区数,以实现更好的处理重叠 / 更高的性能。

汇总 BufferCollectionConstraints 时,这些值会相加。

参与者通常应在此处指定 0 或 1。如果 min_buffer_count_for_camping 已经足以让参与者有点落后时 100% 的时间都处于忙碌状态,那么通常应该指定 0 或 1;如果因最短露营原因而需要的缓冲量超过严格需要的 1 大,则 1 是合适的,这可以留出足够的空闲时间来 100% 的时间保持忙碌(如果时间略有落后时,则 1 可以)。

在测试场景中,系统可能会强制将此字段设为 0,并且所有参与者都应继续工作而不会卡住。如果出于前向进度的原因而需要使用缓冲区,则应在 min_buffer_count_for_camping 中考虑该缓冲区。

min_buffer_count_for_shared_slack uint32

min_buffer_count_for_dedicated_slack 类似,不同之处在于汇总这些值时(而不是添加最大值)。此处的值未与任何参与者的 min_buffer_count_for_dedicated_slack 共享。

如果参与者希望确保总体有一定的空闲时间,但不需要专门留出一定的空闲时间,则可以在此处指定大于 0 的值。

使用 min_buffer_count_for_dedicated_slack 和/或 min_buffer_count_for_shared_slack 的选择通常取决于额外的 Slack 值对性能的提升程度。

在测试场景中,系统可能会强制将此字段设为 0,并且所有参与者都应继续工作而不会卡住。如果出于前向进度的原因而需要使用缓冲区,则应在 min_buffer_count_for_camping 中考虑该缓冲区。

min_buffer_count uint32

遗憾的是,如果您特别挑剔,可能需要一个小范围的 buffer_count,甚至是特定的 buffer_count。除非参与者确实必须设置此字段以限制整个 BufferCollectionInfo.buffer_count,否则此字段应保持为 0。任何此类参与者仍应视情况填写 min_buffer_count_for_* 字段。

如果此字段未设置,则逻辑 min_buffer_count 为 0。

max_buffer_count uint32

遗憾的是,如果您特别挑剔,可能需要一个小范围的 buffer_count,甚至是特定的 buffer_count。除非参与者确实必须设置此字段以限制整个 BufferCollectionInfo.buffer_count,否则此字段应保持为 0。任何此类参与者都应填写 min_buffer_count_for_* 字段。

如果此字段未设置,则逻辑 max_buffer_count 为 0xFFFFFFFF。

buffer_memory_constraints BufferMemoryConstraints

针对 BufferCollectionSettings.buffer_settings 的可选约束条件。

打算设置 image_format_constraints 的参与者通常会通过 image_format_constraints 隐式指定最小缓冲区大小,并且可能通过 buffer_memory_constraints 仅指定最大缓冲区大小。

如果未设置,则客户端会指定“随意”有关任何缓冲区内存限制。

image_format_constraints vector<ImageFormatConstraints>[64]

对存储在集合缓冲区中的图片的图片格式参数的可选限制。其中包括 fuchsia.images2/PixelFormatpixel_format_modifier(用于平铺等)。您可以为每个 pixel_format pixel_format_modifier 对单独指定这些约束条件。不允许重复的 pixel_format pixel_format_modifier 对。

聚合时,仅保留由所有具有非零 image_format_constraints 大小(以及非 null)BufferCollectionConstraints 的参与者指定的 pixel_format pixel_format_modifier 对。

参与者可以指定 pixel_format fuchsia.images2/PixelFormat.DO_NOT_CARE 和/或 pixel_format_modifier fuchsia.images2/FORMAT_MODIFIER_DO_NOT_CARE,以允许选择任何值,但必须至少有一位参与者指定特定格式,才能成功执行整体分配。

在 SetConstraints 消息中,未设置或长度为零意味着没有图片格式限制;如果没有其他参与者指定任何 image_format_constraints 条目,则可以分配原始缓冲区。

BufferCollectionInfo 资源

fuchsia.sysmem2/results.fidl 中定义

有关缓冲区集合及其缓冲区的信息。

添加数量:19

序数字段类型说明
settings SingleBufferSettings

这些设置适用于初始缓冲区分配中的所有缓冲区。

此字段将始终由 sysmem 设置。

buffers vector<VmoBuffer>[128]

VMO 处理集合中的每个缓冲区(以及 vmo_usable_start 偏移)。

该矢量的大小是 buffer_count(buffer_count 不会单独发送)。

所有缓冲区 VMO 句柄的大小和访问权限都相同。大小位于 settings.buffer_settings.size_bytes 中。

VMO 访问权限是根据客户端在分配缓冲区集合时指定的使用情况来确定的。例如,表示只读使用情况的客户端将收到没有写入权限的 VMO。此外,在调用 BufferCollectionToken.Duplicate() 时,该权限还可以被相关参数减弱。

此字段中始终包含 VmoBuffer,即使参与者指定了使用情况,而不需要 VMO 句柄。这样一来,如果对参与者有任何用途,此类参与者就可以知道 vmo_usable_start 值。

此字段将始终由 sysmem 设置,即使参与者未指定任何缓冲区使用情况(但在这种情况下不会设置此字段中的 fuchsia.sysmem2/VmoBuffer.vmo 子字段),也是如此。

buffer_collection_id uint64

此数字在每次启动时的所有逻辑缓冲区集合中都是唯一的。

对于与同一逻辑缓冲区集合(从使用 fuchsia.sysmem2.Allocator.CreateSharedCollection 或 CreateNonSharedCollection 创建的同一根令牌派生)关联的所有 BufferCollectionToken(s)、BufferCollection(s) 和 BufferCollectionTokenGroup(s) 的此 ID 编号都将相同。

可以使用 GetBufferCollectionId 从 BufferCollectionToken、BufferCollection 或 BufferCollectionTokenGroup 检索相同的 ID(以往返 sysmem 为成本)。

此字段将始终由 sysmem 设置。

BufferCollectionSetConstraintsRequest 资源

fuchsia.sysmem2/collection.fidl 中定义

序数字段类型说明
constraints BufferCollectionConstraints

BufferCollectionTokenCreateBufferCollectionTokenGroupRequest 资源

fuchsia.sysmem2/collection.fidl 中定义

序数字段类型说明
group_request server_end<BufferCollectionTokenGroup>

BufferCollectionTokenDuplicateRequest 资源

fuchsia.sysmem2/collection.fidl 中定义

序数字段类型说明
rights_attenuation_mask zx/Rights
token_request server_end<BufferCollectionToken>

BufferCollectionTokenDuplicateSyncRequest

fuchsia.sysmem2/collection.fidl 中定义

序数字段类型说明
rights_attenuation_masks vector<zx/Rights>[64]

BufferCollectionTokenGroupCreateChildRequest 资源

fuchsia.sysmem2/collection.fidl 中定义

序数字段类型说明
token_request server_end<BufferCollectionToken>

必须设置。

rights_attenuation_mask zx/Rights

如果未设置,则默认值为 ZX_RIGHT_SAME_RIGHTS

BufferCollectionTokenGroupCreateChildrenSyncRequest

fuchsia.sysmem2/collection.fidl 中定义

序数字段类型说明
rights_attenuation_masks vector<zx/Rights>[64]

BufferCollectionTokenGroup_CreateChildrenSync_Response 资源

fuchsia.sysmem2/collection.fidl 中定义

序数字段类型说明
tokens vector<BufferCollectionToken>[64]

BufferCollectionToken_DuplicateSync_Response 资源

fuchsia.sysmem2/collection.fidl 中定义

序数字段类型说明
tokens vector<BufferCollectionToken>[64]

BufferCollection_WaitForAllBuffersAl 培训响应资源

fuchsia.sysmem2/collection.fidl 中定义

序数字段类型说明
buffer_collection_info BufferCollectionInfo

BufferMemoryConstraints

fuchsia.sysmem2/constraints.fidl 中定义

添加数量:19

序数字段类型说明
min_size_bytes uint64

未设置时被视为 1

max_size_bytes uint64

未设置时被视为 0xFFFFFFFFFFFFFFFFFF。

physically_contiguous_required bool

如果为 false,缓冲区 VMO 的物理页面可能是非连续的。如果为 true,缓冲区 VMO 的物理页面必须是顺序连续的。不需要物理连续 VMO 的客户端仍必须接受物理连续 VMO 或“物理”VMO。

secure_required bool

如果为 true,则参与者需要安全内存。

聚合 BufferCollectionConstraints 时,这些值为布尔值或。

cpu_domain_supported bool

如果为 true(或 BufferMemoryConstraints 不存在),则参与者同意系统选择 CPU 域。

如果选择了 CPU 域,参与者必须确保 CPU 可以在参与者之外无需执行缓存操作即可对缓冲区执行读写操作。

ram_domain_supported bool

如果为 true,则参与者同意 sysmem 选择 RAM 域。

如果选择了 RAM 域,生产者数据必须在 RAM 中可用(具有 CPU 缓存状态,以确保 RAM 数据不会因脏 CPU 缓存行向 RAM 写入错误数据而损坏),并且使用 CPU 执行读取操作的使用者必须在读取前使 CPU 缓存失效(生产者不保证过时的“干净”缓存行)

inaccessible_domain_supported bool

如果为 true,则参与者同意 sysmem 选择无法访问的网域。

如果选择了 INACCESSIBLE 网域,系统将阻止 CPU 对该数据的读写。尝试使用 CPU 读取/写入数据可能会导致 UB 和/或进程终止。

如果选择了 INACCESSIBLE 网域,参与者只能使用由硬件执行的 DMA 或针对安全环境的与平台特定 DMA 类似的请求,对数据执行操作。

安全堆仅支持 INACCESSIBLE 域,如果 BufferUsage 以外的任何参与者(NONE_USAGE 除外)未将 inaccessibility_domain_supported 设置为 true,则分配将失败。

permitted_heaps vector<Heap>[64]

参与者可以接受哪些堆。不关心分配哪个堆内存的参与者应将此字段保留为未设置状态。仅当所有参与者通过 heap_permitted 或指定 NONE_USAGE 明确表示安全堆可接受时,才会选择安全堆。

BufferMemorySettings

fuchsia.sysmem2/results.fidl 中定义

这些是缓冲区集合所有缓冲区的内存相关设置。

添加数量:19

序数字段类型说明
size_bytes uint64

此字段将始终由 sysmem 设置。

is_physically_contiguous bool

此字段将始终由 sysmem 设置。

is_secure bool

此字段将始终由 sysmem 设置。

coherency_domain CoherencyDomain

此字段将始终由 sysmem 设置。

heap Heap

从中分配缓冲区的特定堆。

此字段将始终由 sysmem 设置。

BufferUsage

fuchsia.sysmem2/usages.fidl 中定义

描述客户端将如何访问缓冲区的内容。

添加数量:19

序数字段类型说明
none uint32

如果客户端设置了此字段,则客户端不应在同一表实例中设置任何其他字段。此字段中唯一有效的位是 NONE_USAGE;如果设置了此字段,则必须设置该位。此字段和此字段中设置的位的要点在于,从本质上证明客户端不会使用缓冲区,因此不需要任何 VMO(不只是无法填写表格)。

cpu uint32

如果设置了此字段,则包含 CPU 使用率位。请参阅 usages.fidl 中的 CPU_USAGE_* 标志。

vulkan uint32

如果设置了此字段,则会保留 Vulkan 用法位。请参阅 usages.fidl 中的 VULKAN_IMAGE_*VULKAN_BUFFER_* 位。VULKAN_USAGE_* 位定义/名称已废弃。

display uint32

如果设置了此字段,则会保留显示使用位。请参阅 usages.fidl 中的 DISPLAY_USAGE_* 位。

video uint32

如果设置了此字段,则包含视频使用位。请参阅 usages.fidl 中的 VIDEO_USAGE_* 位。

fuchsia.sysmem2/constraints.fidl 中定义

对堆实例的引用。

一个给定的堆实例可以有多个可用于引用堆实例的 Heap。在不知道这些 Heap 别名的情况下比较 Heap 表并不能可靠地确定两个 Heap 表是否引用同一堆(匹配表示是,但不匹配表示可能)。允许堆别名可以更轻松地重命名 Heap.type

添加数量:19

序数字段类型说明
heap_type string[128]

堆的类型,使用根据 fuchsia.sysmem.heap.bind 文件中的注释中所述的架构和机制定义的绑定字符串指定。

例如:

  • "fuchsia.sysmem.heap.HEAP_TYPE.SYSTEM_RAM"
  • "fuchsia.goldfish.platform.sysmem.heap.HEAP_TYPE.HOST_VISIBLE"
id uint64

堆的 uint64 ID。仅需对每个(类型、启动)元组具有唯一性。换言之,给定的堆 ID 仅在机器的当前启动中(而非在两次启动之间)有意义,且仅在 Heap.type 内有意义。

对于引用单例堆的 Heap.type,在 fuchsia.sysmem2.BufferMemoryConstraints.permitted_heaps 中指定单例堆的参与者可不设置此字段或将其设置为零。Sysmem 将始终为 fuchsia.sysmem2.BufferMemmorySettings.heap 中指示的堆填充此字段(对于单例堆,id 字段将由 sysmem 设为 0)。

ImageFormatConstraints

fuchsia.sysmem2/constraints.fidl 中定义

描述缓冲区中图片数据布局的约束条件。

序数字段类型说明
pixel_format fuchsia.images2/PixelFormat

应用以下约束条件的 fuchsia.images2/PixelFormat

服务器会将 pixel_formatpixel_format_modifier 字段视为一个额外的 pixel_format_and_modifiers 条目。

一个参与者可以有多个受支持的 fuchsia.sysmem2/PixelFormatAndModifier

  • 如果不同 PixelFormatAndModifier 的图片约束条件相同,参与者可以在 pixel_format_and_modifiers 字段中列出其他应用约束条件的 PixelFormatAndModifier。这样可以减少需要在不改变含义的情况下发送的 ImageFormatConstraints 总数(例如,发送一系列仅在 pixel_formatpixel_format_modifier 上存在差异的单独 ImageFormatConstraints,它们总体上会指定相同的 PixelFormatAndModifier 列表)。
  • 如果不同 PixelFormatAndModifier 的图片限制不同,参与者可以针对具有不同图片限制的每组 PixelFormatAndModifierimage_format_constraints 中使用单独的 ImageFormatConstraints 条目来传达这一点。
  • 参与者可以有两个 image_format_constraints 条目,但这些条目的像素格式和修饰符不同,但这并不是表示这种情况的最紧凑方式,因为可以通过在单个 ImageFormatConstraints 中指定两个 PixelFormatAndModifier 来组合两个条目。

ImageFormatConstraints 的其他字段因 pixel_formatpixel_format_modifier 而异的情况并不罕见,例如,线性格式支持的大小上限小于平铺格式。

另请参阅 fuchsia.sysmem2/ImageFormatConstraints.pixel_format_and_modifiers

除非 pixel_format_and_modifiers 不为空,否则该字段必须设置为 fuchsia.images2/PixelFormat.INVALID 以外的值。换言之,每个 ImageFormatConstraints 必须至少有一个 PixelFormatAndModifier。如果设置了 pixel_format_modifier,还必须设置此字段。

如果参与者需要在不限制 pixel_format 的情况下指定 ImageFormatConstraints,则参与者可以指定 fuchsia.images2/PixelFormat.DO_NOT_CARE

pixel_format_modifier fuchsia.images2/PixelFormatModifier

应用以下约束的像素格式修饰符。

服务器会将 pixel_formatpixel_format_modifier 字段视为一个额外的 pixel_format_and_modifiers 条目。

这是 fuchsia.images2 format_modifier.fidl 中的值,与 pixel_format 结合使用时,参与者可以接受该值。

另请参阅 pixel_format_and_modifiers

如果设置了 pixel_format 但未设置 pixel_format_modifier,则默认值取决于其他字段:

  • 如果 pixel_formatDO_NOT_CARE,则像素格式修饰符隐式为 FORMAT_MODIFIER_DO_NOT_CARE
  • 否则,如果 BufferCollectionConstraints.usage 不是 NONE,则像素格式修饰符隐式为 FORMAT_MODIFIER_LINEAR
  • 否则像素格式修饰符隐式为 FORMAT_MODIFIER_DO_NOT_CARE

设置后,此值是 fuchsia.images2 format_modifier.fidl 中定义的一组值中的特定修饰符(不只是标志)或 FORMAT_MODIFIER_DO_NOT_CARE

color_spaces vector<fuchsia.images2/ColorSpace>[32]

Empty 表示错误。存在重复条目会导致错误。任意排序不是错误。

客户端可以指定单个条目 [fuchsia.sysmem2/ColorSpace.DO_NOT_CARE] if the client doesn't want to constrain which ColorSpaceis chosen. At least one participant must specify at least oneColorSpacevalue other than ColorSpace.DO_NOT_CARE`,否则分配将失败。

min_size fuchsia.math/SizeU

允许的最小尺寸(以像素为单位)。

例如,视频解码器参与者可以将此字段设置为数据流可能指定的最小大小。相反,required_min_size 会设置为数据流指定的当前大小。min_size 通过获取最大值进行汇总,而 required_min_size 通过获取最小值进行聚合。

发送到 sysmem 时,如果参与者已准备好处理可能仅受 pixel_formatpixel_format_modifier 隐式施加的约束的最小可能非零图像布局,则此字段可以取消设置。或者,此字段可以设置为参与者可以处理的实际最小尺寸。

提供方应设置 min_size,并将宽度和高度均设置为提供方可能生成的实际非零最小宽度和高度。例如,视频解码器可以在此处设置单个宏块的大小。

从 sysmem 接收数据时,此字段将始终设置,且宽度和高度均不为 0,因为至少有一个参与者必须指定非零的最小大小(其中宽度和高度均不为零)。

另请参阅 required_min_size

max_size fuchsia.math/SizeU

大小上限(以像素为单位)。例如,Scene 可以将此字段(直接或通过子参与者)设置为可合成的最大大小。

如果发送到 sysmem,则未设置将被视为 0xFFFFFFFF、0xFFFFFFFF。

从 sysmem 接收时,将始终设置此字段。对于宽度值和高度值,如果没有强制设置最大值,该子字段将为 0xFFFFFFFF。

另请参阅 required_max_size

min_bytes_per_row uint32

每行的字节数下限,包括一行中最后一张图片数据以外的任何填充。

这有时称为“步长(以字节为单位)”或“行到行的偏移量”。对于单平面格式,这是指每行像素的字节数。对于多平面格式,这是指平面 0 中每行样本的字节数(例如,如果是多平面 YUV 格式,则为每行亮度样本的字节数)。对于多平面格式,平面 0 以外的平面中的每行字节数因格式而异,但与每行平面 0 字节始终有特定关系。

向 sysmem 发送 ImageFormatConstraints 时,可以选择设置此字段。建议不要设置此字段,除非参与者需要强制 bytes_per_row 大于 min_size.widthpixel_format 加上 pixel_format_modifier(另请参阅 ImageFormatStrideBytesPerWidthPixel)和 bytes_per_row_divisor 所隐含的最小值。

从 sysmem 收到此结构时,此字段将始终被设置(当父结构存在时),并且始终至少是 min_size.widthpixel_format 加上 pixel_format_modifier 的“每宽度像素的步长字节数”所隐含的值。bytes_per_row_divisor

一些提供方参与者可能更愿意简单地将 ImageFormat.bytes_per_row 设置为 ImageFormatConstraints.min_bytes_per_row,因为 sysmem 可确保 min_bytes_per_row 与宽度为 min_size.width 的图片兼容。不过,需要 size.width > min_size.width 的提供方参与者可以从 ImageFormatMinimumRowBytes(在 C++ 中)获取相应的 min_bytes_per_row,也可以直接计算 bytes_per_row

max_bytes_per_row uint32

每行的最大字节数,包括一行中最后一张图片数据以外的任何填充。

发送到 sysmem 时,必须大于等于 max_size.width、“每宽度像素的步长字节数”和 bytes_per_row_divisor,否则约束汇总将失败。如果未设置,则表示参与者不需要/不想设置严格的上限。

如果发送到 sysmem,如果未设置,将被视为 0xFFFFFFFF。

从 sysmem 接收时,将始终设置此字段。如果最大值实际上是无穷大的,则值将为 0xFFFFFFFF(非零)。

max_width_times_height uint64

最大像素数。

图片大小上限(以像素为单位)可通过 fuchsia.sysmem/BufferMemoryConstraints.max_size_bytes 和生成的 fuchsia.sysmem/BufferSettings.size_bytes 间接限制,也可以直接通过此字段强制执行。

与分别限制宽度和高度的 fuchsia.sysmem2/ImageFormatConstraints.max_size 字段相比,此字段会限制像素总数。

fuchsia.sysmem/BufferMemoryConstraints.max_size_bytes 相比,此字段不会限制每行像素之后的非像素填充字节数,也不会限制平铺 pixel_format_modifier 中的非像素字节数。

与更典型的宽高比相比,非常窄或非常短的图片宽高比可能会导致每像素性能更差。当宽高比达到上限时,内边距和/或内存带宽开销往往会增加。参与者可以使用 ['fuchsia.sysmem/ImageFormatConstraints.min_size`] 指明不支持极窄或极短的维度。

如果发送到 sysmem,如果未设置,将被视为 0xFFFFFFFF。

从 sysmem 接收时,此字段将始终被设置,并且可以设置为 0xFFFFFFFF。

size_alignment fuchsia.math/SizeU

图片 size 的对齐要求。

  • size.width % size_alignment.width 必须为 0。
  • size.height % size_alignment.height 必须为 0。

如果未设置,则被视为 1、1。

display_rect_alignment fuchsia.math/SizeU

display_rect 的对齐要求。

  • display_rect.x % display_rect_alignment.width 必须为 0。
  • display_rect.y % display_rect_alignment.height 必须为 0。
  • display_rect.width % display_rect_alignment.width 必须为 0。
  • display_rect.height % display_rect_alignment.height 必须为 0。

如果未设置,则被视为 1、1。

required_min_size fuchsia.math/SizeU

这些字段可用于确保聚合约束具有 min_sizemax_size,从而 required_min_sizerequired_max_size(以及满足对齐要求之间的任何值)都允许使用 ImageFormat.size 的值。

例如,生产方视频解码器不希望限制允许的 ImageFormat.size,因为压缩的数据流可能会在流式传输过程中改变尺寸,但生产方视频解码器需要确保汇总的约束至少允许未压缩帧位于数据流当前位置的当前尺寸。

再比如,想要解码视频的发起者可能知道视频流中的帧的最大预期大小,因此通过设置 required_max_size,可以确保分配的缓冲区足够大,可以支持最大 size。除了成功分配之外,发起者还知道使用方参与者可以接收不超过该上限的 size

提供方或发起者设置这些字段要比使用者设置这些字段更常见。

min_sizemax_size 通过有效求交进行聚合,而 required_min_sizerequired_max_size 则通过有效求和来聚合。

此字段通过获取每个组成部分的最小值进行聚合,而 required_max_size 通过获取每个组成部分的最大值进行聚合。

如果未设置,则被视为 0xFFFFFFFF、0xFFFFFFFF。

required_max_size fuchsia.math/SizeU

另请参阅 required_min_size。如果未设置,则被视为 0、0。

bytes_per_row_divisor uint32

fuchsia_images2.ImageFormat.bytes_per_row % bytes_per_row_divisor 必须为 0。如果未设置,系统会将其视为 1。

如果 intent 是确保“bytes_per_row”为像素大小的倍数(以字节为单位),请优先使用 require_bytes_per_row_at_pixel_boundary

如果 intent 是为了确保对齐宽度(以像素为单位),请优先使用 size_alignment.width。相比之下,此字段可以指定“步幅(字节)”(从图片开头到行首的字节偏移量,从图片开头到第 n-1 行开头的 n 字节偏移量,结果以字节为单位),结果以字节为单位。例如,当使用 PixelFormat.BGR24(24 位颜色;每像素 3 字节)时,参与者要求每行像素从距图片开头 4 字节对齐的偏移量处开始,这可能意味着每行像素末尾、下一行像素的开头之前有一些填充字节。

虽然可以改为通过将 size_alignment.width 设置为“每宽度像素的步长字节数”和步幅对齐要求的最小公倍数来强制执行 bytes_per_row_divisor 的任何值,但强制执行步幅对齐要求可能会导致内边距超出必要(意味着缓冲区超出必要),也可能会导致“虚假的”size.width;此字段的存在可避免这种情况。而是直接在此处指定步幅对齐要求(以字节为单位)。

start_offset_divisor uint32

vmo_usable_start % start_offset_divisor 必须为 0。如果未设置,则被视为 1。

除非确实需要,否则不建议生产方参与者设置非零图像起始偏移量(距离缓冲区基准),因为并非所有参与者都能正确处理非零图像起始偏移量。

pixel_format_and_modifiers vector<PixelFormatAndModifier>[64]

应用以下限制条件的(附加)fuchsia.sysmem2/PixelFormatAndModifier

举一个非限制性示例,如果参与者只想为此 fuchsia.sysmem2/ImageFormatConstraints 设置一个 PixelFormatAndModifier,则参与者可以 (a) 使用 pixel_formatpixel_format_modifier 字段指定其中一个 PixelFormatAndModifier 的字段,而不设置 pixel_format_and_modifiers 的字段,或者 (b) 不设置 pixel_formatpixel_format_modifier 字段,并将其中一个 PixelFormatAndModifier 放入 pixel_format_and_modifiers 中。

如果设置了 pixel_format,服务器将获取 pixel_format 和 pixel_format_modifier 字段(在进程中取消设置它们),将它们打包到 PixelFormatAndModifier 中,然后将其作为一个额外的条目移动到此矢量,总大小限制为 MAX_COUNT_PIXEL_FORMAT_AND_MODIFIERS + 1

服务器将 pixel_formatpixel_format_modifier 移至此矢量中的另外一个条目后,此矢量不得为空。当所得列表包含多个项时,此矢量中的条目相当于列出(大小)单独的 ImageFormatConstraints 条目(每个 pixel_format_and_modifiers 条目一个条目,每个条目有一个 PixelFormatAndModifier),其中所有单独的 ImageFormatConstraints 条目具有相同的约束条件(逐字段比较,不包括 pixel_formatpixel_format_modifierpixel_format_and_modifiers 字段)。

SetConstraints 消息中,每个条目指定一个参与者可以接受的 PixelFormatAndModifier(假设还满足以下约束字段)。

在对 WaitForAllBuffersAllocated 的响应中,此字段将取消设置,并且将使用 pixel_formatpixel_format_modifier 字段指示所选的 PixelFormatAndModifier

参与者发送的 SetConstraints 消息中的所有 PixelFormatAndModifiersimage_format_constraints 下的所有条目中必须是唯一的。如果条目中使用了 fuchsia.images2.PixelFormat.DO_NOT_CARE,则不得有任何其他具有匹配 pixel_format_modifier 的条目(考虑 image_format_constraints 下的所有条目)。如果使用 FORMAT_MODIFIER_DO_NOT_CARE,则不得有任何其他具有匹配 pixel_format 的条目(考虑 image_format_constraints 下的所有条目)。

具有 DO_NOT_CAREFORMAT_MODIFIER_DO_NOT_CAREPixelFormatAndModifier 值(在本示例中,不是两者皆有)可以与来自另一个参与者的 PixelFormatAndModifier(具有另一个表示“不关心”的字段)结合使用,从而生成可以成功分配的完整 PixelFormatAndModifier。 但是,至少目前不允许单个参与者指定两个在不同字段中具有“随意”的单独 PixelFormatAndModifier 值。这不会禁止单个 PixelFormatAndModifier 同时具有 DO_NOT_CARE 和 PIXEL_FORMAT_DO_NOT_CARE(这只是一个 PixelFormatAndModifier 值)。如果客户端确实需要使用 pixel_format_modifier FORMAT_MODIFIER_DO_NOT_CARE 指定与 pixel_format 相关的一些约束,并使用 pixel_format DO_NOT_CARE 指定与 pixel_format_modifier 相关的其他约束,则客户端可以通过复制令牌并使用/驱动两位单独的参与者来实现此目的。

另请参阅 pixel_format,了解与单个 ImageFormatConstraints 中的多个 PixelFormatAndModifier 相关的更多注释。

require_bytes_per_row_at_pixel_boundary bool

如果将此参数设置为 true,则生成的 ImageFormatConstraints 中的 bytes_per_row_divisor 一定为要求 bytes_per_row 为像素整数值的值。与此字段未设置为 true 时相比,这可能会导致每行末尾的内边距更多,但可确保步长可以表示为整数的像素数。

例如,如果所选 PixelFormatB8G8R8,且此字段设置为 true,则生成的 bytes_per_row_divisor 将是 3 的倍数。在此示例中,如果另一位参与者将 bytes_per_row_divisor 设置为 4,则生成的 bytes_per_row_divisor 将是 12 的倍数。

NodeIsAlternateForRequest 资源

fuchsia.sysmem2/collection.fidl 中定义

序数字段类型说明
node_ref handle<event>

NodeSetDebugClientInfoRequest

fuchsia.sysmem2/collection.fidl 中定义

序数字段类型说明
name string[256]
id uint64

NodeSetDebugTimeoutLogDeadlineRequest

fuchsia.sysmem2/collection.fidl 中定义

序数字段类型说明
deadline zx/Time

NodeSetNameRequest

fuchsia.sysmem2/collection.fidl 中定义

序数字段类型说明
priority uint32
name string[64]

NodeSetWeakOkRequest 资源

fuchsia.sysmem2/collection.fidl 中定义

序数字段类型说明
for_child_nodes_also bool

Node_GetBufferCollectionId_Response

fuchsia.sysmem2/collection.fidl 中定义

序数字段类型说明
buffer_collection_id uint64

Node_GetNodeRef_Response 资源

fuchsia.sysmem2/collection.fidl 中定义

序数字段类型说明
node_ref handle<event>

Node_IsAlternateFor_Response

fuchsia.sysmem2/collection.fidl 中定义

序数字段类型说明
is_alternate bool

SingleBufferSettings

fuchsia.sysmem2/results.fidl 中定义

这些设置和约束条件适用于集合中的所有缓冲区。

添加数量:19

序数字段类型说明
buffer_settings BufferMemorySettings

此字段将始终由 sysmem 设置。

image_format_constraints ImageFormatConstraints

对于包含非未压缩图片数据的缓冲区,不会设置此字段。对于包含未压缩图片数据的缓冲区,可以设置此字段。

至少目前,更改 PixelFormat 需要重新分配缓冲区。

如果未设置此字段,则图片格式没有限制。

VmoBuffer 资源

fuchsia.sysmem2/results.fidl 中定义

添加数量:19

序数字段类型说明
vmo handle<vmo>

如果参与者仅将 fuchsia.sysmem2/BufferUsage.none 设为 NONE_USAGE(由 fuchsia.sysmem2/BufferCollection.SetConstraints 明确或隐式地设为 NONE_USAGE,则可以取消设置 vmo)。constraints

vmo_usable_start uint64

第一个可用字节的 VMO 内的偏移量。必须小于 VMO 的大小(以字节为单位),并在 VMO 结束之前留出足够的空间来容纳 BufferMemorySettings.size_bytes。

目前,sysmem 会始终将此字段设置为 0;将来,除非所有参与者明确表示支持非零 vmo_usable_start,否则 sysmem 不会将此字段设置为非零值(截至此评论时,这种机制尚不存在)。尚未明确表示支持非零 vmo_usable_start 的参与者(所有当前客户端)应隐式假设此字段设为 0,而不实际检查此字段。

close_weak_asap handle<eventpair>

当且仅当 vmo 是 sysmem 弱 VMO 句柄时,系统就会设置此字段。客户端必须在 vmo 的时间内保留 close_weak_asap,并且必须注意 ZX_EVENTPAIR_PEER_CLOSED。如果出现该信号,客户端必须尽快关闭 vmo。不这样做会被客户端视为 VMO 泄漏,在这种情况下,sysmem 最终将通过 syslog(目前为 5 秒后)发出大声报警。

联合

Allocator_GetVmoInfo_Result 严格的 资源

fuchsia.sysmem2/allocator.fidl 中定义

序数变体类型说明
response Allocator_GetVmoInfo_Response
err Error
framework_err internal

Allocator_验证 BufferCollectionToken_Result 严格

fuchsia.sysmem2/allocator.fidl 中定义

序数变体类型说明
response Allocator_ValidateBufferCollectionToken_Response
framework_err internal

BufferCollectionTokenGroup_CreateChildrenSync_Result strict 资源

fuchsia.sysmem2/collection.fidl 中定义

序数变体类型说明
response BufferCollectionTokenGroup_CreateChildrenSync_Response
framework_err internal

BufferCollectionToken_DuplicateSync_Result strict 资源

fuchsia.sysmem2/collection.fidl 中定义

序数变体类型说明
response BufferCollectionToken_DuplicateSync_Response
framework_err internal

BufferCollection_CheckAllBuffersAl 小型结果为 strict

fuchsia.sysmem2/collection.fidl 中定义

序数变体类型说明
response BufferCollection_CheckAllBuffersAllocated_Response
err Error
framework_err internal

BufferCollection_WaitForAllBuffersAlfund_Result strict 资源

fuchsia.sysmem2/collection.fidl 中定义

序数变体类型说明
response BufferCollection_WaitForAllBuffersAllocated_Response
err Error
framework_err internal

Node_GetBufferCollectionId_Result 严格

fuchsia.sysmem2/collection.fidl 中定义

序数变体类型说明
response Node_GetBufferCollectionId_Response
framework_err internal

Node_GetNodeRef_Result 严格 资源

fuchsia.sysmem2/collection.fidl 中定义

序数变体类型说明
response Node_GetNodeRef_Response
framework_err internal

Node_IsAlternateFor_Result 严格

fuchsia.sysmem2/collection.fidl 中定义

序数变体类型说明
response Node_IsAlternateFor_Response
err Error
framework_err internal

Node_Sync_Result 严格

fuchsia.sysmem2/collection.fidl 中定义

序数变体类型说明
response Node_Sync_Response
framework_err internal

常量

名称类型说明
CPU_USAGE_READ 1 uint32
添加数量:19
CPU_USAGE_READ_OFTEN 2 uint32
添加数量:19
CPU_USAGE_WRITE 4 uint32
添加数量:19
CPU_USAGE_WRITE_OFTEN 8 uint32
添加数量:19
DISPLAY_USAGE_CURSOR 2 uint32
添加数量:19
DISPLAY_USAGE_LAYER 1 uint32
添加数量:19
MAX_CLIENT_NAME_LENGTH 256 int32

fuchsia.sysmem2/Allocator.SetDebugClientInfofuchsia.sysmem2/Node.SetDebugClientInfo 中的 name 请求字段的最大长度(以字节为单位)。

添加数量:19
MAX_COUNT_BUFFER_COLLECTION_CONSTRAINTS_IMAGE_FORMAT_CONSTRAINTS 64 uint32

fuchsia.sysmem2/BufferCollectionConstraints.image_format_constraints 的大小上限。

添加数量:19
MAX_COUNT_BUFFER_COLLECTION_INFO_BUFFERS 128 uint32

fuchsia.sysmem2/BufferCollectionInfo.buffers 字段中的条目数上限。

添加数量:19
MAX_COUNT_BUFFER_MEMORY_CONSTRAINTS_PERMITTED_HEAPS 64 uint32

fuchsia.sysmem2/BufferMemoryConstraints.permitted_heaps 的大小上限。

添加数量:19
MAX_COUNT_CREATE_CHILDREN 64 int32

每次调用 fuchsia.sysmem2/BufferCollectionTokenGroup.CreateChildrenSync 时可创建的 OR 组令牌子项的数量上限。

实际上,在大多数典型场景中,我们都不建议创建这么多子元素,但出于测试原因,万一有特殊情况需要这样做,我们也不会阻止它。降低 sysmem 中潜在的高时间复杂度会将汇总尝试中考虑的实际组子组组合数限制为无法通过 Symem 协议设置的单独最大值。sysmem 令牌树中的节点总数上限被限制为无法通过这些协议设置的单独最大值。

添加数量:19
MAX_COUNT_DUPLICATES 64 uint32
添加数量:19
MAX_COUNT_IMAGE_FORMAT_CONSTRAINTS_COLOR_SPACES 32 uint32

fuchsia.sysmem2/ImageFormatConstraints.color_spaces 的大小上限。

MAX_COUNT_PIXEL_FORMAT_AND_MODIFIERS 64 uint32

fuchsia.sysmem2/ImageFormatConstraints.pixel_format_and_modifiers 的大小上限。

NONE_USAGE 1 uint32
添加数量:19
VIDEO_USAGE_CAPTURE 8 uint32
添加数量:19
VIDEO_USAGE_DECRYPTOR_OUTPUT 16 uint32
添加数量:19
VIDEO_USAGE_HW_DECODER 1 uint32
添加数量:19
VIDEO_USAGE_HW_DECODER_INTERNAL 32 uint32
添加数量:19
VIDEO_USAGE_HW_ENCODER 2 uint32
添加数量:19
VULKAN_BUFFER_USAGE_INDEX_BUFFER 4194304 uint32
添加数量:19
VULKAN_BUFFER_USAGE_INDIRECT_BUFFER 16777216 uint32
添加数量:19
VULKAN_BUFFER_USAGE_STORAGE_BUFFER 2097152 uint32
添加数量:19
VULKAN_BUFFER_USAGE_STORAGE_TEXEL_BUFFER 524288 uint32
添加数量:19
VULKAN_BUFFER_USAGE_TRANSFER_DST 131072 uint32
添加数量:19
VULKAN_BUFFER_USAGE_TRANSFER_SRC 65536 uint32
添加数量:19
VULKAN_BUFFER_USAGE_UNIFORM_BUFFER 1048576 uint32
添加数量:19
VULKAN_BUFFER_USAGE_UNIFORM_TEXEL_BUFFER 262144 uint32
添加数量:19
VULKAN_BUFFER_USAGE_VERTEX_BUFFER 8388608 uint32
添加数量:19
VULKAN_IMAGE_USAGE_COLOR_ATTACHMENT 16 uint32
添加数量:19
VULKAN_IMAGE_USAGE_INPUT_ATTACHMENT 128 uint32
添加数量:19
VULKAN_IMAGE_USAGE_SAMPLED 4 uint32
添加数量:19
VULKAN_IMAGE_USAGE_STENCIL_ATTACHMENT 32 uint32
添加数量:19
VULKAN_IMAGE_USAGE_STORAGE 8 uint32
添加数量:19
VULKAN_IMAGE_USAGE_TRANSFER_DST 2 uint32
添加数量:19
VULKAN_IMAGE_USAGE_TRANSFER_SRC 1 uint32
添加数量:19
VULKAN_IMAGE_USAGE_TRANSIENT_ATTACHMENT 64 uint32
添加数量:19