Android帧缓冲区(Frame Buffer)硬件抽象层(HAL)模块Gralloc的实现原理分析(6)
-
static int mapFrameBuffer(struct private_module_t* module)
-
{
-
pthread_mutex_lock(&module->lock);
-
int err = mapFrameBufferLocked(module);
-
pthread_mutex_unlock(&module->lock);
-
return err;
-
}
-
int mapFrameBufferLocked(struct private_module_t* module)
-
{
-
// already initialized...
-
if (module->framebuffer) {
-
return 0;
-
}
-
-
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], 0);
-
fd = open(name, O_RDWR, 0);
-
i++;
-
}
-
if (fd < 0)
-
return -errno;
这段代码在首先在系统中检查是否存在设备文件/dev/graphics/fb0或者/dev/fb0。如果存在的话,那么就调用函数open来打开它,并且将得到的文件描述符保存在变量fd中。这样,接下来函数mapFrameBufferLocked就可以通过文件描述符fd来与内核中的帧缓冲区驱动程序交互。
-
struct fb_fix_screeninfo finfo;
-
if (ioctl(fd, FBIOGET_FSCREENINFO, &finfo) == -1)
-
return -errno;
-
-
struct fb_var_screeninfo info;
-
if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
-
return -errno;
-
info.reserved[0] = 0;
-
info.reserved[1] = 0;
-
info.reserved[2] = 0;
-
info.xoffset = 0;
-
info.yoffset = 0;
-
info.activate = FB_ACTIVATE_NOW;
-
-
#if defined(NO_32BPP)
-
/*
-
* Explicitly request 5/6/5
-
*/
-
info.bits_per_pixel = 16;
-
info.red.offset = 11;
-
info.red.length = 5;
-
info.green.offset = 5;
-
info.green.length = 6;
-
info.blue.offset = 0;
-
info.blue.length = 5;
-
info.transp.offset = 0;
-
info.transp.length = 0;
-
#endif
-
-
/*
-
* Request NUM_BUFFERS screens (at lest 2 for page flipping)
-
*/
-
info.yres_virtual = info.yres * NUM_BUFFERS;
-
-
-
uint32_t flags = PAGE_FLIP;
-
if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1) {
-
info.yres_virtual = info.yres;
-
flags &= ~PAGE_FLIP;
-
LOGW("FBIOPUT_VSCREENINFO failed, page flipping not supported");
-
}
-
-
if (info.yres_virtual < info.yres * 2) {
-
// we need at least 2 for page-flipping
-
info.yres_virtual = info.yres;
-
flags &= ~PAGE_FLIP;
-
LOGW("page flipping not supported (yres_virtual=%d, requested=%d)",
-
info.yres_virtual, info.yres*2);
-
}
-
if (ioctl(fd, FBIOGET_VSCREENINFO, &info) == -1)
-
return -errno;
-
-
uint64_t refreshQuotient =
-
(
-
uint64_t( info.upper_margin + info.lower_margin + info.yres )
-
* ( info.left_margin + info.right_margin + info.xres )
-
* info.pixclock
-
);
-
-
/* Beware, info.pixclock might be 0 under emulation, so avoid a
-
* division-by-0 here (SIGFPE on ARM) */
-
int refreshRate = refreshQuotient > 0 ? (int)(1000000000000000LLU / refreshQuotient) : 0;
-
-
if (refreshRate == 0) {
-
// bleagh, bad info from the driver
-
refreshRate = 60*1000; // 60 Hz
-
}