上一篇文章介绍了init进程去启动surfaceflinger的过程;本文将继承上篇文章继续往下分析,上文分析到SurfaceFlinger::init();本文将主要分析init()里面的HWComposer初始化。
时序图如下:
1、HWComposer创建
void SurfaceFlinger::init() {
// Initialize the H/W composer object. There may or may not be an
// actual hardware composer underneath.
mHwc = new HWComposer(this,
*static_cast<HWComposer::EventHandler *>(this));//调用构造函数
}
2、HWComposer构造函数
HWComposer::HWComposer(
const sp<SurfaceFlinger>& flinger,EventHandler& handler)
: mFlinger(flinger),mFbDev(0), mHwc(0), mNumDisplays(1),mCBContext(new cb_context), mEventHandler(handler), mDebugForceFakeVSync(false)
{
// Note: some devices may insist that the FB HAL be opened before HWC.
int fberr = loadFbHalModule();//详见第3节
loadHwcModule();//详见第4节
。。。。。。
if (mFbDev) {
。。。。。。
} else if (mHwc) {
// here we're guaranteed to have at least HWC 1.1
for (size_t i =0 ; i<NUM_BUILTIN_DISPLAYS ; i++) {
queryDisplayProperties(i);//详见第5节
}
}
}
3、loadFbHalModule
这个函数的作用是通过GRALLOC_HARDWARE_MODULE_ID去加载对应的显示屏HAL层模块,并初始化。
int HWComposer::loadFbHalModule()
{
hw_module_t const* module;
int err = hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &module);//详见3.1节
if (err != 0) {
ALOGE("%s module not found", GRALLOC_HARDWARE_MODULE_ID);
return err;
}
return framebuffer_open(module, &mFbDev);//详见3.2节
}
3.1、加载模块
通过GRALLOC_HARDWARE_MODULE_ID找到对应的模块,并将HAL_MODULE_INFO_SYM结构体的地址赋给指针module。
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: BufferManager::gralloc_register_buffer,
unregisterBuffer: BufferManager::gralloc_unregister_buffer,
lock: BufferManager::gralloc_lock,
unlock: BufferManager::gralloc_unlock,
},
};
3.2、调用模块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);
}
由上面可知,module指向的是HMI;那么module->methods->open调用的就是该模块中gralloc_module_methods的open方法。
static struct hw_module_methods_t gralloc_module_methods = {
open: BufferManager::gralloc_device_open//见3.3节
};
3.3 BufferManager中open方法
int BufferManager::gralloc_device_open(const hw_module_t* module, const char* name,
hw_device_t** device)
{
BufferManager* m = BufferManager::getInstance();
if (!strcmp(name, GRALLOC_HARDWARE_GPU0)) {
......
}
else {//前面传入的参数为GRALLOC_HARDWARE_FB0
status = fb_device_open(module, name, device);//见3.4节
}
return status;
}
3.4 打开fb设备
int BufferManager::fb_device_open(hw_module_t const* module, const char* name,
hw_device_t** device)
{
int status = 0;
char value[PROPERTY_VALUE_MAX];
if (!strncmp(name, GRALLOC_HARDWARE_FB, 2)) {
framebuffer_device_t *fbdev;
nr_framebuffers = NUM_BUFFERS;
/* 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_cast<hw_module_t*>(module);
dev->device.common.close = Display::closeDevice;
dev->device.setSwapInterval = Display::setSwapInterval;
dev->device.post = Display::postBuffer;
dev->device.setUpdateRect = 0;
dev->device.compositionComplete = Display::compositionComplete;
dev->device.common.module = const_cast<hw_module_t*>(module);
BufferManager* pBufferManager = BufferManager::getInstance();
int fbid = atoi(name+2);//将Fb0中的0转化为数字赋值给fbid
if (fbid < 0 || fbid > 5) {
ALOGE("%s invalid fb num %d", __FUNCTION__, fbid);
::free(dev);
return -EINVAL;
}
int dispid = 0;
dev->isMainDisp = 1;
ALOGI("fb_device_open dispid:%d, fb:%d", dispid, fbid);
Display* display = pBufferManager->getDisplay(dispid);//通过dispid获取数组对应下标的Display
if (display == NULL) {
ALOGE("%s can't get valid display", __FUNCTION__);
::free(dev);
return -EINVAL;
}
status = display->initialize(fbid);//详见3.5节
if (status >= 0) {
display->setContext(dev);
}
dev->display = display;
*device = &dev->device.common;
fbdev = (framebuffer_device_t*)(*device);
fbdev->reserved[0] = nr_framebuffers;
}
return status;
}
3.5、初始化Fb设备
int Display::initialize(int fb)
{
Mutex::Autolock _l(mLock);
fb_num = fb;
int fbid = fb_num;
char const * const device_template[] = {//设备节点路径
"/dev/graphics/fb%u",
"/dev/fb%u",
0 };
int fd = -1;
int i=0;
char name[64];
while ((fd==-1) && device_template[i]) {
snprintf(name, 64, device_template[i], fbid);
fd = open(name, O_RDWR, 0);//打开设备节点,默认是/dev/graphics/fb0
i++;
}
//获取屏幕固定参数
struct fb_fix_screeninfo finfo;
if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1) {
ALOGE("<%s,%d> FBIOGET_FSCREENINFO failed", __FUNCTION__, __LINE__);
close(fd);
return -errno;
}
//获取屏幕可变参数
struct fb_var_screeninfo info;
if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1) {
ALOGE("<%s,%d> FBIOGET_VSCREENINFO failed", __FUNCTION__, __LINE__);
close(fd);
return -errno;
}
//显存地址映射
void* vaddr = mmap(0, fbSize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0);
if (vaddr == MAP_FAILED) {
ALOGE("Error mapping the framebuffer (%s)", strerror(errno));
close(fd);
return -errno;
}
mFramebuffer->base = intptr_t(vaddr);
mFramebuffer->phys = intptr_t(finfo.smem_start);
memset(vaddr, 0, fbSize);
close(fd);
return 0;
}
4、loadHwcModule
这个函数的作用是通过HWC_HARDWARE_MODULE_ID去加载硬件合成器
void HWComposer::loadHwcModule()
{
hw_module_t const* module;
if (hw_get_module(HWC_HARDWARE_MODULE_ID, &module) != 0) {
ALOGE("%s module not found", HWC_HARDWARE_MODULE_ID);
return;
}
int err = hwc_open_1(module, &mHwc);
if (err) {
ALOGE("%s device failed to initialize (%s)",
HWC_HARDWARE_COMPOSER, strerror(-err));
return;
}
}
4.1 加载模块
hwc_module_t HAL_MODULE_INFO_SYM = {
common: {
tag: HARDWARE_MODULE_TAG,
version_major: 2,
version_minor: 0,
id: HWC_HARDWARE_MODULE_ID,
name: "Freescale i.MX hwcomposer module",
author: "Freescale Semiconductor, Inc.",
methods: &hwc_module_methods,
dso: NULL,
reserved: {0}
}
};
4.2 调用模块open方法
static inline int hwc_open_1(const struct hw_module_t* module,
hwc_composer_device_1_t** device) {
return module->methods->open(module,
HWC_HARDWARE_COMPOSER, (struct hw_device_t**)device);
}
由上面可知,module指向的是HMI;那么module->methods->open调用的就是该模块中hwc_module_methods的open方法。
static struct hw_module_methods_t hwc_module_methods = {
open: hwc_device_open
};
4.3 打开硬件合成器
static int hwc_device_open(const struct hw_module_t* module, const char* name,
struct hw_device_t** device)
{
int status = -EINVAL;
struct hwc_context_t *dev = NULL;
if (!strcmp(name, HWC_HARDWARE_COMPOSER)) {
//struct hwc_context_t *dev;
dev = (hwc_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.module = const_cast<hw_module_t*>(module);
dev->device.common.close = hwc_device_close;
dev->device.prepare = hwc_prepare;
dev->device.set = hwc_set;
dev->device.common.version = HWC_DEVICE_API_VERSION_1_3;
dev->device.registerProcs = hwc_registerProcs;
dev->device.eventControl = hwc_eventControl;
dev->device.query = hwc_query;
dev->device.blank = hwc_blank;
dev->device.getDisplayConfigs = hwc_getDisplayConfigs;
dev->device.getDisplayAttributes = hwc_getDisplayAttributes;
/* our private state goes below here */
dev->m_vsync_thread = new VSyncThread(dev);
dev->m_uevent_thread = new UeventThread(dev);
bool using_fsl_hwc = false;
const hw_module_t *hwc_module;
hwc_get_display_info(dev);//获取显示信息
hw_get_module(GRALLOC_HARDWARE_MODULE_ID, &dev->m_gralloc_module);
struct private_module_t *priv_m =
(struct private_module_t *)dev->m_gralloc_module;
for(int dispid=0; dispid<HWC_NUM_PHYSICAL_DISPLAY_TYPES; dispid++) {
if(dev->mDispInfo[dispid].connected && dev->m_gralloc_module != NULL) {
int fbid = dev->mDispInfo[dispid].fb_num;
char fbname[HWC_STRING_LENGTH];
memset(fbname, 0, sizeof(fbname));
sprintf(fbname, "fb%d", fbid);
ALOGI("hwcomposer: open framebuffer %s", fbname);
dev->mFbDev[dispid] = (framebuffer_device_t*)dispid;
dev->m_gralloc_module->methods->open(dev->m_gralloc_module, fbname,
(struct hw_device_t**)&dev->mFbDev[dispid]);
}
}
*device = &dev->device.common;
ALOGI("%s,%d", __FUNCTION__, __LINE__);
return 0;
}
/****************************************/
return status;
}
5、查询显示属性
status_t HWComposer::queryDisplayProperties(int disp) {
// use zero as default value for unspecified attributes
int32_t values[NUM_DISPLAY_ATTRIBUTES - 1];
memset(values, 0, sizeof(values));
const size_t MAX_NUM_CONFIGS = 128;
uint32_t configs[MAX_NUM_CONFIGS] = {0};
size_t numConfigs = MAX_NUM_CONFIGS;
status_t err = mHwc->getDisplayConfigs(mHwc, disp, configs, &numConfigs);
if (err != NO_ERROR) {
// this can happen if an unpluggable display is not connected
mDisplayData[disp].connected = false;
return err;
}
mDisplayData[disp].currentConfig = 0;
for (size_t c = 0; c < numConfigs; ++c) {
err = mHwc->getDisplayAttributes(mHwc, disp, configs[c],
DISPLAY_ATTRIBUTES, values);
// If this is a pre-1.5 HWC, it may not know about color transform, so
// try again with a smaller set of attributes
if (err != NO_ERROR) {
err = mHwc->getDisplayAttributes(mHwc, disp, configs[c],
PRE_HWC15_DISPLAY_ATTRIBUTES, values);
}
DisplayConfig config = DisplayConfig();
if (config.xdpi == 0.0f || config.ydpi == 0.0f) {
float dpi = getDefaultDensity(config.width, config.height);
config.xdpi = dpi;
config.ydpi = dpi;
}
mDisplayData[disp].configs.push_back(config);//显示数据数组管理
}
mDisplayData[disp].connected = true;
return NO_ERROR;
}
到此,HWComposer初始化分析介绍;接下来分析根据HWComposer来构造DisplayDevice对象;从而达到分层的效果。未完待续。。。。。