首页 文章 精选 留言 我的

精选列表

搜索[Android],共10000篇文章
优秀的个人博客,低调大师

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

3. fb设备的打开过程 在Gralloc模块中,fb设备的ID值定义为GRALLOC_HARDWARE_FB0。GRALLOC_HARDWARE_FB0是一个宏,定义在文件hardware/libhardware/include/hardware/gralloc.h中, 如下所示: #defineGRALLOC_HARDWARE_FB0"fb0" fb设备使用结构体framebuffer_device_t 来描述。结构体framebuffer_device_t是用来描述系统帧缓冲区的信息,它定义在文件hardware/libhardware/include/hardware/gralloc.h中, 如下所示: typedefstructframebuffer_device_t{ structhw_device_tcommon; /*flagsdescribingsomeattributesoftheframebuffer*/ constuint32_tflags; /*dimensionsoftheframebufferinpixels*/ constuint32_twidth; constuint32_theight; /*frambufferstrideinpixels*/ constintstride; /*framebufferpixelformat*/ constintformat; /*resolutionoftheframebuffer'sdisplaypanelinpixelperinch*/ constfloatxdpi; constfloatydpi; /*framebuffer'sdisplaypanelrefreshrateinframespersecond*/ constfloatfps; /*minswapintervalsupportedbythisframebuffer*/ constintminSwapInterval; /*maxswapintervalsupportedbythisframebuffer*/ constintmaxSwapInterval; intreserved[8]; int(*setSwapInterval)(structframebuffer_device_t*window, intinterval); int(*setUpdateRect)(structframebuffer_device_t*window, intleft,inttop,intwidth,intheight); int(*post)(structframebuffer_device_t*dev,buffer_handle_tbuffer); int(*compositionComplete)(structframebuffer_device_t*dev); void*reserved_proc[8]; }framebuffer_device_t; 成员变量flags用来记录系统帧缓冲区的标志,目前没有使用这成员变量,它的值被设置为0。 成员变量width和height分别用来描述设备显示屏的宽度和高度,它们是以像素为单位的。 成员变量stride用来描述设备显示屏的一行有多少个像素点。 成员变量format用来描述系统帧缓冲区的像素格式,支持的像素格式主要有HAL_PIXEL_FORMAT_RGBX_8888和HAL_PIXEL_FORMAT_RGB_565两种。HAL_PIXEL_FORMAT_RGBX_8888表示一个像素使用32位来描述,R、G和B分别占8位,另外8位未使用。HAL_PIXEL_FORMAT_RGB_565表示一个像素使用16位来描述,R、G和B分别占5、6和5位。 成员变量xdpi和ydpi分别用来描述设备显示屏在宽度和高度上的密度,即每英寸有多少个像素点。 成员变量fps用来描述设备显示屏的刷新频率,它的单位是帧每秒。 成员变量minSwapInterval和maxSwapInterval用来描述帧缓冲区交换前后两个图形缓冲区的最小和最大时间间隔。 成员变量reserved是保留给将来使用的。 成员函数setSwapInterval用来设置帧缓冲区交换前后两个图形缓冲区的最小和最大时间间隔。 成员函数setUpdateRect用来设置帧缓冲区的更新区域。 成员函数post用来将图形缓冲区buffer的内容渲染到帧缓冲区中去,即显示在设备的显示屏中去。 成员函数compositionComplete用来通知fb设备device,图形缓冲区的组合工作已经完成,目前没有使用这个成员函数。 成员变量reserved是一个函数指针数组,它们是保留给将来使用的。 在结构体framebuffer_device_t的一系列成员函数中,post是最重要的一个成员函数,用户空间的应用程序通过调用这个成员函数就可以在设备的显示屏中渲染指定的画面,后面我们将详细这个函数的实现。 Gralloc模块在在文件hardware/libhardware/include/hardware/gralloc.h中定义了一个帮助函数framebuffer_open,用来打开fb设备,如下所示: staticinlineintframebuffer_open(conststructhw_module_t*module, structframebuffer_device_t**device){ returnmodule->methods->open(module, GRALLOC_HARDWARE_FB0,(structhw_device_t**)device); } 参数module指向的是一个用来描述Gralloc模块的hw_module_t结构体,前面提到,它的成员变量methods所指向的一个hw_module_methods_t结构体的成员函数open指向了Gralloc模块中的函数gralloc_device_open,这个函数打开fb设备的代码段如下所示: intgralloc_device_open(consthw_module_t*module,constchar*name, hw_device_t**device) { intstatus=-EINVAL; if(!strcmp(name,GRALLOC_HARDWARE_GPU0)){ ...... }else{ status=fb_device_open(module,name,device); } returnstatus; } 参数name的值等于GRALLOC_HARDWARE_FB0,因此,函数gralloc_device_open接下来会调用另外一个函数fb_device_open来执行打开fb设备的操作。 函数fb_device_open定义在文件hardware/libhardware/modules/gralloc/framebuffer.cpp中,如下所示: structfb_context_t{ framebuffer_device_tdevice; }; ...... intfb_device_open(hw_module_tconst*module,constchar*name, hw_device_t**device) { intstatus=-EINVAL; if(!strcmp(name,GRALLOC_HARDWARE_FB0)){ alloc_device_t*gralloc_device; status=gralloc_open(module,&gralloc_device); if(status<0) returnstatus; /*initializeourstatehere*/ fb_context_t*dev=(fb_context_t*)malloc(sizeof(*dev)); memset(dev,0,sizeof(*dev)); /*initializetheprocs*/ dev->device.common.tag=HARDWARE_DEVICE_TAG; dev->device.common.version=0; dev->device.common.module=const_cast<hw_module_t*>(module); dev->device.common.close=fb_close; dev->device.setSwapInterval=fb_setSwapInterval; dev->device.post=fb_post; dev->device.setUpdateRect=0; private_module_t*m=(private_module_t*)module; status=mapFrameBuffer(m); if(status>=0){ intstride=m->finfo.line_length/(m->info.bits_per_pixel>>3); intformat=(m->info.bits_per_pixel==32) ?HAL_PIXEL_FORMAT_RGBX_8888 :HAL_PIXEL_FORMAT_RGB_565; #ifdefNO_32BPP format=HAL_PIXEL_FORMAT_RGB_565; #endif const_cast<uint32_t&>(dev->device.flags)=0; const_cast<uint32_t&>(dev->device.width)=m->info.xres; const_cast<uint32_t&>(dev->device.height)=m->info.yres; const_cast<int&>(dev->device.stride)=stride; const_cast<int&>(dev->device.format)=format; const_cast<float&>(dev->device.xdpi)=m->xdpi; const_cast<float&>(dev->device.ydpi)=m->ydpi; const_cast<float&>(dev->device.fps)=m->fps; const_cast<int&>(dev->device.minSwapInterval)=1; const_cast<int&>(dev->device.maxSwapInterval)=1; *device=&dev->device.common; } } returnstatus; } 这个函数主要是用来创建一个fb_context_t结构体,并且对它的成员变量device进行初始化。结构体fb_context_t的成员变量device的类型为framebuffer_device_t,前面提到,它是用来描述fb设备的。fb设备主要是用来渲染图形缓冲区的,这是通过调用它的成员函数post来实现的。从这里可以看出,函数fb_device_open所打开的fb设备的成员函数post被设置为Gralloc模块中的函数fb_post,后面我们再详细分析它的实现。 本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/967075,如需转载请自行联系原作者

