Android中*_handle_t/ANativeWindowBuffer/ANativeWindow/GraphicBuffer/Surface的關係

在閱讀SurfaceFlinger HardwareComposer以及gralloc相關代碼的過程當中,咱們常常會遇到native_handle private_handle_t ANativeWindowBuffer ANativeWindow GraphicBuffer Surface等等一系列和memory相關的struct和class,他們相互之間究竟是什麼區別,又有什麼聯繫呢?本文從struct/class的結構角度分析下上述類型之間的關聯.android

    歸納來講,native_handle private_handle_t ANativeWindowBuffer GraphicBuffer這四個struct/class所描述的是一塊memory,而ANativeWindow 和Surface所描述的是一系列上述memeory的組合和對buffer的操做方法.有的struct/class在比較低的level使用,和平臺相關,而另一些在比較高的level使用,和平臺無關,還有一些介於低/高level之間,用以消除平臺相關性,讓Android能夠方便的運行在不一樣的平臺上.c++

    咱們依次來看下上述struct/class的定義:api

1. native_handle 數組

system/core/include/cutils/native_handle.h
ide

  1. typedef struct native_handle  
  2. {  
  3.     int version;        /* sizeof(native_handle_t) */  
  4.     int numFds;         /* number of file-descriptors at &data[0] */  
  5.     int numInts;        /* number of ints at &data[numFds] */  
  6.     int data[0];        /* numFds + numInts ints */  
  7. } native_handle_t;  

    native_handle/native_handle_t只是定義了一個描述buffer的結構體原型,這個原型是和平臺無關的,方便buffer在各個進程之間傳遞,注意成員data是一個大小爲0的數組,這意味着data指向緊挨着numInts後面的一個地址.咱們能夠把native_handle_t當作是一個純虛的基類.函數


    通常來講,咱們描述一塊buffer,須要知道它在kernel中對應的fd,虛擬地址/物理地址,offset,size等等信息,後面咱們在private_handle_t中就能夠看到這些字段.
    android的gralloc模塊負責從fb設備或者gpu中分配meomory,因此咱們在gralloc中就能夠找到native_handle的具體實現,gralloc中對buffer的描述就和具體的平臺相關了,咱們以aosp中最基本的gralloc爲例,來看下gralloc中對native_handle是如何使用的.ui


2.private_handle_tspa

