同步處理架構

同步處理架構會明確說明 Android 圖形系統中不同非同步作業之間的依附元件。架構 這類 API 可讓元件指出緩衝區釋放時間。架構還 可讓同步處理基元從核心之間傳遞到驅動程式 以及使用者空間程序本身

舉例來說,應用程式可能會將要執行的作業排入 GPU 工作佇列。GPU 會開始繪製該圖片。雖然圖片尚未繪製到記憶體中,但緩衝區指標會連同表示 GPU 工作何時完成的柵欄傳遞至視窗合成器。視窗合成器會提前開始處理作業,並將工作傳遞至顯示控制器。CPU 運作時 就完成了GPU 完成後,顯示控制器會立即顯示圖片。

同步處理架構也能讓實作者 共用硬體元件最後,該架構會提供圖形處理管道的可視性,以利偵錯。

明確同步

明確同步處理可讓圖形緩衝區的製作者和取用者 在停止使用緩衝區時發出信號。明確同步處理為 並在核心空間中實作。

明確同步的優點包括:

  • 裝置間的行為差異較小
  • 提供更完善的偵錯支援
  • 經過改良的測試指標

同步處理架構有三種物件類型:

  • sync_timeline
  • sync_pt
  • sync_fence

sync_timeline

sync_timeline 是單調遞增的時間軸,供應商應為每個驅動程式例項 (例如 GL 內容、顯示控制器或 2D blit 器) 實作此時間軸。次數:sync_timeline 傳送到特定硬體的核心工作。 sync_timeline 可保證作業順序,並啟用硬體專屬的實作項目。

實作 sync_timeline 時,請遵循下列準則:

  • 為所有驅動程式、時間表和柵欄提供實用的名稱,以簡化偵錯作業。
  • 導入 timeline_value_strpt_value_str 時間軸中的運算子,讓輸出的偵錯更容易理解。
  • 實作填充 driver_data,讓使用者空間程式庫 (例如 GL 程式庫) 存取私人時間軸資料 (如有需要)。data_driver 可讓供應商傳遞無法變更的資訊 使用 sync_fencesync_pts 建構指令列 據此做出調整
  • 請勿允許使用者空間明確建立或發出邊界信號。明確 建立信號/圍欄會導致阻斷服務攻擊, 能終止管道的功能
  • 請勿存取 sync_timelinesync_ptsync_fence 元素。這個 API 提供了 函式。

Sync_pt

sync_ptsync_timeline 上的單一值或點。點有三種狀態:有效、已發出信號和錯誤。積分會以有效狀態開始 並轉換成信號或錯誤狀態舉例來說,當圖片使用者不再需要緩衝區時,系統會發出 sync_pt 信號,讓圖片產生者知道可以再次寫入緩衝區。

sync_fence

sync_fence 是一組 sync_pt 值 經常 有不同的 sync_timeline 父項 (例如針對螢幕) 和 GPU)。sync_fencesync_ptsync_timeline 是驅動程式和使用者空間用來傳達其依附元件的必要元素。當邊界發出信號時,系統會保證邊界前發出的所有指令都已完成,因為核心驅動程式或硬體區塊會依序執行指令。

同步處理架構可讓多個消費者或生產者在使用緩衝區後傳送信號,藉此透過一個函式參數傳達依附元件資訊。柵欄由檔案描述元支援,並從核心空間傳遞至使用者空間。例如,一個圍欄可以包含兩個 sync_pt 值,用於表示兩張圖片消費者分別完成的操作 讀取緩衝區圍欄發出訊號時,圖片生產者會知道兩者皆是 包括所得體驗

柵欄與 sync_pt 值一樣,會在啟用後根據其點的狀態變更狀態。如果所有 sync_pt 值都變成信號,系統就會判定 sync_fence 已發出訊號。如果一個 sync_pt 下降 變成錯誤狀態,整個 sync_fence 都有錯誤狀態。

建立柵欄後,sync_fence 的成員資格即無法變更。如要在一個圍欄中取得多個資料點,合併作業是 執行時,會將兩個不同圍欄的點新增到第三個圍欄。 如果有其中一個點收到了原圍欄的訊號,另一個定點則沒有。 也不會處於訊號狀態。

如要實作明確的同步處理,請提供下列資訊:

  • 實作同步處理架構的核心空間子系統 特定硬體驅動程式的安裝記錄需要支援邊界功能的驅動程式,通常是指任何會存取或與硬體編譯器通訊的驅動程式。主要檔案包括:
    • 核心實作:
      • kernel/common/include/linux/sync.h
      • kernel/common/drivers/base/sync.c
    • kernel/common/Documentation/sync.txt 的說明文件
    • 可與 platform/system/core/libsync 中的核心空間通訊的程式庫
  • 供應商必須提供適當的同步處理作業 做為 validateDisplay() 和 HAL 中使用 presentDisplay() 函式。
  • 兩個圍欄相關 GL 擴充功能 (EGL_ANDROID_native_fence_syncEGL_ANDROID_wait_sync) 在圖形中支援圍欄 驅動程式庫。

個案研究:實作顯示驅動程式

如要使用支援同步處理函式的 API, 開發具有顯示緩衝區函式的顯示驅動程式。之前 已存在的同步處理架構,此函式將收到 dma-buf 這些緩衝區,請在顯示器上放置這些緩衝區,當緩衝區顯示時,接著封鎖。例如:

