天天看點

Android圖形顯示系統——下層顯示2:圖形記憶體的申請與顯示圖形記憶體的申請與顯示

這一篇回答序言中的第一個問題:

如何申請可以用來送顯的記憶體,如何将其送往lcd?

圖形記憶體是程序共享記憶體,且根據其标志支援不同硬體裝置的讀與寫。

buffer_handle_t 是 *private_handle_t,gralloc子產品自定義private_handle_t類型,并實作圖形記憶體的實際申請。

graphicbuffer跨程序共享的流程是用binder傳輸必要資訊到另一程序,另一程序調用gralloc子產品的registerbuffer方法映射其到自己的記憶體空間。

graphicbuffer與surfaceflinger 沒有 直接關系,圖形記憶體不僅僅是提供給視窗系統用的,也不是非得在surfaceflinger程序裡申請。

調用 gralloc 子產品的 post 函數指針,并在hal層發送 fbiopan_display 指令,是将圖形記憶體送顯的一個路徑,但不是惟一。

圖形記憶體是用來渲染和顯示的,它需要被跨程序共享,并支援不同硬體(gpu、dsp等)使用。

android中的圖形記憶體包裹類為graphicbuffer。

Android圖形顯示系統——下層顯示2:圖形記憶體的申請與顯示圖形記憶體的申請與顯示

graphicbuffer繼承于anativewindowbuffer。

anativewindowbuffer包含w,h,stride和handle屬性,其中handle對應一個private_handle_t的指針。

graphicbuffer額外包括 mbuffermapper(映射器,為單例),mid(每塊graphicbuffer的獨立id,根據程序号與申請順序編号),minitcheck(表示申請狀态,用來檢查是否實際申請到了記憶體)。

申請釋放圖形記憶體的流程如下:

Android圖形顯示系統——下層顯示2:圖形記憶體的申請與顯示圖形記憶體的申請與顯示
Android圖形顯示系統——下層顯示2:圖形記憶體的申請與顯示圖形記憶體的申請與顯示

盡管已經将graphicbuffer映射到了自己的程序空間,在進一步使用時,流程上需要在使用前lock,使用完後unlock,這兩個步驟一般用來作cache同步(根據共享記憶體政策,如果是緩存式,cpu/gpu會先把資料寫到緩存,達到一定量才同步到graphicbuffer中,unlock時可以強制把緩存同步一次)。

在 graphicbuffer申請及lock的參數裡,有個flags屬性值,gralloc子產品根據這個值,去判斷從什麼地方申請記憶體,按什麼方式組織記憶體,我們來看一下:

gralloc_usage_sw_read_never,gralloc_usage_sw_read_rarely,gralloc_usage_sw_read_often

分别表示cpu不需要/很少會/經常會讀這塊graphicbuffer,對于read_often經常讀的情況,gralloc子產品應該考慮建讀緩存了。

cpu寫的三個标志類似。

當發覺graphicbuffer操作起來速度慢時,就得看一下,是不是忘了配cpu的讀寫标志了。

gralloc_usage_hw_texture

gralloc_usage_hw_render

這兩個标志分别表示需要gpu讀與寫,texture表示可以映射為一個opengl的紋理,render表示可以作為opengl的渲染目标。

一般來說,gralloc配置設定的記憶體都是gpu可讀寫的,也不需要加這兩個标志。

gralloc_usage_hw_composer

這個表示這個graphicbuffer可以由硬體合成器直接合成。

gralloc_usage_hw_video_encoder

這個表示這個graphicbuffer可以作為video硬解碼(一般是dsp)的輸入輸出對象。

gralloc子產品需要實作如下三個裝置及函數指針。

關于gralloc子產品如何注冊如何打開,可看老羅的部落格:

<a href="http://blog.csdn.net/luoshengyang/article/details/7747932">http://blog.csdn.net/luoshengyang/article/details/7747932</a>

這裡面需要校正的是 hardware/libhardware/modules/gralloc下面的代碼編譯出來的是gralloc.default.so,即android系統預設提供的。一般來說廠商不會用這個so。

如下是arm為mali系列gpu提供的開源gralloc代碼的連結,相對而言更有參考意義。

<a href="http://malideveloper.arm.com/cn/develop-for-mali/drivers/open-source-mali-gpus-android-gralloc-module/">http://malideveloper.arm.com/cn/develop-for-mali/drivers/open-source-mali-gpus-android-gralloc-module/</a>

arm提供的代碼裡面包括自家的ump方案和标準的ion方案,一般而言,在android4.2之後,普遍用的都是ion方案,ion記憶體共享方案可參考此部落格的文章。

<a href="http://blog.csdn.net/qq160816/article/details/38082579">http://blog.csdn.net/qq160816/article/details/38082579</a>

<a href="http://blog.csdn.net/qq160816/article/details/38299251">http://blog.csdn.net/qq160816/article/details/38299251</a>

我們隻看一下這份代碼裡面送顯的部分:

送顯的核心代碼是這一句:

再往下看得跟廠商的核心代碼了,這裡沒代碼略過。關于lcd顯示原理看老羅那篇就好了。

調用gralloc子產品的post函數不是惟一一種将圖形記憶體送到lcd顯示的方法,另一種方式是overlay(hwcomposer的硬體合成)。

繼續閱讀