协议
ImagePipe2
在 fuchsia.images/image_pipe2.fidl 中定义
ImagePipe 是一种用于在生产方和使用方之间流式传输共享映像的机制,这些共享映像可能在不同进程中运行。
从概念上讲,图像管道会维护一个由生产方提供的图像资源表(其中可存储图形内容),以及一个呈现队列,该队列中包含生产方要求使用方呈现的一系列图像。
展示队列最初是空的。
呈现队列中的每个条目都由一张图片和一对可选的同步栅栏组成:
- 获取栅栏:在图像准备好使用时,由生产方发出信号
- 释放栅栏:当图像可以由生产方自由释放或修改时,由使用方发出信号
提供方执行以下一系列步骤来呈现内容:
- 分配一定数量的 BufferCollection 并将其添加到图像管道,以允许使用方设置约束条件。
- 为映像管道分配一定数量的映像(通常是 2 或 3)并将其添加到映像管道中,以使用
AddImage()
建立池。 - 从池中获取下一个可用的映像。
- 要求使用方将图像加入队列进行呈现,并使用
PresentImage()
提供栅栏。 - 开始渲染图片。
- 在渲染完成时向图片的获取栅栏发出信号。
- 循环呈现更多图像,监听释放栅栏上的信号,以将图像回收回池中。
使用方对在呈现队列中加入队列的每个图像执行以下一系列步骤:
- 等待图片的获取栅栏上的信号。
- 如果无法满足栅栏等待时间或检测到其他错误,请关闭图像管道。否则,开始呈现图片的内容。
- 从呈现队列中退出之前呈现的图像(如果有),并在不再需要时将其释放栅栏变为信号状态。
- 继续展示同一张图片,直到下一张图片准备就绪。循环播放。
如果生产方想要关闭图像管道,应执行以下操作:
- 关闭设备端的连接。
- 在所有释放栅栏上等待其已通过
PresentImage()
提交的缓冲区。 - 继续进行资源清理。
当使用方检测到图片管道已关闭时,应:
- 停止使用/显示管道中的任何图片。
- 取消映射与管道中的图像关联的所有内存对象。
- 关闭所有 BufferCollection 资源。
- 针对呈现的缓冲区和加入队列的缓冲区的所有释放栅栏发出信号。
- 关闭栅栏的所有手柄。
- 关闭设备端的连接。
当任一方检测到某个栅栏已被放弃(在没有收到信号的情况下远程关闭)时,它应假定相关图像处于不确定状态。当其他方(或其某个受托人)崩溃时,通常就会发生这种情况。最安全的方法是关闭映像管道,释放与其他方共享的所有资源,然后重新建立连接以进行恢复。
添加缓冲区集合
将 BufferCollection 资源添加到图像管道。
提供方需要为通过 AddImage()
添加的图片设置此资源的约束条件。使用方可以在 buffer_collection_token
之前或之后为其设置约束条件。请注意,只有在使用所有 BufferCollectionToken 实例在生产方和使用方端设置限制条件之前,才会分配缓冲区。如需了解详情,请参阅 collection.fidl。
以下错误会导致连接关闭:
- “
buffer_collection_id
”已注册
请求
名称 | 类型 |
---|---|
buffer_collection_id |
uint32
|
buffer_collection_token |
fuchsia.sysmem/BufferCollectionToken
|
添加图片
向映像管道添加图片资源。
buffer_collection_id
是指通过 AddBufferCollection()
注册的 BufferCollectionToken 实例。分配的底层内存对象用于寻址图片数据。buffer_collection_index
是指在 BufferCollection 中分配的内存对象的索引。
image_format
指定图片属性。coded_width
和 coded_height
用于设置图片尺寸。
创建由同一内存对象支持的多个图像是有效的;这些图像甚至可能重叠。使用方必须检测此问题并相应地处理。
以下错误会导致连接关闭:
- “
image_id
”已注册 buffer_collection_id
是指未注册的 BufferCollection。buffer_collection_index
指向初始化的 BufferCollection 边界中的资源索引- 未在已注册的 BufferCollection 中分配任何资源。
请求
名称 | 类型 |
---|---|
image_id |
uint32
|
buffer_collection_id |
uint32
|
buffer_collection_index |
uint32
|
image_format |
fuchsia.sysmem/ImageFormat_2
|
展示图片
将指定图像加入队列,以供使用方呈现。
acquire_fences
是一组栅栏,在使用方呈现图像之前,提供方必须全部发出信号。release_fences
是一组栅栏,用于告知生产方可以安全地释放或修改 image_id
图像,并且可以放心地在 acquire_fences
中重复使用这些栅栏。当不再呈现 image_id
后,使用方必须在 release_fences
中的所有栅栏变为信号状态。提供方可以在任何 release_fences
收到信号后重复使用资源。
这种设计允许生产者跨多个线程 / 进程分配图像处理,而不会出现不必要的协调延迟。每个线程 / 进程在完成渲染自己的 image_id
部分后,会在 acquire_fences
中指示自己的栅栏,并在 release_fences
中等待自己的栅栏,以便在 image_id
中渲染新内容。
presentation_time
指定客户端希望加入队列的操作在多长时间内或之后生效(屏幕上的亮起像素),以纳秒为单位,以 CLOCK_MONOTONIC
时基表示。所需的呈现时间必须是单调非递减的。
presentation_info
会返回有关已提交帧和未来帧的时间信息(请参阅 Presentation_info.fidl)。
提供方可能决定不为图片发出 acquire_fences
信号。在这种情况下,如果后一幅图像已加入队列,并且到达后一幅图像的 presentation_time
,那么当该图像的 acquire_fences
收到信号时,使用方会呈现后一幅图像。使用方还会发出之前图像的 release_fences
信号,并将其从呈现队列中移除。此序列起到取消机制的作用。
以下错误会导致连接关闭:
image_id
不引用当前注册的图片资源
请求
名称 | 类型 |
---|---|
image_id |
uint32
|
presentation_time |
uint64
|
acquire_fences |
vector<event>[16]
|
release_fences |
vector<event>[16]
|
回复
名称 | 类型 |
---|---|
presentation_info |
PresentationInfo
|
移除 BufferCollection
从管道中移除 BufferCollection 资源。
buffer_collection_id
资源以及与该 BufferCollection 关联的所有图片都会分离。与在所有图片上针对 buffer_collection_id
调用 RemoveImage()
产生的结果相同。
在释放或修改底层内存对象之前,生产方必须等待与图像相关联的所有释放栅栏都收到信号,因为图像可能仍在呈现队列中使用。
以下错误会导致连接关闭:
buffer_collection_id
不引用当前注册的 BufferCollection
请求
名称 | 类型 |
---|---|
buffer_collection_id |
uint32
|
移除图片
从管道中移除图片资源。
image_id
与映像资源分离,可以重复使用以添加新的映像资源。
从图像管道中移除图像不会影响呈现队列或当前呈现的图像。
在释放或修改底层内存对象之前,生产方必须等待与图像关联的所有释放栅栏都收到信号,因为图像可能仍在呈现队列中使用。
以下错误会导致连接关闭:
image_id
不引用当前注册的图片资源
请求
名称 | 类型 |
---|---|
image_id |
uint32
|
结构
图像信息
在 fuchsia.images/image_info.fidl 中定义
有关图形图片(纹理)的信息,包括其格式和大小。
字段 | 类型 | 说明 | 默认 |
---|---|---|---|
transform |
Transform
|
指定是否应在显示图像前进行镜像。 |
Transform.NORMAL |
width |
uint32
|
图片的宽度和高度(以像素为单位)。 |
无默认值 |
height |
uint32
|
无默认值 | |
stride |
uint32
|
图像缓冲区中每行的字节数。 |
无默认值 |
pixel_format |
PixelFormat
|
图片的像素格式。 |
PixelFormat.BGRA_8 |
color_space |
ColorSpace
|
像素颜色空间。 |
ColorSpace.SRGB |
tiling |
Tiling
|
内存中的像素排列方式。 |
Tiling.LINEAR |
alpha_format |
AlphaFormat
|
指定 alpha 通道(如果存在)的解释。 |
AlphaFormat.OPAQUE |
演示文稿信息
在 fuchsia.images/presentation_info.fidl 中定义
当使用方开始准备包含所呈现内容的第一帧时,ImagePipe.PresentImage()
和 Session.Present()
等方法返回的信息。
字段 | 类型 | 说明 | 默认 |
---|---|---|---|
presentation_time |
uint64
|
已加入队列的操作预计生效的实际时间,以 此值随每个新帧的增加单调递增,通常以 |
无默认值 |
presentation_interval |
uint64
|
依次呈现的帧之间预计会流逝的标称时间,以纳秒为单位。渲染到显示屏时,该时间间隔通常由显示屏刷新率得出。 该值为非零值。它可能会不时发生变化,例如当您更改显示模式时。 |
无默认值 |
枚举
AlphaFormat 严格
类型:uint32
在 fuchsia.images/image_info.fidl 中定义
指定如何解读 Alpha 信息。
名称 | 值 | 说明 |
---|---|---|
不透明 |
0 |
图片被视为不透明。Alpha 渠道会被忽略。 混合函数为:src.RGB |
预乘 |
1 |
颜色通道已通过 alpha 预乘。混合函数为:src.RGB + (dest.RGB * (1 - src.A)) |
不预增 |
2 |
颜色通道尚未被 alpha 预乘。混合函数为:(src.RGB * src.A) + (dest.RGB * (1 - src.A)) |
ColorSpace 严格
类型:uint32
在 fuchsia.images/image_info.fidl 中定义
指定应如何解读像素颜色信息。
名称 | 值 | 说明 |
---|---|---|
单声道 |
0 |
MemoryType 严格
类型:uint32
在 fuchsia.images/memory_type.fidl 中定义
指定 VMO 的内存类型。
名称 | 值 | 说明 |
---|---|---|
主机内存 |
0 |
VMO 是指常规的主机 CPU 内存。 |
VK_DEVICE_MEMORY |
1 |
通过使用封装在 VkMemoryAllocateInfo 中的 VkImportMemoryFuchsiaHandleInfoKHR 调用 VkAllocateMemory,可将 VMO 作为 VkDeviceMemory 导入。 |
PixelFormat 严格
类型:uint32
在 fuchsia.images/image_info.fidl 中定义
指定像素在图像缓冲区中的表示方式。
名称 | 值 | 说明 |
---|---|---|
BGRA_8 |
0 |
BGRA_8 32 位四组件无符号整数格式。
字节顺序:B、G、R、A(小端字节序 ARGB 打包 32 位字)。相当于 Skia |
年元 2 |
1 |
年元 2 4:2:2(水平下采样 2 倍;垂直全分辨率 UV) 一个包含 2 个像素信息的 32 位组件:字节顺序:Y1、U、Y2、V。解压缩到 2 个 RGB 像素,其中 RGB1 = func(Y1, U, V) 和 RGB2 = func(Y2, U, V) 相当于 YUV422 |
NV12 |
2 |
NV12 4:2:0(两个方向的 2 倍下采样 UV) 偏移 0:每像素 8 位 Y 平面,字节 YYY。偏移高度 * 步幅:8 位 UV 数据交错字节作为 UVUVUV 了。 Y 平面的线步长 >= 宽度。 在这种情况下,宽度和高度必须均匀。 UV 数据会分为“线”,每条“线”的字节宽度与 Y 数据行的字节宽度相同,“线”步长与 Y 数据的行步长相同。UV 数据具有高度 / 2 条“线”。 在转换为 RGB 时,UV 数据在两个方向上整体而言都被放大 2 倍。这条注释特意没有提及 UV 放大阶段/过滤/信号处理的工作原理,因为这是一个复杂的主题,可能会因实现而异,并且通常牺牲了提升的速度和质量。请查看相关转化代码中的注释,了解任何给定转化路径所采取的方法。目前还无法传达 UV 数据的确切相对相位。 |
YV12 |
3 |
YV12 与 I420 类似,但交换的是 V 和 U。 4:2:0(两个方向的 2 倍下采样 UV) 偏移 0:每像素 8 位 Y 平面,字节 YYY。偏移高度 * 步长:8 位 V 数据,uv_stride = stride / 2 偏移高度 * stride + uv_stride * 高度 / 2: 8 位 U 数据(uv_stride = stride / 2 Y 平面的线步长 >= 宽度。 宽度和高度必须是均匀的。 |
R8G8B8A8 |
4 |
R8G8B8A8 32 位四组件无符号整数格式。
字节顺序:R、G、B、A(采用小端字节序的 ABGR 打包 32 位字)。相当于 Skia 此格式只能与 VK_DEVICE_MEMORY 搭配使用。 |
平铺严格
类型:uint32
在 fuchsia.images/image_info.fidl 中定义
指定像素在内存中的排列方式。
名称 | 值 | 说明 |
---|---|---|
线性 |
0 |
像素以线性方式打包。
等同于 |
GPU_优化 |
1 |
像素以依赖于 GPU 的最佳格式打包。等同于 |
转换 Strict
类型:uint32
在 fuchsia.images/image_info.fidl 中定义
名称 | 值 | 说明 |
---|---|---|
中 |
0 |
像素显示正常。 |
小菲_HORIZONTAL |
1 |
像素自左向右镜像。 |
FLIP_VERTIAL |
2 |
像素垂直翻转。 |
FLIP_VERTIAL_AND_HORIZONTAL |
3 |
像素垂直翻转并左右镜像。 |
常量
名称 | 值 | 类型 | 说明 |
---|---|---|---|
MAX_ACQUIRE_RELEASE_FENCE_COUNT 次 |
16
|
int32 |
已弃用:13
|