hardware/libhardware/modules/gralloc/gralloc_priv.h
.net

  1. #ifdef __cplusplus  
  2. //在c++編譯環境下private_handle_t繼承於native_handle  
  3. struct private_handle_t : public native_handle {  
  4. #else  
  5. //在c編譯環境下,private_handle_t的第一個成員是native_handle類型,其實和c++的繼承是一個意思,  
  6. //總之就是一個指向private_handle_t的指針一樣也能夠表示一個指向native_handle的指針.  
  7. struct private_handle_t {  
  8.     struct native_handle nativeHandle;  
  9. #endif  
  10.     // file-descriptors  
  11.     int     fd;   
  12.     // ints  
  13.     int     magic;  
  14.     int     flags;  
  15.     int     size;  
  16.     int     offset;  
  17.     // 由於native_handle的data成員是一個大小爲0的數組,因此data[0]其實就是指向了fd,data[1]指向magic,以此類推.  
  18.     // 上面提到咱們能夠把native_handle當作是一個純虛的基類,那麼在private_handle_t這個派生類中,numFds=1 numInts=4.  
  19.     ...  
  20. }  

    gralloc分配的buffer均可以用一個private_handle_t來描述,同時也能夠用一個native_handle來描述.在不一樣的平臺的實現上,private_handle_t可能會有不一樣的定義,因此private_handle_t在各個模塊之間傳遞的時候很不方便,而若是用native_handle的身份來傳遞,就能夠消除平臺的差別性.在HardwareComposer中,由SurfaceFlinger傳給hwc的handle便是native_handle類型,而hwc做爲平臺相關的模塊,他須要知道native_handle中各個字段的具體含義,因此hwc每每會將native_handle指針轉化爲private_handle_t指針來使用.
指針

3. buffer_handle_t

    標題中並無提到這個類型,由於這個類型實在是太簡單了,咱們看code

system/core/include/system/window.h

  1. typedef const native_handle_t* buffer_handle_t;  

    在window.h中又把指向native_handle_t的指針define爲buffer_handle_t,

sturct native_handle

native_handle_t

struct private_handle_t
這三個類型能夠看做是同一個東西,而buffer_handle_t則是指向他們的指針.

    那麼android是如何使用這些struct的,gralloc分配的buffer如何和android聯繫起來呢?
咱們繼續來看window.h

4. ANativeWindowBuffer和ANativeWindow

    在具體分析ANativeWindowBuffer和ANativeWindow以前,咱們先來看下和這兩個類型都相關的另一個結構體android_native_base_t

system/core/include/system/window.h

  1. typedef struct android_native_base_t  
  2. {  
  3.     /* a magic value defined by the actual EGL native type */  
  4.     int magic;  
  5.   
  6.     /* the sizeof() of the actual EGL native type */  
  7.     int version;  
  8.   
  9.     void* reserved[4];  
  10.   
  11.     /* reference-counting interface */  
  12.     void (*incRef)(struct android_native_base_t* base);  
  13.     void (*decRef)(struct android_native_base_t* base);  
  14. } android_native_base_t;  

incRef和decRef是爲了把派生類和android全部class的老祖宗RefBase聯繫起來所預留的函數指針,在後面咱們在會看到指針具體會指向哪些函數.

  1. typedef struct ANativeWindowBuffer  
  2. {  
  3. #ifdef __cplusplus  
  4.     ANativeWindowBuffer() {  
  5.         // ANDROID_NATIVE_BUFFER_MAGIC的值是"_bfr"  
  6.         common.magic = ANDROID_NATIVE_BUFFER_MAGIC;  
  7.         common.version = sizeof(ANativeWindowBuffer);  
  8.         memset(common.reserved, 0, sizeof(common.reserved));  
  9.     }     
  10.   
  11.     // Implement the methods that sp<ANativeWindowBuffer> expects so that it  
  12.     // can be used to automatically refcount ANativeWindowBuffer's.  
  13.     // 調用common,也就是android_native_base_t的incRef和decRef函數,具體函數是什麼還不知道  
  14.     void incStrong(const void* /*id*/) const {  
  15.         common.incRef(const_cast<android_native_base_t*>(&common));  
  16.     }     
  17.     void decStrong(const void* /*id*/) const {  
  18.         common.decRef(const_cast<android_native_base_t*>(&common));  
  19.     }     
  20. #endif  
  21.   
  22.     // common的incRef和decRef尚未明確是什麼  
  23.    struct android_native_base_t common;  
  24.   
  25.     int width;  
  26.     int height;  
  27.     int stride;  
  28.     int format;  
  29.     int usage;  
  30.   
  31.     void* reserved[2];  
  32.     // buffer_handle_t是指向sturct native_handle, native_handle_t, struct private_handle_t的指針.  
  33.     buffer_handle_t handle;  
  34.   
  35.     void* reserved_proc[8];  
  36. } ANativeWindowBuffer_t;  
  37. // Old typedef for backwards compatibility.  
  38. typedef ANativeWindowBuffer_t android_native_buffer_t;  

ANativeWindow的定義以下

  1. struct ANativeWindow  
  2. {  
  3. #ifdef __cplusplus  
  4.     ANativeWindow()  
  5.         : flags(0), minSwapInterval(0), maxSwapInterval(0), xdpi(0), ydpi(0)  
  6.     {  
  7.         // ANDROID_NATIVE_WINDOW_MAGIC的值是"_wnd"  
  8.         common.magic = ANDROID_NATIVE_WINDOW_MAGIC;  
  9.         common.version = sizeof(ANativeWindow);  
  10.         memset(common.reserved, 0, sizeof(common.reserved));  
  11.     }  
  12.   
  13.     /* Implement the methods that sp<ANativeWindow> expects so that it 
  14.        can be used to automatically refcount ANativeWindow's. */  
  15.     // 調用common,也就是android_native_base_t的incRef和decRef函數,具體函數是什麼還不知道  
  16.     void incStrong(const void* /*id*/) const {  
  17.         common.incRef(const_cast<android_native_base_t*>(&common));  
  18.     }  
  19.     void decStrong(const void* /*id*/) const {  
  20.         common.decRef(const_cast<android_native_base_t*>(&common));  
  21.     }  
  22. #endif  
  23.     // common的incRef和decRef尚未明確是什麼  
  24.     struct android_native_base_t common;  
  25.     ...  
  26.     int     (*dequeueBuffer)(struct ANativeWindow* window,  
  27.                 struct ANativeWindowBuffer** buffer, int* fenceFd);  
  28.     int     (*queueBuffer)(struct ANativeWindow* window,  
  29.                 struct ANativeWindowBuffer* buffer, int fenceFd);  
  30.     int     (*cancelBuffer)(struct ANativeWindow* window,  
  31.                 struct ANativeWindowBuffer* buffer, int fenceFd);  
  32. };  
  33.  /* Backwards compatibility: use ANativeWindow (struct ANativeWindow in C). 
  34.   * android_native_window_t is deprecated. 
  35.   */  
  36. typedef struct ANativeWindow ANativeWindow;  
  37. typedef struct ANativeWindow android_native_window_t __deprecated;  

咱們目前須要注意的是ANativeWindow的函數指針成員所指向的函數都須要一個struct ANativeWindowBuffer* buffer的參數.

ANativeWindowBuffer和ANativeWindow仍是沒有給android_native_base_t的incRef和decRef指針賦值,ANativeWindowBuffer和ANativeWindow兩個仍是能夠理解爲抽象類!


5. GraphicBuffer和Surface

frameworks/native/include/ui/GraphicBuffer.h 

  1. class GraphicBuffer  
  2.     : public ANativeObjectBase< ANativeWindowBuffer, GraphicBuffer, RefBase >,  
  3.       public Flattenable<GraphicBuffer>  
  4. {  
  5. ...  
  6. }  

GraphicBuffer繼承於模版類ANativeObjectBase,這個模版類有三個模版.

frameworks/native/include/ui/ANativeObjectBase.h

  1. // NATIVE_TYPE=ANativeWindowBuffer TYPE=GraphicBuffer REF=RefBase  
  2. template <typename NATIVE_TYPE, typename TYPE, typename REF>  
  3. // ANativeObjectBase多重繼承於ANativeWindowBuffer和RefBase  
  4. class ANativeObjectBase : public NATIVE_TYPE, public REF   
  5. {  
  6. public:  
  7.     // Disambiguate between the incStrong in REF and NATIVE_TYPE  
  8.     // incStrong和decStrong直接調用其中一個基類RefBase的對應函數  
  9.     void incStrong(const void* id) const {  
  10.         REF::incStrong(id);  
  11.     }     
  12.     void decStrong(const void* id) const {  
  13.         REF::decStrong(id);  
  14.     }     
  15.   
  16. protected:  
  17.     // 給ANativeObjectBase取了個別名BASE  
  18.     typedef ANativeObjectBase<NATIVE_TYPE, TYPE, REF> BASE;  
  19.     ANativeObjectBase() : NATIVE_TYPE(), REF() {  
  20.         // 構造函數中給ANativeWindowBuffer.common的兩個函數指針賦值了!這兩個指針就是咱們以前在分析ANativeWindowBuffer的時候懸而未決的地方.  
  21.         // incRef和decRef指針分別指向內部函數incRef和decRef  
  22.         NATIVE_TYPE::common.incRef = incRef;  
  23.         NATIVE_TYPE::common.decRef = decRef;  
  24.     }     
  25.     static inline TYPE* getSelf(NATIVE_TYPE* self) {  
  26.         return static_cast<TYPE*>(self);  
  27.     }     
  28.     static inline TYPE const* getSelf(NATIVE_TYPE const* self) {  
  29.         return static_cast<TYPE const *>(self);  
  30.     }     
  31.     static inline TYPE* getSelf(android_native_base_t* base) {  
  32.         return getSelf(reinterpret_cast<NATIVE_TYPE*>(base));  
  33.     }     
  34.     static inline TYPE const * getSelf(android_native_base_t const* base) {  
  35.         return getSelf(reinterpret_cast<NATIVE_TYPE const*>(base));  
  36.     }  
  37.     // 內部函數incRef和decRef調用上面的incStong和decStrong,也就是說ANativeWindowBuffer.common的兩個函數指針最終會調用到RefBase的incStrong和decStrong.  
  38.     static void incRef(android_native_base_t* base) {  
  39.         ANativeObjectBase* self = getSelf(base);  
  40.         self->incStrong(self);  
  41.     }     
  42.     static void decRef(android_native_base_t* base) {  
  43.         ANativeObjectBase* self = getSelf(base);  
  44.         self->decStrong(self);  
  45.     }   
  46. };  

    搞了半天,原來GraphicBuffer就是ANativeWindowBuffer一種具體實現,把ANativeWindowBuffer的common成員的兩個函數指針incRef decRef指向了GraphicBuffer的另外一個基類RefBase的incStrong和decStrong,而ANativeWindowBuffer無非就是把buffer_handle_t包了一層.咱們看下另一個從ANativeObjectBase派生的類,他就是大名鼎鼎的,Surface!

frameworks/native/include/gui/Surface.h

  1. class Surface  
  2.     : public ANativeObjectBase<ANativeWindow, Surface, RefBase>  
  3. {  
  4.     enum { NUM_BUFFER_SLOTS = BufferQueue::NUM_BUFFER_SLOTS };  
  5.     ...  
  6.     struct BufferSlot {  
  7.         sp<GraphicBuffer> buffer;  
  8.         Region dirtyRegion;  
  9.     };  
  10.     // mSlots stores the buffers that have been allocated for each buffer slot.  
  11.     // It is initialized to null pointers, and gets filled in with the result of  
  12.     // IGraphicBufferProducer::requestBuffer when the client dequeues a buffer from a  
  13.     // slot that has not yet been used. The buffer allocated to a slot will also  
  14.     // be replaced if the requested buffer usage or geometry differs from that  
  15.     // of the buffer allocated to a slot.  
  16.     BufferSlot mSlots[NUM_BUFFER_SLOTS];  
  17.     ...  
  18. }  

    Surface和GraphicBuffer都繼承自模版類ANativeObjectBase,他使用的三個模版是ANativeWindow, Surface, RefBase,關於incRef和decRef兩個函數指針的指向問題和上面GraphicBuffer是徹底相同的, 這裏就不贅述了.咱們須要注意的是Surface有一個BufferSlot類型的成員數組mSlots,BufferSlot是GraphicBuffer的包裝,因此咱們能夠理解爲每一個Surface中都有一個大小爲NUM_BUFFER_SLOTS的GraphicBuffer數組.


    由於Surface繼承自ANativeWindow,因此Surface須要實現ANativeWindow中定義的一些接口,這些實如今Surface的構造函數中:

frameworks/native/libs/gui/Surface.cpp

  1. Surface::Surface(  
  2.         const sp<IGraphicBufferProducer>& bufferProducer,  
  3.         bool controlledByApp)  
  4.     : mGraphicBufferProducer(bufferProducer)  
  5. {  
  6.     // Initialize the ANativeWindow function pointers.  
  7.     ANativeWindow::setSwapInterval  = hook_setSwapInterval;  
  8.     ANativeWindow::dequeueBuffer    = hook_dequeueBuffer;  
  9.     ANativeWindow::cancelBuffer     = hook_cancelBuffer;  
  10.     ANativeWindow::queueBuffer      = hook_queueBuffer;  
  11.     ANativeWindow::query            = hook_query;  
  12.     ANativeWindow::perform          = hook_perform;  
  13.   
  14.     ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;  
  15.     ANativeWindow::cancelBuffer_DEPRECATED  = hook_cancelBuffer_DEPRECATED;  
  16.     ANativeWindow::lockBuffer_DEPRECATED    = hook_lockBuffer_DEPRECATED;  
  17.     ANativeWindow::queueBuffer_DEPRECATED   = hook_queueBuffer_DEPRECATED;  
  18.   
  19.     const_cast<int&>(ANativeWindow::minSwapInterval) = 0;  
  20.     const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;  
  21. }  

ANativeWindow定義的這些接口有什麼用呢?誰會來call這些函數呢?舉個例子來看.咱們在EGL的api中能夠找到eglCreateWindowSurface這個函數的定義:

frameworks/native/opengl/libs/EGL/eglApi.cpp

  1. EGLSurface eglCreateWindowSurface(  EGLDisplay dpy, EGLConfig config,  
  2.                                     NativeWindowType window,  
  3.                                     const EGLint *attrib_list)  
  4. {  
  5.     ...  
  6. }  

注意其中一個參數NativeWindowType window,這個NativeWindowType又是什麼呢?

frameworks/native/opengl/include/EGL/eglplatform.h

  1. typedef struct ANativeWindow*           EGLNativeWindowType;  
  2. typedef EGLNativeWindowType  NativeWindowType;  

原來NativeWindowType在Android環境下,就是ANativeWindow*,也就是Surface*!

總結一下,

native_handle/native_handle_t是private_handle_t的抽象表示方法,消除平臺相關性,方便private_handle_t所表示的memory信息在android各個層次之間傳遞.而buffer_handle_t是指向他們的指針.

ANativeWindowBuffer將buffer_handle_t進行了包裝,ANativeWindow和ANativeWindowBuffer都繼承於android_native_base_t,定義了common.incRef和common.decRef兩個函數指針,可是並無爲函數指針賦值,因此ANativeWindow和ANativeWindowBuffer仍然是抽象類.

GraphicBuffer和Surface經過繼承模版類ANativeObjectBase並指定其中一個模版是RefBase,爲incRef和decRef兩個指針分別賦值爲RefBase的incStrong和decStrong,這樣

GraphicBuffer繼承了ANativeWindowBuffer,Surface繼承了ANativeWindow,而且二者都具備的和RefBase一樣的incStong decStrong成員函數.

Surface的成員BufferSlot mSlots[NUM_BUFFER_SLOTS];能夠看做是sp<GraphicBuffer>類型的數組,也就是說每一個Surface中都包含有NUM_BUFFER_SLOTS個sp<GraphicBuffer>.


關於ANativeWindow的使用方法,咱們能夠在SurfaceFlinger中找到一個很好的列子,就是SF的captureScreen接口.

相關文章
相關標籤/搜索