Jimmy Chen

A Programmer

(转载)Android图形显示之硬件抽象层Gralloc

  FrameBuffer驱动程序分析文中介绍了Linux系统下的显示驱动框架,每个显示屏被抽象为一个帧缓冲区,注册到FrameBuffer模块中,并在/dev/graphics目录下创建对应的fbX设备。Android系统在硬件抽象层中提供了一个Gralloc模块,封装了对帧缓冲区的所有访问操作。用户空间的应用程序在使用帧缓冲区之间,首先要加载Gralloc模块,并且获得一个gralloc设备和一个fb设备。有了gralloc设备之后,用户空间中的应用程序就可以申请分配一块图形缓冲区,并且将这块图形缓冲区映射到应用程序的地址空间来,以便可以向里面写入要绘制的画面的内容。最后,用户空间中的应用程序就通过fb设备来将已经准备好了的图形缓冲区渲染到帧缓冲区中去,即将图形缓冲区的内容绘制到显示屏中去。相应地,当用户空间中的应用程序不再需要使用一块图形缓冲区的时候,就可以通过gralloc设备来释放它,并且将它从地址空间中解除映射。

  Gralloc模块实现源码位于:hardware/libhardware/modules/gralloc

  Android硬件抽象Hardware库加载过程源码分析介绍了Android系统中的硬件抽象层模块的加载过程,并指出每个硬件抽象层模块都必须定义HAL_MODULE_INFO_SYM符号,并且有自己唯一的ID,Gralloc也不例外,Gralloc模块ID定义为:

  同时定义了以HAL_MODULE_INFO_SYM为符号的类型为private_module_t的结构体:

hardware\libhardware\modules\gralloc\gralloc.cpp

  通过Android硬件抽象Hardware库加载过程源码分析的方法将Gralloc模块加载到内存中来之后,就可以调用函数dlsym来获得它所导出的符号HMI,得到private_module_t的首地址后,由于private_module_t的第一个成员变量的类型为gralloc_module_t,因此也是gralloc_module_t的首地址,由于gralloc_module_t的第一个成员变量类型为hw_module_t,因此也是hw_module_t的首地址,因此只要得到这三种类型中其中一种类型变量的地址,就可以相互转换为其他两种类型的指针。

数据结构定义

  在分析Gralloc模块之前,首先介绍Gralloc模块定义的一些数据结构。private_module_t用于描述Gralloc模块下的系统帧缓冲区信息

  framebuffer_device_t用来描述系统帧缓冲区设备的信息

  gralloc_module_t用于描述gralloc模块信息

  alloc_device_t用于描述gralloc设备的信息

《(转载)Android图形显示之硬件抽象层Gralloc》

  硬件抽象层Gralloc模块定义了设备fb和设备gpu:

《(转载)Android图形显示之硬件抽象层Gralloc》

  设备gpu用于分配图形缓冲区,而设备fb用于渲染图形缓冲区;hw_module_t用于描述硬件抽象层Gralloc模块,而hw_device_t则用于描述硬件抽象层Gralloc设备,通过硬件抽象层设备可以找到对应的硬件抽象层模块。在Gralloc模块中,无论是定义fb设备还是gpu设备,都是用来处理图形缓冲区,以下是关于缓冲区的数据结构 定义:

  private_handle_t用来描述一块缓冲区,Android对缓冲区的定义提供了C和C++两种方式,C语言编译器下的定义:

C++编译器下的定义:

  两种编译器下的private_handle_t定义都继承于native_handle,native_handle的定义如下:

《(转载)Android图形显示之硬件抽象层Gralloc》

  Gralloc模块的打开过程在Android硬件抽象Hardware库加载过程源码分析中详细分析过了,下面就分析Gralloc模块中定义了两种设备的打开过程。

《(转载)Android图形显示之硬件抽象层Gralloc》

Fb设备打开过程

  fb设备的ID值定义为#define GRALLOC_HARDWARE_FB0 "fb0",fb设备使用结构体framebuffer_device_t来描述。结构体framebuffer_device_t是用来描述系统帧缓冲区的信息

hardware\libhardware\include\hardware\fb.h

  module指向的是一个用来描述Gralloc模块的hw_module_t结构体,前面提到,它的成员变量methods所指向的一个hw_module_methods_t结构体的成员函数open指向了Gralloc模块中的函数gralloc_device_open

hardware\libhardware\modules\gralloc\gralloc.cpp

  gralloc_device_open函数即可以打开fb设备,也可以用于打开gpu设备,这里根据设备名来区分打开的设备,对应fb设备,则调用fb_device_open函数来完成设备打开操作。

hardware\libhardware\modules\gralloc\framebuffer.cpp

  这个函数主要是用来创建一个fb_context_t结构体,并且对它的成员变量device进行初始化。结构体fb_context_t的成员变量device的类型为framebuffer_device_t,它是用来描述fb设备的。fb设备主要是用来渲染图形缓冲区的,这是通过调用它的成员函数post来实现的。函数fb_device_open所打开的fb设备的成员函数post被设置为Gralloc模块中的函数fb_post。函数mapFrameBuffer除了用来获得系统帧缓冲区的信息之外,还会将系统帧缓冲区映射到当前进程的地址空间来。line_length用来描述显示屏一行像素总共所占用的字节数,bits_per_pixel用来描述显示屏每一个像素所占用的位数,bits_per_pixel的值向右移3位,就可以得到显示屏每一个像素所占用的字节数。用显示屏像素总共所占用的字节数line_length除以每一个像素所占用的字节数就可以得到显示屏一行有多少个像素点,并保存在stride中。

  调用mapFrameBufferLocked函数执行映射过程,该函数在线程保护下完成。

《(转载)Android图形显示之硬件抽象层Gralloc》

  在了解本节内容之前首先需要了解Linux的FrameBuffer驱动,请查看FrameBuffer驱动程序分析.

Gpu设备打开过程

  gralloc设备使用结构体alloc_device_t来描述。结构体alloc_device_t有两个成员函数alloc和free,分别用来分配和释放图形缓冲区,gralloc设备的ID值定义为:

hardware\libhardware\include\hardware\gralloc.h

  module指向的是一个用来描述Gralloc模块的hw_module_t结构体,它的成员变量methods所指向的一个hw_module_methods_t结构体的成员函数open指向了Gralloc模块中的函数gralloc_device_open。前面介绍了函数gralloc_device_open即可以打开fb设备也可用来打开gpu设备,这里传入的设备名为GRALLOC_HARDWARE_GPU0,表示当前打开的是gpu设备。

hardware\libhardware\modules\gralloc\gralloc.cpp

  这个函数主要是用来创建一个gralloc_context_t结构体,并且对它的成员变量device进行初始化。结构体gralloc_context_t的成员变量device的类型为gralloc_device_t,它用来描述一个gralloc设备。前面提到,gralloc设备是用来分配和释放图形缓冲区的,这是通过调用它的成员函数alloc和free来实现的。从这里可以看出,函数gralloc_device_open所打开的gralloc设备的成员函数alloc和free分别被设置为Gralloc模块中的函数gralloc_alloc和gralloc_free。

《(转载)Android图形显示之硬件抽象层Gralloc》

转载自:https://blog.csdn.net/yangwen123/article/details/12192401

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注