客户端请求一组用于作为未来取景帧的一部分呈现的命令。单个取景帧可以有多个客户端“演示”,其中每个“演示”都表示会话对全局场景图的更新。本文档介绍了 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 会处理命令并将结果发送给显示驱动程序。
- 显示驱动程序将像素推送到屏幕。