旅游网站建设方案之目标,长春网站建设公司,seo网站有哪些,医院网站建设公司价格低关于Android下gralloc#xff0c;hwcompoer以及surface模块的重新认识 引言
欠债还钱天经地义#xff0c;知识的债也是如此#xff01;这不必须得将我前面欠下来的债给补上#xff01;对于任何复杂的知识点#xff0c;我们都可以采用庖丁解牛的学习方式#xff0c;一步步…关于Android下grallochwcompoer以及surface模块的重新认识 引言
欠债还钱天经地义知识的债也是如此这不必须得将我前面欠下来的债给补上对于任何复杂的知识点我们都可以采用庖丁解牛的学习方式一步步的分解。将知识由大到小吃透。虽说Android的graphics图形栈是一个非常负责的模块但是完事开头难我们先从基本面入手 一. allocator service的实现
这里我只能无力的吐糟下Android为了所谓的system,vendor隔离搞了一个HIDL这可苦了我们这些搞Android的。这里我以最简单的alloctaor 2.0来作为参考简单介绍其实现 1.1 . allocator 2.0 service代码结构
这个比较简单我们直接上代码
//hardware/interfaces/graphics/allocator/2.0
├── Android.bp
├── default
│ ├── Android.bp
│ ├── android.hardware.graphics.allocator2.0-service.rc
│ ├── OWNERS
│ ├── passthrough.cpp
│ └── service.cpp
├── IAllocator.hal
└── utils├── gralloc1-adapter│ ├── Android.bp│ ├── gralloc1-adapter.cpp│ ├── gralloc1-adapter.h│ ├── Gralloc1On0Adapter.cpp│ └── Gralloc1On0Adapter.h├── hal│ ├── Android.bp│ └── include│ └── allocator-hal│ └── 2.0│ ├── Allocator.h│ └── AllocatorHal.h├── OWNERS└── passthrough├── Android.bp└── include└── allocator-passthrough└── 2.0├── Gralloc0Hal.h├── Gralloc1Hal.h└── GrallocLoader.h11 directories, 20 files 1.2 allocator 2.0 service passthrough方式的实现
这里我们不对细节做过多的纠缠我们只梳理其大体框架 /*** The id of this module*/
#define GRALLOC_HARDWARE_MODULE_ID gralloc
/*** Name of the graphics device to open*/#define GRALLOC_HARDWARE_GPU0 gpu0//[passthrough.cpp]
HIDL_FETCH_IAllocator(...)GrallocLoader::load() //GrallocLoader.hloadModule()//核心是这个加载HAL MODLEhw_get_module(GRALLOC_HARDWARE_MODULE_ID, module)createHal(module)//这里无论是Gralloc1Hal还是Gralloc0Hal最终都会调用 gralloc_open(module, mDevice)gralloc_open(module, mDevice)module-methods-open(module, GRALLOC_HARDWARE_GPU0, TO_HW_DEVICE_T_OPEN(device)) //注意这里传递的id为GRALLOC_HARDWARE_GPU0createAllocator(std::move(hal))
这里我们重点需要关心的是这里hw_get_modul传递的id是GRALLOC_HARDWARE_MODULE_ID! 1.3 allocator HAL的实现
通过前面分析可知hw_get_module会加载HAL模块这里我们以Android默认的gralloc实现来说明:
//[hardware/libhardware/modules/gralloc]├── Android.mk
├── framebuffer.cpp
├── gralloc.cpp
├── gralloc_priv.h
├── gr.h
└── mapper.cppstruct private_module_t HAL_MODULE_INFO_SYM {.base {.common {.tag HARDWARE_MODULE_TAG,.version_major 1,.version_minor 0,.id GRALLOC_HARDWARE_MODULE_ID,//注意这里的ID.name Graphics Memory Allocator Module,.author The Android Open Source Project,.methods gralloc_module_methods},.registerBuffer gralloc_register_buffer,.unregisterBuffer gralloc_unregister_buffer,.lock gralloc_lock,.unlock gralloc_unlock,},.framebuffer 0,.flags 0,.numBuffers 0,.bufferMask 0,.lock PTHREAD_MUTEX_INITIALIZER,.currentBuffer 0,
};int gralloc_device_open(const hw_module_t* module, const char* name,hw_device_t** device)
{int status -EINVAL;if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {//allocator的gralloc加载会走次分支gralloc_context_t *dev;dev (gralloc_context_t*)malloc(sizeof(*dev));/* initialize our state here */memset(dev, 0, sizeof(*dev));/* initialize the procs */dev-device.common.tag HARDWARE_DEVICE_TAG;dev-device.common.version 0;dev-device.common.module const_casthw_module_t*(module);dev-device.common.close gralloc_close;dev-device.alloc gralloc_alloc;dev-device.free gralloc_free;*device dev-device.common;status 0;} else {status fb_device_open(module, name, device);}return status;
} 这里需要注意的是此时allocator service调用open时候传递下来的id为GRALLOC_HARDWARE_GPU0这个地方要和后面的composer的open对比来看 1.4 allocator HAL alloc的实现
上面的都是常规操作下面我们接下来看下 allocator HAL alloc的实现
//[gralloc.cpp]
static int gralloc_alloc(alloc_device_t* dev,int width, int height, int format, int usage,buffer_handle_t* pHandle, int* pStride)
{...if (usage GRALLOC_USAGE_HW_FB) {err gralloc_alloc_framebuffer(dev, size, format, usage, pHandle);} else {err gralloc_alloc_buffer(dev, size, usage, pHandle);}if (err 0) {return err;}*pStride stride;return 0;
}
此时的你是不是蒙圈了尼玛gralloc_alloc里面又有两个分支: gralloc_alloc_framebuffer 这个分支比较特殊主要用于GPU合成时候FramebufferSurface使用然后该buffer在后面就可以用于hwcompower合成使用了。 并且这里注意这里的FramebufferSurface是消费者当消费者设置了GRALLOC_USAGE_HW_FB后这个值在其对应的生产者申请buffer类型的时候会获取到这个usage然后这个usage就会随着生产者allocat()的调用逻辑传递到gralloc来了 //[frameworks/native/services/surfaceflinger/DisplayHardware/FramebufferSurface.cpp]FramebufferSurface::FramebufferSurface(HWComposer hwc, DisplayId displayId,const spIGraphicBufferConsumer consumer,uint32_t maxWidth, uint32_t maxHeight): ConsumerBase(consumer),mDisplayId(displayId),mMaxWidth(maxWidth),mMaxHeight(maxHeight),mCurrentBufferSlot(-1),mCurrentBuffer(),mCurrentFence(Fence::NO_FENCE),mHwc(hwc),mHasPendingRelease(false),mPreviousBufferSlot(BufferQueue::INVALID_BUFFER_SLOT),mPreviousBuffer() {ALOGV(Creating for display %s, to_string(displayId).c_str());mName FramebufferSurface;mConsumer-setConsumerName(mName);mConsumer-setConsumerUsageBits(GRALLOC_USAGE_HW_FB |//注意这个地方GRALLOC_USAGE_HW_RENDER |GRALLOC_USAGE_HW_COMPOSER);...} 关于这块可以参考博客: 图像显示系统 - SurfaceFlinger GPU合成/CLIENT合成方式 gralloc_alloc_buffer 它是基本的像App的渲染buffer啊其它的通用buffer都是通过它alloc的 二. hwcomposer service的实现
这里我只能无力的吐糟下Android为了所谓的system,vendor隔离搞了一个HIDL这可苦了我们这些搞Android的。composer 2.1来作为参考简单介绍其实现 2.1 . composer 2.1 service代码结构
这个比较简单我们直接上代码
//[hardware/interfaces/graphics/composer/2.1]├── Android.bp
├── default
│ ├── Android.bp
│ ├── android.hardware.graphics.composer2.1-service.rc
│ ├── OWNERS
│ └── service.cpp
├── IComposerCallback.hal
├── IComposerClient.hal
├── IComposer.hal
├── types.hal
└── utils├── command-buffer│ ├── Android.bp│ └── include│ └── composer-command-buffer│ └── 2.1│ └── ComposerCommandBuffer.h├── hal│ ├── Android.bp│ └── include│ └── composer-hal│ └── 2.1│ ├── ComposerClient.h│ ├── ComposerCommandEngine.h│ ├── Composer.h│ └── ComposerHal.h├── hwc2on1adapter│ ├── Android.bp│ ├── CleanSpec.mk│ ├── HWC2On1Adapter.cpp│ ├── include│ │ └── hwc2on1adapter│ │ ├── HWC2On1Adapter.h│ │ └── MiniFence.h│ └── MiniFence.cpp├── hwc2onfbadapter│ ├── Android.bp│ ├── HWC2OnFbAdapter.cpp│ └── include│ └── hwc2onfbadapter│ └── HWC2OnFbAdapter.h├── OWNERS├── passthrough│ ├── Android.bp│ └── include│ └── composer-passthrough│ └── 2.1│ ├── HwcHal.h│ └── HwcLoader.h└── resources├── Android.bp├── ComposerResources.cpp└── include└── composer-resources└── 2.1└── ComposerResources.h24 directories, 32 files 2.2 composer 2.1 service passthrough方式的实现
这里我们不对细节做过多的纠缠我们只梳理其大体框架 这里有一点需要注意composer使用Android默认的实现即不设置ro属性指定 //[service.cpp]
android::spIComposer composer HwcLoader::load()//HwcLoader.hloadModule()hw_get_module(HWC_HARDWARE_MODULE_ID, module)//默认使用这个分支加载失败hw_get_module(GRALLOC_HARDWARE_MODULE_ID, module)//加载这个分支和gralloc使用的HAL是同一个模块createHalWithAdapter()openDeviceWithAdapter()adaptGrallocModule...module-methods-open(module,GRALLOC_HARDWARE_FB0, TO_HW_DEVICE_T_OPEN(device));createComposer
这里我需要重点注意的几点
composer的默认实现加载的HAL库的实现是gralloc.default调用HAL下open方法的时候传递的ID的名称是GRALLOC_HARDWARE_FB0这个是需要和allocator实现区分开来的 2.3 composer 2.1 service HAL的实现
这里的实现就很简单了。因为这里使用gralloc.default作为composer HAL的实现只实现了其H2C 1.0。
//[hardware/libhardware/modules/gralloc]├── Android.mk
├── framebuffer.cpp
├── gralloc.cpp
├── gralloc_priv.h
├── gr.h
└── mapper.cppstruct private_module_t HAL_MODULE_INFO_SYM {.base {.common {.tag HARDWARE_MODULE_TAG,.version_major 1,.version_minor 0,.id GRALLOC_HARDWARE_MODULE_ID,//注意这里的ID.name Graphics Memory Allocator Module,.author The Android Open Source Project,.methods gralloc_module_methods},.registerBuffer gralloc_register_buffer,.unregisterBuffer gralloc_unregister_buffer,.lock gralloc_lock,.unlock gralloc_unlock,},.framebuffer 0,.flags 0,.numBuffers 0,.bufferMask 0,.lock PTHREAD_MUTEX_INITIALIZER,.currentBuffer 0,
};int gralloc_device_open(const hw_module_t* module, const char* name,hw_device_t** device)
{int status -EINVAL;if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {....} else {status fb_device_open(module, name, device);//composer的HAL加载会走次分支}return status;
}int fb_device_open(hw_module_t const* module, const char* name,hw_device_t** device)
{int status -EINVAL;if (!strcmp(name, GRALLOC_HARDWARE_FB0)) {//前面传递进来的id 那么就是GRALLOC_HARDWARE_FB0/* initialize our state here */fb_context_t *dev (fb_context_t*)malloc(sizeof(*dev));memset(dev, 0, sizeof(*dev));/* initialize the procs */dev-device.common.tag HARDWARE_DEVICE_TAG;dev-device.common.version 0;dev-device.common.module const_casthw_module_t*(module);dev-device.common.close fb_close;dev-device.setSwapInterval fb_setSwapInterval;dev-device.post fb_post;dev-device.setUpdateRect 0;private_module_t* m (private_module_t*)module;status mapFrameBuffer(m);if (status 0) {int stride m-finfo.line_length / (m-info.bits_per_pixel 3);int format (m-info.bits_per_pixel 32)? (m-info.red.offset ? HAL_PIXEL_FORMAT_BGRA_8888 : HAL_PIXEL_FORMAT_RGBX_8888): HAL_PIXEL_FORMAT_RGB_565;const_castuint32_t(dev-device.flags) 0;const_castuint32_t(dev-device.width) m-info.xres;const_castuint32_t(dev-device.height) m-info.yres;const_castint(dev-device.stride) stride;const_castint(dev-device.format) format;const_castfloat(dev-device.xdpi) m-xdpi;const_castfloat(dev-device.ydpi) m-ydpi;const_castfloat(dev-device.fps) m-fps;const_castint(dev-device.minSwapInterval) 1;const_castint(dev-device.maxSwapInterval) 1;*device dev-device.common;} else {free(dev);}}return status;
}三. gralloc和hwcompoer中各种让人眼花缭乱的数据关系
这块之前的花式关系真的是让人眼花缭乱不知道是李鬼还是李逵。尼玛让人不得不一吐为快啊 3.1 native_handle_t*和buffer_handle_t
其它它们是一个东西具体的定义如下:
//[system/core/libcutils/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] */
#if defined(__clang__)
#pragma clang diagnostic push
#pragma clang diagnostic ignored -Wzero-length-array
#endifint data[0]; /* numFds numInts ints */
#if defined(__clang__)
#pragma clang diagnostic pop
#endif
} native_handle_t;typedef const native_handle_t* buffer_handle_t; 它的源码目录比较奇特在libcutils里面。这点大家需要注意。 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是如何使用的. 3.2 private_handle_t
我们来看下Android aosp为我们打样实现的一个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这个派生类中,numFds1 numInts4. ...
} 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.3 小结 对于native_handle和native_handle_t以及private_handle_t这三个类型可以看作是同一个东西,而buffer_handle_t则是指向他们的指针. 那么android是如何使用这些struct的,gralloc分配的buffer如何和android联系起来呢?我们继续来看window.h 3.4 ANativeWindowBuffer和ANativeWindow
在具体分析ANativeWindowBuffer和ANativeWindow之前,我们先来看下和这两个类型都相关的另外一个结构体android_native_base_t。
[frameworks/native/libs/nativebase/include/nativebase/nativebase.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联系起来所预留的函数指针,在后面我们在会看到指针具体会指向哪些函数.
好了前面该说的也已经说了。是时候亮出看家本领了我们直接来看ANativeWindowBuffer。
ANativeWindowBuffer: [frameworks/native/libs/nativebase/include/nativebase/nativebase.h]typedef struct ANativeWindowBuffer{#ifdef __cplusplusANativeWindowBuffer() {// 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 spANativeWindowBuffer expects so that it// can be used to automatically refcount ANativeWindowBuffers.// 调用common,也就是android_native_base_t的incRef和decRef函数void incStrong(const void* /*id*/) const {common.incRef(const_castandroid_native_base_t*(common));}void decStrong(const void* /*id*/) const {common.decRef(const_castandroid_native_base_t*(common));}#endif// common的incRef和decRef struct android_native_base_t common;int width;int height;int stride;int format;int usage_deprecated;uintptr_t layerCount;void* reserved[1];const native_handle_t* handle;uint64_t usage;// we needed extra space for storing the 64-bits usage flags// the number of slots to use from reserved_proc depends on the// architecture.void* reserved_proc[8 - (sizeof(uint64_t) / sizeof(void*))];} ANativeWindowBuffer_t;typedef struct ANativeWindowBuffer ANativeWindowBuffer;// Old typedef for backwards compatibility.typedef ANativeWindowBuffer_t android_native_buffer_t;**ANativeWindow** 的定义如下[frameworks/native/libs/nativewindow/include/system/window.h]
struct ANativeWindow
{
#ifdef __cplusplusANativeWindow(): 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));}/* Implement the methods that spANativeWindow expects so that itcan be used to automatically refcount ANativeWindows. */void incStrong(const void* /*id*/) const {common.incRef(const_castandroid_native_base_t*(common));}void decStrong(const void* /*id*/) const {common.decRef(const_castandroid_native_base_t*(common));}
#endifstruct android_native_base_t common;const uint32_t flags;const int minSwapInterval;const int maxSwapInterval;const float xdpi;const float ydpi;intptr_t oem[4];int (*setSwapInterval)(struct ANativeWindow* window,int interval);int (*dequeueBuffer_DEPRECATED)(struct ANativeWindow* window,struct ANativeWindowBuffer** buffer);int (*lockBuffer_DEPRECATED)(struct ANativeWindow* window,struct ANativeWindowBuffer* buffer);int (*queueBuffer_DEPRECATED)(struct ANativeWindow* window,struct ANativeWindowBuffer* buffer);int (*query)(const struct ANativeWindow* window,int what, int* value);int (*perform)(struct ANativeWindow* window,int operation, ... );int (*cancelBuffer_DEPRECATED)(struct ANativeWindow* window,struct ANativeWindowBuffer* buffer);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);
};//没有定义在这里这里只是为了学习方便
[frameworks/native/libs/nativewindow/include/android/native_window.h]
typedef struct ANativeWindow ANativeWindow;我们目前需要注意的是ANativeWindow的函数指针成员所指向的函数都需要一个struct ANativeWindowBuffer* buffer的参数.
ANativeWindowBuffer和ANativeWindow还是没有给android_native_base_t的incRef和decRef指针赋值,ANativeWindowBuffer和ANativeWindow两个还是可以理解为抽象类! 3.5 GraphicBuffer和Surface
前面我们认知了ANativeWindow和ANativeWindowBuffer接下来也让我们揭开GraphicBuffer和Surface的庐山真面目。
frameworks/native/libs/ui/include/ui/GraphicBuffer.h]
class GraphicBuffer: public ANativeObjectBaseANativeWindowBuffer, GraphicBuffer, RefBase,public FlattenableGraphicBuffer
{...
}
GraphicBuffer继承于模板类模版类ANativeObjectBase,这个模版类有三个模版.它的定义如下:
[frameworks/native/libs/ui/include/ui/ANativeObjectBase.h]
// NATIVE_TYPEANativeWindowBuffer TYPEGraphicBuffer REFRefBase
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 ANativeObjectBaseNATIVE_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_castTYPE*(self); } static inline TYPE const* getSelf(NATIVE_TYPE const* self) { return static_castTYPE const *(self); } static inline TYPE* getSelf(android_native_base_t* base) { return getSelf(reinterpret_castNATIVE_TYPE*(base)); } static inline TYPE const * getSelf(android_native_base_t const* base) { return getSelf(reinterpret_castNATIVE_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!它的定义如下:
class Surface : public ANativeObjectBaseANativeWindow, Surface, RefBase
{ enum { NUM_BUFFER_SLOTS BufferQueue::NUM_BUFFER_SLOTS }; ... struct BufferSlot { spGraphicBuffer 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 spIGraphicBufferProducer 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_castint(ANativeWindow::minSwapInterval) 0; const_castint(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类型的数组,也就是说每个Surface中都包含有NUM_BUFFER_SLOTS个sp.
关于ANativeWindow的使用方法,我们可以在SurfaceFlinger中找到一个很好的列子,就是SF的captureScreen接口。 3.6 关于GraphicBuffer和Surface牵涉的各种数据结构小结
通过上述的一通咔咔学习我们在以后的SurfaceFlinger HardWare Composer以及gralloc相关代码的学习过程中native_handle private_handle_t ANativeWindowBuffer ANativeWindow GraphicBuffer Surface等等一系列和memory相关的struct和class,他们相互之间到底是什么区别,又有什么联系呢我们应该已经很清楚了。
概括来说native_handle,private_handle_t,ANativeWindowBuffer,GraphicBuffer这四个struct/class所描述的是一块memory。而ANativeWindow和Surface所描述的是一系列上述memeofy的组合和对buffer的操作方法有的struct/class在比较低的level使用和平台有关而另外一些在比较高的level使用和平台无关还有一些介于低/高level之间用以消除平台相关性让android可以方便运行在不同的平台上。 写在最后
好了今天的博客关于Android下grallochwcompoer以及surface模块的重新认识就到这里了。总之青山不改绿水长流先到这里了。如果本博客对你有所帮助麻烦关注或者点个赞如果觉得很烂也可以踩一脚谢谢各位了