无法理解有助于异步显示的BufferQueue同步逻辑

时间:2015-11-21 09:44:08

标签: android opengl-es egl grafika

我正在从this链接阅读android架构。

在第一次尝试时,除了点点滴滴之外,我无法理解一切。

我的理解是什么?

1)

有一种叫做“同步框架”的东西。 - 好的

2)

此同步框架可用于进程之间以及用户空间和内核空间之间。 - 好的

3)

用于异步机制。 - 好。

4)

假设没有同步框架。

   void display_buffer(struct dma_buf *buf);

有一个显示给定缓冲区的显示系统。

 while (1) {
    -> Fill the buffer( buf)
    -> call display_buffer(buf);  -> Displays into the screen.
  }

可能存在延迟,因为它是同步

5)

假设我们有同步框架支持。     它类似于:我将为显示系统提供缓冲区和startfence,当你在startfence上获得信号时需要显示缓冲区。与此同时,当你完成后,你需要与我有所帮助。显示系统为我提供的。 [我不完全理解,但我觉得它对异步模型有帮助],所以我可以在系统渲染时填充缓冲区。

struct sync_fence* display_buffer(struct dma_buf *buf,
    struct sync_fence *fence);

灰色区域:但是,我仍然无法编写伪代码,以便在异步模式下使用display_buffer?

从android官方链接中读取段落。

最近的Android设备支持”同步框架“。当与可以异步操作图形数据的硬件组件结合使用时,系统可以做一些漂亮的事情。例如,制作人可以提交一系列OpenGL ES绘制命令然后在渲染完成之前将输出缓冲区入队。缓冲区附带一个栅栏,在内容准备好时发出信号。当缓冲区返回到空闲列表时,第二个栅栏伴随缓冲区,以便消费者在内容仍在使用时可以释放缓冲区。当缓冲区在系统中移动时,这种方法可以提高延迟和吞吐量。

问题:

我特别对此声明感到困惑。

“当缓冲区返回到空闲列表时,第二个围栏伴随缓冲区,以便使用者可以在内容仍在使用时释放缓冲区。这种方法可以提高延迟和吞吐量作为缓冲区在系统中移动。“

同一个缓冲区上的第二个围栏?还是不同的缓冲区?因为我看到有两个缓冲队列,一个是填充列表,另一个是空列表。

1 个答案:

答案 0 :(得分:1)

如果您想深入了解同步框架,还应该阅读this document,尤其是this document的“显式同步”部分。

您的描述很接近但不太正确。每个缓冲区都有一个“获取”围栏和一个“释放”围栏。 “获取”栅栏指示生产者(例如OpenGL ES)何时完成渲染。它不会告诉消费者(硬件组件,它提供显示器)它需要来显示缓冲区,而是告诉它现在允许显示缓冲区,因为渲染已经完成了。当显示硬件不再访问缓冲区时,HWC会发出“释放”围栏信号,这意味着再次允许消费者写入。

延迟减少是因为没有将缓冲区的状态绑定到队列中的状态。 BufferQueue可以在渲染完成之前认为您已经充满了数据,并且可以在显示完成显示缓冲区之前将您置于“空闲”列表中。这允许IPC队列机制在不阻塞GPU或显示的情况下完成它们的工作。

一旦发出栅栏信号,它就永远不会变为无信号,因此您不能将单个栅栏用于多个事件。这就是为什么你需要两个不同的栅栏来“准备好数据”和“不再需要数据”。

FWIW,名称“BufferQueue”略有误导。填充缓冲区在队列中,空缓冲区在池中。 (池有一个FIFO策略,所以它本质上是一个队列,但不能保证。)