影格排程是 View 如何決定套用用戶端更新和繪製影格的時機。風景優美的影格排程器會在 Gfx 和 Flatland 共用。本節包含有關 View 如何安排時間決策及用戶端可回應的高階概念。
簡報要求
「簡報要求」是指對 Present() 的一次用戶端呼叫。單一要求指的是套用自上次呼叫 Present() 以來所做的所有更新,並使畫面顯示 (例如「呈現」畫面)。
影格排程佇列
影格排程佇列是 View 內部在內部追蹤顯示要求的方式。影格排程佇列是一組佇列,每個佇列各有一個佇列。Display & Video 360 會從所有個別佇列提取簡報要求,並在達到想要的顯示時間時結合這些要求。
每次用戶端呼叫 Present() View 時,都會將簡報要求放入影格排程佇列,此時所有相關聯的取得柵欄都發出訊號。
影格排程程序
當佇列不是空白時,Resion 會檢查每個用戶端的呈現佇列中的第一個項目,並選擇最早要求的顯示時間。這項工具會使用該時間和螢幕的 vsync 時間資訊,判斷喚醒的時間。風景會盡可能在 vsync 上產生下一個影格,並盡可能在最接近 (但時間不超過要求的顯示時間) 處產生下一個影格。景色隨後進入睡眠狀態,直到經過計算的起床時間。
喚醒 View 後,會從影格排程佇列收集每個用戶端的下一個要求,而要求的顯示時間會達到計算的呈現時間。接著,風景區就會套用與每項個別要求相關的更新。
這個起床時間有時也稱為「閂點」。達到鎖定點後,目前影格的呈現要求會「鎖定」,而在閂點之後收到的所有要求都會延後至較新的影格。我們會透過 Present() API 向用戶端傳達簡報前預測的經緯度,以啟用用戶端低延遲影格排程。
如果向前要求的顯示時間在達到目前目標的閂點之前送達,View View 可能會重設較早目標的閂鎖。
套用所有相關的更新後,Vision 會轉譯下一個影格,然後等待螢幕傳回 vsync 訊號,此時系統會喚醒螢幕,並向已處理該影格的所有要求的所有用戶端發出信號。
如果顯示佇列中仍有剩餘的要求,Vision 會在佇列中找到下一個要求,並計算新的喚醒時間並等待,然後繼續這個循環。
壁球
用戶端保證會顯示至少一種 vsync 間隔時間,並顯示來自用戶端的「無法壓縮」。
「擠壓」是指 View 如何將多個後續的顯示要求合併至單一影格中。如果影格在風景區端可能會延遲,或在用戶端產生的速度過快,這項功能就會縮短延遲時間。壓縮後的結果,即使只有單一影格,畫面上也不會顯示擠壓的呈現要求。
顯示要求預設為「可壓縮」,且用戶端可在 Present() 呼叫中將顯示要求標示為「unsquashable」。
如果簡報要求標示為「可擠壓」,則在套用更新時,看看 Resion 會有哪些要求,看看用戶端要求的顯示時間是否也符合這個時間點的計算時間。如果 View 也套用了該項要求的更新,則「壓縮」成單一影格。
「squashable」屬性類似於 Vulkan 的 VK_PRESENT_MODE_FIFO_KHR 和 VK_PRESENT_MODE_EMAILBOX_KHR 交換鏈呈現模式,差別在於屬性是依每個影格套用,而非設定時間。