Android: 显示系统模块加载以及调用流程 HWComposer::loadFbHalModule() -> framebuffer_open()
2016-11-28 21:47
1511 查看
http://blog.csdn.net/hongzg1982/article/details/49681705
1.在HWComposer中,加载module
HWComposer::HWComposer(
const sp<SurfaceFlinger>& flinger,
EventHandler& handler)
{
...
// Note: some devices may insist that the FB HAL be opened before HWC.
int fberr = loadFbHalModule();
loadHwcModule();
...
}
1)loadFbHalModule()直接从下面的路径打开fb,初始化并保存framebuffer_device_t类型成员变量mFbDev。
gralloc_device_open()->fb_device_open()->mapFrameBuffer() -> mapFrameBufferLocked()
//gralloc.cpp文件中
static struct hw_module_methods_t gralloc_module_methods = {
.open = gralloc_device_open
};
struct private_module_t HAL_MODULE_INFO_SYM = {
.base = {
.common = {
.tag = HARDWARE_MODULE_TAG,
.version_major = 1,
.version_minor = 0,
.id = GRALLOC_HARDWARE_MODULE_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,
};
这个Module会在HWComposer::loadFbHalModule()中被加载,调用对应的open函数。
看以下代码注释
int HWComposer::loadFbHalModule()
{
hw_module_t const* module;
//根据GRALLOC_HARDWARE_MODULE_ID这个值,加载对应的module代码,也就是上面说的内容
int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
if (err != 0) {
ALOGE("%s module not found", GRALLOC_HARDWARE_MODULE_ID);
return err;
}
return framebuffer_open(module, &mFbDev);
}
//这里methods->open当然就是调用上面module的open函数,也就是gralloc_device_open()
static inline int framebuffer_open(const struct hw_module_t* module,
struct framebuffer_device_t** device) {
return module->methods->open(module,
GRALLOC_HARDWARE_FB0, (struct hw_device_t**)device);
}
//由于第二个参数是GRALLOC_HARDWARE_FB0,所以会跑到fb_device_open中
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)) {
const private_module_t* m = reinterpret_cast<const private_module_t*>(
module);
gpu_context_t *dev;
IAllocController* alloc_ctrl = IAllocController::getInstance();
dev = new gpu_context_t(m, alloc_ctrl);
if(!dev)
return status;
*device = &dev->common;
status = 0;
} else {
status = fb_device_open(module, name, device);
}
return status;
}
//由于name是GRALLOC_HARDWARE_FB0,会跑到if语句里进行初始化工作,包括打开/dev/graphics/fb0等
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)) {
alloc_device_t* gralloc_device;
status = gralloc_open(module, &gralloc_device);
if (status < 0)
return status;
/* initialize our state here */
fb_context_t *dev = (fb_context_t*)malloc(sizeof(*dev));
if(dev == NULL) {
gralloc_close(gralloc_device);
return status;
}
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_cast<hw_module_t*>(module);
dev->device.common.close = fb_close;
dev->device.setSwapInterval = fb_setSwapInterval;
dev->device.post = fb_post;
dev->device.setUpdateRect = 0;
dev->device.compositionComplete = fb_compositionComplete;
status = mapFrameBuffer((framebuffer_device_t*)dev);
private_module_t* m = (private_module_t*)dev->device.common.module;
if (status >= 0) {
int stride = m->finfo.line_length / (m->info.bits_per_pixel >> 3);
const_cast<uint32_t&>(dev->device.flags) = 0;
const_cast<uint32_t&>(dev->device.width) = m->info.xres;
const_cast<uint32_t&>(dev->device.height) = m->info.yres;
const_cast<int&>(dev->device.stride) = stride;
const_cast<int&>(dev->device.format) = m->fbFormat;
const_cast<float&>(dev->device.xdpi) = m->xdpi;
const_cast<float&>(dev->device.ydpi) = m->ydpi;
const_cast<float&>(dev->device.fps) = m->fps;
const_cast<int&>(dev->device.minSwapInterval) =
PRIV_MIN_SWAP_INTERVAL;
const_cast<int&>(dev->device.maxSwapInterval) =
PRIV_MAX_SWAP_INTERVAL;
const_cast<int&>(dev->device.numFramebuffers) = m->numBuffers;
dev->device.setUpdateRect = 0;
*device = &dev->device.common;
}
// Close the gralloc module
gralloc_close(gralloc_device);
}
return status;
}
2)loadHwcModule()函数通过以下路径打开fb,初始化并保存hwc_composer_device_1_t类型的成员变量mHwc。
HWComposer::loadHwcModule()->hw_get_module(HWC_HARDWARE_MODULE_ID, &module)
然后在调用hwc_open_1(module, &mHwc)->hwc_device_open()->initContext()->
CopyBit::CopyBit()[hwc_copybit.cpp]->hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module)
->open_copybit()->open("/dev/graphics/fb0", O_RDWR, 0);
这里的module加载以及调用open函数的过程基本和上面的一样,不多说了。
到此可以知道framework层是怎么打开的/dev/graphics/fb0节点,以待后续进行处理的!!
void SurfaceFlinger::postFramebuffer()
{
ATRACE_CALL();
#ifdef PRODUCT_DEV
if (CC_UNLIKELY(mDebugFps)) {
debugShowFPS();
}
/*
if(CC_UNLIKELY(ATRACE_ENABLED())){
debugShowGPUInfoToSysTrace();
}*/
#endif
const nsecs_t now = systemTime();
mDebugInSwapBuffers = now;
HWComposer& hwc(getHwComposer());
if (hwc.initCheck() == NO_ERROR) {
if (!hwc.supportsFramebufferTarget()) {
getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
}
//这个函数当然就是调用HWComposer::commit()函数,,不言而喻~
hwc.commit();
}
...
}
status_t HWComposer::commit() {
int err = NO_ERROR;
if (mHwc) {
...
for (size_t i=VIRTUAL_DISPLAY_ID_BASE; i<mNumDisplays; i++) {
DisplayData& disp(mDisplayData[i]);
if (disp.outbufHandle) {
mLists[i]->outbuf = disp.outbufHandle;
mLists[i]->outbufAcquireFenceFd =
disp.outbufAcquireFence->dup();
}
}
//这里的mHwc是加载了/hardware/qcom/display/libhwcomposer/Hwc.cpp的内容的
//理由吗,,和上面说的一样,根据id来选择module加载~
//所以set函数就是需要在Hwc.cpp文件中寻找了~
//这里mLists是hwc_display_contents_1_t类型,包含要画的buffer[]
//而mLists是HWComposer::prepare()函数中,从
//DisplayData& disp(mDisplayData[i]);
//mLists[i] = disp.list
//这样取出来的!!
//SurfaceFlinger怎么把内容赋给mDisplayData的,需要后面分析
err = mHwc->set(mHwc, mNumDisplays, mLists);
....
}
return (status_t)err;
}
//hwc_display_contents_1_t这个结构体包含要画的buffer内容,以及fense等成员的
//需要后面仔细看看每个成员表示什么
static int hwc_set(hwc_composer_device_1 *dev,
size_t numDisplays,
hwc_display_contents_1_t** displays)
{
int ret = 0;
hwc_context_t* ctx = (hwc_context_t*)(dev);
for (int dpy = 0; dpy < (int)numDisplays; dpy++) {
hwc_display_contents_1_t* list = displays[dpy];
switch(dpy) {
case HWC_DISPLAY_PRIMARY:
//这个就是主屏!!!看hwc_set_primary()函数
ret = hwc_set_primary(ctx, list);
break;
case HWC_DISPLAY_EXTERNAL:
ret = hwc_set_external(ctx, list);
break;
case HWC_DISPLAY_VIRTUAL:
if(ctx->mHWCVirtual)
ret = ctx->mHWCVirtual->set(ctx, list);
break;
default:
ret = -EINVAL;
}
}
return ret;
}
static int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
ATRACE_CALL();
int ret = 0;
const int dpy = HWC_DISPLAY_PRIMARY;
if (LIKELY(list) && ctx->dpyAttr[dpy].isActive
&& !ctx->dpyAttr[dpy].isPause) {
...
//利用copybit或者mdp,每个layer都有几个flags来标记用哪个去画
//以做过的一个平台为例,有以下两种方式
//// LayerProp::flag values
/* enum {
HWC_MDPCOMP = 0x00000001,
HWC_COPYBIT = 0x00000002,
};
*/
if (ctx->mCopyBit[dpy]) {
if (ctx->mMDP.version < qdutils::MDP_V4_0)
copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
else
fd = ctx->mMDPComp[dpy]->drawOverlap(ctx, list);
}
...
if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
ALOGE("%s: MDPComp draw failed", __FUNCTION__);
ret = -1;
}
...
if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd, lRoi, rRoi)) {
ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy);
ret = -1;
}
...
}
}
![](http://img.blog.csdn.net/20151201103941571)
在加载完fb相关的module之后,SurfaceFlinger就可以通过HWC把Layer画上去。流程如下:
SurfaceFlinger creates a list of layers and sends them to the HWC in the
prepare phase (hwc_prepare).
HWC sets the compositionType for those layers to be composed by
SurfaceFlinger as HWC_FRAMEBUFFER.
All layers marked as HWC_FRAMEBUFFER and layers whose flag is set
as HWC_SKIP are drawn by SurfaceFlinger.
SurfaceFlinger sends the layer list back to HWC after composing in
Framebuffer.
HWC draws the layers marked for copybit (HWC_COPYBIT) using the
copybit HAL respectively. This is the path taken if MDP composition is set.
The MDP composition mode in the MSM8x25 makes use of the copybit
HAL, which in turn uses the MDP IOCTLs to fill the framebuffer.
HWC invokes eglSwapBuffers.
到这里就可以知道怎么加载的模块,也看了SurfaceFlinger通过HWComposer和HWC.cpp模块的内容进行显示数据的刷写的过程。接下来看一下SurfaceFlinger,,
打开/dev/graphics/fb0节点的过程:
打开/dev/graphics/fb0这个设备的调用过程如下:1.在HWComposer中,加载module
HWComposer::HWComposer(
const sp<SurfaceFlinger>& flinger,
EventHandler& handler)
{
...
// Note: some devices may insist that the FB HAL be opened before HWC.
int fberr = loadFbHalModule();
loadHwcModule();
...
}
1)loadFbHalModule()直接从下面的路径打开fb,初始化并保存framebuffer_device_t类型成员变量mFbDev。
gralloc_device_open()->fb_device_open()->mapFrameBuffer() -> mapFrameBufferLocked()
加载module和调用open函数过程如下
这里gralloc_device_open定义在HAL层定义的://gralloc.cpp文件中
static struct hw_module_methods_t gralloc_module_methods = {
.open = gralloc_device_open
};
struct private_module_t HAL_MODULE_INFO_SYM = {
.base = {
.common = {
.tag = HARDWARE_MODULE_TAG,
.version_major = 1,
.version_minor = 0,
.id = GRALLOC_HARDWARE_MODULE_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,
};
这个Module会在HWComposer::loadFbHalModule()中被加载,调用对应的open函数。
看以下代码注释
int HWComposer::loadFbHalModule()
{
hw_module_t const* module;
//根据GRALLOC_HARDWARE_MODULE_ID这个值,加载对应的module代码,也就是上面说的内容
int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);
if (err != 0) {
ALOGE("%s module not found", GRALLOC_HARDWARE_MODULE_ID);
return err;
}
return framebuffer_open(module, &mFbDev);
}
//这里methods->open当然就是调用上面module的open函数,也就是gralloc_device_open()
static inline int framebuffer_open(const struct hw_module_t* module,
struct framebuffer_device_t** device) {
return module->methods->open(module,
GRALLOC_HARDWARE_FB0, (struct hw_device_t**)device);
}
//由于第二个参数是GRALLOC_HARDWARE_FB0,所以会跑到fb_device_open中
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)) {
const private_module_t* m = reinterpret_cast<const private_module_t*>(
module);
gpu_context_t *dev;
IAllocController* alloc_ctrl = IAllocController::getInstance();
dev = new gpu_context_t(m, alloc_ctrl);
if(!dev)
return status;
*device = &dev->common;
status = 0;
} else {
status = fb_device_open(module, name, device);
}
return status;
}
//由于name是GRALLOC_HARDWARE_FB0,会跑到if语句里进行初始化工作,包括打开/dev/graphics/fb0等
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)) {
alloc_device_t* gralloc_device;
status = gralloc_open(module, &gralloc_device);
if (status < 0)
return status;
/* initialize our state here */
fb_context_t *dev = (fb_context_t*)malloc(sizeof(*dev));
if(dev == NULL) {
gralloc_close(gralloc_device);
return status;
}
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_cast<hw_module_t*>(module);
dev->device.common.close = fb_close;
dev->device.setSwapInterval = fb_setSwapInterval;
dev->device.post = fb_post;
dev->device.setUpdateRect = 0;
dev->device.compositionComplete = fb_compositionComplete;
status = mapFrameBuffer((framebuffer_device_t*)dev);
private_module_t* m = (private_module_t*)dev->device.common.module;
if (status >= 0) {
int stride = m->finfo.line_length / (m->info.bits_per_pixel >> 3);
const_cast<uint32_t&>(dev->device.flags) = 0;
const_cast<uint32_t&>(dev->device.width) = m->info.xres;
const_cast<uint32_t&>(dev->device.height) = m->info.yres;
const_cast<int&>(dev->device.stride) = stride;
const_cast<int&>(dev->device.format) = m->fbFormat;
const_cast<float&>(dev->device.xdpi) = m->xdpi;
const_cast<float&>(dev->device.ydpi) = m->ydpi;
const_cast<float&>(dev->device.fps) = m->fps;
const_cast<int&>(dev->device.minSwapInterval) =
PRIV_MIN_SWAP_INTERVAL;
const_cast<int&>(dev->device.maxSwapInterval) =
PRIV_MAX_SWAP_INTERVAL;
const_cast<int&>(dev->device.numFramebuffers) = m->numBuffers;
dev->device.setUpdateRect = 0;
*device = &dev->device.common;
}
// Close the gralloc module
gralloc_close(gralloc_device);
}
return status;
}
2)loadHwcModule()函数通过以下路径打开fb,初始化并保存hwc_composer_device_1_t类型的成员变量mHwc。
HWComposer::loadHwcModule()->hw_get_module(HWC_HARDWARE_MODULE_ID, &module)
然后在调用hwc_open_1(module, &mHwc)->hwc_device_open()->initContext()->
CopyBit::CopyBit()[hwc_copybit.cpp]->hw_get_module(COPYBIT_HARDWARE_MODULE_ID, &module)
->open_copybit()->open("/dev/graphics/fb0", O_RDWR, 0);
这里的module加载以及调用open函数的过程基本和上面的一样,不多说了。
到此可以知道framework层是怎么打开的/dev/graphics/fb0节点,以待后续进行处理的!!
操作/dev/graphics/fb0节点的过程:
在SurfaceFlinger中最后进行数据刷新的函数,我们知道是postFrameBuffer()函数。定义如下:void SurfaceFlinger::postFramebuffer()
{
ATRACE_CALL();
#ifdef PRODUCT_DEV
if (CC_UNLIKELY(mDebugFps)) {
debugShowFPS();
}
/*
if(CC_UNLIKELY(ATRACE_ENABLED())){
debugShowGPUInfoToSysTrace();
}*/
#endif
const nsecs_t now = systemTime();
mDebugInSwapBuffers = now;
HWComposer& hwc(getHwComposer());
if (hwc.initCheck() == NO_ERROR) {
if (!hwc.supportsFramebufferTarget()) {
getDefaultDisplayDevice()->makeCurrent(mEGLDisplay, mEGLContext);
}
//这个函数当然就是调用HWComposer::commit()函数,,不言而喻~
hwc.commit();
}
...
}
status_t HWComposer::commit() {
int err = NO_ERROR;
if (mHwc) {
...
for (size_t i=VIRTUAL_DISPLAY_ID_BASE; i<mNumDisplays; i++) {
DisplayData& disp(mDisplayData[i]);
if (disp.outbufHandle) {
mLists[i]->outbuf = disp.outbufHandle;
mLists[i]->outbufAcquireFenceFd =
disp.outbufAcquireFence->dup();
}
}
//这里的mHwc是加载了/hardware/qcom/display/libhwcomposer/Hwc.cpp的内容的
//理由吗,,和上面说的一样,根据id来选择module加载~
//所以set函数就是需要在Hwc.cpp文件中寻找了~
//这里mLists是hwc_display_contents_1_t类型,包含要画的buffer[]
//而mLists是HWComposer::prepare()函数中,从
//DisplayData& disp(mDisplayData[i]);
//mLists[i] = disp.list
//这样取出来的!!
//SurfaceFlinger怎么把内容赋给mDisplayData的,需要后面分析
err = mHwc->set(mHwc, mNumDisplays, mLists);
....
}
return (status_t)err;
}
//hwc_display_contents_1_t这个结构体包含要画的buffer内容,以及fense等成员的
//需要后面仔细看看每个成员表示什么
static int hwc_set(hwc_composer_device_1 *dev,
size_t numDisplays,
hwc_display_contents_1_t** displays)
{
int ret = 0;
hwc_context_t* ctx = (hwc_context_t*)(dev);
for (int dpy = 0; dpy < (int)numDisplays; dpy++) {
hwc_display_contents_1_t* list = displays[dpy];
switch(dpy) {
case HWC_DISPLAY_PRIMARY:
//这个就是主屏!!!看hwc_set_primary()函数
ret = hwc_set_primary(ctx, list);
break;
case HWC_DISPLAY_EXTERNAL:
ret = hwc_set_external(ctx, list);
break;
case HWC_DISPLAY_VIRTUAL:
if(ctx->mHWCVirtual)
ret = ctx->mHWCVirtual->set(ctx, list);
break;
default:
ret = -EINVAL;
}
}
return ret;
}
static int hwc_set_primary(hwc_context_t *ctx, hwc_display_contents_1_t* list) {
ATRACE_CALL();
int ret = 0;
const int dpy = HWC_DISPLAY_PRIMARY;
if (LIKELY(list) && ctx->dpyAttr[dpy].isActive
&& !ctx->dpyAttr[dpy].isPause) {
...
//利用copybit或者mdp,每个layer都有几个flags来标记用哪个去画
//以做过的一个平台为例,有以下两种方式
//// LayerProp::flag values
/* enum {
HWC_MDPCOMP = 0x00000001,
HWC_COPYBIT = 0x00000002,
};
*/
if (ctx->mCopyBit[dpy]) {
if (ctx->mMDP.version < qdutils::MDP_V4_0)
copybitDone = ctx->mCopyBit[dpy]->draw(ctx, list, dpy, &fd);
else
fd = ctx->mMDPComp[dpy]->drawOverlap(ctx, list);
}
...
if (!ctx->mMDPComp[dpy]->draw(ctx, list)) {
ALOGE("%s: MDPComp draw failed", __FUNCTION__);
ret = -1;
}
...
if(!Overlay::displayCommit(ctx->dpyAttr[dpy].fd, lRoi, rRoi)) {
ALOGE("%s: display commit fail for %d dpy!", __FUNCTION__, dpy);
ret = -1;
}
...
}
}
在加载完fb相关的module之后,SurfaceFlinger就可以通过HWC把Layer画上去。流程如下:
SurfaceFlinger creates a list of layers and sends them to the HWC in the
prepare phase (hwc_prepare).
HWC sets the compositionType for those layers to be composed by
SurfaceFlinger as HWC_FRAMEBUFFER.
All layers marked as HWC_FRAMEBUFFER and layers whose flag is set
as HWC_SKIP are drawn by SurfaceFlinger.
SurfaceFlinger sends the layer list back to HWC after composing in
Framebuffer.
HWC draws the layers marked for copybit (HWC_COPYBIT) using the
copybit HAL respectively. This is the path taken if MDP composition is set.
The MDP composition mode in the MSM8x25 makes use of the copybit
HAL, which in turn uses the MDP IOCTLs to fill the framebuffer.
HWC invokes eglSwapBuffers.
到这里就可以知道怎么加载的模块,也看了SurfaceFlinger通过HWComposer和HWC.cpp模块的内容进行显示数据的刷写的过程。接下来看一下SurfaceFlinger,,
相关文章推荐
- Android: 显示系统模块加载以及调用流程
- Android系统应用---SystemUI之二:Statusbar显示流程以及系统状态图标更新分析
- Android研究_Hardware Composer_2 加载HWComposer模块及编译分析
- Android 拍照以及一些常用的处理,例如将图片显示到相册(包含了安卓系统6.0以上调用相机的处理)
- LDD3之scull--从open系统调用到模块的scull_open执行流程分析
- 加载内核模块,实现新的系统调用:遍历系统当前所有进程的任务描述符,并将pid组织成树状结构显示
- Android系统调用流程---以open为例
- Android 调用系统相机拍照并且显示在相册中,以及中间可能会遇到的一些问题的解决
- Android使用webview调用系统浏览器以及项目内显示并支持图片和输入
- android framebuffer和HAL以及显示系统
- Android系统Recovery工作原理之使用update.zip升级过程分析(九)---updater-script脚本语法简介以及执行流程
- linux设备驱动模型一字符设备open系统调用流程
- open系统调用在内核中的流程分析
- 【android基础】之Android 调用系统地图(Google Map)并显示具体方位
- usleep的--系统调用流程--及不准确的问题 - Android4.0.1
- (转)android如何调用显示和隐藏系统默认的输入法
- android 通过Intent action 跳转到系统页面,调用系统功能以及action动...
- Android 调用系统地图(Google Map)并显示具体方位
- Android中的自定义Adapter(继承自BaseAdapter)——与系统Adapter的调用方法一致——含ViewHolder显示效率的优化
- Android 调用系统地图(Google Map)并显示具体方位