EGL資源的資料共享應用和底層驅動實現

2021-10-24 19:36:09 字數 4347 閱讀 2152

已有 4201 次閱讀 2015-8-12 19:22 |個人分類:opengl|系統分類:科研筆記

為了某個原因成文於2023年,本文最有意義的是在最後揭示了如何實現免拷貝的資料共享(non-copy,zero-copy),我還沒有在之前的書籍教材中有看到過介紹的。通過cpu和gpu直接的資料直接共享,gpu之上各api之間的資料直接共享,可以大幅度的提高效能。這是個普遍的思路,在各種應用背景下都可以實現並使用。

摘  要   隨著移動裝置的廣泛應用,如何以更低的功耗提供更佳的使用者體驗成為乙個非常重要的課題。egl通過定義eglsu***ce和egl image等資源,使得不同renderingapi間以及和原生平台間的資料可以實現直接共享,從而降低功耗提高效能。本文整合分散在各種規範中的概念介紹了如何在應用層使用egl資源進行資料共享,並解釋了在驅動程式中是如何支援的思路,以深入理解,不僅知其然,而且知其所以然。

1.引言

egl是由khronos組織維護的、連線opengl es[[1]]和openvg[[2]]等rendering api與原生平台系統(native platformwindow system)的一套api介面,由核心規範[[3]]和擴充套件規範[[4]]組成。隨著移動裝置的廣泛應用,如何以更低的功耗提供更佳的使用者體驗成為乙個非常重要的課題。egl通過定義egl su***ce和egl image等資源,使得不同rendering api間以及和原生平台間的資料可以實現直接共享,而無需拷貝。這種無拷貝機制不僅減少了記憶體讀寫從而降低功耗,而且提高了效能從而改善使用者的體驗。

由於不同的egl資源在概念上相近,卻在核心規範和多個擴充套件規範中被分別定義,容易混淆,因此,很有必要總結成文釐清概念,並解釋其驅動程式的底層實現思路,以加深理解,從而更好的在移動裝置上的應用程式中用好egl資源。

2.egl資源在應用層的資料共享

egl su***ce和eglimage等egl資源在應用程式中的建立和使用是類似的,具體函式名不同,但是形式上是類似的。而且兩者最終都是通過成為繪製目標(renderingtarget)或者紋理資源(texture)來實現的,很容易造成函式的誤用。

2.1 egl su***ce的建立和使用

egl su***ce的建立和使用在egl核心規範中定義。egl su***ce分成 windowsu***ce、pixmapsu***ce和pbuffersu***ce三種型別,分別由函式eglcreatewindowsu***ce、eglcreatepixmapsu***ce和eglcreatepbuffersu***ce/eglcreatepbufferfromclientbuffer建立,如圖1所示,箭頭上的注釋是函式名。其中,windowsu***ce來自視窗系統,是最終在螢幕可見的su***ce;pixmapsu***ce和pbuffersu***ce則是不可見的,兩者區別在於pbuffersu***ce屬於egl建立,而pixmapsu***ce則是來自原生平台系統。隨著函式eglcreatepbufferfromclientbuffer的出現,使得pbuffersu***ce也可以來自原生平台系統。由於pixmapsu***ce的概念相對簡單,而且和視窗系統的不可見資源具有對應關係,因此,一般來說,我們會傾向使用pixmapsu***ce而不是pbuffersu***ce。

在圖1中,指向橢圓形egl su***ce的箭頭表示su***ce的被建立,而源自egl su***ce的箭頭則表示su***ce的被使用。箭頭起始端的矩形中的變數是該箭頭函式的主要引數,其中,eglnativewindowtype win和eglnativepixmaptype pixmap一般都在原生平台中被定義,所以可以被原生平台中支援的函式所直接訪問。例如x11系統中由xlib庫建立的window和pixmap。

無論哪種egl su***ce,都可以通過eglmakecurrent函式成為render target,但是,由於eglmakecurrent會導致graphics context的切換從而影響效能,所以,在可能的情況下,不可見的rendertarget一般不使用egl su***ce,而使用fbo技術(framebuffer object[[5]])。pbuffersu***ce還可以通過eglbindteximage函式成為紋理資源(texture),以作為graphicspipeline的資料**;一般來說,原生平台提供商還會增加乙個擴充套件規範,使得pixmapsu***ce也可以通過eglbindteximage函式成為texture。

2.2egl image的建立和使用

