首页 > Android, Graphic > Android的Graphic系统代码分析杂记7

Android的Graphic系统代码分析杂记7

2011-10-20 13:28 星期四    浏览: 4,092    绿 发表评论 阅读评论

Graphic HAL

gralloc

 

库libgralloc的头文件位于:

hardware/libhardware/include/hardware/

android中默认库源码文件位于:

hardware/libhardware/modules/gralloc/

最终生成的库文件libgralloc.default.so,但一般vendor厂商都有自己的实现。

 

在默认实现中,符号变量HAL_MODULE_INFO_SYM是库libgralloc.default的入口点,它是一个private_module_t类型的结构体,在galloc.cpp文件的前面作为全局变量而存在并被初始化。结构体gralloc_module_t相当于其父类,而hw_module_t又相当于gralloc_module_t的父类,因此它们在private_module_t被初始化时一并都被初始化。

默认的初始化只到currentBuffer变量处,另外private_handle_t结构体变量也是到映射缓冲区时才初始化,后面的变量都是在mapFrameBuffer之中或之后进行的。

对于gralloc_module_t中registerBuffer/unregisgerBuffe和lock/unlockr等函数指针依赖于具体vendor的实现,由vendor提供。

 

gralloc设备打开过程(gralloc_device_open

在gralloc.cpp的函数gralloc_device_open中,主要是打开GRALLOC_HARDWARE_GPU0(即“gpu0”)设备,它不是通常所说的去打开某一个文件,而是像内核里打开某个文件时所做的那样,初始化一些数据结构,关联成员函数。因此,起打开过程就是:为结构体gralloc_context_t分配内层,并为其成员alloc_device_t中的函数指针赋值(为两个函数指针成员alloc和free等赋值),让gralloc设备与对应函数关联起来,这也是在内核里大多数设备open函数所要做的。

gralloc_device_open

fb设备打开过程(fb_device_open

在framebuffer.cpp的fb_device_open函数中,首先调用gralloc_open即调用gralloc_device_open打开gralloc设备,然后打开framebuffer设备:为fb_context_t分配内存,为framebuffer_device_t中的结构体成员赋值当然包括对函数指针成员赋值,让它们与对应的函数关联起来;之后调用mapFrameBuffer,对framebuffer进行内存映射。

 

fb_device_open

alloc_device_t.alloc=gralloc_alloc
alloc_device_t.free = gralloc_free

gralloc_device_open

 

 

framebuffer_device_t.setSwapInterval=fb_setSwapInterval;

framebuffer_device_t.post=fb_post;

framebuffer_device_t.setUpdateRect=0;

mapFrameBuffer

mapFrameBufferLocked

mmap,将设备文件fd(如/dev/fb0)映射到内存空间

在打开fb的过程如中,在最后有个很重要的函数mapFrameBufferLocked。在该函数中,会按如下优先顺序尝试打开系统的一个图形硬件设备,得到fd:

“/dev/graphics/fb0″->”/dev/fb0″->”/dev/graphics/fb1″->”/dev/fb1″

然后获取屏幕的固定和可变信息fb_fix_screeninfo和fb_var_screeninfo,并对可变信息进行设置;根据分辨率和预定义的缓冲区个数(默认为2)计算出所需的屏幕显示缓冲区大小fbSize(两屏幕所需的大小);然后,为private_module_t中的第二个变量private_handle_t结构体分配内存;最后,调用mmap将fd映射到内存空间,返回的虚拟地址赋值给private_handle_t中的base成员。因此,以后对base起始处fbSize大小的内存空间的操作,即是对显示缓冲区的操作。

 

图形缓冲区分配与释放(gralloc_alloc/gralloc_free

当调用者如Layer请求调用requestBuffer请求获得一块缓冲区时,GraphicBufferAllocator会负责打开gralloc设备,然后向alloc_device_t调用gralloc_alloc请求缓冲区。

在gralloc_alloc_framebuffer_locked中,前半部分是检查,大部分情况下,会执行到后半部分,也是该函数的主体,代码如下:

// create a “fake” handles for it
intptr_t vaddr = intptr_t(m->framebuffer->base);
private_handle_t* hnd = new private_handle_t(dup(m->framebuffer->fd), size,
private_handle_t::PRIV_FLAGS_FRAMEBUFFER);

// find a free slot
for (uint32_t i=0 ; i<numBuffers ; i++) {//2个缓冲区
if ((bufferMask & (1LU<<i)) == 0) {
m->bufferMask |= (1LU<<i);
break;
}
vaddr += bufferSize;
}

hnd->base = vaddr;
hnd->offset = vaddr – intptr_t(m->framebuffer->base);
*pHandle = hnd;

return 0;
}

它会创建一个private_handle_t,里面包含了base和offset的信息,被转换为其父类native_handle_t的指针通过实参指针所指赋值返回给调用者。

若不使用GRALLOC_USAGE_HW_FB,则使用AShMem内存,并创建private_handle_t,然后返回给调用者。

 

对于gralloc_free,则进行相反的操作,将bufferMask对应的位归零;或者是调用terminateBuffer进行munmap操作解除映射。

函数fb_post用于交换前后缓冲区,前缓冲区即为屏幕显示内容。

 

overlay

 

http://en.wikipedia.org/wiki/Hardware_overlay

 

默认的实现源码路径是:

hardware/libhardware/modules/overlay

它生成的库liboverlay.default.so,但它是一个空的实现。真正的实现需要各vendor提供,如TI的实现在hardware/ti/omap3/liboverlay

 

 

 

 

 

 

 

 

 

 

 

DisplayHardware

 

 

 

Overlay

 

 

 

libui.so

 

 

 

 

overlay_data_device_t

HAL(libgralloc)

 

 

 

overlay_module_t

 

 

 

 

overlay_control_device_t

 

 

 

 

本文链接地址: http://blog.redwolf-soft.com/?p=1420

原创文章,版权©红狼博客所有, 转载随意,但请注明出处。

    分享到:

相关文章:

  • 无相关文章
  1. 本文目前尚无任何评论.
  1. 本文目前尚无任何 trackbacks 和 pingbacks.
订阅评论
  欢迎参与讨论,请在这里发表您的看法、交流您的观点。