Gralloc 总结-程序员宅基地

从字面就可以看出来Gralloc接口是为了显示内存分配与释放 – Graphics Allocation。
它的主要目的有三个:
Ø  为应用分配显示用内存;
Ø  可以把显示内存在不同进程间进行映射;
Ø  同步

通过加载gralloc抽象层(gralloc.xxx.so),可以打开fb设备(/dev/fb0)和gpu设备(/dev/graphic/),
fb设备用于操作framebuffer,gpu设备负责图形缓冲区的分配和释放。
对于SurfaceFlinger服务端的本地窗口FramebufferNativeWindow将分别打开fb设备和gpu设备,
FramebufferNativeWindow通过gpu设备从Framebuffer中分配图形缓冲区,可用来GPU render。
通过fb设备来分配framebuffer,可以显示经SurfaceFlinger混合后的图像。
是在FrameBufferNativeWindow的构造代码中,可以看到打开fb0设备获取Framebuffer Info,然后使用gralloc为该FrameBufferNativeWindow分配两个或者三个Framebuffer,即双缓冲或者三缓冲。
而对于应用程序端的SurfaceTextureClient本地窗口,其需要的图形缓冲区也是由SurfaceFlinger服务端来分配,应用程序进程只需要将服务端分配的图形缓冲区映射到应用程序的虚拟地址空间,图形缓冲区的映射过程也是由Gralloc模块完成。

gpu设备
Gpu打开过程就是创建并初始化一个gralloc_context_t对象,gpu负责图形buffer的分配和释放。
fb设备
Fb设备打开过程就是创建并初始化一个fb_context_t对象,关于屏幕大小、格式、刷新频率等信息都是通过Framebuffer驱动来获取,最后将Framebuffer映射到SurfaceFlinger进程地址空间,并将映射后的首地址保持到private_module_t的framebuffer->base变量中。

可以认为Gralloc module中有两个设备gpu_alloc_device和fb_device,前者用于分配GPU0使用的内存和FB内存,GPU0内存管理使用ION allocator;后者用于获取分配Framebuffer Info并操作fb。
注意,在Android系统中,在系统帧缓冲区中分配的图形缓冲区是在SurfaceFlinger服务中使用的,
而在内存中分配的图形缓冲区既可以在SurfaceFlinger服务中使用,也可以在其它的应用程序中使用。
当其它的应用程序需要使用图形缓冲区的时候,它们就会请求SurfaceFlinger服务为它们分配。
因此,对于其它的应用程序来说,它们只需要将SurfaceFlinger服务返回来的图形缓冲区映射到自己的进程地址空间来使用就可以了。

