RFC-0174:在平面上縮放 | |
---|---|
狀態 | 已接受 |
區域 |
|
說明 | 定義在 Flatland 中處理圖形縮放作業的方式。 |
問題 | |
Gerrit 變更 | |
作者 | |
審查人員 | |
提交日期 (年-月-日) | 2022-06-02 |
審查日期 (年-月-日) | 2022-07-01 |
摘要
這份 RFC 說明如何在 Flatland 中處理圖形縮放作業。Scenic 是 Fuchsia 的系統合成器,可透過 Flatland 的 SetScale() 方法,處理 Flatland 例項輸出的向上或向下縮放作業。您可以使用浮點縮放因數,確保產生的圖片不會進行子像素算繪。Flatland 例項只知道裝置像素比例值。除了設計比例外,本 RFC 也定義了一些常見的術語,用於指稱像素空間。
提振精神
許多 UI 功能通常需要圖形縮放作業,而 Flatland 作為完整的系統合成器,應提供這類功能。以下將詳細說明其中三個。
向上取樣
上採樣是指增加 Flatland 例項或圖片的算繪大小。舉例來說,請考慮放大功能。您可以要求 Scenic 將 Flatland 用戶端應用程式的輸出內容向上取樣,以便放大圖像。
縮小取樣
降採樣是指縮減 Flatland 例項或圖片的算繪大小。舉例來說,請考慮使用 GNOME 的活動總覽。圖形系統殼層可能會希望讓 Flatland 用戶端應用程式繼續以相同解析度算繪,但透過 Scenic 將內容輸出縮減至較小的矩形。
裝置像素比例
裝置像素比率的定義可讓螢幕製造商在升級裝置解析度的同時,仍能以相同大小顯示為較低解析度設計的內容。舉例來說,從遠處看,4K 和 1080p 螢幕版本的筆電會看起來一模一樣,所有按鈕和版面配置的大小都相同。只有在靠近觀看時,你才能看出 4K 畫面更清晰,因為 4K 畫面在相同實體空間中可容納 1080p 畫面 4 倍的實體像素。
相關人員
協助人員:neelsa@google.com
審查者:
- 輸入:neelsa@google.com、quiche@google.com
- 無障礙工具:lucasradaelli@google.com
- Scenic:jaeheon@google.com、dworsham@google.com、jjosh@google.com
社會化:
我們已在內部審查這項設計的詳細版本,並與 Scenic、輸入和無障礙功能團隊進行討論。我們也討論了其他解決方案。
詞彙解釋
- Flatland
- Scenic 的新 2D 合成 API。
- Gfx
- Scenic 已淘汰的舊 3D 組合 API。
- 查看
- 圖像內容的視覺區域。
- 它具有座標系統、邊界框,以及透過 View 樹狀圖定義的祖系空間關係。
- HiDPI
- 高解析度 (每英寸像素數)。
- 這個術語是業界用來描述在相同實體區域中,將更多像素塞入螢幕的做法。舉例來說,解析度為 240 dpi 以上的螢幕就屬於高解析度。
- PP
- 實體像素。
- 螢幕的實體像素數量。舉例來說,如果我們有 4K 和 FHD 螢幕的不同版本筆電,4K 的實體像素為 3840 x 2160,FHD 的實體像素為 1920 x 1080,因此兩種筆電版本的圖示大小相同,但 HiDPI 螢幕的圖示會更清晰
- DIP
- 裝置獨立像素,又稱為邏輯顯示像素或密度獨立像素。
- 螢幕的邏輯像素數量,也就是說,如果我們有 4K 和 FHD 螢幕的變化版本,同樣都是 4K 和 FHD,則兩者都很可能有 1920x1080 個裝置獨立像素。
- DPR
- 裝置像素比例。
- 螢幕的實體像素與裝置獨立像素之間的比例。
- 到達網頁
- 邏輯 View 像素,又稱為 View 的裝置獨立像素
- View 的邏輯像素數量。會影響內容版面配置。
- AP
- 分配像素。
- View 的繪圖緩衝區分配像素數量。
- PSS
- 父項設定的刻度,又稱為累積刻度。
- 所有父項 SetScale() 值相乘。View 的 DIP 與螢幕 DIP 之間的比率。
設計
為了滿足「動機」一節所述的所有用途,我們定義了一組關係,藉此建立上層檢視畫面可在子項上設定的值 (由上層定義)、僅可由 Flatland 設定的值 (由系統定義),以及子項可觀察的值 (由子項觀察)。
裝置像素比例是系統為單一螢幕上的所有檢視畫面統一定義的值。兒童觀察的 DPR
子檢視畫面的大小以 LPs 為單位。這個大小是由父項定義並由子項觀察。如果畫面檢視區塊的大小和對齊方式與用於轉譯畫面檢視區塊的螢幕 DIP 完全一致,則畫面檢視具有最佳解析度。檢視區塊應以最佳解析度運作,其中 LP=DIP 的大小和對齊方式。不過,最佳解析度「不會」由子項觀察,且可由父項檢視畫面 (使用 Scale,請見下文) 故意中斷,以便使用放大鏡或 GNOME 的「活動」概覽等功能。
比例會以浮點值的形式提供。它是由父項定義,但不是由子項觀察到!子項檢視畫面的父項設定比例是該子項所有祖系檢視畫面引入的所有比例相乘。PSS 會說明子檢視區塊的 LP 與螢幕 DIP 的比例。隱藏 PSS 後,Flatland 會保留對子項檢視畫面在螢幕上佔用多少「實體像素」的控制權,不會在向上或向下取樣時強制子項重新分配或重新呈現。
我們進一步區分分配像素,這是用於呈現內容的緩衝區大小。這是用戶端實作細節,但為了避免混淆,我們會說明其與其他像素空間的關係:
- HiDPI 感知用戶端希望顯示清晰的畫面,並能控制內容大小。其分配像素是邏輯觀看次數像素乘以 DPR。
- 不重視 DPR 的客戶只想以一種尺寸呈現內容。這些廣告會忽略 DPR,且其分配像素等同於邏輯檢視像素。
- 自訂分配用戶端的內容會強制執行分配像素,例如影片播放器或 WebCanvas。這些用戶端會在分配像素和邏輯檢視像素之間定義關係。
Flatland 對應:
- PPDisplay = DIPDisplay* DPR
- PPView = LPView * PSS * DPR
- 客戶是否要將 APView 轉換為 LPView,其實是他們自己的事。
- 建議針對支援高解析度的用戶端,使用 APView = LPView * DPR。
上述像素空間關係如圖 1 所示。
圖 1 - 平面世界
以下 FIDL 程式碼片段代表建議的變更:
type LayoutInfo = table {
/// The layout size of a View in logical pixels, defined by the parent's call to
/// [`SetViewportProperties`]. Clients should re-layout their content when this value changes.
1: logical_size fuchsia.math.SizeU;
/// The ratio from physical display pixels to the display's device independent pixels.
/// Clients should not necessarily re-layout their content when this value changes. Clients may
/// accommodate by reallocating their Image buffers that are adjusted by [`device_pixel_ratio`].
/// HiDPI-aware clients that want to avoid sampling artifacts should render onto a buffer with
/// at least the size round([`logical_size`] * [`device_pixel_ratio`]).
/// Note that rounding is not C-style float-to-int truncation. The floating-point product should
/// be converted to the nearest integer.
2: device_pixel_ratio fuchsia.math.VecF;
};
protocol Flatland {
/// Sets the scale on a Transform. The order of geometric attribute application is addressed
/// in the documentation for SetTranslation().
/// Note that if there is a Viewport set on this Transform, the child Flatland will not be notified
/// about the changes made here. This method should only be used if the intention is to upsample or
/// downsample the Viewport's output. Use [`SetViewportProperties`] if the intention is to resize or
/// relayout the Viewport.
SetScale(struct {
transform_id TransformId;
scale fuchsia.math.VecF;
});
}
在 Scenic 算繪或傳送至螢幕之前,系統會將 DPR 套用為每個圖片的比例。如果用戶端想要支援 HiDPI,則應使用指定的 LP 進行內容版面配置,但使用回報的 DPR 分配較大的緩衝區,以便反轉 Scenic 縮放的效果。
我們不會向兒童提供 PSS。也就是說,透過 Flatland 放大可能會產生模糊的構件。不過,這比強制要求用戶端重新分配和重新呈現更為理想,因為緩衝區大小會隨著比例因數增加,並導致 OOM 風險。
我們可能會得到非整數像素,並且具有浮點比例。如果我們有一致的方式來附加附近的整數像素值(四捨五入),就不會產生人工製品。
Flatland 客戶可能會想從邏輯像素轉換為實體像素,除了 DPR 之外,還需要知道 PSS。不過,這項功能只適用於輸入內容,因此這個設計會將轉換資訊推送至 fuchsia.ui.pointer
API。
用戶端可以使用這個 API,自行決定何時回應 DPR 變更。這些變更都會同時傳送信號,因此不會出現層層遞延的卡頓模式。
用戶端應一律預期使用單一 DPR 值。日後支援多螢幕時,我們可以回報來自多螢幕的單一 DPR 值,或是所用螢幕的 DPR 值。
與舊版比較
請注意,在 Gfx(舊版 3D API) 中,DPR 和 PSS 會相乘為單一值,並回報給子項。因此,縮放操控會導致用戶端程式碼中的配置副作用,進而導致 OOM 和其他非預期的副作用,包括為了達到放大效果和 DPR 相關的混淆,而採用大規模架構因應措施。這項 Flatland 設計的差異在於,它建議子項只需要知道 DPR 的圖形用途。
Gfx 對應:
- PPView = LPView * pixel_scale
- pixel_scale = PSS * DPR
- pixel_scale 是 Gfx 傳回的唯一指標。
實作
這項設計涉及 fuchsia.ui.composition/Flatland
API 的變更。實作程序主要分為三個步驟:
- 移除已淘汰的
pixel_scale
欄位使用情形,樹狀結構內和樹狀結構外。 - 完成樹狀結構內變更。根據螢幕回報的內容,傳送 DPR 資訊。
- 變更樹狀結構內和樹狀結構外的用戶端程式碼,以便利用 DPR 資訊調整 AP。
成效
相較於 Gfx API,本提案可減少 DPI 感知用戶端的記憶體用量。在 Gfx 中,DPR 和 PSS 會相乘為單一值,並回報給子項。DPI 感知用戶端會回應所有縮放比例的累積值。舉例來說,如果父項變數將其縮放 5,並套用 DPR 2,則會收到 pixel_scale
10,並分配 10 倍大的緩衝區。這項提案會區分 DPR 和 PSS,因此不會有不必要的配置。
這項提案可降低用戶端重新分配和重新排版的預期。我們不再需要仰賴 Flatland 用戶端回應縮放變更,因此可以實作更流暢的升取樣和降取樣作業。
安全性考量
這項提案不會影響 Flatland API 的安全性模型。其他圖形作業 (例如限制 View 輸入接收區域的剪輯) 的 API 保證仍會套用至經過縮放的內容。
這項提案可減少傳遞至 Flatland 檢視畫面的資訊範圍。在 Gfx 中,DPR 和 PSS 會相乘為單一值,並回報給子項。這個提案只會回報 DPR 資訊。子 Flatland 執行個體無法得知其父 Flatland 執行個體如何決定要呈現內容 (是否經過縮放),也無法回應縮放變更。
隱私權注意事項
這項提案建議將 DPR 資訊傳送給 Flatland 客戶。裝置像素比例取決於顯示單元的物理和技術屬性。雖然這項屬性和比率非常具體,但不具唯一性,且可能在多種硬體中通用,因此不太適合用於指紋辨識。此外,為準備高品質的圖形輸出內容,DPR 絕對是必要的。
測試
Flatland API 已以分層方式進行測試,並將採用下列縮放功能:
- Scenic 程式碼庫中的單元測試。
- 位於 /src/ui/tests 中的 UI 整合測試,可執行 Flatland API 相關的契約。
- 系統測試,可擷取 DPR 值不等於 1 的裝置輸出像素。
- Chromium 和 Flutter 等執行階段會編寫整合測試,以測試 SetScale() 的使用情形和不同的 DPR 值。
說明文件
我們會根據這份 RFC 更新部分 Flatland 說明文件,以便說明支援高 DPI 的用戶端行為,以及縮放功能的運作方式。
缺點、替代方案和未知事項
實施這項提案不會產生太多成本。這項提案建議使用 DPR 解決方案,無論使用哪種顯示硬體都能運作。也可能會擴展至多螢幕用途。
我們考慮了幾種替代設計。
- 在部分 Chromium 設定中,DPR 已新增為可設定的靜態值。這顯然無法在不同應用程式中擴充。
- 為避免捨入問題,我們只考慮允許整數比例因子。不過,部分 DPR 設定有例外狀況。
- 當我們有浮點值時,可能會陷入緩慢的子像素轉譯路徑。不過,這麼做並沒有必要,而且會阻礙效能,因為無法讓效能直接將緩衝區傳送至螢幕。
既有技術與參考資料
- RFC-0162:Flatland
- RFC-0147:View 系統
- RFC-0166:One UI 堆疊
- Flatland 與 Wayland 通訊協定有一些相似的架構,兩者處理高密度介面的方式也與建議的設計類似。