用戶端要求一組指令,以便在日後的 Scenic 影格中呈現。單一 Scenic 影格可以有多個用戶端「呈現」,每個呈現代表工作階段對全域場景圖的更新。本文說明 Scenic 內部架構,瞭解要求如何變成像素。
下圖顯示用戶端 Present 收到要求時採取的步驟。Scenic 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 會處理指令,並將結果傳送至顯示驅動程式庫。
- 顯示器驅動程式庫會將像素推送到螢幕。