下面是分配内存最核心的函数:

  1. static int gralloc_alloc(alloc_device_t* dev,  
  2.        int w, int h, int format, int usage,  
  3.        buffer_handle_t* pHandle, int* pStride)  
  4.   
  5.    if (!pHandle || !pStride)  
  6.        return -EINVAL;  
  7.    size_t size, stride;  
  8.    int align = 4;  
  9.    int bpp = 0;  
  10.    switch (format) {  
  11.        case HAL_PIXEL_FORMAT_RGBA_8888:  
  12.        case HAL_PIXEL_FORMAT_RGBX_8888:  
  13.        case HAL_PIXEL_FORMAT_BGRA_8888:  
  14.            bpp = 4;  
  15.            break;  
  16.        case HAL_PIXEL_FORMAT_RGB_888:  
  17.            bpp = 3;  
  18.            break;  
  19.        case HAL_PIXEL_FORMAT_RGB_565:  
  20.        case HAL_PIXEL_FORMAT_RAW_SENSOR:  
  21.            bpp = 2;  
  22.            break;  
  23.        default:  
  24.            return -EINVAL;  
  25.    }  
  26.    size_t bpr = (w*bpp + (align-1)) & ~(align-1);  
  27.    size = bpr * h;  
  28.    stride = bpr / bpp;  
  29.    int err;  
  30.    if (usage & GRALLOC_USAGE_HW_FB) {  
  31.        err = gralloc_alloc_framebuffer(dev, size, usage, pHandle); //申请图形缓冲区,用来render  
  32.    } else {  
  33.        err = gralloc_alloc_buffer(dev, size, usage, pHandle);   //申请帧缓冲区,用来显示  
  34.    }  
  35.    if (err < 0) {  
  36.        return err;  
  37.    }  
  38.    *pStride = stride;  
  39.    return 0;  

 在申请gralloc的时候,下面的enum表示要申请的buffer的用途
  1. {  
  2.     /* buffer is never read in software */  
  3.     GRALLOC_USAGE_SW_READ_NEVER         = 0x00000000,  
  4.     /* buffer is rarely read in software */  
  5.     GRALLOC_USAGE_SW_READ_RARELY        = 0x00000002,  
  6.     /* buffer is often read in software */  
  7.     GRALLOC_USAGE_SW_READ_OFTEN         = 0x00000003,  
  8.     /* mask for the software read values */  
  9.     GRALLOC_USAGE_SW_READ_MASK          = 0x0000000F,  
  10.       
  11.     /* buffer is never written in software */  
  12.     GRALLOC_USAGE_SW_WRITE_NEVER        = 0x00000000,  
  13.     /* buffer is rarely written in software */  
  14.     GRALLOC_USAGE_SW_WRITE_RARELY       = 0x00000020,  
  15.     /* buffer is often written in software */  
  16.     GRALLOC_USAGE_SW_WRITE_OFTEN        = 0x00000030,  
  17.     /* mask for the software write values */  
  18.     GRALLOC_USAGE_SW_WRITE_MASK         = 0x000000F0,  
  19.     /* buffer will be used as an OpenGL ES texture */  
  20.     GRALLOC_USAGE_HW_TEXTURE            = 0x00000100,  
  21.     /* buffer will be used as an OpenGL ES render target */  
  22.     GRALLOC_USAGE_HW_RENDER             = 0x00000200,  
  23.     /* buffer will be used by the 2D hardware blitter */  
  24.     GRALLOC_USAGE_HW_2D                 = 0x00000400,  
  25.     /* buffer will be used by the HWComposer HAL module */  
  26.     GRALLOC_USAGE_HW_COMPOSER           = 0x00000800,  
  27.     /* buffer will be used with the framebuffer device */  
  28.     GRALLOC_USAGE_HW_FB                 = 0x00001000,  
  29.     /* buffer will be used with the HW video encoder */  
  30.     GRALLOC_USAGE_HW_VIDEO_ENCODER      = 0x00010000,  
  31.     /* buffer will be written by the HW camera pipeline */  
  32.     GRALLOC_USAGE_HW_CAMERA_WRITE       = 0x00020000,  
  33.     /* buffer will be read by the HW camera pipeline */  
  34.     GRALLOC_USAGE_HW_CAMERA_READ        = 0x00040000,  
  35.     /* buffer will be used as part of zero-shutter-lag queue */  
  36.     GRALLOC_USAGE_HW_CAMERA_ZSL         = 0x00060000,  
  37.     /* mask for the camera access values */  
  38.     GRALLOC_USAGE_HW_CAMERA_MASK        = 0x00060000,  
  39.     /* mask for the software usage bit-mask */  
  40.     GRALLOC_USAGE_HW_MASK               = 0x00071F00,  
  41.     /* buffer will be used as a RenderScript Allocation */  
  42.     GRALLOC_USAGE_RENDERSCRIPT          = 0x00100000,  
  43.     GRALLOC_USAGE_HW_FIMC1        = 0x01000000,  
  44.     GRALLOC_USAGE_HW_ION          = 0x02000000,  
  45.     GRALLOC_USAGE_YUV_ADDR        = 0x04000000,  
  46.     /* SEC Private usage , for Overlay path at HWC */  
  47.     GRALLOC_USAGE_HWC_HWOVERLAY     = 0x20000000,  
  48.     /* buffer should be displayed full-screen on an external display when 
  49.      * possible 
  50.      */  
  51.     GRALLOC_USAGE_EXTERNAL_DISP         = 0x00002000,  
  52.     /* Must have a hardware-protected path to external display sink for 
  53.      * this buffer.  If a hardware-protected path is not available, then 
  54.      * either don't composite only this buffer (preferred) to the 
  55.      * external sink, or (less desirable) do not route the entire 
  56.      * composition to the external sink. 
  57.      */  
  58.     GRALLOC_USAGE_PROTECTED             = 0x00004000,  
  59.     /* implementation-specific private usage flags */  
  60.     GRALLOC_USAGE_PRIVATE_0             = 0x10000000,  
  61.     GRALLOC_USAGE_PRIVATE_1             = 0x20000000,  
  62.     GRALLOC_USAGE_PRIVATE_2             = 0x40000000,  
  63.     GRALLOC_USAGE_PRIVATE_3             = 0x80000000,  
  64.     GRALLOC_USAGE_PRIVATE_MASK          = 0xF0000000,  
  65. }  

