Pixel 的壽命

用戶端要求一組指令,以便在日後的 Scenic 影格中呈現。單一 Scenic 影格可以有多個用戶端「呈現」,每個呈現代表工作階段對全域場景圖的更新。本文說明 Scenic 內部架構,瞭解要求如何變成像素。

下圖顯示用戶端 Present 收到要求時採取的步驟。Scenic 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 要求在畫面上顯示為像素的類別和呼叫視覺化表示。