优秀的个人博客,低调大师

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

结构体gralloc_module_t定义在文件hardware/libhardware/include/hardware/gralloc.h中,它主要是定义了四个用来操作图形缓冲区的成员函数,如下所示: typedefstructgralloc_module_t{ ...... int(*registerBuffer)(structgralloc_module_tconst*module, buffer_handle_thandle); int(*unregisterBuffer)(structgralloc_module_tconst*module, buffer_handle_thandle); int(*lock)(structgralloc_module_tconst*module, buffer_handle_thandle,intusage, intl,intt,intw,inth, void**vaddr); int(*unlock)(structgralloc_module_tconst*module, buffer_handle_thandle); ...... } 成员函数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中,它主要是用来描述帧缓冲区的属性,如下所示: structprivate_module_t{ gralloc_module_tbase; private_handle_t*framebuffer; uint32_tflags; uint32_tnumBuffers; uint32_tbufferMask; pthread_mutex_tlock; buffer_handle_tcurrentBuffer; intpmem_master; void*pmem_master_base; structfb_var_screeninfoinfo; structfb_fix_screeninfofinfo; floatxdpi; floatydpi; floatfps; }; 成员变量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文件中,如下所示: typedefconstnative_handle*buffer_handle_t; 它是一个类型为native_handle_t的指针,而结构体native_handle_t用来描述一个本地句柄值,它定义在系统运行时层的文件system/core/include/cutils/native_handle.h文件中,如下所示: typedefstruct { intversion;/*sizeof(native_handle_t)*/ intnumFds;/*numberoffile-descriptorsat&data[0]*/ intnumInts;/*numberofintsat&data[numFds]*/ intdata[0];/*numFds+numIntsints*/ }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文件中,如下所示: #ifdef__cplusplus structprivate_handle_t:publicnative_handle{ #else structprivate_handle_t{ structnative_handlenativeHandle; #endif enum{ PRIV_FLAGS_FRAMEBUFFER=0x00000001 }; //file-descriptors intfd; //ints intmagic; intflags; intsize; intoffset; //FIXME:theattributesbelowshouldbeout-of-line intbase; intpid; #ifdef__cplusplus staticconstintsNumInts=6; staticconstintsNumFds=1; staticconstintsMagic=0x3141592; private_handle_t(intfd,intsize,intflags): fd(fd),magic(sMagic),flags(flags),size(size),offset(0), base(0),pid(getpid()) { version=sizeof(native_handle); numInts=sNumInts; numFds=sNumFds; } ~private_handle_t(){ magic=0; } staticintvalidate(constnative_handle*h){ constprivate_handle_t*hnd=(constprivate_handle_t*)h; if(!h||h->version!=sizeof(native_handle)|| h->numInts!=sNumInts||h->numFds!=sNumFds|| hnd->magic!=sMagic) { LOGE("invalidgrallochandle(at%p)",h); return-EINVAL; } return0; } #endif }; 为了方便描述,我们假设我们是在C++环境中编译文件gralloc_priv.h,即编译环境定义有宏__cplusplus。这样,结构体private_handle_t就是从结构体native_handle_t继承下来的,它包含有1个文件描述符以及6个整数,以及三个静态成员变量。 本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/967065,如需转载请自行联系原作者

