首页 文章 精选 留言 我的

精选列表

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

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

成员变量fd指向一个文件描述符,这个文件描述符要么指向帧缓冲区设备,要么指向一块匿名共享内存,取决于它的宿主结构体private_handle_t描述的一个图形缓冲区是在帧缓冲区分配的,还是在内存中分配的。 成员变量magic指向一个魔数,它的值由静态成员变量sMagic来指定,用来标识一个private_handle_t结构体。 成员变量flags用来描述一个图形缓冲区的标志,它的值要么等于0,要么等于PRIV_FLAGS_FRAMEBUFFER。当一个图形缓冲区的标志值等于PRIV_FLAGS_FRAMEBUFFER的时候,就表示它是在帧缓冲区中分配的。 成员变量size用来描述一个图形缓冲区的大小。 成员变量offset用来描述一个图形缓冲区的偏移地址。例如,当一个图形缓冲区是在一块内存中分块的时候,假设这块内存的地址为start,那么这个图形缓冲区的起始地址就为start + offset。 成员变量base用来描述一个图形缓冲区的实际地址,它是通过成员变量offset来计算得到的。例如,上面计算得到的start + offset的值就保存在成员变量base中。 成员变量pid用来描述一个图形缓冲区的创建者的PID。例如,如果一个图形缓冲区是在ID值为1000的进程中创建的,那么用来描述这个图形缓冲区的private_handle_t结构体的成员变量pid的值就等于1000。 结构体private_handle_t的静态成员变量sMagic前面已经描述过了,另外两个静态成员变量sNumInts和sNumFds的值分别等于1和6,表示结构体private_handle_t包含有1个文件描述符和6个整数,它们是用来初始化结构体private_handle_t的父类native_handle_t的成员变量numInts和numFds的,如结构体private_handle_t的构造函数所示。从这里就可以看出,结构体private_handle_t的父类native_handle_t的成员变量data所指向的缓冲区就是由结构体private_handle_t的成员变量fds、magic、flags、size、offset、base和pid所占用的连续内存块来组成的,一共包含有7个整数。 结构体private_handle_t还定义了一个静态成员函数validate,用来验证一个native_handle_t指针是否指向了一个private_handle_t结构体。 至此,Gralloc模块的加载过程以及相关的数据结构体就介绍到这里,接下来我们分别分析定义在Gralloc模块中的gralloc和fb设备的打开过程。 2. gralloc设备的打开过程 在Gralloc模块中,gralloc设备的ID值定义为GRALLOC_HARDWARE_GPU0。GRALLOC_HARDWARE_GPU0是一个宏,定义在文件hardware/libhardware/include/hardware/gralloc.h中, 如下所示: #defineGRALLOC_HARDWARE_GPU0"gpu0" gralloc设备使用结构体alloc_device_t 来描述。结构体alloc_device_t有两个成员函数alloc和free,分别用来分配和释放图形缓冲区。 结构体alloc_device_t 也是定义在文件hardware/libhardware/include/hardware/gralloc.h中, 如下所示: typedefstructalloc_device_t{ structhw_device_tcommon; int(*alloc)(structalloc_device_t*dev, intw,inth,intformat,intusage, buffer_handle_t*handle,int*stride); int(*free)(structalloc_device_t*dev, buffer_handle_thandle); }alloc_device_t; Gralloc模块在在文件hardware/libhardware/include/hardware/gralloc.h中定义了一个帮助函数gralloc_open,用来打开gralloc设备,如下所示: staticinlineintgralloc_open(conststructhw_module_t*module, structalloc_device_t**device){ returnmodule->methods->open(module, GRALLOC_HARDWARE_GPU0,(structhw_device_t**)device); } 参数module指向的是一个用来描述Gralloc模块的hw_module_t结构体,它的成员变量methods所指向的一个hw_module_methods_t结构体的成员函数open指向了Gralloc模块中的函数gralloc_device_open。 函数gralloc_device_open定义在文件hardware/libhardware/modules/gralloc/gralloc.cpp文件中,如下所示: structgralloc_context_t{ alloc_device_tdevice; /*ourprivatedatahere*/ }; ...... intgralloc_device_open(consthw_module_t*module,constchar*name, hw_device_t**device) { intstatus=-EINVAL; if(!strcmp(name,GRALLOC_HARDWARE_GPU0)){ gralloc_context_t*dev; dev=(gralloc_context_t*)malloc(sizeof(*dev)); /*initializeourstatehere*/ 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=gralloc_close; dev->device.alloc=gralloc_alloc; dev->device.free=gralloc_free; *device=&dev->device.common; status=0; } ...... returnstatus; } 这个函数主要是用来创建一个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,后面我们再详细分析它们的实现。 至此,gralloc设备的打开过程就分析完成了,接下来我们继续分析fb设备的打开过程。 本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/967071,如需转载请自行联系原作者

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

