协议
ImagePipe2
在 fuchsia.images/image_pipe2.fidl 中定义
ImagePipe 是一种机制,用于在可能在不同进程中运行的生产者和使用方之间流式传输共享图片。
从概念上讲,图片管道会维护一个由生产方提供的图片资源表,其中可以存储图形内容,以及一个包含生产方要求使用方呈现的一系列图片的呈现队列。
演示文稿队列最初为空。
呈现队列中的每个条目都包含一张图片以及一对可选的同步栅栏:
- 获取栅栏:生产方在图像准备好供消费时发出的信号
- 释放栅栏:当图片可供生产方释放或修改时,由使用方发出信号
生产者会执行以下一系列步骤来呈现内容:
- 为图像管道分配并添加一定数量的 BufferCollection,以允许使用方设置限制条件。
- 向图片管道分配并添加一定数量的图片(通常为 2 或 3 张),以使用
AddImage()
建立一个池。 - 从池中获取下一个可用映像。
- 让使用方将图片加入队列以进行呈现,并使用
PresentImage()
提供栅栏。 - 开始渲染图片。
- 渲染完成后,向图片的获取栅栏发出信号。
- 循环呈现更多图片,监听释放栅栏上的信号,以将图片回收到池中。
使用方会针对加入呈现队列中的每个图片执行以下一系列步骤:
- 等待图像的获取栅栏上的信号。
- 如果无法满足栅栏等待条件或检测到其他错误,请关闭图片管道。否则,开始呈现图片的内容。
- 从呈现队列中移除之前呈现的图片(如果有),并在不再需要时发出其释放栅栏信号。
- 继续展示同一张图片,直到下一个图片准备就绪。循环。
如果生产方想要关闭图片管道,则应:
- 关闭其连接端。
- 等待使用
PresentImage()
提交的缓冲区的所有释放栅栏。 - 继续进行资源清理。
当使用方检测到图片管道已关闭时,应执行以下操作:
- 停止使用/显示管道中的任何图片。
- 取消映射与管道中的图片关联的所有内存对象。
- 关闭所有 BufferCollection 资源。
- 为已呈现和已加入队列的缓冲区发出所有释放栅栏信号。
- 关闭所有围栏把手。
- 关闭其连接端。
当任一方检测到栅栏已被废弃(在未收到信号的情况下被远程关闭)时,应假定关联的图片处于不确定状态。当其他方(或其某个受托方)崩溃时,通常会发生这种情况。最安全的做法是关闭映像管道,释放与对方共享的所有资源,然后重新建立连接以进行恢复。
AddBufferCollection
请求
名称 | 类型 |
---|---|
buffer_collection_id |
uint32
|
buffer_collection_token |
client_end:fuchsia.sysmem/BufferCollectionToken
|
AddBufferCollection2
向图片管道添加 BufferCollection 资源。
生产者应针对通过 AddImage()
添加的图片对此资源设置约束条件。使用方可以在 buffer_collection_token
之前或之后设置其约束条件。请注意,在生产方和使用方都使用所有 BufferCollectionToken 实例来设置约束条件之前,系统不会分配缓冲区。如需了解详情,请参阅 collection.fidl。
以下错误会导致连接关闭:
- “
buffer_collection_id
”已注册
请求
名称 | 类型 |
---|---|
buffer_collection_id |
uint32
|
buffer_collection_token |
client_end:fuchsia.sysmem2/BufferCollectionToken
|
AddImage
向图片管道添加图片资源。
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
|
PresentImage
将指定的图片加入队列,以供使用方呈现。
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<handle<event>>:16
|
release_fences |
vector<handle<event>>:16
|
响应
名称 | 类型 |
---|---|
presentation_info |
PresentationInfo
|
RemoveBufferCollection
从管道中移除 BufferCollection 资源。
系统会分离 buffer_collection_id
资源以及与该 BufferCollection 关联的所有 Image。这与对所有图片针对 buffer_collection_id
调用 RemoveImage()
的结果相同。
由于图片可能仍在呈现队列中使用,因此提供方必须等待与图片关联的所有释放栅栏发出信号,然后才能释放或修改底层内存对象。
以下错误会导致连接关闭:
buffer_collection_id
未引用当前注册的 BufferCollection
请求
名称 | 类型 |
---|---|
buffer_collection_id |
uint32
|
RemoveImage
从流水线中移除图片资源。
image_id
会与图片资源分离,并且可以随意重复使用来添加新的图片资源。
从图片管道中移除图片不会影响呈现队列或当前呈现的图片。
生产方必须等待与图像关联的所有释放栅栏都收到信号后,才能释放或修改底层内存对象,因为图像可能仍在呈现队列中使用。
以下错误会导致连接关闭:
image_id
未引用当前注册的图片资源
请求
名称 | 类型 |
---|---|
image_id |
uint32
|
结构体
ImageInfo
在 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 |
PresentationInfo
在 fuchsia.images/presentation_info.fidl 中定义
当使用方开始准备包含所呈现内容的第一个帧时,ImagePipe.PresentImage()
和 Session.Present()
等方法返回的信息。
字段 | 类型 | 说明 | 默认 |
---|---|---|---|
presentation_time |
uint64
|
已加入队列的操作预计产生可见效果的实际时间,以 此值会随着每帧新帧的增加而单调递增,通常以 |
无默认设置 |
presentation_interval |
uint64
|
预计在连续呈现的帧之间经过的典型时间量,以纳秒为单位。渲染到显示屏时,间隔时间通常根据显示屏刷新率计算得出。 此值不为零。它可能会不时发生变化,例如在更改显示模式时。 |
无默认设置 |
枚举
AlphaFormat strict
类型:uint32
在 fuchsia.images/image_info.fidl 中定义
指定应如何解读 Alpha 信息。
名称 | 值 | 说明 |
---|---|---|
不透明 |
0 |
图片被视为不透明。Alpha 渠道会被忽略。 混合函数为:src.RGB |
PREMULTIPLIED |
1 |
颜色通道已与 alpha 预乘。 混合函数为:src.RGB + (dest.RGB * (1 - src.A)) |
NON_PREMULTIPLIED |
2 |
颜色通道尚未与 alpha 预乘。 混合函数为:(src.RGB * src.A) + (dest.RGB * (1 - src.A)) |
ColorSpace strict
类型:uint32
在 fuchsia.images/image_info.fidl 中定义
指定应如何解读像素颜色信息。
名称 | 值 | 说明 |
---|---|---|
SRGB |
0 |
MemoryType 严格
类型:uint32
在 fuchsia.images/memory_type.fidl 中定义
指定 VMO 的内存类型。
名称 | 值 | 说明 |
---|---|---|
HOST_MEMORY |
0 |
VMO 是常规的主机 CPU 内存。 |
VK_DEVICE_MEMORY |
1 |
您可以通过以下方式将 VMO 导入为 VkDeviceMemory:使用 VkMemoryAllocateInfo 封装的 VkImportMemoryFuchsiaHandleInfoKHR 调用 VkAllocateMemory。 |
PixelFormat 严格
类型:uint32
在 fuchsia.images/image_info.fidl 中定义
指定像素在图片缓冲区中的表示方式。
名称 | 值 | 说明 |
---|---|---|
BGRA_8 |
0 |
BGRA_8 32 位四分量无符号整数格式。字节顺序:B、G、R、A(小端字节序 ARGB 打包的 32 位字)。
相当于 Skia |
YUY2 |
1 |
YUY2 4:2:2(水平方向 UV 2 倍下采样;垂直方向 UV 全分辨率) 一个 32 位组件,包含 2 个像素的信息: 字节顺序:Y1、U、Y2、V 解压缩为 2 个 RGB 像素,其中 RGB1 = func(Y1, U, V) 和 RGB2 = func(Y2, U, V) 等同于 YUV422 |
NV12 |
2 |
NV12 4:2:0(UV 在两个方向上均经过 2 倍下采样) 偏移量 0:每像素 8 位 Y 平面,字节为 YYY。偏移高度 * 步长:8 位 UV 数据交错字节为 UVUVUV。 Y 平面中的线条步长大于等于宽度。 在这种情况下,宽度和高度都必须为偶数。 UV 数据会分隔为“行”,每行“字节宽度”与 Y 数据的行字节宽度相同,并且“行”步长与 Y 数据的行步长相同。UV 数据的行高为“height / 2”。 在转换为 RGB 时,UV 数据在两个方向上总体上会放大 2 倍。此注释故意不详细说明 UV 放大阶段/滤波/信号处理的确切工作原理,因为这是一个复杂的主题,可能会因实现而异,通常会在放大速度和质量之间进行权衡。如需了解任何给定转化路径所采取的方法,请参阅相关转化代码中的注释。目前无法传输 UV 数据的精确相对相位。 |
YV12 |
3 |
YV12 与 I420 类似,但 V 和 U 已交换。 4:2:0(UV 在两个方向上均经过 2 倍下采样) 偏移量 0:每像素 8 位 Y 平面,字节为 YYY。偏移量为 height * stride:8 位 V 数据,uv_stride = stride / 2 偏移量为 height * stride + uv_stride * height / 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_OPTIMAL |
1 |
像素以依赖于 GPU 的最佳格式进行打包。等同于 |
转换 strict
类型:uint32
在 fuchsia.images/image_info.fidl 中定义
名称 | 值 | 说明 |
---|---|---|
正常 |
0 |
像素会正常显示。 |
FLIP_HORIZONTAL |
1 |
像素从左向右镜像。 |
FLIP_VERTICAL |
2 |
像素会垂直翻转。 |
FLIP_VERTICAL_AND_HORIZONTAL |
3 |
像素会垂直翻转并左右镜像。 |
常量
名称 | 值 | 类型 | 说明 |
---|---|---|---|
MAX_ACQUIRE_RELEASE_FENCE_COUNT |
16
|
int32 |
已弃用:13
|