优秀的个人博客,低调大师

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

函数load也是实现在文件hardware/libhardware/hardware.c文件中,如下所示: staticintload(constchar*id, constchar*path, conststructhw_module_t**pHmi) { intstatus; void*handle; structhw_module_t*hmi; /* *loadthesymbolsresolvingundefinedsymbolsbefore *dlopenreturns.SinceRTLD_GLOBALisnotor'dinwith *RTLD_NOWtheexternalsymbolswillnotbeglobal */ handle=dlopen(path,RTLD_NOW); if(handle==NULL){ charconst*err_str=dlerror(); LOGE("load:module=%s\n%s",path,err_str?err_str:"unknown"); status=-EINVAL; gotodone; } /*Gettheaddressofthestructhal_module_info.*/ constchar*sym=HAL_MODULE_INFO_SYM_AS_STR; hmi=(structhw_module_t*)dlsym(handle,sym); if(hmi==NULL){ LOGE("load:couldn'tfindsymbol%s",sym); status=-EINVAL; gotodone; } /*Checkthattheidmatches*/ if(strcmp(id,hmi->id)!=0){ LOGE("load:id=%s!=hmi->id=%s",id,hmi->id); status=-EINVAL; gotodone; } hmi->dso=handle; /*success*/ status=0; done: if(status!=0){ hmi=NULL; if(handle!=NULL){ dlclose(handle); handle=NULL; } }else{ LOGV("loadedHALid=%spath=%shmi=%phandle=%p", id,path,*pHmi,handle); } *pHmi=hmi; returnstatus; } 在Linux系统中,后缀名为"so"的文件为动态链接库文件,可能通过函数dlopen来加载到内存中。硬件抽象层模块编写规范规定每一个硬件抽象层模块都必须导出一个符号名称为HAL_MODULE_INFO_SYM_AS_STR的符号,而且这个符号必须是用来描述一个类型为hw_module_t的结构体的。 HAL_MODULE_INFO_SYM_AS_STR是一个宏,定义在文件hardware/libhardware/include/hardware/hardware.h文件中,如下所示: #defineHAL_MODULE_INFO_SYM_AS_STR"HMI" 将Gralloc模块加载到内存中来之后,就可以调用函数dlsym来获得它所导出的符号HMI。由于这个符号指向的是一个hw_module_t结构体,因此,最后函数load就可以强制地将这个符号转换为一个hw_module_t结构体指针,并且保存在输出参数pHmi中返回给调用者。调用者获得了这个hw_module_t结构体指针之后,就可以创建一个gralloc设备或者一个fb设备。 模块Gralloc实现在目录hardware/libhardware/modules/gralloc中,它导出的符号HMI定义在文件hardware/libhardware/modules/gralloc/gralloc.cpp文件中,如下所示: staticstructhw_module_methods_tgralloc_module_methods={ open:gralloc_device_open }; structprivate_module_tHAL_MODULE_INFO_SYM={ base:{ common:{ tag:HARDWARE_MODULE_TAG, version_major:1, version_minor:0, id:GRALLOC_HARDWARE_MODULE_ID, name:"GraphicsMemoryAllocatorModule", author:"TheAndroidOpenSourceProject", methods:&gralloc_module_methods }, registerBuffer:gralloc_register_buffer, unregisterBuffer:gralloc_unregister_buffer, lock:gralloc_lock, unlock:gralloc_unlock, }, framebuffer:0, flags:0, numBuffers:0, bufferMask:0, lock:PTHREAD_MUTEX_INITIALIZER, currentBuffer:0, }; HAL_MODULE_INFO_SYM也是一个宏,它的值是与宏HAL_MODULE_INFO_SYM_AS_STR对应的,它也是定义在文件hardware/libhardware/include/hardware/hardware.h文件中,如下所示:图1 private_module_t结构体定义 结构体private_module_t的第一个成员变量base指向一个gralloc_module_t结构体,而gralloc_module_t结构体的第一个成员变量common又指向了一个hw_module_t结构体,这意味着,指向一个private_module_t结构体的指针同时可以用作一个gralloc_module_t或者hw_module_t结构体提针来使用。事实上,这是使用C语言来实现的一种继承关系,等价于结构体private_module_t继承结构体gralloc_module_t,而结构体gralloc_module_t继承hw_module_t结构体。这样,我们就可以把在Gralloc模块中定义的符号HAL_MODULE_INFO_SYM看作是一个hw_module_t结构体。 hw_module_t结构体有一个重要的成员变量methods,它的类型为hw_module_methods_t,它用来描述一个HAL模块的操作方法列表。结构体hw_module_methods_t只定义有一个操作方法open,用来打开一个指定的设备。在Gralloc模块中,用来打开指定设备的函数被指定为gralloc_device_open,通过这个函数就可以打开Gralloc模块中的gralloc或者fb设备,后面我们再详细分析。 本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/967062,如需转载请自行联系原作者

