转android gralloc流程分析for msm8960

原文转载自http://blog.csdn.net/g_salamander/article/details/8424334

增加了Gralloc模块的平台背景和功能概述部分。

对原文针对msm8960 android display做了修正。

增加了Surfaceflinger初始化FrameBufferNativeWindow的代码部分。

平台中内存有ashmen、PMEM等多种内存类型,为了Video、Graphics、GPU内存访问的需要,android引入Gralloc模块实现内存的管理。Gralloc把FrameBuffer的分配也纳入了其中,并且新引入ION做为Gralloc的非FrameBuffer内存的分配器。ION对于内核态内存在用户进程之间的访问和硬件平台模块之间数据流转提供了高效的解决方案。

Android 中 lcd 是一个帧缓冲设备,驱动程序通过处理器的 lcd 控制器将物理内存的一段区域设置为显存,如果向这段内存区域写入数据就会马上在 lcd 上显示出来。Android 在 HAL 中提供了gralloc 模块,封装了用户层对帧缓冲设备的所有操作接口,并通过 SurfaceFlinger 服务向应用提供显示支持。在启动过程中系统会加载 gralloc 模块,然后打开帧缓冲设备,获取设备的各种参数并完成 gralloc 模块的初始化。当应用程序需要把内容显示到 lcd 上时,需要通过 gralloc 模块申请一块图形缓冲区,然后将这块图形缓冲区映射到自己的地址空间并写入内容即可。当应用程序不再需要这块图形缓冲区时需要通过 gralloc 模块释放掉,然后解除对缓冲区的映射。


1、基础数据结构

gralloc 模块通过 struct private_module_t 来描述,该结构定义如下:

[cpp] view plaincopy
  1. "font-size:12px;">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;           /* 保护结构体private_module_t的并行访问 */  
  9.     buffer_handle_t currentBuffer;  /* 描述当前正在被渲染的图形缓冲区 */  
  10.     int pmem_master;                /* pmem设备节点的描述符 */  
  11.     void* pmem_master_base;         /* pmem的起始虚拟地址 */  
  12.   
  13.     struct fb_var_screeninfo info;  /* lcd的可变参数 */  
  14.     struct fb_fix_screeninfo finfo; /* lcd的固定参数 */  
  15.     float xdpi;                     /* x方向上每英寸的像素数量 */  
  16.     float ydpi;                     /* y方向上每英寸的像素数量 */  
  17.     float fps;                      /* lcd的刷新率 */  
  18.       
  19.     int orientation;                /* 显示方向 */  
  20.   
  21.     enum {  
  22.         PRIV_USAGE_LOCKED_FOR_POST = 0x80000000  /* flag to indicate we'll post this buffer */  
  23.     };  
  24. };  