egl image最初在擴充套件規範egl_khr_image中定義,為了進一步擴充套件的需要,在2023年11月19號被分成為兩個擴充套件規範,如圖2的橢圓形eglimage向上部分所示,其中,egl_khr_image_base定義了eglimage的相關概念和相應的eglcreateimagekhr函式,該函式的兩個關鍵引數是target和buffer,另乙個擴充套件規範是egl_khr_image_pixmap,使得原生平台的pixmap可以被建立為egl image。在此基礎上,android平台提出了egl_android_image_native_buffer使得android平台定義的anativewindowbuffer可以被建立為egl image;還有egl_khr_gl_texture_2d_image,egl_khr_gl_texture_3d_image,egl_khr_gl_renderbuffer_image和egl_khr_gl_texture_cubemap_image等擴充套件規範使得opengles中的資源可以被建立為egl image。一般的,每個原生平台提供者都會提供其私有的擴充套件規範來建立相應的eglimage。

egl image的使用在opengles的擴充套件規範中被定義,如圖2的橢圓形egl su***ce部分向下所示,首先,egl image被重新定義(typedef)為gleglimageoes,然後,擴充套件規範gl_oes_egl_image定義了兩個函式,使得egl image可以被當做2d texture或者renderbuffer使用,可分別作為graphicspipeline的資料**和繪製目標。另乙個擴充套件規範gl_oes_egl_image_external定義了乙個新的texture型別gl_texture_external_oes,使得諸如yuv等以前不被opengl es支援的格式的egl image,可以被直接作為乙個texture從而被opengl es所支援,當然,其背後離不開驅動程式內部增加shader指令進行格式轉換,假以時日,可能會出現直接支援yuv等格式的texture取樣硬體。

3.egl資源在驅動底層的實現

egl su***ce和eglimage資料結構的c語言定義都是void *,它們可以從多種**被建立,也有多個使用場合,那麼,在驅動底層是如何光憑void *就能知道當前情況呢,乙個參考實現是使用基礎struct和magic number,其中,magic number在基礎struct中被定義,所有相關資源資料結構的最開始部分就是基礎struct。這樣,在建立時返回對應資源資料結構(struct)的指標作為void *的handle,在使用時則將此handle強制轉回基礎struct指標,然後根據struct中magic number資料成員的值來得知原始資源是什麼從而將其用好。

之前提到,有些資源還可以被原生平台提供的函式讀寫,那麼,是怎麼實現cpu和gpu對同一資源的訪問呢?拋開表象看本質,我們知道所有資源最終都是由物理儲存器中的記憶體頁面組成,cpu通過其記憶體管理單元(mmu)進行位址對映從而訪問到真實儲存,有了這些資訊,核心態的驅動程式就可以通過配置gpu的類mmu單元,從而使得gpu也可以訪問這些資源,這也就意味著graphicspipeline可以讀寫這些資源。在此,需要特別關注並解決好cpu和gpu對同一資源的併發訪問和cache重新整理的技術問題。

4.結語

知其然,也知其所以然。通過以上對egl su***ce和eglimage的介紹,包括如何建立和使用,也包括在驅動底層的支援思路,可以深入理解這些egl資源的無需拷貝的資料共享機制是如何降低功耗和提高效能。特別地,將所有相關重要概念都在文中的兩幅圖中表現出來,做到一目了然,這對用好egl資源具有重要意義。限於篇幅所限,無法對egl su***ce和eglimage進行更多細節上的介紹,需要使用者在使用細節上參考相應的egl和opengles的核心規範和擴充套件規範。

參考文獻

[1]opengl es - the standard for embedded accelerated 3d graphics, 

[2]openvg - the standard for vector graphics acceleration, 

[3]jon leech, khronos native platform graphics inte***ce (egl version 1.4 – april6, 2011) 

[4]khronos egl api registry, 

[5]aaftab munshi, gl_oes_framebuffer_object, 

擴充套件參考

執行緒的共享資源和私有資源

執行緒共享的環境包括 程序 段 程序的公有資料 利用這些共享的資料,執行緒很容易的實現相互之間的通訊 程序開啟的檔案描述符 訊號的處理器 程序的當前目錄和程序使用者id與程序組id。程序擁有這許多共性的同時,還擁有自己的個性。有了這些個性,執行緒才能實現併發性。這些個性包括 1.執行緒id 每個執行...

用資料共享和大資料思維挖掘應用系統市場的新商機

隨著新經濟環境和新商業規則的產生,應用系統使用者的業務運作環境和需求也發生了巨大的變化,以前的應用系統產品關注的是企業使用者本身內部的業務資料,而現在隨著新商業規則的建立,企業的管理範圍擴大了,需要協同的業務以及整合的資源也更多了,這就使得資料互動和共享的需求越發的強烈,應用系統廠商如果能變換角度,...

關於TCP的Ack(應用層和底層協議)

當用tcp ip協議進行通訊時,在傳送端,send首先會將資料copy到協議的快取區,然後協議會將資料傳送到接收端,接著會等待接收端協議收到資料的ack,如果沒有收到ack,協議就會重發資料,在這一過程中send一直在等待,直到收到ack,當協議收到ack後才將協議快取中的資料刪除,因此從協議上來說...