在阅读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接口.