该结构的成员记录了 gralloc 模块的各种参数,主要为模块自己使用,应用程序操作的图形缓冲区的数据结构是struct private_handle_t,定义如下:
[cpp] view plaincopy
  1. "font-size:12px;">#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.         PRIV_FLAGS_USES_PMEM      = 0x00000002,  
  11.         PRIV_FLAGS_USES_MMEM      = 0x00000004,  
  12.         PRIV_FLAGS_NEEDS_FLUSH    = 0x00000008,  
  13.     };  
  14.   
  15.     enum {  
  16.         LOCK_STATE_WRITE     =   1<<31,  
  17.         LOCK_STATE_MAPPED    =   1<<30,  
  18.         LOCK_STATE_READ_MASK =   0x3FFFFFFF  
  19.     };  
  20.   
  21.     /* 指向一个文件描述符,这个文件描述符要么指向帧缓冲区设备,要么指向一块匿名共享内存 
  22.      * 取决于private_handle_t描述的图形缓冲区是在帧缓冲区分配的,还是在内存中分配的 */  
  23.     int     fd;  
  24.     /* 指向一个魔数,它的值由静态成员变量sMagic来指定,用来标识一个private_handle_t结构体 */  
  25.     int     magic;  
  26.     /* 用来描述一个图形缓冲区的标志,它的值要么等于0,要么等于PRIV_FLAGS_FRAMEBUFFER 
  27.      * 当一个图形缓冲区的标志值等于PRIV_FLAGS_FRAMEBUFFER的时候,就表示它是在帧缓冲区中分配的 */  
  28.     int     flags;  
  29.     int     size;   /* 描述一个图形缓冲区的大小 */  
  30.     int     offset; /* 描述一个图形缓冲区的偏移地址 */  
  31.   
  32.     int     phys;   /* 图形缓冲区或帧缓冲的起始物理地址 */  
  33.     int     base;   /* 图形缓冲区或帧缓冲的起始虚拟地址 */  
  34.     int     lockState;  
  35.     int     writeOwner;  
  36.     int     pid;    /* 描述一个图形缓冲区的创建者的PID */  
  37.   
  38. #ifdef __cplusplus  
  39.     static const int sNumInts = 9;  /* 有9个整数变量 */  
  40.     static const int sNumFds = 1;   /* 有1个文件描述符 */  
  41.     static const int sMagic = 0x3141592;  
  42.   
  43.     private_handle_t(int fd, int size, int flags) :  
  44.         fd(fd), magic(sMagic), flags(flags), size(size), offset(0),  
  45.         phys(0), base(0), lockState(0), writeOwner(0), pid(getpid())  
  46.     {  
  47.         version = sizeof(native_handle);  
  48.         numInts = sNumInts;  
  49.         numFds = sNumFds;  
  50.     }  
  51.     ~private_handle_t() {  
  52.         magic = 0;  
  53.     }  
  54.   
  55.     bool usesPhysicallyContiguousMemory() {  
  56.         return (flags & PRIV_FLAGS_USES_PMEM) != 0;  
  57.     }  
  58.   
  59.     /* 用来验证一个native_handle_t指针是否指向了一个private_handle_t结构体 */  
  60.     static int validate(const native_handle* h) {  
  61.         const private_handle_t* hnd = (const private_handle_t*)h;  
  62.         if (!h || h->version != sizeof(native_handle) ||  
  63.                 h->numInts != sNumInts || h->numFds != sNumFds ||  
  64.                 hnd->magic != sMagic)   
  65.         {  
  66.             LOGE("invalid gralloc handle (at %p)", h);  
  67.             return -EINVAL;  
  68.         }  
  69.         return 0;  
  70.     }  
  71.   
  72.     static private_handle_t* dynamicCast(const native_handle* in) {  
  73.         if (validate(in) == 0) {  
  74.             return (private_handle_t*) in;  
  75.         }  
  76.         return NULL;  
  77.     }  
  78. #endif  
  79. };  

图形缓冲区的操作接口由结构 struct gralloc_module_t 定义:

[cpp] view plaincopy
  1. "font-size:12px;">typedef struct gralloc_module_t {  
  2.     struct hw_module_t common;  
  3.   
  4.     /* 注册一个图形缓冲区,这个指定的图形缓冲区使用一个buffer_handle_t句柄来描述 */  
  5.     int (*registerBuffer)(struct gralloc_module_t const* module,  
  6.             buffer_handle_t handle);  
  7.   
  8.     /* 注销一个图形缓冲区 */  
  9.     int (*unregisterBuffer)(struct gralloc_module_t const* module,  
  10.             buffer_handle_t handle);  
  11.   
  12.     /* 用来锁定一个图形缓冲区并将缓冲区映射到用户进程 
  13.      * 在锁定一块图形缓冲区的时候,可以指定要锁定的图形绘冲区的位置以及大小 
  14.      * 这是通过参数l、t、w和h来指定的,其中,参数l和t指定的是要访问的图形缓冲区的左上角位置 
  15.      * 而参数w和h指定的是要访问的图形缓冲区的宽度和长度 
  16.      * 锁定之后,就可以获得由参数参数l、t、w和h所圈定的一块缓冲区的起始地址,保存在输出参数vaddr中 
  17.      * 另一方面,在访问完成一块图形缓冲区之后,需要解除这块图形缓冲区的锁定 */  
  18.     int (*lock)(struct gralloc_module_t const* module,  
  19.             buffer_handle_t handle, int usage,  
  20.             int l, int t, int w, int h,  
  21.             void** vaddr);  
  22.   
  23.     int (*unlock)(struct gralloc_module_t const* module,  
  24.             buffer_handle_t handle);  
  25.   
  26.     int (*perform)(struct gralloc_module_t const* module,  
  27.             int operation, ... );  
  28.   
  29.     /* reserved for future use */  
  30.     void* reserved_proc[7];  
  31. } gralloc_module_t;  