上面参数usage用来描述要分配的图形缓冲区的用途。
如果是用来在系统帧缓冲区中渲染的,GRALLOC_USAGE_HW_FB,那么就必须要系统帧缓冲区中分配,即framebuffer中。
否则的话,就在内存中分配。目前大多数采用android的ION机制分配共享的graphicbuffer。如果GPU为MALI,还可以采用MALI的UMP机制。
或者注意,在内存中分配的图形缓冲区,最终是需要渲染到系统帧缓冲区去的,以便可以将它所描述的图形显示出来。
 
申请好的图形缓冲区或者framebuffer,都是采用了bufferqueue的方式来管理的。 
网上很多大牛写的很好。我就不赘述了。
 
 
 
 最后大体讲一下显示:

 下面是framebuffer显示使用的函数

  1. static int fb_post(struct framebuffer_device_t* dev, buffer_handle_t buffer)  
  2. {  
  3.     if (hnd->flags & private_handle_t::PRIV_FLAGS_FRAMEBUFFER)  
  4.     {  
  5.         m->base.lock(&m->base, buffer, private_module_t::PRIV_USAGE_LOCKED_FOR_POST,   
  6.                 0, 0, m->info.xres, m->info.yres, NULL);  
  7.         const size_t offset = hnd->base - m->framebuffer->base;  
  8.         int interrupt;  
  9.         m->info.activate = FB_ACTIVATE_VBL;  
  10.         m->info.yoffset = offset / m->finfo.line_length;  
  11. #ifdef STANDARD_LINUX_SCREEN  
  12. #define FBIO_WAITFORVSYNC       _IOW('F', 0x20, __u32)  
  13. #define S3CFB_SET_VSYNC_INT _IOW('F', 206, unsigned int)  
  14.         if (ioctl(m->framebuffer->fd, FBIOPAN_DISPLAY, &m->info) == -1)   
  15.         {  
  16.             AERR( "FBIOPAN_DISPLAY failed for fd: %d", m->framebuffer->fd );  
  17.             m->base.unlock(&m->base, buffer);   
  18.             return 0;  
  19.         }  
  20.         {  
  21.             // enable VSYNC  
  22.             interrupt = 1;  
  23.             if(ioctl(m->framebuffer->fd, S3CFB_SET_VSYNC_INT, &interrupt) < 0)   
  24.             {  
  25.                 AERR( "S3CFB_SET_VSYNC_INT enable failed for fd: %d", m->framebuffer->fd );  
  26.                 return 0;  
  27.             }  
  28.             // wait for VSYNC  
  29. #ifdef MALI_VSYNC_EVENT_REPORT_ENABLE  
  30.             gralloc_mali_vsync_report(MALI_VSYNC_EVENT_BEGIN_WAIT);  
  31. #endif  
  32.             int crtc = 0;  
  33.             if(ioctl(m->framebuffer->fd, FBIO_WAITFORVSYNC, &crtc) < 0)  
  34.             {  
  35.                 AERR( "FBIO_WAITFORVSYNC failed for fd: %d", m->framebuffer->fd );  
  36. #ifdef MALI_VSYNC_EVENT_REPORT_ENABLE  
  37.                 gralloc_mali_vsync_report(MALI_VSYNC_EVENT_END_WAIT);  
  38. #endif  
  39.                 return 0;  
  40.             }  
  41. #ifdef MALI_VSYNC_EVENT_REPORT_ENABLE  
  42.             gralloc_mali_vsync_report(MALI_VSYNC_EVENT_END_WAIT);  
  43. #endif  
  44.             // disable VSYNC  
  45.             interrupt = 0;  
  46.             if(ioctl(m->framebuffer->fd, S3CFB_SET_VSYNC_INT, &interrupt) < 0)   
  47.             {  
  48.                 AERR( "S3CFB_SET_VSYNC_INT disable failed for fd: %d", m->framebuffer->fd );  
  49.                 return 0;  
  50.             }  
  51.         }  
  52. #else   
  53.         /*Standard Android way*/  
  54. #ifdef MALI_VSYNC_EVENT_REPORT_ENABLE  
  55.         gralloc_mali_vsync_report(MALI_VSYNC_EVENT_BEGIN_WAIT);  
  56. #endif  
  57.         if (ioctl(m->framebuffer->fd, FBIOPUT_VSCREENINFO, &m->info) == -1)   
  58.         {  
  59.             AERR( "FBIOPUT_VSCREENINFO failed for fd: %d", m->framebuffer->fd );  
  60. #ifdef MALI_VSYNC_EVENT_REPORT_ENABLE  
  61.             gralloc_mali_vsync_report(MALI_VSYNC_EVENT_END_WAIT);  
  62. #endif  
  63.             m->base.unlock(&m->base, buffer);   
  64.             return -errno;  
  65.         }  
  66. #ifdef MALI_VSYNC_EVENT_REPORT_ENABLE  
  67.         gralloc_mali_vsync_report(MALI_VSYNC_EVENT_END_WAIT);  
  68. #endif  
  69. #endif  
  70.         m->currentBuffer = buffer;  
  71.     }   
  72.     return 0;  
  73. }  
  1. 注意:  

 这个函数只有在离线合成的方式下,由openGL调用eglSwapbuffer,才会被调用到。

