RFC-0161:Scenic Allocator API | |
---|---|
狀態 | 已接受 |
區域 |
|
說明 | 針對 Scenic Allocator 的舊版 API 設計文件,用於 API 校正。 |
Gerrit 變更 | |
作者 | |
審查人員 | |
提交日期 (年-月-日) | 2021-03-19 |
審查日期 (年-月-日) | 2021-04-05 |
舊版 API 設計文件
這項 RFC 先前是以 API 設計文件提交,後來在 API 設計文件範本淘汰後轉換為 RFC。
摘要
本文件提出了提案,將 Scenic 的圖像資源分配提取到個別通訊協定中。
目標和用途
Allocator API 旨在改善現有的圖片分配流程,並使其與即將推出的變更相容。
擴大從 Scenic::Session 配置的 BufferCollection 資源範圍。一個 BufferCollection 可用於在多個 Scenic::Session 和即將推出的 2D API Flatland 工作階段中建立 Image 資源。
將緩衝區配置與 Scenic::Session 分開,可讓通訊協定的用途更加明確。Allocator 只會處理緩衝區配置,而 Scenic::Sessions 則用於呈現和繪製。
分配器可供 3D API 和即將推出的 2D API 使用。這可讓您使用更複雜的圖形。
使用這個 API 後,更複雜的使用者可以在各自的獨立 Scenic::Session 之間共用圖片資源。但目前無法執行此操作,而且通常會強制重新配置。
設計
我們建議您將緩衝區註冊和註銷功能從 Scenic::Session 移至新通訊協定。請參閱下方的建議通訊協定。
library fuchsia.ui.composition;
/// A typed wrapper for an eventpair, representing the registry endpoint of a buffer collection.
resource struct BufferCollectionExportToken {
zx.handle:EVENTPAIR value;
};
/// A typed wrapper for an eventpair, representing the Image import endpoint of a buffer
/// collection.
resource struct BufferCollectionImportToken {
zx.handle:EVENTPAIR value;
};
protocol Allocator {
/// A BufferCollection is a set of VMOs created by Sysmem and shared by a number of
/// participants, one of which is the Flatland Renderer. Some content, such as Images, use a
/// BufferCollection as their backing memory.
///
/// Clients can send `export_token` to register buffer collections with Allocator to be used
/// later in [`fuchsia.ui.composition/Flatland`] instances or other Scenic APIs. For
/// example, by passing a [`BufferCollectionImportToken`] containing the matching peer of
/// [`BufferCollectionExportToken`], they can create image resources via
/// [`fuchsia.ui.composition/Flatland.CreateImage`]. Clients should wait for the response
/// before using `import_token`.
///
/// Flatland participates in the allocation of buffers by setting constraints on the
/// BufferCollection referenced by `buffer_collection_token`. It will not block on buffers
/// being allocated until the client creates content using the BufferCollection.
///
/// The buffer collection registered with `export_token` is available and kept alive as long
/// as the client holds a valid [`BufferCollectionImportToken`]. They will be garbage collected
/// when all [`BufferCollectionImportToken`]s are closed and all the associated Image resources
/// are released.
RegisterBufferCollection(BufferCollectionExportToken export_token,
fuchsia.sysmem.BufferCollectionToken buffer_collection_token)
-> () error RegisterBufferCollectionError;
};
圖 1 - 圖片建立流程
請注意,您不再需要取消緩衝區註冊。您可以透過在用戶端端捨棄所有 BufferCollectionImportToken 例項,隱含執行這項操作。許多用戶端在發生意外關機時,無法順利執行註銷流程,因此這項功能可更有效地防範記憶體外洩。
現有的緩衝區註冊功能要求用戶端定義專屬 ID,以便參照 BufferCollection。這個事件已由 EVENTPAIR 取代,客戶可以輕鬆複製這個事件,並用於參照。請參閱下方的現有流程。
protocol Session {
RegisterBufferCollection(uint32 buffer_id, fuchsia.sysmem.BufferCollectionToken token);
DeregisterBufferCollection(uint32 buffer_id);
};
我們持續進行建議設計的開發工作,並完成必要的重構。如需瞭解實際變更,請參閱 fxr/498558 和 fxr/499479。
可用性
Allocator API 可讓您以不同的方式實現現有功能,從客戶的角度來看,這麼做會更簡單。
- 用戶端會建立 EVENTPAIR,而非找出專屬 ID。
- 用戶端可以放棄事件組的另一端,而非明確呼叫具有相同唯一 ID 的 DeregisterBufferCollection。
- 用戶端可以在多個 Scenic::Session 中複製並使用事件對的另一端,以便建立 Image 資源。
請參閱下方 Scenic::Session 的使用模式示例。
fuchsia::ui::composition::AllocatorPtr scenic_allocator;
fuchsia::sysmem::BufferCollectionTokenSyncPtr token;
auto ref_pair = allocation::BufferCollectionImportExportTokens::New();
scenic::SessionPtr session;
scenic_allocator->RegisterBufferCollection(std::move(ref_pair.export_token), std::move(token),
[&]() {
session->Enqueue(scenic::NewCreateImage3Cmd(
image_id, width, height,
std::move(ref_pair.import_token), vmo_index));
});
測試
我們計畫針對 API 新增大量單元測試。整合測試需要使用分配器,並與 Scenic::Session 協調,您可以透過轉換樹狀結構內的像素測試來執行這類測試。
效能考量
Allocator API 不會新增任何額外的 API 呼叫。這樣一來,用戶端就不會執行 DeregisterBufferCollection 呼叫。
安全性考量
Allocator API 會利用 EVENTPAIR 功能解決安全性問題。由於 EVENTPAIR 具有唯一性,且在建立時與其他端點有強烈關聯,因此惡意用戶端無法劫持並存取基礎緩衝區。如果他們以某種方式取得 EVENTPAIR,就只能顯示這張圖片,無法修改或讀取。
缺點和替代方案
Allocator API 提案有兩個主要改善要點,其中任一要點都可以由現有的通訊協定和流程取代。
- 我們可以繼續使用專屬 ID 參照緩衝區集合,而非事件組合。我們可以預期用戶端會選取專屬的收集 ID,或是從註冊呼叫中傳回專屬的收集 ID。
- 選擇專屬 ID 時需要進行同步處理,因為用戶端必須找到可運作的 ID,並等待分配器確認才能使用。
- 惡意用戶端很容易劫持專屬 ID。
- 我們需要明確的 DeregisterBufferCollection() 呼叫。
- 我們可以將 Allocator 保留在 Scenic::Session 和 Flatland 例項中,而非公開新的通訊協定。
- 使用多個工作階段的複雜用戶端仍有限制,無法使用註冊的一個工作階段以外的緩衝區集合。