gralloc 设备则用结构 struct alloc_device_t 来描述,其定义如下:

[cpp] view plaincopy
  1. "font-size:12px;">typedef struct alloc_device_t {  
  2.     struct hw_device_t common;  
  3.   
  4.     /* 申请图形缓冲区的内存空间 */      
  5.     int (*alloc)(struct alloc_device_t* dev,int w, int h, int format, int usage,buffer_handle_t* handle, int* stride);  
  6.   
  7.     /* 释放图形缓冲区的内存空间 */  
  8.     int (*free)(struct alloc_device_t* dev,buffer_handle_t handle);  
  9. } alloc_device_t;  
帧缓冲设备则采用结构 struct framebuffer_device_t 描述:
[cpp] view plaincopy
  1. "font-size:12px;">typedef struct framebuffer_device_t {  
  2.     struct hw_device_t common;  
  3.   
  4.     const uint32_t  flags;  /* 用来记录系统帧缓冲区的标志 */  
  5.   
  6.     const uint32_t  width;  /* lcd显示区域的像素点数 */  
  7.     const uint32_t  height;  
  8.   
  9.     const int       stride; /* 描述设备显示屏的一行有多少个像素点 */  
  10.   
  11.     /* 描述系统帧缓冲区的像素格式,主要有HAL_PIXEL_FORMAT_RGBX_8888和HAL_PIXEL_FORMAT_RGB_565两种 */  
  12.     const int       format;  
  13.   
  14.     const float     xdpi;  
  15.     const float     ydpi;  
  16.     const float     fps;              /* lcd刷新率 */  
  17.     const int       minSwapInterval;  /* 交换两帧图像的最小间隔时间 */  
  18.     const int       maxSwapInterval;  /* 交换两帧图像的最大间隔时间 */  
  19.   
  20.     int reserved[8];  
  21.   
  22.     /* 设置帧交换间隔 */  
  23.     int (*setSwapInterval)(struct framebuffer_device_t* window,int interval);  
  24.   
  25.     /* 设置帧缓冲区的更新区域 */  
  26.     int (*setUpdateRect)(struct framebuffer_device_t* window,int left, int top, int width, int height);  
  27.   
  28.     /* 用来将图形缓冲区buffer的内容渲染到帧缓冲区中去,即显示在设备的显示屏中去 */  
  29.     int (*post)(struct framebuffer_device_t* dev, buffer_handle_t buffer);  
  30.   
  31.     /* 用来通知fb设备device,图形缓冲区的组合工作已经完成 */  
  32.     int (*compositionComplete)(struct framebuffer_device_t* dev);  
  33.   
  34.     void* reserved_proc[8];  
  35. } framebuffer_device_t;  
其中成员函数 post对应用程序来说是最重要的接口,它将完成数据写入显存的工作。

2、gralloc 模块

HAL 中通过 hw_get_module 接口加载指定 id 的模块,并获得一个 hw_module_t 结构来打开设备,流程如下:  

[cpp]

你可能感兴趣的:(转android gralloc流程分析for msm8960)