天天看点

Android图形显示系统——下层显示2:图形内存的申请与显示图形内存的申请与显示

这一篇回答序言中的第一个问题:

如何申请可以用来送显的内存,如何将其送往lcd?

图形内存是进程共享内存,且根据其标志支持不同硬件设备的读与写。

buffer_handle_t 是 *private_handle_t,gralloc模块自定义private_handle_t类型,并实现图形内存的实际申请。

graphicbuffer跨进程共享的流程是用binder传输必要信息到另一进程,另一进程调用gralloc模块的registerbuffer方法映射其到自己的内存空间。

graphicbuffer与surfaceflinger 没有 直接关系,图形内存不仅仅是提供给窗口系统用的,也不是非得在surfaceflinger进程里申请。

调用 gralloc 模块的 post 函数指针,并在hal层发送 fbiopan_display 指令,是将图形内存送显的一个路径,但不是惟一。

图形内存是用来渲染和显示的,它需要被跨进程共享,并支持不同硬件(gpu、dsp等)使用。

android中的图形内存包裹类为graphicbuffer。

Android图形显示系统——下层显示2:图形内存的申请与显示图形内存的申请与显示

graphicbuffer继承于anativewindowbuffer。

anativewindowbuffer包含w,h,stride和handle属性,其中handle对应一个private_handle_t的指针。

graphicbuffer额外包括 mbuffermapper(映射器,为单例),mid(每块graphicbuffer的独立id,根据进程号与申请顺序编号),minitcheck(表示申请状态,用来检查是否实际申请到了内存)。

申请释放图形内存的流程如下:

Android图形显示系统——下层显示2:图形内存的申请与显示图形内存的申请与显示
Android图形显示系统——下层显示2:图形内存的申请与显示图形内存的申请与显示

尽管已经将graphicbuffer映射到了自己的进程空间,在进一步使用时,流程上需要在使用前lock,使用完后unlock,这两个步骤一般用来作cache同步(根据共享内存策略,如果是缓存式,cpu/gpu会先把数据写到缓存,达到一定量才同步到graphicbuffer中,unlock时可以强制把缓存同步一次)。

在 graphicbuffer申请及lock的参数里,有个flags属性值,gralloc模块根据这个值,去判断从什么地方申请内存,按什么方式组织内存,我们来看一下:

gralloc_usage_sw_read_never,gralloc_usage_sw_read_rarely,gralloc_usage_sw_read_often

分别表示cpu不需要/很少会/经常会读这块graphicbuffer,对于read_often经常读的情况,gralloc模块应该考虑建读缓存了。

cpu写的三个标志类似。

当发觉graphicbuffer操作起来速度慢时,就得看一下,是不是忘了配cpu的读写标志了。

gralloc_usage_hw_texture

gralloc_usage_hw_render

这两个标志分别表示需要gpu读与写,texture表示可以映射为一个opengl的纹理,render表示可以作为opengl的渲染目标。

一般来说,gralloc分配的内存都是gpu可读写的,也不需要加这两个标志。

gralloc_usage_hw_composer

这个表示这个graphicbuffer可以由硬件合成器直接合成。

gralloc_usage_hw_video_encoder

这个表示这个graphicbuffer可以作为video硬解码(一般是dsp)的输入输出对象。

gralloc模块需要实现如下三个设备及函数指针。

关于gralloc模块如何注册如何打开,可看老罗的博客:

<a href="http://blog.csdn.net/luoshengyang/article/details/7747932">http://blog.csdn.net/luoshengyang/article/details/7747932</a>

这里面需要校正的是 hardware/libhardware/modules/gralloc下面的代码编译出来的是gralloc.default.so,即android系统默认提供的。一般来说厂商不会用这个so。

如下是arm为mali系列gpu提供的开源gralloc代码的链接,相对而言更有参考意义。

<a href="http://malideveloper.arm.com/cn/develop-for-mali/drivers/open-source-mali-gpus-android-gralloc-module/">http://malideveloper.arm.com/cn/develop-for-mali/drivers/open-source-mali-gpus-android-gralloc-module/</a>

arm提供的代码里面包括自家的ump方案和标准的ion方案,一般而言,在android4.2之后,普遍用的都是ion方案,ion内存共享方案可参考此博客的文章。

<a href="http://blog.csdn.net/qq160816/article/details/38082579">http://blog.csdn.net/qq160816/article/details/38082579</a>

<a href="http://blog.csdn.net/qq160816/article/details/38299251">http://blog.csdn.net/qq160816/article/details/38299251</a>

我们只看一下这份代码里面送显的部分:

送显的核心代码是这一句:

再往下看得跟厂商的内核代码了,这里没代码略过。关于lcd显示原理看老罗那篇就好了。

调用gralloc模块的post函数不是惟一一种将图形内存送到lcd显示的方法,另一种方式是overlay(hwcomposer的硬件合成)。

继续阅读