Android帧缓冲区(Frame Buffer)硬件抽象层(HAL)模块Gralloc的实现原理分析(3)

简介:
   结构体gralloc_module_t定义在文件hardware/libhardware/include/hardware/gralloc.h中,它主要是定义了四个用来操作图形缓冲区的成员函数,如下所示:
  1. typedef struct gralloc_module_t {  
  2.     ......  
  3.   
  4.     int (*registerBuffer)(struct gralloc_module_t const* module,  
  5.             buffer_handle_t handle);  
  6.   
  7.     int (*unregisterBuffer)(struct gralloc_module_t const* module,  
  8.             buffer_handle_t handle);  
  9.   
  10.   
  11.     int (*lock)(struct gralloc_module_t const* module,  
  12.             buffer_handle_t handle, int usage,  
  13.             int l, int t, int w, int h,  
  14.             void** vaddr);  
  15.   
  16.     int (*unlock)(struct gralloc_module_t const* module,  
  17.             buffer_handle_t handle);  
  18.   
  19.     ......  
  20. }  
        成员函数registerBuffer和unregisterBuffer分别用来注册和注销一个指定的图形缓冲区,这个指定的图形缓冲区使用一个buffer_handle_t句柄来描述。所谓注册图形缓冲区,实际上就是将一块图形缓冲区映射到一个进程的地址空间去,而注销图形缓冲区就是执行相反的操作。
 
        成员函数lock和unlock分别用来锁定和解锁一个指定的图形缓冲区,这个指定的图形缓冲区同样是使用一个buffer_handle_t句柄来描述。在访问一块图形缓冲区的时候,例如,向一块图形缓冲写入内容的时候,需要将该图形缓冲区锁定,用来避免访问冲突。在锁定一块图形缓冲区的时候,可以指定要锁定的图形绘冲区的位置以及大小,这是通过参数l、t、w和h来指定的,其中,参数l和t指定的是要访问的图形缓冲区的左上角位置,而参数w和h指定的是要访问的图形缓冲区的宽度和长度。锁定之后,就可以获得由参数参数l、t、w和h所圈定的一块缓冲区的起始地址,保存在输出参数vaddr中。另一方面,在访问完成一块图形缓冲区之后,需要解除这块图形缓冲区的锁定。
        在Gralloc模块中,符号HAL_MODULE_INFO_SYM指向的gralloc结构体的成员函数registerBuffer、unregisterBuffer、lock和unlock分别被指定为函数gralloc_register_buffer、gralloc_unregister_buffer、gralloc_lock和gralloc_unlock,后面我们再详细分析它们的实现。
        结构体private_module_t定义在文件hardware/libhardware/modules/gralloc/gralloc_priv.h中,它主要是用来描述帧缓冲区的属性,如下所示:
  1. struct private_module_t {  
  2.     gralloc_module_t base;  
  3.   
  4.     private_handle_t* framebuffer;  
  5.     uint32_t flags;  
  6.     uint32_t numBuffers;  
  7.     uint32_t bufferMask;  
  8.     pthread_mutex_t lock;  
  9.     buffer_handle_t currentBuffer;  
  10.     int pmem_master;  
  11.     void* pmem_master_base;  
  12.   
  13.     struct fb_var_screeninfo info;  
  14.     struct fb_fix_screeninfo finfo;  
  15.     float xdpi;  
  16.     float ydpi;  
  17.     float fps;  
  18. };  
       成员变量framebuffer的类型为private_handle_t,它是一个指向系统帧缓冲区的句柄,后面我们再分析结构体private_handle_t的定义。
 
       成员变量flags用来标志系统帧缓冲区是否支持双缓冲。如果支持的话,那么它的PAGE_FLIP位就等于1,否则的话,就等于0。
       成员变量numBuffers表示系统帧缓冲区包含有多少个图形缓冲区。一个帧缓冲区包含有多少个图形缓冲区是与它的可视分辨率以及虚拟分辨率的大小有关的。例如,如果一个帧缓冲区的可视分辨率为800 x 600,而虚拟分辨率为1600 x 600,那么这个帧缓冲区就可以包含有两个图形缓冲区。
       成员变量bufferMask用来记录系统帧缓冲区中的图形缓冲区的使用情况。例如,假设系统帧缓冲区有两个图形缓冲区,这时候成员变量bufferMask就有四种取值,分别是二进制的00、01、10和11,其中,00分别表示两个图缓冲区都是空闲的,01表示第1个图形缓冲区已经分配出去,而第2个图形缓冲区是空闲的,10表示第1个图形缓冲区是空闲的,而第2个图形缓冲区已经分配出去,11表示两个图缓冲区都已经分配出去。
       成员变量lock是一个互斥锁,用来保护结构体private_module_t的并行访问。
       成员变量currentBuffer的类型为buffer_handle_t,用来描述当前正在被渲染的图形缓冲区,后面我们再分析它的定义。
       成员变量pmem_master和pmem_master_base目前没有使用。
       成员变量info和finfo的类型分别为fb_var_screeninfo和fb_fix_screeninfo,它们用来保存设备显示屏的属性信息,其中,成员变量info保存的属性信息是可以动态设置的,而成员变量finfo保存的属性信息是只读的。这两个成员变量的值可以通过IO控制命令FBIOGET_VSCREENINFO和FBIOGET_FSCREENINFO来从帧缓冲区驱动模块中获得。
       成员变量xdpi和ydpi分别用来描述设备显示屏在宽度和高度上的密度,即每英寸有多少个像素点。
       成员变量fps用来描述显示屏的刷新频率,它的单位的fps,即每秒帧数。
       接下来, 我们再分析结构体buffer_handle_t和private_handle_t的定义。
       结构体buffer_handle_t定义在文件hardware/libhardware/include/hardware/gralloc.h文件中,如下所示:
  1. typedef const native_handle* buffer_handle_t;  
       它是一个类型为native_handle_t的指针,而结构体native_handle_t用来描述一个本地句柄值,它定义在系统运行时层的文件system/core/include/cutils/native_handle.h文件中,如下所示:
  1. typedef struct  
  2. {  
  3.     int version;        /* sizeof(native_handle_t) */  
  4.     int numFds;         /* number of file-descriptors at &data[0] */  
  5.     int numInts;        /* number of ints at &data[numFds] */  
  6.     int data[0];        /* numFds + numInts ints */  
  7. } native_handle_t;  
       成员变量version的大小被设置为结构体native_handle_t的大小,用来标识结构体native_handle_t的版本。
 
       成员变量numFds和numInts表示结构体native_handle_t所包含的文件描述符以及整数值的个数,这些文件描述符和整数保存在成员变量data所指向的一块缓冲区中。
       我们一般不直接使用native_handle_t结构体来描述一个本地句柄值,而是通过它的子类来描述一个具体的本地句柄值。接下来我们就通过结构体private_handle_t的定义来说明native_handle_t结构体的用法。
       结构体private_handle_t用来描述一块图形缓冲区,这块图形缓冲区可能是在帧缓冲区中分配的,也可能是在内存中分配的,视具体情况而定,它定义在文件hardware/libhardware/modules/gralloc/gralloc_priv.h文件中,如下所示:
  1. #ifdef __cplusplus  
  2. struct private_handle_t : public native_handle {  
  3. #else  
  4. struct private_handle_t {  
  5.     struct native_handle nativeHandle;  
  6. #endif  
  7.   
  8.     enum {  
  9.         PRIV_FLAGS_FRAMEBUFFER = 0x00000001  
  10.     };  
  11.   
  12.     // file-descriptors  
  13.     int     fd;  
  14.     // ints  
  15.     int     magic;  
  16.     int     flags;  
  17.     int     size;  
  18.     int     offset;  
  19.   
  20.     // FIXME: the attributes below should be out-of-line  
  21.     int     base;  
  22.     int     pid;  
  23.   
  24. #ifdef __cplusplus  
  25.     static const int sNumInts = 6;  
  26.     static const int sNumFds = 1;  
  27.     static const int sMagic = 0x3141592;  
  28.   
  29.     private_handle_t(int fd, int size, int flags) :  
  30.         fd(fd), magic(sMagic), flags(flags), size(size), offset(0),  
  31.         base(0), pid(getpid())  
  32.     {  
  33.         version = sizeof(native_handle);  
  34.         numInts = sNumInts;  
  35.         numFds = sNumFds;  
  36.     }  
  37.     ~private_handle_t() {  
  38.         magic = 0;  
  39.     }  
  40.   
  41.     static int validate(const native_handle* h) {  
  42.         const private_handle_t* hnd = (const private_handle_t*)h;  
  43.         if (!h || h->version != sizeof(native_handle) ||  
  44.                 h->numInts != sNumInts || h->numFds != sNumFds ||  
  45.                 hnd->magic != sMagic)  
  46.         {  
  47.             LOGE("invalid gralloc handle (at %p)", h);  
  48.             return -EINVAL;  
  49.         }  
  50.         return 0;  
  51.     }  
  52. #endif  
  53. };  
        为了方便描述,我们假设我们是在C++环境中编译文件gralloc_priv.h,即编译环境定义有宏__cplusplus。这样,结构体private_handle_t就是从结构体native_handle_t继承下来的,它包含有1个文件描述符以及6个整数,以及三个静态成员变量。




本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/967065,如需转载请自行联系原作者
目录
相关文章
|
1月前
|
安全 Android开发 数据安全/隐私保护
深入探讨iOS与Android系统安全性对比分析
在移动操作系统领域,iOS和Android无疑是两大巨头。本文从技术角度出发,对这两个系统的架构、安全机制以及用户隐私保护等方面进行了详细的比较分析。通过深入探讨,我们旨在揭示两个系统在安全性方面的差异,并为用户提供一些实用的安全建议。
|
3月前
|
开发工具 Android开发 Swift
安卓与iOS开发环境对比分析
在移动应用开发的广阔舞台上,安卓和iOS这两大操作系统无疑是主角。它们各自拥有独特的特点和优势,为开发者提供了不同的开发环境和工具。本文将深入浅出地探讨安卓和iOS开发环境的主要差异,包括开发工具、编程语言、用户界面设计、性能优化以及市场覆盖等方面,旨在帮助初学者更好地理解两大平台的开发特点,并为他们选择合适的开发路径提供参考。通过比较分析,我们将揭示不同环境下的开发实践,以及如何根据项目需求和目标受众来选择最合适的开发平台。
51 2
|
2月前
|
缓存 Java Shell
Android 系统缓存扫描与清理方法分析
Android 系统缓存从原理探索到实现。
67 15
Android 系统缓存扫描与清理方法分析
|
2月前
|
存储 Linux Android开发
Android底层:通熟易懂分析binder:1.binder准备工作
本文详细介绍了Android Binder机制的准备工作,包括打开Binder驱动、内存映射(mmap)、启动Binder主线程等内容。通过分析系统调用和进程与驱动层的通信,解释了Binder如何实现进程间通信。文章还探讨了Binder主线程的启动流程及其在进程通信中的作用,最后总结了Binder准备工作的调用时机和重要性。
Android底层:通熟易懂分析binder:1.binder准备工作
|
3月前
|
安全 Android开发 数据安全/隐私保护
探索安卓与iOS的安全性差异:技术深度分析与实践建议
本文旨在深入探讨并比较Android和iOS两大移动操作系统在安全性方面的不同之处。通过详细的技术分析,揭示两者在架构设计、权限管理、应用生态及更新机制等方面的安全特性。同时,针对这些差异提出针对性的实践建议,旨在为开发者和用户提供增强移动设备安全性的参考。
145 3
|
2月前
|
开发工具 Android开发 Swift
安卓与iOS开发环境的差异性分析
【10月更文挑战第8天】 本文旨在探讨Android和iOS两大移动操作系统在开发环境上的不同,包括开发语言、工具、平台特性等方面。通过对这些差异性的分析,帮助开发者更好地理解两大平台,以便在项目开发中做出更合适的技术选择。
|
3月前
|
安全 Linux Android开发
探索安卓与iOS的安全性差异:技术深度分析
本文深入探讨了安卓(Android)和iOS两个主流操作系统平台在安全性方面的不同之处。通过比较它们在架构设计、系统更新机制、应用程序生态和隐私保护策略等方面的差异,揭示了每个平台独特的安全优势及潜在风险。此外,文章还讨论了用户在使用这些设备时可以采取的一些最佳实践,以增强个人数据的安全。
|
4月前
|
Java 开发工具 Android开发
安卓与iOS开发环境对比分析
【8月更文挑战第20天】在移动应用开发的广阔天地中,Android和iOS两大平台各自占据着重要的位置。本文将深入探讨这两种操作系统的开发环境,从编程语言到开发工具,从用户界面设计到性能优化,以及市场趋势对开发者选择的影响。我们旨在为读者提供一个全面的比较视角,帮助理解不同平台的优势与挑战,并为那些站在选择十字路口的开发者提供有价值的参考信息。
104 17
|
3月前
|
IDE 开发工具 Android开发
安卓与iOS开发环境对比分析
本文将探讨安卓和iOS这两大移动操作系统在开发环境上的差异,从工具、语言、框架到生态系统等多个角度进行比较。我们将深入了解各自的优势和劣势,并尝试为开发者提供一些实用的建议,以帮助他们根据自己的需求选择最适合的开发平台。
52 1
|
4月前
|
开发框架 Android开发 Swift
安卓与iOS应用开发对比分析
【8月更文挑战第20天】在移动应用开发的广阔天地中,安卓和iOS两大平台各占半壁江山。本文将深入探讨这两大操作系统在开发环境、编程语言、用户界面设计、性能优化及市场分布等方面的差异和特点。通过比较分析,旨在为开发者提供一个宏观的视角,帮助他们根据项目需求和目标受众选择最合适的开发平台。同时,文章还将讨论跨平台开发框架的利与弊,以及它们如何影响着移动应用的开发趋势。