客户端请求一组用于作为未来取景帧的一部分呈现的命令。单个取景帧可以有多个客户端“演示”,其中每个“演示”都表示会话对全局场景图的更新。本文档介绍了 View 内部架构,用以说明请求如何变为像素。
下图显示了使用“客户端”功能在收到请求时所遵循的步骤。风景 FIDL 边界和 Vulkan 驱动程序之间的目前是单线程的,并按顺序执行。
- 客户端
Enqueue()包含一组命令以更改其场景中的内容,并调用Present2()来提交它们。 Present2()请求会进入scenic_impl::Session。scenic_impl::Session会等待所有获取栅栏信号,以及之前尚未达到栅栏的所有Present2()调用。然后,scenic_impl::Session会使用FrameScheduler为目标presentation_time安排更新。FrameScheduler会开始休眠,直到有足够的时间来让目标帧为目标呈现时间做好准备。这时,FrameScheduler会对所有SessionUpdaters唤醒并调用SessionUpdater::UpdateSessions()。- 对于每个客户端会话,
GfxSystem都会调用ApplyScheduledUpdates(),后者会将命令应用到您在第 1 步中已加入队列的场景图。注意:GfxSystem是SessionUpdater。 - 来自会话的命令会应用于全局场景图。场景图目前处于不一致状态(“脏”),在场景图经过后处理之前,不应被其他系统(即输入)读取。
- 当所有
SessionUpdaters都已成功更新后,FrameScheduler会收到通知,得知场景图脏了,并针对FrameRenderer触发RenderFrame()调用。 - 为了绘制一帧,
gfx::Engine的渲染程序会遍历场景图,并为场景中的每个元素创建Escher::objects。然后,渲染程序会将这些对象传递给Escher并调用DrawFrame()。注意:gfx::Engine是FrameRenderer。 Escher将场景图对象解释为vk::commands,并将这些命令发送到 GPU。- GPU 会处理命令并将结果发送给显示驱动程序。
- 显示驱动程序将像素推送到屏幕。