Android表面管理器Surfaceflinger和OpenGL ES

3

我有几个关于SurfaceFlinger的问题:

1)我了解应用程序会直接向Surface中写入内容,然后将缓冲区移动到SurfaceFlinger(假设我正在使用硬件画布或EGL)。缓冲区内部是什么?原始像素还是已编译的OpenGL代码? 缓冲区可以在一个事务中保存像素,在另一个事务中保存其他类型的数据吗?

2)我在某个地方读到过,SurfaceFlinger使用OpenGL ES 1.0 API写入HWC/DisplayController命令。这是真的吗?

如果是这样,那么如何将版本3.0命令转换为版本1.0命令,以及在哪里进行转换?

谢谢

1个回答

4
假设您正在使用OpenGL ES,应用程序将命令排队到GL驱动程序,该驱动程序将输出呈现到缓冲区。Surface是生产者和消费者之间共享的缓冲池/队列;在这种情况下,应用程序是生产者,而SurfaceFlinger是消费者。对于GLES渲染到表面,池将具有两个或三个缓冲区(即双缓冲或三缓冲)。缓冲区由gralloc分配,具有描述内容的标题(宽度、高度、像素格式等),并保存原始像素。
原始像素不存在也没有关系,因为足够复杂的系统可以在需要时重播GLES命令,但实际上实现正在填充缓冲区并传递处理器。
由于gralloc标题指定了缓冲区属性,因此可以随时更改缓冲区大小和像素格式。系统的某些部分不希望出现这种情况。例如,如果将RGB像素提供给MediaCodec的Surface输入,然后切换到YUV,则编解码器可能无法检测到更改。(可以使用一些隐藏选项来演示此操作screenrecord)

(2) 硬件组合器有自己的API。它与GLES无关。在超过叠加平面数量的情况下,可能会使用GLES进行部分或全部合成,但这是由SurfaceFlinger处理的。

更多细节可以在图形架构文档中找到。


谢谢,但我仍然不确定我是否理解:I)gralloc缓冲区内的命令是可以在支持openGL的任何设备上运行的“已编译”openGL命令(这是什么样的“已编译”代码?) II)当未使用过多平面时,Surface flinger是否确实只支持GLES 1.0命令? GLES 3.0到GLES 1.0的转换在哪里完成? - EyalBellisha
gralloc 缓冲区包含像素数据。GLES 驱动程序具有供应商特定的命令队列。“理论上”,您可以在缓冲区组合时重放命令,但实际上,在信号灯发出信号并且下一个阶段能够访问像素之前,命令会运行到完成,该过程通过从 gralloc 缓冲区读取像素数据来完成。SurfaceFlinger 将使用 GLES 1.x 或 2.x 来进行非叠加合成;请参见 https://android.googlesource.com/platform/frameworks/native/+/lollipop-release/services/surfaceflinger/RenderEngine/。 - fadden

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接