Android中native_handle private_handle_t ANativeWindowBuffer ANativeWindow GraphicBuffer Surface的关系
2015-05-03 14:29
543 查看
在阅读SurfaceFlinger HardwareComposer以及gralloc相关代码的过程中,我们经常会遇到native_handle private_handle_t ANativeWindowBuffer ANativeWindow GraphicBuffer Surface等等一系列和memory相关的struct和class,他们相互之间到底是什么区别,又有什么联系呢?本文从struct/class的结构角度分析下上述类型之间的关联.
概括来说,native_handle private_handle_t ANativeWindowBuffer GraphicBuffer这四个struct/class所描述的是一块memory,而ANativeWindow 和Surface所描述的是一系列上述memeory的组合和对buffer的操作方法.有的struct/class在比较低的level使用,和平台相关,而另外一些在比较高的level使用,和平台无关,还有一些介于低/高level之间,用以消除平台相关性,让android可以方便的运行在不同的平台上.
我们依次来看下上述struct/class的定义:
1. native_handle
system/core/include/cutils/native_handle.h
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是如何使用的.
2.private_handle_t
hardware/libhardware/modules/gralloc/gralloc_priv.h
3. buffer_handle_t
标题中并没有提到这个类型,因为这个类型实在是太简单了,我们看code
system/core/include/system/window.h
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
ANativeWindowBuffer和ANativeWindow还是没有给android_native_base_t的incRef和decRef指针赋值,ANativeWindowBuffer和ANativeWindow两个还是可以理解为抽象类!
5. GraphicBuffer和Surface
frameworks/native/include/ui/GraphicBuffer.h
frameworks/native/include/ui/ANativeObjectBase.h
frameworks/native/include/gui/Surface.h
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
frameworks/native/opengl/libs/EGL/eglApi.cpp
frameworks/native/opengl/include/EGL/eglplatform.h
总结一下,
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接口,我们下一篇文章继续讨论.
概括来说,native_handle private_handle_t ANativeWindowBuffer GraphicBuffer这四个struct/class所描述的是一块memory,而ANativeWindow 和Surface所描述的是一系列上述memeory的组合和对buffer的操作方法.有的struct/class在比较低的level使用,和平台相关,而另外一些在比较高的level使用,和平台无关,还有一些介于低/高level之间,用以消除平台相关性,让android可以方便的运行在不同的平台上.
我们依次来看下上述struct/class的定义:
1. native_handle
system/core/include/cutils/native_handle.h
typedef struct native_handle { int version; /* sizeof(native_handle_t) */ int numFds; /* number of file-descriptors at &data[0] */ int numInts; /* number of ints at &data[numFds] */ int data[0]; /* numFds + numInts ints */ } 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是如何使用的.
2.private_handle_t
hardware/libhardware/modules/gralloc/gralloc_priv.h
#ifdef __cplusplus //在c++编译环境下private_handle_t继承于native_handle struct private_handle_t : public native_handle { #else //在c编译环境下,private_handle_t的第一个成员是native_handle类型,其实和c++的继承是一个意思, //总之就是一个指向private_handle_t的指针同样也可以表示一个指向native_handle的指针. struct private_handle_t { struct native_handle nativeHandle; #endif // file-descriptors int fd; // ints int magic; int flags; int size; int offset; // 因为native_handle的data成员是一个大小为0的数组,所以data[0]其实就是指向了fd,data[1]指向magic,以此类推. // 上面提到我们可以把native_handle看成是一个纯虚的基类,那么在private_handle_t这个派生类中,numFds=1 numInts=4. ... }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 { /* a magic value defined by the actual EGL native type */ int magic; /* the sizeof() of the actual EGL native type */ int version; void* reserved[4]; /* reference-counting interface */ 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() { // ANDROID_NATIVE_BUFFER_MAGIC的值是"_bfr" common.magic = ANDROID_NATIVE_BUFFER_MAGIC; common.version = sizeof(ANativeWindowBuffer); memset(common.reserved, 0, sizeof(common.reserved)); } // Implement the methods that sp<ANativeWindowBuffer> expects so that it // can be used to automatically refcount ANativeWindowBuffer's. // 调用common,也就是android_native_base_t的incRef和decRef函数,具体函数是什么还不知道 void incStrong(const void* /*id*/) const { common.incRef(const_cast<android_native_base_t*>(&common)); } void decStrong(const void* /*id*/) const { common.decRef(const_cast<android_native_base_t*>(&common)); } #endif // common的incRef和decRef还没有明确是什么 struct android_native_base_t common; int width; int height; int stride; int format; int usage; void* reserved[2]; // buffer_handle_t是指向sturct native_handle, native_handle_t, struct private_handle_t的指针. buffer_handle_t handle; void* reserved_proc[8]; } ANativeWindowBuffer_t; // Old typedef for backwards compatibility. typedef ANativeWindowBuffer_t android_native_buffer_t;ANativeWindow的定义如下
struct ANativeWindow { #ifdef __cplusplus ANativeWindow() : flags(0), minSwapInterval(0), maxSwapInterval(0), xdpi(0), ydpi(0) { // ANDROID_NATIVE_WINDOW_MAGIC的值是"_wnd" common.magic = ANDROID_NATIVE_WINDOW_MAGIC; common.version = sizeof(ANativeWindow); memset(common.reserved, 0, sizeof(common.reserved)); } /* Implement the methods that sp<ANativeWindow> expects so that it can be used to automatically refcount ANativeWindow's. */ // 调用common,也就是android_native_base_t的incRef和decRef函数,具体函数是什么还不知道 void incStrong(const void* /*id*/) const { common.incRef(const_cast<android_native_base_t*>(&common)); } void decStrong(const void* /*id*/) const { common.decRef(const_cast<android_native_base_t*>(&common)); } #endif // common的incRef和decRef还没有明确是什么 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); }; /* Backwards compatibility: use ANativeWindow (struct ANativeWindow in C). * android_native_window_t is deprecated. */ 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
// NATIVE_TYPE=ANativeWindowBuffer TYPE=GraphicBuffer REF=RefBase template <typename NATIVE_TYPE, typename TYPE, typename REF> // ANativeObjectBase多重继承于ANativeWindowBuffer和RefBase class ANativeObjectBase : public NATIVE_TYPE, public REF { public: // Disambiguate between the incStrong in REF and NATIVE_TYPE // incStrong和decStrong直接调用其中一个基类RefBase的对应函数 void incStrong(const void* id) const { REF::incStrong(id); } void decStrong(const void* id) const { REF::decStrong(id); } protected: // 给ANativeObjectBase取了个别名BASE typedef ANativeObjectBase<NATIVE_TYPE, TYPE, REF> BASE; ANativeObjectBase() : NATIVE_TYPE(), REF() { // 构造函数中给ANativeWindowBuffer.common的两个函数指针赋值了!这两个指针就是我们之前在分析ANativeWindowBuffer的时候悬而未决的地方. // incRef和decRef指针分别指向内部函数incRef和decRef 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)); } // 内部函数incRef和decRef调用上面的incStong和decStrong,也就是说ANativeWindowBuffer.common的两个函数指针最终会调用到RefBase的incStrong和decStrong. 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; }; // mSlots stores the buffers that have been allocated for each buffer slot. // It is initialized to null pointers, and gets filled in with the result of // IGraphicBufferProducer::requestBuffer when the client dequeues a buffer from a // slot that has not yet been used. The buffer allocated to a slot will also // be replaced if the requested buffer usage or geometry differs from that // of the buffer allocated to a slot. 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) { // Initialize the ANativeWindow function pointers. 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接口,我们下一篇文章继续讨论.
相关文章推荐
- Android中native_handle private_handle_t ANativeWindowBuffer ANativeWindow GraphicBuffer Surface的关系
- Android中native_handle private_handle_t ANativeWindowBuffer ANativeWindow GraphicBuffer Surface的关系
- Android中native_handle private_handle_t ANativeWindowBuffer ANativeWindow GraphicBuffer Surface的关系
- Android中*_handle_t/ANativeWindowBuffer/ANativeWindow/GraphicBuffer/Surface的关系
- Android使用ANativeWindow_fromSurface返回空
- android opengl: createWindowSurface returned EGL_BAD_NATIVE_WINDOW.
- Activity、Window和View三者间的关系【Android】
- android 中的 window,view,activity具体关系
- https://github.com/havlenapetr/android_frameworks_base/blob/froyo-sgs/native/video/jni/surface.cpp
- android handle thread runnable的关系
- Android graphic: how wms measure the activity window size?
- Android 中Activity,Window和View之间的关系
- GUI系统之SurfaceFlinger(8)应用程序与BufferQueue的关系
- Android的UI底层是用CPU绘图的还是GPU绘图的呢?以及surfaceview,window,普通view是如何实现的?
- Android杂谈--Activity、Window、View的关系
- 显示Gralloc模块分配内存(buffer_handle_t、private_handle_t数据结构的关系)
- Android GraphicBuffer分配过程
- Android 中Activity,Window和View之间的关系
- Android 中Activity,Window和View之间的关系
- Android 中Activity,Window和View之间的关系 - 2