参考:

http://blog.csdn.NET/wan8180192/article/details/50269405

在线合成的方式下,会调用HWC->set 函数,即exynos4_set--->exynos4_post_fimd ---> window_pan_display最终显示

参考:

http://blog.csdn.Net/wan8180192/article/details/50719123


版权声明:本文为博主原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/prike/article/details/72934711

智能推荐

USB学习(3):USB描述符和USB类设备_usb 接口描述符 class-程序员宅基地

文章浏览阅读1.1k次,点赞2次,收藏14次。它描述了高速USB设备的信息,如果设备以另一速度运行,该描述符将发生更改,这在支持两种速度配置的设备中是必需的。同样,如果在设备以高速运行时请求此描述符,描述符读取将告诉主机有关全速配置的信息。在上一节的USB描述符部分,USB设备类的定义在:设备描述符的第四个字节和接口描述符的第六个字节。接口描述符描述了配置中的特定接口,此描述符中确定了接口的端点数量,声明了设备的USB类,供主机加载适合适驱动程序。设备描述符提供给主机一些信息,如设备符合的USB规范、设备支持的配置数量、支持的协议、制造商标识(_usb 接口描述符 class

java留言板源码_jsp留言板示例源码下载(入门级)-程序员宅基地

文章浏览阅读1.7k次,点赞2次,收藏4次。【实例简介】留言板,主要用于初学者利用开发其他软件采用纯jsp页面 Mysql的方法实现功能项目编码是gb2312,要转换格式的请自己装换,界面简洁,功能简单,实现容易,非常适合初学者有助于加深初学者对jsp的理解和使用Mysql数据库String DBDRIVER= "com.mysql.jdbc.Driver";String DBURL="jdbc:mysql://localhost:3306..._jsp云日记源码

揭秘被Arm编译器所隐藏的浮点运算_float-abi-程序员宅基地

文章浏览阅读1.6k次,点赞2次,收藏13次。引言笔者接触嵌入式领域软件开发以来,几乎用的都是 ARM Cortex M 内核系列的微控制器。感谢C语言编译器的存在,让我不用接触汇编即可进行开发,但是彷佛也错过了一些风景,没有领域到编译器之美和CPU之美,所以决定周末无聊的休息时间通过寻找资料、动手实验、得出结论的方法来探索 ARM CPU 架构的美妙,以及C语言编译器的奥秘。(因为我个人实在是不赞同学校中微机原理类课程的教学方法)。 ARM探索之旅 01 | 带你认识ARM Cortex-M阵营 ARM探索之旅 02 | ..._float-abi

linux系统更新字体,更换Linux下字体-程序员宅基地

文章浏览阅读1.5k次。我的Linux系统是Ubuntu 14.04,更换完字体之后,Web页面效果是这样的:Shell显示效果是这样的:我采用的字体方案是,Monaco雅黑混合字体下面是具体更换步骤:一、下载安装字体1.1 下载下载 微软雅黑 、 Monaco、Monaco雅黑混合字体 字体,解压后得到三个 .ttf 文件放到 ~/.fonts 文件夹下。1.1 刷新缓存运行fc-cache来更新字体缓存。二、更改系统..._linux font 字体包更新

linux 划分两个VDisk,HP-UNIX.关于LUN,Vdisk,VG,LV,挂载点,设备文件等查询实例描述 -- 转载...-程序员宅基地

文章浏览阅读514次。摘要:总结近期工作中所掌握的部分关于存储与主机的知识点。曾经只是通过定性的文字描述去了解什么是VG,什么是Vdisk,什么是LV…但这里将通过一则查询实例来加深对文字定义的理解!当前任务为,整理HP存储产品EVA3000磁盘阵列柜和若干HP小型机的映射关系。这里将通过EVA3000中commandview结合主机命令工具(bdf、strings、ioscan、vgdisplay、diskinfo..._linux vdisk -l命令详解

mysql的sys删了_误把mysql的数据库删了一个 怎么恢复 大家都还在做项目 我要完蛋了 大神救命啊...-程序员宅基地

文章浏览阅读3.1k次。展开全部每个 DBA 是不是都有过删库的经历?删库了没有备份怎么办?备份恢复后无法启32313133353236313431303231363533e4b893e5b19e31333433626437动服务什么情况?表定义损坏数据无法读取怎么办?我曾遇到某初创互联网企业,因维护人员不规范的备份恢复操作,导致系统表空间文件被初始化,上万张表无法读取,花了数小时才抢救回来。当你发现数据无法读取时,也许..._mysql中sys数据库被删除

随便推点

高一计算机课期中考试总结反思,2017高一数学期中考试反思总结-程序员宅基地

文章浏览阅读76次。引导语:数学新课改的基本理念是:学有价值的数学,反映出学生实践能力和创新意识方面的不足,应引起我们的高度重视,学生的动手能力还有待提高。以下是百分网小编分享给大家的2017高一数学期中考试反思总结,欢迎阅读!过去的一学期里,我班在学校领导的统一组织下,在任课教师的大力支持和配合下,各项工作顺利开展,学习、生活等方面都取得较突出的成绩。现将本学期期中考试前的工作总结如下:一、 加强对学生的思想政治工...

如何使用Stripe和Syncano建立每日确认短信服务-程序员宅基地

文章浏览阅读276次。这篇文章是由赞助Syncano 。 感谢您支持谁使SitePoint可能的赞助商。 Syncano提供了实时应用的基于云的平台。 它存储数据,微服务代码,日程安排用于自动执行代码,用户帐户,网络挂接通过HTTP多以访问这些功能。 他们甚至已经得到的代码片段的开源社区,并支持多种运行环境,包括节点,巨蟒,围棋和Ruby。 从一个开发者角度,Syncano可以更容易获得通过提供大量的,否则你就需..._如何用stripe

MQ和ActiveMQ浅析_activemq和ibmmq的区别-程序员宅基地

文章浏览阅读844次。文章目录什么是JMS MQ消息中间件应用场景**异步通信**缓冲解耦冗余扩展性可恢复性顺序保证**过载保护****数据流处理**常用消息队列(ActiveMQ、RabbitMQ、RocketMQ、Kafka)比较JMS中的一些角色**Broker**providerConsumerp2ppub/subPTP 和 PUB/SUB 简单对QueueTopicConnectionFactoryConnectionDestinationSessionJMS的消息格式JMS消息由以下三部分组成的:TextMessag_activemq和ibmmq的区别

造梦师手记:SDXL更新最勤奋的梦幻模型_dreamshaper模型和sdxl模型的区别-程序员宅基地

文章浏览阅读238次。天道酬勤,这个模型也成为C站下载量最大的SDXL模型之一(当然,距离dreamshaperXL还有不小的差距)。但是,随着拥护者的增多,越来越多的建议得到反馈,就有望成为SDXL时代的顶尖少数几个大模型之一。可以预见的未来,至少在SDXL时代,由于SDXL本身的强大数据集,模型也会出现“马太效应”,会向极少数模型聚集。当然了,如果你能习惯comfyUI,也是非常不错的,这个UI虽然对很多新手界面不太友好,但对系统资源占用较少。短短不到一个月的时间,涌现出大量的模型和LoRA,丰富了我们的创作素材。_dreamshaper模型和sdxl模型的区别

【漏洞复现】Office远程代码执行漏洞(CVE-2017-11882)-程序员宅基地

文章浏览阅读152次。昨晚看到的有复现的文章,一直到今天才去自己复现了一遍,还是例行记录一下。POC:https://github.com/Ridter/CVE-2017-11882/一、简单的生成弹计算器的doc文件。网上看到的改进过的POC,我们直接拿来用,命令如下:#python Command_CVE-2017-11882.py -c "cmd.exe /c calc.exe"..._msf cve-2017-11882 pyj脚本无法下载

android编译自己 内置的jar做法-程序员宅基地

文章浏览阅读100次。1.首先 android.mkLOCAL_PATH := $(call my-dir)# ============================================================include $(CLEAR_VARS)LOCAL_SRC_FILES := java/com/xxx/xxx/xxx.java..._local_dx_flags:= --core-library

推荐文章

热门文章

相关标签