RFC-0162:Flatland API | |
---|---|
狀態 | 已接受 |
領域 |
|
說明 | 說明 Flatland,此為 Fuchsia 專用的 2D 組合 API。 |
更小鳥 | |
作者 | |
審查人員 | |
提交日期 (年月分) | 2021-05-24 |
審查日期 (年-月-日) | 2021-05-30 |
舊 API 設計文件
這份 RFC 先前是做為 API 設計文件提交,之後在 API 設計文件範本淘汰後轉換成 RFC。
摘要
本文件提議適用於 Fuchsia 圖形用戶端的 2D API。Flatland 可為用戶端提供類似於螢幕控制器的功能,並在 2D 環境中定義資源。
目標和用途
View 目前會在 fuchsia.ui.gfx
命名空間 (「gfx API」) 底下提供含有 3D API 的圖形用戶端。這個 3D API 能為用戶端提供類似於電玩遊戲引擎或其他 3D 圖形程式的場景模型。繪圖順序由 Z 深度處理,不透明度則透過 Alpha 混合 (以深度度為準) 處理。很遺憾地,gfx API 不再適合以產品角度和效能考量點為詳情所設的需求,群組不透明度等功能是不可能,因為如何處理半透明內容群組的陰影。
從產品的角度來看,現有客戶是 2D 產品沒有深度和繪製順序的概念。它們的原理只是按照繪製不同批次的繪製幾何圖形順序。由於沒有深度,因此透明度效果也會透過繪製順序決定。「2D」用戶端 (透過 Flutter、Chromium 和工作階段架構) 必須執行額外工作,以解決畫面 3D 場景表示法與使用者遇到的 2D 表示法不相符的問題。
從效能的角度來看,新型影片顯示控制器 (VDC) 硬體提供加速功能,例如未來未來會使用的多個螢幕平面和硬體疊加層,為了降低耗電量和 GPU 用量。硬體是以嚴格 2D 模式運作,且僅理解可放置在 X/Y 中的矩形層。View 目前採用的 3D API 可讓您鼓勵客戶提交不屬於這個範例的內容,而且會讓最佳化作業陷入困境。
藉由公開真實的 2D API,我們的目標是讓 2D 用戶端更生活:
- 2D API 更符合 2D API 的預期。
- 盡可能將工作委派給 VDC,降低 GPU 用量。
- 更輕巧的景象,僅針對 2D 矩形圖層進行最佳化處理。
設計
建議您從頭開始編寫 2D 通訊協定,避免重複使用 fuchsia.ui.gfx
的部分。
提議的 2D API 目前狀態位於於這次審查中提交的 fuchsia.ui.scenic.internal.flatland
程式庫。請查看及放置留言。
以下是關於 Flatland API 的一些高階決策:
- Flatland 會密切遵循,並提供與
fuchsia.hardware.display/Controller
中定義的顯示控制器 API 類似的功能。- 最成功的情境是,Landscape 中的 Flatland 實作項目會將資源傳遞至螢幕,而沒有組合。因此,顯示控制器 API 的常見資源會以相同方式定義。也就是在可以安全存取資源的情況下,用來傳遞訊號的 zx.handle:EVENT 會藉由這些通訊協定傳送,並且具有相同的意義和用途。
- Flatland 的最終目的在於提供確定性的 CPU 成本給客戶。有一個排程的轉譯執行緒。每個 Flatland 工作階段都會以各自的調度器執行,而這些調度器位於目前設定中的專屬執行緒上。
- 為了算繪螢幕上的矩形圖層,各 Flatland 工作階段可能會有多個管道與 Flatland 進行通訊。這些課程不會影響彼此的簡報內容或表現。
- 系統是透過
fuchsia.ui.composition/Allocator
中定義的 View 配置器通訊協定強制執行映像檔配置作業。- 由於用戶端都同意分配方式與格式,因此所有映像檔使用資料均為零副本,且在使用 Sysmem 進行分配前,都同意 Sysmem 配置與格式。
- 配置器可讓圖片跨多個 Flatland 工作階段使用。
- Flatland 未提供指令聯集模式。Present() 呼叫是用來處理已排入佇列指令的標記,這些是個別方法。
- Flatland 會嚴格限制用戶端呼叫 Present() 的次數。此做法會透過 OnPresentProcessed() 回應傳達。這可做為節流機制使用。
- Flatland 可能會在 OnPresentProcessed() 回呼中傳回錯誤,通知用戶端非法作業。而 Flatland 管道隨後就會關閉。
- Flatland 希望用戶端定義及追蹤「不重複資源 ID」。系統會透過這些 ID 周圍定義的結構強制執行類型安全性,例如 TransformId 和 ContentId。
- Flatland 使用 hang-gets 來通知用戶端連結結構或屬性的變更。這些符記是透過獨立的通訊協定傳送。
不明
為了滿足客戶需求,平面設計在某些領域可能會有所調整。
- 用戶端可能會預期合成器處理一些螢幕硬體無法處理的 2D 效果,例如模糊處理。這些作業的費用較高。我們計劃將這兩種運算分離,以便明確區別。Flatland 的目前狀態僅支援螢幕可處理的作業。
- 根據客戶的意見調整簡報和意見回饋流程。定義目前的 Flatland 流程之前,gfx API 的呈現流程有三個疊代作業。因此,PresentArgs 定義為資料表,以便針對日後的變更彈性調整。
- 我們在設計與簡報意見回饋時,將重點放在低延遲用戶端,以及高處理量的用戶端。在適合下一個影格開始的工作時,OnPresentProcessed() 會通知用戶端。OnFramePresented() 會通知進階用戶端,指出顯示畫面顯示在螢幕畫面上的時間。
可用性
請查看 flatland_unittest 的樹狀結構內測試,找出大量的 Flatland API 使用範例。
下圖說明連結多個 Flatland 工作階段的連結圖表如何運作。這是較複雜但常見的用途。
圖 1 - 平地
測試
Flatland 目前定義為內部 API,且測試是由樹狀結構內單元測試提供。由於測試只能執行測試,才能以其他方式執行 Flatland 程式碼,因此我們透過自動化測試廣泛涵蓋每個程式碼。我們打算維持這項測試的涵蓋率和品質。
我們計劃最終將每個圖像範例轉換為 Flatland。我們沒有任何用戶端必須嚴格居住在 3D 環境中。我們目前正努力利用 Flatland 簡報者做為樹狀結構內整合測試 https://fxbug.dev/42156206 的新增及遷移基礎。以便我們做好日後遷移,包括 Flutter 和 Chromium 等重要外部用戶端的遷移作業。
Flatland 的設計可讓您在不依賴 Vulkan 和螢幕等硬體功能的情況下執行商業邏輯。Vulkan 可由空值轉譯器實作取代,而會略過合成。螢幕可替換現有的假螢幕實作。
我們將在 Compatibility Test Suite 底下提供其他 Flatland API 整合測試。
效能注意事項
Flatland 可讓許多客戶同時作業,而不影響彼此的工作。
- 每個方法都是單向 FIDL 方法,代表用戶端指令轉譯至螢幕的矩形部分。Present() 會發出來自用戶端的指令序列結束,並發出畫面更新作業開始,進行下一個螢幕更新。
- 大多數用戶端會在主動更新內容時,針對每個 vsync 呼叫至少一次呼叫。60 fps 顯示情境約為 16 毫秒。在每個 vsync 間隔中:
- 用戶端可以進行 N 次呼叫來修改場景圖,接著執行一次 Present() 呼叫。
- Flatland 會發出 OnPresentProcessed() 訊息,通知用戶端作業已排入佇列,用戶端應開始產生下一個影格。我們的客戶目前不知道何時是開始作業的最佳時機,因此需要透過硬式編碼偏移來避免重疊,以及 OnPresentProcessed() 的修正項目。這項回饋也會提示用戶端未來理想中的 Present() 呼叫,並告知其 Present() 許可。
- 用戶端可能會忽略 OnPresentProcessed() 中提供的時間和提示,並依照其內部時鐘持續顯示。這仍然有效,但不保證能避免資源爭用。
- Flatland 會發出 OnFramePresented() 通知,告知用戶端內容已實際顯示在螢幕上。這項意見回饋對於進階用戶端同步處理 (例如音訊/影片) 的必要性。
- Flatland 藉由明確定義
num_presents_returned
,阻止惡意用戶端排入過多 Present() 呼叫。用戶端呼叫 Present() 的次數不能超過 OnPresentProcessed() 所允許的次數。每個用戶端一開始只能取得一個限額。 - 請記住,Flatland 會以自己的調度程式執行每個管道連線。這些意見回饋機制是非同步的。
安全性考量
「平地」使用者彼此獨立。每一個都能透過各自的頻道 連結至 View不重複資源 ID 僅在所屬管道範圍內定義。他們只能指定畫面根據父項「Flatland」工作階段所定義的部分。
每個錯誤情況都會導致 Flatland 管道關閉。在這些錯誤狀態中,我們不清楚畫面上應繪製的內容,因此沒有任何點能允許用戶端繼續呈現。
隱私權注意事項
Flatland 不會公開任何裝置 ID 或隱私機密資訊。用戶端不會直接與硬體互動。
Flatland 可讓用戶端透過 SetDebugName() 設定可識別的偵錯字串。列印錯誤相關系統記錄時,這會用做前置字串,以協助用戶端區分錯誤內容。用戶端可完全掌控此處設定的內容,如未設定,系統記錄中就不會有前置字串。
缺點和替代方案
我們從 fuchsia.ui.gfx
的現有 3D API 中學到,是 Flatland 2D API 制定決策的基礎。我們在製定設計決策時,會將使用者的意見、錯誤和收穫
- 可以選擇在現有的 3D API 中推動 2D API 的演變。然而,在一些基本差異會讓用戶端和實作造成不必要的複雜。
- Flatland 可以使用類似
fuchsia.ui.gfx
的指令聯集模式。目前,每個 Flatland 指令都會對應到 FIDL 方法。之所以做出這項決定,是因為使用 3D API 中的現有指令模式觀察到陰性。我們必須為用戶端提供及維護不同語言的包裝函式。不過,將每則留言對應做為方法時,有一些負面見解。在我們支援在單一寫入中支援多則訊息之前,這項設計可避免進行批次處理。但我們不希望用戶端經常操弄場景圖,也認為這個情況的成本不高。
未來工作
我們計劃努力改善 Flatland API:
- 每個 Flatland 例項都會有相關聯的 ViewRef,以及擷取您和子項的 ViewRef 方法。請參閱 https://fxbug.dev/42159888。
- 這個「工廠函式」可將輸入通訊協定繫結至特定 Flatland 執行個體,因此將其範圍限制在執行個體的檢視畫面子樹狀結構。請參閱 https://fxbug.dev/42159922。
- 大小和指標會從父項到子項,但父項 (和中介伺服器) 不知道這些大小和指標生效的是哪個影格,只有第一個影格除外。這會造成影響:使用者可以看到瑕疵的影格,而其他 API 則是在用戶端邏輯中暴露於延遲情況。請參閱 https://fxbug.dev/42156345。
- 在多個執行個體間同步處理 Present() 時,視為尚未解決。請參閱 https://fxbug.dev/42159935。
- 扁平地將位於 fuchsia.ui.composition 命名空間及其依附元件底下。fuchsia.scenic.allocation 和 fuchsia.scenic.scheduling 同樣位於該處。請參閱 https://fxbug.dev/42158797。