Pixel 的生命周期

客户端请求一组用于作为未来取景帧的一部分呈现的命令。单个取景帧可以有多个客户端“演示”,其中每个“演示”都表示会话对全局场景图的更新。本文档介绍了 View 内部架构,用以说明请求如何变为像素。

下图显示了使用“客户端”功能在收到请求时所遵循的步骤。风景 FIDL 边界和 Vulkan 驱动程序之间的目前是单线程的,并按顺序执行。

  1. 客户端 Enqueue() 包含一组命令以更改其场景中的内容,并调用 Present2() 来提交它们。
  2. Present2() 请求会进入 scenic_impl::Sessionscenic_impl::Session 会等待所有获取栅栏信号,以及之前尚未达到栅栏的所有 Present2() 调用。然后,scenic_impl::Session 会使用 FrameScheduler 为目标 presentation_time 安排更新。
  3. FrameScheduler 会开始休眠,直到有足够的时间来让目标帧为目标呈现时间做好准备。这时,FrameScheduler 会对所有 SessionUpdaters 唤醒并调用 SessionUpdater::UpdateSessions()
  4. 对于每个客户端会话,GfxSystem 都会调用 ApplyScheduledUpdates(),后者会将命令应用到您在第 1 步中已加入队列的场景图。注意:GfxSystemSessionUpdater
  5. 来自会话的命令会应用于全局场景图。场景图目前处于不一致状态(“脏”),在场景图经过后处理之前,不应被其他系统(即输入)读取。
  6. 当所有 SessionUpdaters 都已成功更新后,FrameScheduler 会收到通知,得知场景图脏了,并针对 FrameRenderer 触发 RenderFrame() 调用。
  7. 为了绘制一帧,gfx::Engine 的渲染程序会遍历场景图,并为场景中的每个元素创建 Escher::objects。然后,渲染程序会将这些对象传递给 Escher 并调用 DrawFrame()。注意:gfx::EngineFrameRenderer
  8. Escher 将场景图对象解释为 vk::commands,并将这些命令发送到 GPU。
  9. GPU 会处理命令并将结果发送给显示驱动程序。
  10. 显示驱动程序将像素推送到屏幕。

此类的图片和调用,客户端 Present 请求将经过上述处理,成为屏幕上的像素。这是上述枚举列表的直观表示形式。