在閱讀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
- typedef struct native_handle
- {
- int version;
- int numFds;
- int numInts;
- int data[0];
- } 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
- #ifdef __cplusplus
- struct private_handle_t : public native_handle {
- #else
- struct private_handle_t {
- struct native_handle nativeHandle;
- #endif
-
- int fd;
-
- int magic;
- int flags;
- int size;
- int offset;
-
-
- ...
- }
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
- 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
- typedef struct android_native_base_t
- {
-
- int magic;
-
-
- int version;
-
- void* reserved[4];
-
-
- void (*incRef)(struct android_native_base_t* base);
- void (*decRef)(struct android_native_base_t* base);
- } android_native_base_t;
incRef和decRef是爲了把派生類和android全部class的老祖宗RefBase聯繫起來所預留的函數指針,在後面咱們在會看到指針具體會指向哪些函數.
- typedef struct ANativeWindowBuffer
- {
- #ifdef __cplusplus
- ANativeWindowBuffer() {
-
- common.magic = ANDROID_NATIVE_BUFFER_MAGIC;
- common.version = sizeof(ANativeWindowBuffer);
- memset(common.reserved, 0, sizeof(common.reserved));
- }
-
-
-
-
- void incStrong(const void*
- common.incRef(const_cast<android_native_base_t*>(&common));
- }
- void decStrong(const void*
- common.decRef(const_cast<android_native_base_t*>(&common));
- }
- #endif
-
-
- struct android_native_base_t common;
-
- int width;
- int height;
- int stride;
- int format;
- int usage;
-
- void* reserved[2];
-
- buffer_handle_t handle;
-
- void* reserved_proc[8];
- } ANativeWindowBuffer_t;
- typedef ANativeWindowBuffer_t android_native_buffer_t;
ANativeWindow的定義以下
- struct ANativeWindow
- {
- #ifdef __cplusplus
- ANativeWindow()
- : flags(0), minSwapInterval(0), maxSwapInterval(0), xdpi(0), ydpi(0)
- {
-
- common.magic = ANDROID_NATIVE_WINDOW_MAGIC;
- common.version = sizeof(ANativeWindow);
- memset(common.reserved, 0, sizeof(common.reserved));
- }
-
-
-
- void incStrong(const void*
- common.incRef(const_cast<android_native_base_t*>(&common));
- }
- void decStrong(const void*
- common.decRef(const_cast<android_native_base_t*>(&common));
- }
- #endif
-
- struct android_native_base_t common;
- ...
- int (*dequeueBuffer)(struct ANativeWindow* window,
- struct ANativeWindowBuffer** buffer, int* fenceFd);
- int (*queueBuffer)(struct ANativeWindow* window,
- struct ANativeWindowBuffer* buffer, int fenceFd);
- int (*cancelBuffer)(struct ANativeWindow* window,
- struct ANativeWindowBuffer* buffer, int fenceFd);
- };
-
- typedef struct ANativeWindow ANativeWindow;
- 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
- class GraphicBuffer
- : public ANativeObjectBase< ANativeWindowBuffer, GraphicBuffer, RefBase >,
- public Flattenable<GraphicBuffer>
- {
- ...
- }
GraphicBuffer繼承於模版類ANativeObjectBase,這個模版類有三個模版.
frameworks/native/include/ui/ANativeObjectBase.h
- template <typename NATIVE_TYPE, typename TYPE, typename REF>
- class ANativeObjectBase : public NATIVE_TYPE, public REF
- {
- public:
-
-
- void incStrong(const void* id) const {
- REF::incStrong(id);
- }
- void decStrong(const void* id) const {
- REF::decStrong(id);
- }
-
- protected:
-
- typedef ANativeObjectBase<NATIVE_TYPE, TYPE, REF> BASE;
- ANativeObjectBase() : NATIVE_TYPE(), REF() {
-
-
- NATIVE_TYPE::common.incRef = incRef;
- NATIVE_TYPE::common.decRef = decRef;
- }
- static inline TYPE* getSelf(NATIVE_TYPE* self) {
- return static_cast<TYPE*>(self);
- }
- static inline TYPE const* getSelf(NATIVE_TYPE const* self) {
- return static_cast<TYPE const *>(self);
- }
- static inline TYPE* getSelf(android_native_base_t* base) {
- return getSelf(reinterpret_cast<NATIVE_TYPE*>(base));
- }
- static inline TYPE const * getSelf(android_native_base_t const* base) {
- return getSelf(reinterpret_cast<NATIVE_TYPE const*>(base));
- }
-
- static void incRef(android_native_base_t* base) {
- ANativeObjectBase* self = getSelf(base);
- self->incStrong(self);
- }
- static void decRef(android_native_base_t* base) {
- ANativeObjectBase* self = getSelf(base);
- self->decStrong(self);
- }
- };
搞了半天,原來GraphicBuffer就是ANativeWindowBuffer一種具體實現,把ANativeWindowBuffer的common成員的兩個函數指針incRef decRef指向了GraphicBuffer的另外一個基類RefBase的incStrong和decStrong,而ANativeWindowBuffer無非就是把buffer_handle_t包了一層.咱們看下另一個從ANativeObjectBase派生的類,他就是大名鼎鼎的,Surface!
frameworks/native/include/gui/Surface.h
- class Surface
- : public ANativeObjectBase<ANativeWindow, Surface, RefBase>
- {
- enum { NUM_BUFFER_SLOTS = BufferQueue::NUM_BUFFER_SLOTS };
- ...
- struct BufferSlot {
- sp<GraphicBuffer> buffer;
- Region dirtyRegion;
- };
-
-
-
-
-
-
- BufferSlot mSlots[NUM_BUFFER_SLOTS];
- ...
- }
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
- Surface::Surface(
- const sp<IGraphicBufferProducer>& bufferProducer,
- bool controlledByApp)
- : mGraphicBufferProducer(bufferProducer)
- {
-
- ANativeWindow::setSwapInterval = hook_setSwapInterval;
- ANativeWindow::dequeueBuffer = hook_dequeueBuffer;
- ANativeWindow::cancelBuffer = hook_cancelBuffer;
- ANativeWindow::queueBuffer = hook_queueBuffer;
- ANativeWindow::query = hook_query;
- ANativeWindow::perform = hook_perform;
-
- ANativeWindow::dequeueBuffer_DEPRECATED = hook_dequeueBuffer_DEPRECATED;
- ANativeWindow::cancelBuffer_DEPRECATED = hook_cancelBuffer_DEPRECATED;
- ANativeWindow::lockBuffer_DEPRECATED = hook_lockBuffer_DEPRECATED;
- ANativeWindow::queueBuffer_DEPRECATED = hook_queueBuffer_DEPRECATED;
-
- const_cast<int&>(ANativeWindow::minSwapInterval) = 0;
- const_cast<int&>(ANativeWindow::maxSwapInterval) = 1;
- }
ANativeWindow定義的這些接口有什麼用呢?誰會來call這些函數呢?舉個例子來看.咱們在EGL的api中能夠找到eglCreateWindowSurface這個函數的定義:
frameworks/native/opengl/libs/EGL/eglApi.cpp
- EGLSurface eglCreateWindowSurface( EGLDisplay dpy, EGLConfig config,
- NativeWindowType window,
- const EGLint *attrib_list)
- {
- ...
- }
注意其中一個參數NativeWindowType window,這個NativeWindowType又是什麼呢?
frameworks/native/opengl/include/EGL/eglplatform.h
- typedef struct ANativeWindow* EGLNativeWindowType;
- 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接口.