为了完整性起见,最后我们再简要分析函数gralloc_lock和gralloc_unlock的实现,以便可以了解一个图形缓冲区的锁定和解锁操作是如何实现的。
函数gralloc_lock实现在文件hardware/libhardware/modules/gralloc/mapper.cpp文件中,如下所示:
-
int gralloc_lock(gralloc_module_t const* module,
-
buffer_handle_t handle, int usage,
-
int l, int t, int w, int h,
-
void** vaddr)
-
{
-
// this is called when a buffer is being locked for software
-
// access. in thin implementation we have nothing to do since
-
// not synchronization with the h/w is needed.
-
// typically this is used to wait for the h/w to finish with
-
// this buffer if relevant. the data cache may need to be
-
// flushed or invalidated depending on the usage bits and the
-
// hardware.
-
-
if (private_handle_t::validate(handle) < 0)
-
return -EINVAL;
-
-
private_handle_t* hnd = (private_handle_t*)handle;
-
*vaddr = (void*)hnd->base;
-
return 0;
-
}
从这里可以看出,函数gralloc_lock其实并没有执行锁定参数handle所描述的一个缓冲区的操作,它只简单地将要锁定的缓冲区的开始地址返回给调用者。
理论上来说,函数gralloc_lock应该检查参数handle所描述的一个缓冲区是否正在被其进程或者线程使用。如果是的话,那么函数gralloc_lock就必须要等待,直到要锁定的缓冲区被其它进程或者线程使用结束为止,以便接下来可以独占它。由于函数gralloc_lock实际上并没有作这些操作,因此,就必须要由调用者来保证要锁定的缓冲区当前是没有被其它进程或者线程使用的。
函数gralloc_unlock也是实现在文件hardware/libhardware/modules/gralloc/mapper.cpp文件中,如下所示:
-
int gralloc_unlock(gralloc_module_t const* module,
-
buffer_handle_t handle)
-
{
-
// we're done with a software buffer. nothing to do in this
-
// implementation. typically this is used to flush the data cache.
-
-
if (private_handle_t::validate(handle) < 0)
-
return -EINVAL;
-
return 0;
-
}
函数gralloc_unlock执行的操作本来是刚好与函数gralloc_lock相反的,但是由于函数gralloc_lock并没有真实地锁定参数handle所描述的一个缓冲区的,因此,函数gralloc_unlock是不需要执行实际的解锁工作的。
至此,我们就分析完成Android帧缓冲区硬件抽象层模块Gralloc的实现原理了。从分析的过程可以知道,为了在屏幕中绘制一个指定的画面,我们需要:
1. 分配一个匹配屏幕大小的图形缓冲区
2. 将分配好的图形缓冲区注册(映射)到当前进程的地址空间来
3. 将要绘制的画面的内容写入到已经注册好的图形缓冲区中去,并且渲染(拷贝)到系统帧缓冲区中去
为了实现以上三个操作,我们还需要:
1. 加载Gralloc模块
2. 打开Gralloc模块中的gralloc设备和fb设备
其中,gralloc设备负责分配图形缓冲区,Gralloc模块负责注册图形缓冲区,而fb设备负责渲染图形缓冲区。
理解了Gralloc模块的实现原理之后,就可以为后续分析SurfaceFlinger服务的实现打下坚实的基础了。
本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/967095,如需转载请自行联系原作者