Tegra3 vSMP架构Android运行时CPU热插拔及高低功耗CPU切换

Tegra3采用vSMP(VariableSymmetric Multiprocessing)架构,共5个cortex-a9处理器,其中4个为高性能设计,1个为低功耗设计: 在系统运行过程中,会根据CPU负载切换低功耗处理器和高功耗处理器: 除此之外,4个高性能ARM核心也会根据运行情况,动态借用Linux kernel支持的CPU hotplug进行CPU的UP/DOWN操作。 动态切换主处理器和Companion 处理器借用的是软硬件配套的CPU Governor 和 CPU Management Logic。 我们用华硕EeePad运行高负载,低负载应用,通过dmesg查看内核消息也确实验证了多核的热插拔以及主ARM和LP ARM之间的动态切换。 CPU hotplug记录: <4>[104626.426957] CPU1: Booted secondary processor <7>[104627.427412] tegra CPU: force EDP limit 720000 kHz <4>[104627.427670] CPU2: Booted secondary processor <4>[104628.537005] stop_machine_cpu_stop cpu=0 <4>[104628.537017] stop_machine_cpu_stop cpu=2 <4>[104628.537059] stop_machine_cpu_stop cpu=1 <4>[104628.537702] __stop_cpus: wait_for_completion_timeout+ <4>[104628.537810] __stop_cpus: smp=0 done.executed=1 done.ret =0- <5>[104628.537960] CPU1: clean shutdown <4>[104630.537092] stop_machine_cpu_stop cpu=0 <4>[104630.537172] stop_machine_cpu_stop cpu=2 <4>[104630.537739] __stop_cpus: wait_for_completion_timeout+ <4>[104630.538060] __stop_cpus: smp=0 done.executed=1 done.ret =0- <5>[104630.538203] CPU2: clean shutdown <4>[104631.306984] tegra_watchdog_touch 高性能处理器和低功耗处理器切换: <3>[104666.799152] LP=>G: prolog 22 us, switch 2129 us, epilog 24 us, total 2175 us <3>[104667.807273] G=>LP: prolog 18 us, switch 157 us, epilog 25 us, total 200 us <4>[104671.407008] tegra_watchdog_touch <4>[104671.408816] nct1008_get_temp: ret temp=35C <3>[104671.939060] LP=>G: prolog 17 us, switch 2127 us, epilog 22 us, total 2166 us <3>[104672.938091] G=>LP: prolog 18 us, switch 156 us, epilog 24 us, total 198 us 本文转自 21cnbao 51CTO博客,原文链接:http://blog.51cto.com/21cnbao/768381,如需转载请自行联系原作者

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

Android Studio - 第四十二期 几个经常用到的字符串的截取

string str="123abc456"; int i=3; 1 取字符串的前i个字符 str=str.Substring(0,i); // or str=str.Remove(i,str.Length-i); 2 去掉字符串的前i个字符: str=str.Remove(0,i); // or str=str.Substring(i); 3 从右边开始取i个字符: str=str.Substring(str.Length-i); // or str=str.Remove(0,str.Length-i); 4 从右边开始去掉i个字符: str=str.Substring(0,str.Length-i); // or str=str.Remove(str.Length-i,i); 5 判断字符串中是否有"abc" 有则去掉之 using System.Text.RegularExpressions; string str = "123abc456"; string a="abc"; Regex r = new Regex(a); Match m = r.Match(str); if (m.Success) { //绿色部分与紫色部分取一种即可。 str=str.Replace(a,""); Response.Write(str); string str1,str2; str1=str.Substring(0,m.Index); str2=str.Substring(m.Index+a.Length,str.Length-a.Length-m.Index); Response.Write(str1+str2); } 6 如果字符串中有"abc"则替换成"ABC" str=str.Replace("abc","ABC"); 7.字符串中怎么截取指定字符的前面的字符和后面的字符 String str = "key:value:other"; String[] strs = str.split(":"); key = strs[0]; value = strs[1]; other = strs[2]; ************************************************ string str="adcdef"; int indexStart = str.IndexOf("d"); int endIndex =str.IndexOf("e"); string toStr = str.SubString(indexStart,endIndex-indexStart); c#截取字符串最后一个字符的问题! str1.Substring(str1.LastIndexOf(",")+1) 本文转自 吴雨声 51CTO博客,原文链接:http://blog.51cto.com/liangxiao/1949055,如需转载请自行联系原作者

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

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