/*
 * assumes buffer is ready to be displayed.  returns when buffer is no longer on
 * screen.
 */
void display_buffer(struct dma_buf *buffer);

透過同步處理架構,display_buffer 函式 較複雜將緩衝區顯示在螢幕上時,緩衝區會與柵欄建立關聯,以便指出緩衝區何時會就緒。可加入待播清單 待圍欄消除後再開始工作

在圍欄消除後排出及啟動工作不會阻擋任何現象。 您會立即傳回自己的邊界,確保緩衝區何時會離開顯示畫面。將緩衝區排入佇列時,核心清單 與同步處理架構的依附元件:

/*
 * displays buffer when fence is signaled.  returns immediately with a fence
 * that signals when buffer is no longer displayed.
 */
struct sync_fence* display_buffer(struct dma_buf *buffer, struct sync_fence
*fence);

同步整合

本節說明如何整合核心空間同步架構與 Android 架構的使用者空間部分和必須通訊的驅動程式 彼此之間的通訊核心空間物件會在 使用者空間

整合慣例

遵循 Android HAL 介面慣例:

  • 如果 API 提供參照 sync_pt 的檔案描述元,使用 API 的供應商驅動程式或 HAL 必須關閉檔案描述元。
  • 如果供應商驅動程式或 HAL 將包含 sync_pt 的檔案描述元傳遞至 API 函式,則供應商驅動程式或 HAL 不得關閉檔案描述元。
  • 如要繼續使用柵欄檔案描述元,供應商驅動程式或 HAL 必須複製描述元。

每次通過 BufferQueue 時,Fence 物件都會重新命名。 核心圍欄支援可讓 Fences 擁有名稱字串,因此同步處理 架構會使用目前正在排入佇列的視窗名稱和緩衝區索引 圍欄,例如 SurfaceView:0。這個 有助偵錯在名稱顯示時,找出死結的來源 會列於 /d/sync 和錯誤報告的輸出內容中。

ANativeWindow 整合

ANativeWindow 會偵測圍欄。dequeueBuffer, queueBuffercancelBuffer 具有圍欄參數。

OpenGL ES 整合

OpenGL ES 同步整合功能需要使用兩個 EGL 擴充功能:

  • EGL_ANDROID_native_fence_sync 可讓您 納入或建立原生 Android 圍欄檔案描述元 EGLSyncKHR 物件。
  • EGL_ANDROID_wait_sync 允許 GPU 端停滯,而非 CPU 端,讓 GPU 等待 EGLSyncKHREGL_ANDROID_wait_sync 副檔名與 EGL_KHR_wait_sync 擴充功能。

如要獨立使用這些擴充功能,請實作 EGL_ANDROID_native_fence_sync 擴充功能,並提供相關的核心支援。接著,請在驅動程式中啟用 EGL_ANDROID_wait_sync 擴充功能。EGL_ANDROID_native_fence_sync 擴充功能由獨特的原生圍欄 EGLSyncKHR 物件組成 類型。因此,凡是套用至現有EGLSyncKHR的額外資訊 物件類型不一定適用於 EGL_ANDROID_native_fence 避免不必要的互動

EGL_ANDROID_native_fence_sync 擴充功能採用對應的原生圍欄檔案描述元屬性,只能在建立時設定,且無法直接從現有的同步物件查詢。這個屬性可設為下列兩種模式之一:

  • 有效的圍欄檔案描述元會包裝現有的原生檔案 EGLSyncKHR 物件中的 Android 圍欄檔案描述元。
  • -1 會根據 EGLSyncKHR 物件。

使用 DupNativeFenceFD() 函式呼叫,從原生 Android 圍欄檔案描述元中擷取 EGLSyncKHR 物件。這與查詢 set 屬性所產生的結果相同,但會遵循收件者關閉圍欄的慣例 (因此是重複作業)。最後,銷毀 EGLSyncKHR 物件會關閉內部柵欄屬性。

硬體 Composer 整合

Hardware Composer 會處理三種類型的同步圍欄:

  • 取得圍欄會連同輸入緩衝區一併傳遞給 setLayerBuffersetClientTarget 呼叫。 這些代表緩衝區的待寫入資料,必須在 SurfaceFlinger 或 HWC 嘗試從相關聯的緩衝區讀取資料以執行合成作業之前,先發出信號。
  • 使用 getReleaseFences 呼叫對 presentDisplay 的呼叫後,系統會擷取釋放柵欄。這些代表來自相同圖層上前一個緩衝區的待處理讀取。當 HWC 不再使用先前的緩衝區,因為目前的緩衝區已取代顯示器上的先前緩衝區,此時會發出釋放柵欄信號。釋放柵欄會連同先前的緩衝區傳回應用程式,這些緩衝區會在目前的組合期間替換。應用程式必須等待 先釋放柵欄信號,再將新內容寫入緩衝區 傳回的訊息。
  • 系統會在呼叫 presentDisplay 時傳回Present 柵欄,每個影格一個。圍欄 是指 這個影格完成 或 相反地 不再需要前一個影格的組合結果。實體適用 螢幕,presentDisplay 會在 螢幕上就會顯示目前的畫面當現況柵欄傳回後,如果適用,您可以放心再次寫入 SurfaceFlinger 目標緩衝區。對於虛擬螢幕,當從輸出緩衝區讀取資料時,系統會傳回目前的邊界。