RFC-0161:風景式 Allocator API

RFC-0161:景觀配置器 API
狀態已接受
區域
  • 顯示卡
說明

用於 API 校正的前版 API 設計文件。

變更
作者
  • emircan@google.com
審查人員
提交日期 (年/月)2021-03-19
審查日期 (年/月)2021-04-05

過去 API 設計文件

這個 RFC 先前是以 API 設計文件的形式提交,之後在 API 設計文件範本淘汰時轉換為 RFC。

摘要

本文件提議將風景圖像資源配置擷取為獨立通訊協定的計畫。

目標和應用實例

Allocator API 旨在改善現有的圖像配置流程,並確保該流程與即將發布的變更相容。

  • 從「風景」:延伸分配的 BufferCollection 資源範圍。一個 BufferCollection 可用來在多個「::Sessions」中建立圖片資源,以及我們即將推出的 2D API Flatland 工作階段。

  • 將緩衝區分配與 View::Session 區分開來,讓通訊協定明確易懂。配置器只會處理緩衝區配置,而「View::Sessions」則是用來顯示及繪圖。

  • 我們的 3D API 和即將推出的 2D API,都能使用配置器。這允許較複雜的圖形用途。

利用這個 API,更複雜的使用者可以在獨立的場景::工作階段之間共用圖片資源。但這個做法目前並不可行,且通常會強制運作。

設計

我們的建議主要是將緩衝區註冊和取消註冊功能移出 View::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 - 映像檔建立流程 這張圖顯示了關係用戶端、分配器和呈現 API。

請注意,不再需要取消註冊緩衝區。您可以直接在用戶端捨棄所有 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。
  • 用戶端可複製,並在多個「View::Sessions」中重複使用事件組合的另一端,以建立圖片資源。

請參閱以下的「風景::工作階段」使用模式範例。

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 進行大量單元測試。如果需要使用配置器與「風景::工作階段」協調的整合測試,可以轉換我們的樹狀結構內像素測試來完成。

效能注意事項

Allocator API 不會新增其他任何 API 呼叫。這可防止用戶端執行 DeregisterBufferCollection 呼叫。

安全性考量

分配器 API 仰賴 EVENTPAIR 功能解決安全性問題。EVENTPAIR 也具有獨特性,在建立時與其他端點建立緊密關係,確保惡意用戶端不能盜用及存取基礎緩衝區。如果他們以某種方式取得 EVENTPAIR,他們只能分享這張圖片,無法修改或讀取。

缺點與替代方案

Allocator API 提案有兩個主要改善點,兩者可由現有的通訊協定和流程取代。

  • 我們可以繼續使用專屬 ID 參照緩衝區集合,而非事件組合。我們可預期用戶端選取不重複的集合 ID,或從註冊呼叫傳回專屬集合 ID。
    • 選擇專屬 ID 需要同步,無論用戶端要尋找工作 ID 並等待 Allocator 確認才能使用。
    • 專屬 ID 很容易遭到惡意用戶端駭客入侵。
    • 我們需要明確的 DeregisterBufferCollection() 呼叫。
  • 我們可以將 Allocator 保留在 View::Session 和 Flatland 執行個體,而非公開新的通訊協定。
    • 處理多個工作階段的複雜用戶端仍會受限於其註冊工作階段後,無法使用緩衝區集合的限制。