7. 图形缓冲区的注销过程 图形缓冲区使用完成之后,就需要从当前进程中注销。前面提到,注销图形缓冲区是由Gralloc模块中的函数gralloc_unregister_buffer来实现的,这个函数实现在文件hardware/libhardware/modules/gralloc/mapper.cpp中,如下所示: intgralloc_unregister_buffer(gralloc_module_tconst*module, buffer_handle_thandle) { if(private_handle_t::validate(handle)<0) return-EINVAL; //neverunmapbuffersthatwerecreatedinthisprocess private_handle_t*hnd=(private_handle_t*)handle; if(hnd->pid!=getpid()){ if(hnd->base){ gralloc_unmap(module,handle); } } return0; } 这个函数同样是首先调用private_handle_t类的静态成员函数validate来验证参数handle指向的一块图形缓冲区的确是由Gralloc模块分配的,接着再将将参数handle指向的一块图形缓冲区转换为一个private_handle_t结构体hnd来访问。 一块图形缓冲区只有被注册过,即被Gralloc模块中的函数gralloc_register_buffer注册过,才需要注销,而由函数gralloc_register_buffer注册的图形缓冲区都不是由当前进程分配的,因此,当前进程在注销一个图形缓冲区的时候,会检查要注销的图形缓冲区是否是由自己分配的。如果是由自己分配的话,那么它什么也不做就返回了。 假设要注销的图形缓冲区hnd不是由当前进程分配的,那么接下来就会调用另外一个函数galloc_unmap来注销图形缓冲区hnd。 函数galloc_unmap也是实现在文件hardware/libhardware/modules/gralloc/mapper.cpp中,如下所示: staticintgralloc_unmap(gralloc_module_tconst*module, buffer_handle_thandle) { private_handle_t*hnd=(private_handle_t*)handle; if(!(hnd->flags&private_handle_t::PRIV_FLAGS_FRAMEBUFFER)){ void*base=(void*)hnd->base; size_tsize=hnd->size; //LOGD("unmappingfrom%p,size=%d",base,size); if(munmap(base,size)<0){ LOGE("Couldnotunmap%s",strerror(errno)); } } hnd->base=0; return0; } 这个函数的实现与前面所分析的函数gralloc_map的实现是类似的,只不过它执行的是相反的操作,即将解除一个指定的图形缓冲区在当前进程的地址空间中的映射,从而完成对这个图形缓冲区的注销工作。 这样,图形缓冲区的注销过程就分析完成了,接下来我们再继续分析一个图形缓冲区是如何被渲染到系统帧缓冲区去的,即它的内容是如何绘制在设备显示屏中的。 8. 图形缓冲区的渲染过程 用户空间的应用程序将画面内容写入到图形缓冲区中去之后,还需要将图形缓冲区渲染到系统帧缓冲区中去,这样才可以把画面绘制到设备显示屏中去。前面提到,渲染图形缓冲区是由Gralloc模块中的函数fb_post来实现的,这个函数实现在文件hardware/libhardware/modules/gralloc/framebuffer.cpp中,如下所示: staticintfb_post(structframebuffer_device_t*dev,buffer_handle_tbuffer) { if(private_handle_t::validate(buffer)<0) return-EINVAL; fb_context_t*ctx=(fb_context_t*)dev; private_handle_tconst*hnd=reinterpret_cast<private_handle_tconst*>(buffer); private_module_t*m=reinterpret_cast<private_module_t*>( dev->common.module); if(hnd->flags&private_handle_t::PRIV_FLAGS_FRAMEBUFFER){ constsize_toffset=hnd->base-m->framebuffer->base; m->info.activate=FB_ACTIVATE_VBL; m->info.yoffset=offset/m->finfo.line_length; if(ioctl(m->framebuffer->fd,FBIOPUT_VSCREENINFO,&m->info)==-1){ LOGE("FBIOPUT_VSCREENINFOfailed"); m->base.unlock(&m->base,buffer); return-errno; } m->currentBuffer=buffer; }else{ //Ifwecan'tdothepage_flip,justcopythebuffertothefront //FIXME:usecopybitHALinsteadofmemcpy void*fb_vaddr; void*buffer_vaddr; m->base.lock(&m->base,m->framebuffer, GRALLOC_USAGE_SW_WRITE_RARELY, 0,0,m->info.xres,m->info.yres, &fb_vaddr); m->base.lock(&m->base,buffer, GRALLOC_USAGE_SW_READ_RARELY, 0,0,m->info.xres,m->info.yres, &buffer_vaddr); memcpy(fb_vaddr,buffer_vaddr,m->finfo.line_length*m->info.yres); m->base.unlock(&m->base,buffer); m->base.unlock(&m->base,m->framebuffer); } return0; } 参数buffer用来描述要渲染的图形缓冲区,它指向的必须要是一个private_handle_t结构体,这是通过调用private_handle_t类的静态成员函数validate来验证的。验证通过之后,就可以将参数buffer所描述的一个buffer_handle_t结构体转换成一个private_handle_t结构体hnd。 参数dev用来描述在Gralloc模块中的一个fb设备。从前面第3部分的内容可以知道,在打开fb设备的时候,Gralloc模块返回给调用者的实际上是一个fb_context_t结构体,因此,这里就可以将参数dev所描述的一个framebuffer_device_t结构体转换成一个fb_context_t结构体ctx。 参数dev的成员变量common指向了一个hw_device_t结构体,这个结构体的成员变量module指向了一个Gralloc模块。从前面第1部分的内容可以知道,一个Gralloc模块是使用一个private_module_t结构体来描述的,因此,我们可以将dev->common.moudle转换成一个private_module_t结构体m。 由于private_handle_t结构体hnd所描述的图形缓冲区可能是在系统帧缓冲区分配的,也有可能是内存中分配的,因此,我们分两种情况来讨论图形缓冲区渲染过程。 当private_handle_t结构体hnd所描述的图形缓冲区是在系统帧缓冲区中分配的时候,即这个图形缓冲区的标志值flags的PRIV_FLAGS_FRAMEBUFFER位等于1的时候,我们是不需要将图形缓冲区的内容拷贝到系统帧缓冲区去的,因为我们将内容写入到图形缓冲区的时候,已经相当于是将内容写入到了系统帧缓冲区中去了。虽然在这种情况下,我们不需要将图形缓冲区的内容拷贝到系统帧缓冲区去,但是我们需要告诉系统帧缓冲区设备将要渲染的图形缓冲区作为系统当前的输出图形缓冲区,这样才可以将要渲染的图形缓冲区的内容绘制到设备显示屏来。例如,假设系统帧缓冲区有2个图形缓冲区,当前是以第1个图形缓冲区作为输出图形缓冲区的,这时候如果我们需要渲染第2个图形缓冲区,那么就必须告诉系统帧绘冲区设备,将第2个图形缓冲区作为输出图形缓冲区。 设置系统帧缓冲区的当前输出图形缓冲区是通过IO控制命令FBIOPUT_VSCREENINFO来进行的。IO控制命令FBIOPUT_VSCREENINFO需要一个fb_var_screeninfo结构体作为参数。从前面第3部分的内容可以知道,private_module_t结构体m的成员变量info正好保存在我们所需要的这个fb_var_screeninfo结构体。有了个m->info这个fb_var_screeninfo结构体之后,我们只需要设置好它的成员变量yoffset的值(不用设置成员变量xoffset的值是因为所有的图形缓冲区的宽度是相等的),就可以将要渲染的图形缓冲区设置为系统帧缓冲区的当前输出图形缓冲区。fb_var_screeninfo结构体的成员变量yoffset保存的是当前输出图形缓冲区在整个系统帧缓冲区的纵向偏移量,即Y偏移量。我们只需要将要渲染的图形缓冲区的开始地址hnd->base的值减去系统帧缓冲区的基地址m->framebuffer->base的值,再除以图形缓冲区一行所占据的字节数m->finfo.line_length,就可以得到所需要的Y偏移量。 在执行IO控制命令FBIOPUT_VSCREENINFO之前,还会将作为参数的fb_var_screeninfo结构体的成员变量activate的值设置FB_ACTIVATE_VBL,表示要等到下一个垂直同步事件出现时,再将当前要渲染的图形缓冲区的内容绘制出来。这样做的目的是避免出现屏幕闪烁,即避免前后两个图形缓冲区的内容各有一部分同时出现屏幕中。 成功地执行完成IO控制命令FBIOPUT_VSCREENINFO之后,函数还会将当前被渲染的图形缓冲区保存在private_module_t结构体m的成员变量currentBuffer中,以便可以记录当前被渲染的图形缓冲区是哪一个。 当private_handle_t结构体hnd所描述的图形缓冲区是在内存中分配的时候,即这个图形缓冲区的标志值flags的PRIV_FLAGS_FRAMEBUFFER位等于0的时候,我们就需要将它的内容拷贝到系统帧缓冲区中去了。这个拷贝的工作是通过调用函数memcpy来完成的。在拷贝之前,我们需要三个参数。第一个参数是要渲染的图形缓冲区的起址地址,这个地址保存在参数buffer所指向的一个private_handle_t结构体中。第二个参数是要系统帧缓冲区的基地址,这个地址保存在private_module_t结构体m的成员变量framebuffer所指向的一个private_handle_t结构体中。第三个参数是要拷贝的内容的大小,这个大小就刚好是一个屏幕像素所占据的内存的大小。屏幕高度由m->info.yres来描述,而一行屏幕像素所占用的字节数由m->finfo.line_length来描述,将这两者相乘,就可以得到一个屏幕像素所占据的内存的大小。 在将一块内存缓冲区的内容拷贝到系统帧缓冲区中去之前,需要对这两块缓冲区进行锁定,以保证在拷贝的过程中,这两块缓冲区的内容不会被修改。这个锁定的工作是由Gralloc模块中的函数gralloc_lock来实现的。从前面第1部分的内容可以知道,Gralloc模块中的函数gralloc_lock的地址正好就保存在private_module_t结构体m的成员变量base所描述的一个gralloc_module_t结构体的成员函数lock中。 在调用函数gralloc_lock来锁定一块缓冲区之后,还可以通过最后一个输出参数来获得被锁定的缓冲区的开始地址,因此,通过调用函数gralloc_lock来锁定要渲染的图形缓冲区以及系统帧缓冲区,就可以得到前面所需要的第一个和第二个参数。 将要渲染的图形缓冲区的内容拷贝到系统帧缓冲区之后,就可以解除前面对它们的锁定了,这个解锁的工作是由Gralloc模块中的函数gralloc_unlock来实现的。从前面第1部分的内容可以知道,Gralloc模块中的函数gralloc_unlock的地址正好就保存在private_module_t结构体m的成员变量base所描述的一个gralloc_module_t结构体的成员函数unlock中。 这样,一个图形缓冲区的渲染过程就分析完成了。 本文转自 Luoshengyang 51CTO博客,原文链接:http://blog.51cto.com/shyluo/967093,如需转载请自行联系原作者

资源下载

更多资源
Mario

Mario

马里奥是站在游戏界顶峰的超人气多面角色。马里奥靠吃蘑菇成长,特征是大鼻子、头戴帽子、身穿背带裤,还留着胡子。与他的双胞胎兄弟路易基一起,长年担任任天堂的招牌角色。

Spring

Spring

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

Sublime Text

Sublime Text

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

WebStorm

WebStorm

WebStorm 是jetbrains公司旗下一款JavaScript 开发工具。目前已经被广大中国JS开发者誉为“Web前端开发神器”、“最强大的HTML5编辑器”、“最智能的JavaScript IDE”等。与IntelliJ IDEA同源,继承了IntelliJ IDEA强大的JS部分的功能。

用户登录
用户注册