资源下载

更多资源
腾讯云软件源

腾讯云软件源

为解决软件依赖安装时官方源访问速度慢的问题,腾讯云为一些软件搭建了缓存服务。您可以通过使用腾讯云软件源站来提升依赖包的安装速度。为了方便用户自由搭建服务架构,目前腾讯云软件源站支持公网访问和内网访问。

Spring

Spring

Spring框架(Spring Framework)是由Rod Johnson于2002年提出的开源Java企业级应用框架,旨在通过使用JavaBean替代传统EJB实现方式降低企业级编程开发的复杂性。该框架基于简单性、可测试性和松耦合性设计理念,提供核心容器、应用上下文、数据访问集成等模块,支持整合Hibernate、Struts等第三方框架,其适用范围不仅限于服务器端开发,绝大多数Java应用均可从中受益。

Rocky Linux

Rocky Linux

Rocky Linux(中文名:洛基)是由Gregory Kurtzer于2020年12月发起的企业级Linux发行版,作为CentOS稳定版停止维护后与RHEL(Red Hat Enterprise Linux)完全兼容的开源替代方案,由社区拥有并管理,支持x86_64、aarch64等架构。其通过重新编译RHEL源代码提供长期稳定性,采用模块化包装和SELinux安全架构,默认包含GNOME桌面环境及XFS文件系统,支持十年生命周期更新。

Sublime Text

Sublime Text

Sublime Text具有漂亮的用户界面和强大的功能,例如代码缩略图,Python的插件,代码段等。还可自定义键绑定,菜单和工具栏。Sublime Text 的主要功能包括:拼写检查,书签,完整的 Python API , Goto 功能,即时项目切换,多选择,多窗口等等。Sublime Text 是一个跨平台的编辑器,同时支持Windows、Linux、Mac OS X等操作系统。

用户登录
用户注册