nipad android 4.0.33 RC4.2...

当前位置 &
14:51:07&&&&
编辑:鲲鹏[])
系统版本升级是否及时一直以来都是我们判定一个厂商服务质量好与差的标准之一,君不见曾有用户对Android 4.0以上的版本望眼欲穿,而厂商却早早的放弃了升级计划,让自己的爱机只能停留在Android 2.3阶段。
那么我们有没有想过一个问题,那就是系统升级真的有用吗?你在升级的时候有考虑过手机的感受吗?Andorid 2.3到4.0真的能带来性能上的飞速提升吗?
对于这个问题国外网站Computerbase就专门做了一个测试,他们使用曾经的机皇Galaxy S2分别刷上了来自官方的Andorid 2.3.6、4.0.4、4.1以及来自第三方的Android 4.2.2(CM10.1)来进行跑分对比,给我们提供了一个直观的参考。
系统界面:
从系统界面上来看,三星的官方系统都尽可能的保证了自家TouchWiz UI的原汁原味,从2.3到4.1并没有带来什么实质性的改变,而基于Android 4.2.2的CM10.1则尽可能的保证了原生系统的界面。
CPU性能测试
CPU性能测试的结果令人非常诧异,对Galaxy S2来说CPU性能表现最好的居然是Andorid 2.3.6系统,几乎所有测试中Android 2.3.6都是排行第一的,在部分测试中的领先幅度还非常的大。而官方的Andorid 4.0和4.1表现则不相伯仲,第三方的CM10.1一直都处于垫底的位置,这应该是由于第三方系统对硬件优化不足所导致的(CM10.1更流畅是因为没有过多的预装应用)。
GPU性能测试
GPU性能方面相对CPU正好反了过来,CM10.1的表现最好,而官方的Android 2.3.6表现则非常差劲。原文并没有给出原因,在这里笔者猜测是因为GPU驱动版本不同所导致的,一般CM系统的驱动版本都会采用最新的,而官方Android 2.3使用的自然是较老的驱动,驱动对于GPU性能的影响还是比较大的。
浏览器性能测试
浏览器性能主要涉及内核优化等方面,从测试结果来看除了Browermark中官方2.3.6略占优势之外,其余项目中都是官方的4.1.2系统表现更好一些,而CM10.1的变现相对来说比较平衡一些。
视频播放时间
视频播放时间和电池续航能力有较大的关系,主要还是与内核的性能优化有关。表现最好的是官方的4.0.4系统,比4.1.2和2.3.6长了20分钟左右,而CM10.1的表现则比前者短了一小时左右。
值得一提的是在以上测试中CM10.1的GPU性能优化是最强的,而视频播放则对GPU依赖较大,看来GPU性能优化得力之后带来的就是续航能力的下降。
总的来说系统版本的升级对手机整体性能的提升还是有不小的帮助的,尽管Andorid 2.3.6中CPU的性能更强一些,但综合续航、性能以及流畅度方面来说还是Android 4.0以上的系统更强一些,所以如果能升级的话还是推荐大家去升级。
另外原文还提到了CM系统以及官方ROM的对比,大意是虽然CM系列的ROM能够提供给大家更高的系统版本,但由于三星并不开放源代码,所以CM系统上像FM收音机、TV Out等功能可能会无法正常工作了,刷到CM10.1还是存在一定风险的。
其实笔者倒认为更多的用户是为了满足自己的好奇心或者&尝鲜&心理才去升级系统的,实际上使用的体验不会很大,而且对于一些配置较低的机型来说还是Android 2.3.6更加流畅一些。以笔者曾经使用过的GT-I9001为例,由于它仅配备了512MB的内存,因此在运行Andorid 4.0/4.1(CM9/10)的时候还是有一些力不从心的感觉,到了CM10.1的时候有了黄油计划的帮助才好了一些,但相对来说流畅度还是不如官方的2.3.6。
阅读更多:
相关阅读:
文章观点支持
为文章报道质量打分
当前平均分:0(0 次打分)
登录驱动之家
没有帐号?
用合作网站帐户直接登录trackbacks-0
出处:http://blog.csdn.net/myarrow/article/details/71805611.&简介&&&&&& &&&&&& &网上已经有很多兄弟对Android的显示系统做了深入解剖,很是佩服。可最近小弟在研究Android4.0时发现出入比较大,也许是Android4.0的修改比较多吧!因为小弟没有看Android4.0以前的代码。 &&&&&& 面对这么复杂一个Android显示系统,如何入手呢? 根据以前的经验,不管它有多么复杂,其功能不就是以下三步曲吗?   1)显示系统的创建及初始化 &&&&&& 2)画图 &&&&&& 3)销毁 &&&&&& 哪我的分析就从显示系统的创建及初始化开始吧!由于小弟对Java没有什么研究兴趣,所有重点就分析Native部分。当然Native的入口就在android_view_Surface.cpp中,此文件主要包含以下两部分给Java层调用: &&&&&& 1)gSurfaceSessionMethods: 操作SurfaceSession的方法 &&&&&&&2)gSurfaceMethods:操作Surface的方法 2. android_view_Surface.cpp & 2.1 SurfaceSession操作方法 & [cpp] static&JNINativeMethod&gSurfaceSessionMethods[]&=&{&&&&&&&&{"init",&&&&&"()V",&&(void*)SurfaceSession_init&},&//创建SurfaceComposerClient&&&&&&&{"destroy",&&"()V",&&(void*)SurfaceSession_destroy&},&//直接销毁SurfaceComposerClient&&&&&&&{"kill",&&&&&"()V",&&(void*)SurfaceSession_kill&},//先clear,再销毁SurfaceComposerClient&&};&&&&
&2.1.1 SurfaceSession_init &&&&&&& 其功能如下: &&&&&&& 1)创建SurfaceComposerClient对象 &&&&&&& 2)调用SurfaceComposerClient::onFirstRef方法 &&&&&&& 现在已经进入到SurfaceComposerClient的地盘,根据其名字含义,它应该是一个进行Surface合成的客户端,通过它发命令给SurfaceFlinger来进行需要的操作。其初始化流程如下图所示:
2.1.2 SurfaceComposerClient.cpp中的宝贝 &&&&&&& 为了方便后面的理解,先看看SurfaceComposerClient中有些什么宝贝来完成这个任务。在其中定义了如下几个类: 2.1.2.1 ComposerService(获取SurfaceFlinger服务) &&&&&&& 一看到名字为Service,应该是用于从SurfaceFlinger中获取Service以建立连接关系&它是一个单实例,一个进程有且只有一个实例对象&,然后供后面进行相关的操作。其构造函数代码如下:&&&&&& & [cpp] class&ComposerService&:&public&Singleton&ComposerService&&&{&&&&&&//实质为BpSurfaceComposer,通过它与SurfaceFlinger进行通信,&&&&&&//BnSurfaceComposer是SurfaceFlinger基类中的一个&&&&&&sp&ISurfaceComposer&&mComposerS&&&&&&&&//实质为BpMemoryHeap,它在SurfaceFlinger中对应为管理一个4096字节的&&&&&&//一个MemoryHeapBase对象,在SurfaceFlinger::readyToRun中创建&&&&&&sp&IMemoryHeap&&mServerCblkM&&&&&&&&&&&&//为MemoryHeapBase管理的内存在用户空间的基地址,通过mmap而来,&&&&&&//具体见MemoryHeapBase::mapfd&&&&&&surface_flinger_cblk_t&volatile*&mServerC&&&&&&ComposerService();&&&&&&friend&class&Singleton&ComposerService&;&&public:&&&&&&static&sp&ISurfaceComposer&&getComposerService();&&&&&&static&surface_flinger_cblk_t&const&volatile&*&getControlBlock();&&};&&&&ComposerService::ComposerService()&&:&Singleton&ComposerService&()&{&&&&&&const&String16&name("SurfaceFlinger");&&&&&&//获取SurfaceFlinger服务,即BpSurfaceComposer对象&&&&&&while&(getService(name,&&mComposerService)&!=&NO_ERROR)&{&&&&&&&&&&usleep(250000);&&&&&&}&&&&&&//获取共享内存块&&&&&&mServerCblkMemory&=&mComposerService-&getCblk();&&&&&&//获取共享内存块基地址&&&&&&mServerCblk&=&static_cast&surface_flinger_cblk_t&volatile&*&(&&&&&&&&&&&&&&mServerCblkMemory-&getBase());&&}&& &&&&& 由此可见,ComposerService主要是获取SurfaceFlinger服务、获取在SurfaceFlinger::readyToRun中创建的共享内存块及其基地址。在Client中,谁要想与SurfaceFlinger通信,需要通过接口getComposerService来获取此BpSurfaceComposer。 &&&&&此ComposerService是在调用ComposerService::getInstance时进行有且只有一个的实例化,因为前面讲过,它是一个单实例。 & 2.1.2.2 Composer &&&&& 它也是一个单实例,管理并发送每个layer的ComposerState。其定义如下: & [cpp] struct&ComposerState&{&&&&&&sp&ISurfaceComposerClient&&&&&&&&layer_state_t&&&&&&&status_t&&&&write(Parcel&&output)&&&&&&&status_t&&&&read(const&Parcel&&input);&&};&&&&class&Composer&:&public&Singleton&Composer&&&{&&&&&&friend&class&Singleton&Composer&;&&&&&&&&mutable&Mutex&&&&&&&&&&&&&&&mL&&&&&&//SurfaceComposerClient+SurfaceID与一个ComposerState一一对应&&&&&&SortedVector&ComposerState&&mS&&&&&&&&&&&int&&&&&&&&&&&&&&&&&&&&&&&&&mO//整个屏幕的方向&&&&&&Composer()&:&Singleton&Composer&(),&&&&&&&&&&mOrientation(ISurfaceComposer::eOrientationUnchanged)&{&}&&&&&&//通过BpSurfaceComposer把mStates发送给SurfaceFlinger处理&&&&&&void&closeGlobalTransactionImpl();&&&&&&&&//根据client和id从mStates中获取对应原ComposerState,从而获取对应的layer_state_t&&&&&&layer_state_t*&getLayerStateLocked(&&&&&&&&&&&&&&const&sp&SurfaceComposerClient&&&client,&SurfaceID&id);&&&&public:&&&&&&//设置与client和id对应的layer_state_t中的位置信息,并保存在mStates中&&&&&&status_t&setPosition(const&sp&SurfaceComposerClient&&&client,&SurfaceID&id,&&&&&&&&&&&&&&float&x,&float&y);&&&&&&//设置与client和id对应的layer_state_t中的Size信息,并保存在mStates中&&&&&&status_t&setSize(const&sp&SurfaceComposerClient&&&client,&SurfaceID&id,&&&&&&&&&&&&&&uint32_t&w,&uint32_t&h);&&&&&&//设置与client和id对应的layer_state_t中的z-order信息,并保存在mStates中&&&&&&status_t&setLayer(const&sp&SurfaceComposerClient&&&client,&SurfaceID&id,&&&&&&&&&&&&&&int32_t&z);&&&&&&//设置与client和id对应的layer_state_t中的flags信息,并保存在mStates中&&&&&&status_t&setFlags(const&sp&SurfaceComposerClient&&&client,&SurfaceID&id,&&&&&&&&&&&&&&uint32_t&flags,&uint32_t&mask);&&&&&&//设置与client和id对应的layer_state_t中的透明区域信息,并保存在mStates中&&&&&&status_t&setTransparentRegionHint(&&&&&&&&&&&&&&const&sp&SurfaceComposerClient&&&client,&SurfaceID&id,&&&&&&&&&&&&&&const&Region&&transparentRegion);&&&&&&//设置与client和id对应的layer_state_t中的alpha信息,并保存在mStates中&&&&&&status_t&setAlpha(const&sp&SurfaceComposerClient&&&client,&SurfaceID&id,&&&&&&&&&&&&&&float&alpha);&&&&&&//设置与client和id对应的layer_state_t中的矩阵信息,并保存在mStates中&&&&&&status_t&setMatrix(const&sp&SurfaceComposerClient&&&client,&SurfaceID&id,&&&&&&&&&&&&&&float&dsdx,&float&dtdx,&float&dsdy,&float&dtdy);&&&&&&//设置与client和id对应的layer_state_t中的位置信息,并保存在mStates中&&&&&&status_t&setFreezeTint(&&&&&&&&&&&&&&const&sp&SurfaceComposerClient&&&client,&SurfaceID&id,&&&&&&&&&&&&&&uint32_t&tint);&&&&&&//设置整个屏幕的方向&&&&&&status_t&setOrientation(int&orientation);&&&&&&//通过BpSurfaceComposer把mStates发送给SurfaceFlinger处理&&&&&&static&void&closeGlobalTransaction()&{&&&&&&&&&&Composer::getInstance().closeGlobalTransactionImpl();&&&&&&}&&}&& &&&&& 把上面的comments看完就明白了,Composer管理每个SurfaceComposerClient中的每一个Surface的状态,并记录在ComposerState的layer_state_t中,然后调用者可以调用其closeGlobalTransaction方法把这些mStates发送给SurfaceFlinger处理(处理函数为:SurfaceFlinger::setTransactionState)。 &&&&& 谁来调用它的方法设置层的属性及发送mStates呢? -----***是由SurfaceComposerClient来调用。
&&2.1.2.3& SurfaceComposerClient &&&&&&&前面介绍的两个类一个用于获取SurfaceFlinger服务;一个 用于记录每个Layer的状态,且可按要求把这些CoposerState发送给SurfaceFlinger。这个类是不是来使用前面两个类提供的服务 呢? --***是肯定的。其定义及详细注释如下: & [cpp] #define&NUM_DISPLAY_MAX&4&&//最多支持四个显示屏&&struct&display_cblk_t&//每个显示屏的配置参数&&{&&&&&&uint16_t&&&&w;&&&&&&uint16_t&&&&h;&&&&&&uint8_t&&&&&&&&&&&uint8_t&&&&&&&&&&&uint8_t&&&&&reserved[2];&&&&&&float&&&&&&&&&&&&&float&&&&&&&&&&&&&float&&&&&&&&&&&&&float&&&&&&&&&&&&&uint32_t&&&&pad[2];&&};&&//在SurfaceFlinger::readyToRun中创建的共享控制块&&struct&surface_flinger_cblk_t&&&//&4KB&max,管理系统中所有的显示屏&&{&&&&&&uint8_t&&&&&&&&&&//每一个bit表示一个显示屏&&&&&&uint8_t&&&&&&&&&reserved[3];&&&&&&uint32_t&&&&&&&&pad[7];&&&&&&display_cblk_t&&displays[NUM_DISPLAY_MAX];&&};&&&&class&SurfaceComposerClient&:&public&RefBase&&{&&&&&&friend&class&C&&public:&&&&&&&&&&&&&&&//获取Composer实例,并保存在mComposer中&&&&&&&&&&&&&&&&&&SurfaceComposerClient();&&&&&&virtual&&&&&~SurfaceComposerClient();&&&&&&&&//通过BpSurfaceComposerClient&mClient&创建Surface,&&&&&&//同时通过ISurfaceComposerClient::surface_data_t返回SurfaceID.然后创建一个SurfaceControl&&&&&&//并把返回的BpSurface和当前的SurfaceComposerClient保存在SurfaceControl中,&&&&&&//然后返回此SurfaceControl&&&&&&sp&SurfaceControl&&createSurface(&&&&&&&&&&&&&&const&String8&&name,//&name&of&the&surface&&&&&&&&&&&&&&DisplayID&display,&&//&Display&to&create&this&surface&on&&&&&&&&&&&&&&uint32_t&w,&&&&&&&&&//&width&in&pixel&&&&&&&&&&&&&&uint32_t&h,&&&&&&&&&//&height&in&pixel&&&&&&&&&&&&&&PixelFormat&format,&//&pixel-format&desired&&&&&&&&&&&&&&uint32_t&flags&=&0&&//&usage&flags&&&&&&);&&&&&&&&&&//&Composer¶meters&&合成参数&&&&&&&//所有的合成参数必须在一个transaction中被修改,多个surface可在一个transaction中被更新,&&&&&&//所有的变化在关闭transaction时被一次性提交(通过调用closeGlobalTransaction来提交所有变化)。&&&&&&&&//什么都没有做&&&&&&static&void&openGlobalTransaction();&&&&&&&&&&&&&&&&//通过调用Composer::closeGlobalTransaction(),&&&&&&//&把Composer中记录的ComposerState(即mStates)发送给SurfaceFlinger&&&&&&static&void&closeGlobalTransaction();&&&&&&&&&&&&//什么都没做&&&&&&static&status_t&freezeDisplay(DisplayID&dpy,&uint32_t&flags&=&0);&&&&&&&&&&&&&&&&//什么都没做&&&&&&static&status_t&unfreezeDisplay(DisplayID&dpy,&uint32_t&flags&=&0);&&&&&&&&//把新的显示方向保存在Composer实例中&&&&&&static&int&setOrientation(DisplayID&dpy,&int&orientation,&uint32_t&flags);&&&&&&&&//从surface_flinger_cblk_t.connected中获取显示屏个数&&&&&&static&ssize_t&getNumberOfDisplays();&&&&&&&&//获取显示屏的信息&&&&&&static&status_t&getDisplayInfo(DisplayID&dpy,&DisplayInfo*&info);&&&&&&static&ssize_t&getDisplayWidth(DisplayID&dpy);&&&&&&static&ssize_t&getDisplayHeight(DisplayID&dpy);&&&&&&static&ssize_t&getDisplayOrientation(DisplayID&dpy);&&&&&&&&&&&&//通过注册,当Binder异常退出时,可以获得通知&&&&&&status_t&linkToComposerDeath(const&sp&IBinder::DeathRecipient&&&recipient,&&&&&&&&&&&&&&void*&cookie&=&NULL,&uint32_t&flags&=&0);&&&&&&&&//Start####:&以下函数都是把相应的修改状态记录在Composer的mStates中&&&&&&//调用Composer::setFlags来设置对应(client+id)的layer状态〈即ComposerState中的layer_state_t〉&&&&&&status_t&&&&hide(SurfaceID&id);&&&&&&status_t&&&&show(SurfaceID&id,&int32_t&layer&=&-1);&&&&&&status_t&&&&freeze(SurfaceID&id);&&&&&&status_t&&&&unfreeze(SurfaceID&id);&&&&&&status_t&&&&setFlags(SurfaceID&id,&uint32_t&flags,&uint32_t&mask);&&&&&&//调用Composer::setTransparentRegionHint&&&&&&status_t&&&&setTransparentRegionHint(SurfaceID&id,&const&Region&&transparent);&&&&&&//调用Composer::setLayer&&&&&&status_t&&&&setLayer(SurfaceID&id,&int32_t&layer);&&&&&&//调用Composer::setAlpha&&&&&&status_t&&&&setAlpha(SurfaceID&id,&float&alpha=1.0f);&&&&&&//调用Composer::setFreezeTint&&&&&&status_t&&&&setFreezeTint(SurfaceID&id,&uint32_t&tint);&&&&&&//调用Composer::setMatrix&&&&&&status_t&&&&setMatrix(SurfaceID&id,&float&dsdx,&float&dtdx,&float&dsdy,&float&dtdy);&&&&&&//调用Composer::setPosition&&&&&&status_t&&&&setPosition(SurfaceID&id,&float&x,&float&y);&&&&&&//调用Composer::setSize&&&&&&status_t&&&&setSize(SurfaceID&id,&uint32_t&w,&uint32_t&h);&&&&&&//End####:&&&&&&status_t&&&&destroySurface(SurfaceID&sid);//通过BpSurfaceComposerClient销毁Surface&&&&private:&&&&&&//通过BpSurfaceComposer从SurfaceFlinger获取BpSurfaceComposerClient,&&&&&&//并把它保存在mClient中&&&&&&virtual&void&onFirstRef();&&&&&&Composer&&getComposer();&&&&&&&&mutable&&&&&Mutex&&&&&&&&&&&&&&&&&&&&&&&mL&&&&&&&&&&&&&&&&&&status_t&&&&&&&&&&&&&&&&&&&&mS&&&&&&&&&&&&&&&&&&//实质为BpSurfaceComposerClient,与SurfaceFlinger.cpp中的Client相对应&&&&&&&&&&&&&&&&&&&&&sp&ISurfaceComposerClient&&&mC&&&&&&&&&&&&&&&&&&&//Composer实例&&&&&&&&&&&&&&&&&&&&Composer&&&&&&&&&&&&&&&&&&&&mC&&}&& &&& 其功能列表如下: &&&& 1)获取BpSurfaceComposerClient(即mClient),在onFirstRef中实现 &&&& 2)通过BpSurfaceComposerClient(即mClient)创建和销毁Surface &&&& 3)通过Composer来记录Surface和显示屏状态变化,及在Composer中通过BpSurfaceComposer把状态变化发给SurfaceFlinger处理 &&&&
至此,SurfaceComposerClient功能已经分析清楚。可是从这三个类中,我们已经看到三个 Bp(BpSurfaceComposer,BpSurfaceComposerClient和BpSurface)及三个对应的接口。下面总结一下,每 个接口的功能,在客户端由谁使用,在服务器端谁来实现。 &2.1.2.4 Surface相关接口总结 &&&&&
& &2.2 Surface操作 其相关接口如下: [cpp] static&JNINativeMethod&gSurfaceMethods[]&=&{&&&&&&{"nativeClassInit",&&&&&"()V",&&(void*)nativeClassInit&},&&&&&&{"init",&&&&&&&&&&&&&&&&"(Landroid/view/SurfaceSILjava/lang/SIIIII)V",&&(void*)Surface_init&},&&&&&&{"init",&&&&&&&&&&&&&&&&"(Landroid/os/P)V",&&(void*)Surface_initParcel&},&&&&&&{"initFromSurfaceTexture",&"(Landroid/graphics/SurfaceT)V",&(void*)Surface_initFromSurfaceTexture&},&&&&&&{"getIdentity",&&&&&&&&&"()I",&&(void*)Surface_getIdentity&},&&&&&&{"destroy",&&&&&&&&&&&&&"()V",&&(void*)Surface_destroy&},&&&&&&{"release",&&&&&&&&&&&&&"()V",&&(void*)Surface_release&},&&&&&&{"copyFrom",&&&&&&&&&&&&"(Landroid/view/S)V",&&(void*)Surface_copyFrom&},&&&&&&{"isValid",&&&&&&&&&&&&&"()Z",&&(void*)Surface_isValid&},&&&&&&{"lockCanvasNative",&&&&"(Landroid/graphics/R)Landroid/graphics/C",&&(void*)Surface_lockCanvas&},&&&&&&{"unlockCanvasAndPost",&"(Landroid/graphics/C)V",&(void*)Surface_unlockCanvasAndPost&},&&&&&&{"unlockCanvas",&&&&&&&&"(Landroid/graphics/C)V",&(void*)Surface_unlockCanvas&},&&&&&&{"openTransaction",&&&&&"()V",&&(void*)Surface_openTransaction&},&&&&&&{"closeTransaction",&&&&"()V",&&(void*)Surface_closeTransaction&},&&&&&&{"setOrientation",&&&&&&"(III)V",&(void*)Surface_setOrientation&},&&&&&&{"freezeDisplay",&&&&&&&"(I)V",&(void*)Surface_freezeDisplay&},&&&&&&{"unfreezeDisplay",&&&&&"(I)V",&(void*)Surface_unfreezeDisplay&},&&&&&&{"screenshot",&&&&&&&&&&"(II)Landroid/graphics/B",&(void*)Surface_screenshotAll&},&&&&&&{"screenshot",&&&&&&&&&&"(IIII)Landroid/graphics/B",&(void*)Surface_screenshot&},&&&&&&{"setLayer",&&&&&&&&&&&&"(I)V",&(void*)Surface_setLayer&},&&&&&&{"setPosition",&&&&&&&&&"(FF)V",(void*)Surface_setPosition&},&&&&&&{"setSize",&&&&&&&&&&&&&"(II)V",(void*)Surface_setSize&},&&&&&&{"hide",&&&&&&&&&&&&&&&&"()V",&&(void*)Surface_hide&},&&&&&&{"show",&&&&&&&&&&&&&&&&"()V",&&(void*)Surface_show&},&&&&&&{"freeze",&&&&&&&&&&&&&&"()V",&&(void*)Surface_freeze&},&&&&&&{"unfreeze",&&&&&&&&&&&&"()V",&&(void*)Surface_unfreeze&},&&&&&&{"setFlags",&&&&&&&&&&&&"(II)V",(void*)Surface_setFlags&},&&&&&&{"setTransparentRegionHint","(Landroid/graphics/R)V",&(void*)Surface_setTransparentRegion&},&&&&&&{"setAlpha",&&&&&&&&&&&&"(F)V",&(void*)Surface_setAlpha&},&&&&&&{"setMatrix",&&&&&&&&&&&"(FFFF)V",&&(void*)Surface_setMatrix&},&&&&&&{"setFreezeTint",&&&&&&&"(I)V",&&(void*)Surface_setFreezeTint&},&&&&&&{"readFromParcel",&&&&&&"(Landroid/os/P)V",&(void*)Surface_readFromParcel&},&&&&&&{"writeToParcel",&&&&&&&"(Landroid/os/PI)V",&(void*)Surface_writeToParcel&},&&};&&
2.2.1 Surface_init调用流程 &&&& 在SurfaceFlinger端创建BSurface,在客户端返回SurfaceControl,同时在SurfaceControl中拥有了BpSurface用于与BSurface交互。
& 2.2.1.1 调用流程分析 &&&& BpSurfaceComposerClient-&createSurface返回BpSurface。且通过参数返回ISurfaceComposerClient::surface_data_t,其定义如下: &&&& 其中token在SurfaceComposerClient的函数参数中,对应于SurfaceID。即在客户端,它就是SurfaceID。 &&&& token: 加入到Client::mLayers中的序号,在Client中单调递增,初始值为:1,一个Layer创建一个BSurface &&&& identity: LayerBaseClient中的mIdentity,在所有的Layer中单调递增,初始值为:1 [cpp] struct&surface_data_t&{&&&&&&int32_t&&&&&&&&&&&&&&&//加入到Client::mLayers中的序号,在Client中单调递增,初始值为:1&&&&&&int32_t&&&&&&&&&&&&&&//LayerBaseClient中的mIdentity,在所有的Layer中单调递增,初始值为:1&&&&&&status_t&readFromParcel(const&Parcel&&parcel);&&&&&&status_t&writeToParcel(Parcel*&parcel)&&&};&& 2.2.1.2 创建真正的Surface &&&&& 在Layer::createSurface中创建真正的BSurface,在SurfaceFlinger::createSurface中调用layer-&getSurface时创建的。此BSurface定义如下: [cpp] sp&ISurface&&Layer::createSurface()&&{&&&&&&class&BSurface&:&public&BnSurface,&public&LayerCleaner&{&&&&&&&&&&wp&const&Layer&&mO&&&&&&&&&&virtual&sp&ISurfaceTexture&&getSurfaceTexture()&const&{&//实现了ISurface的接口&&&&&&&&&&&&&&sp&ISurfaceTexture&&&&&&&&&&&&&&&&sp&const&Layer&&that(&mOwner.promote()&);&&&&&&&&&&&&&&if&(that&!=&NULL)&{&&&&&&&&&&&&&&&&&&res&=&that-&mSurfaceT&&&&&&&&&&&&&&}&&&&&&&&&&&&&&return&&&&&&&&&&&}&&&&&&public:&&&&&&&&&&BSurface(const&sp&SurfaceFlinger&&&flinger,&&&&&&&&&&&&&&&&&&const&sp&Layer&&&layer)&&&&&&&&&&&&&&:&LayerCleaner(flinger,&layer),&mOwner(layer)&{&}&&&&&&};&&&&&&sp&ISurface&&sur(new&BSurface(mFlinger,&this));&&&&&&return&&&}&& &&&&&&&&
在此BSurface中实现了ISurface的接口getSurfaceTexture,在此接口中返回 Layer::mSurfaceTexture(类型为:SurfaceTextureLayer,它才是真正操作内存的东东),此成员在 Layer::onFirstRef中创建,SurfaceTextureLayer是SurfaceTexture的派生类,代码如下: [cpp] void&Layer::onFirstRef()&&{&&&&&&LayerBaseClient::onFirstRef();&&&&&&&&struct&FrameQueuedListener&:&public&SurfaceTexture::FrameAvailableListener&{&&&&&&&&&&FrameQueuedListener(Layer*&layer)&:&mLayer(layer)&{&}&&&&&&private:&&&&&&&&&&wp&Layer&&mL&&&&&&&&&&virtual&void&onFrameAvailable()&{&&&&&&&&&&&&&&sp&Layer&&that(mLayer.promote());&&&&&&&&&&&&&&if&(that&!=&0)&{&&&&&&&&&&&&&&&&&&that-&onFrameQueued();&&&&&&&&&&&&&&}&&&&&&&&&&}&&&&&&};&&&&&&mSurfaceTexture&=&new&SurfaceTextureLayer(mTextureName,&this);&//创建Layer中的mSurfaceTexture&&&&&&mSurfaceTexture-&setFrameAvailableListener(new&FrameQueuedListener(this));&&&&&&mSurfaceTexture-&setSynchronousMode(true);&&&&&&mSurfaceTexture-&setBufferCountServer(2);&&}&&
2.2.1.3 不得不说的SurfaceControl &&&&&& 本来Surface_init调用SurfaceComposerClient::createSurface创建一个Surface,可却返回了一个SurfaceControl,下面看看SurfaceCotrol到底做了些什么,以及如何做的? &&&&&&& 相关数据结构如下图所示: & &SurfaceControl定义如下: & [cpp] class&SurfaceControl&:&public&RefBase&&{&&public:&&&&&&//&release&surface&data&from&java&&&&&&void&&&&&&&&clear();&&&&&&&&&&&&//调用SurfaceComposerClient中对应方法,把对应信息保存在&&&&&&//Composer的ComposerState中&&&&&&&&&&status_t&&&&setLayer(int32_t&layer);&&&&&&status_t&&&&setPosition(int32_t&x,&int32_t&y);&&&&&&status_t&&&&setSize(uint32_t&w,&uint32_t&h);&&&&&&status_t&&&&hide();&&&&&&status_t&&&&show(int32_t&layer&=&-1);&&&&&&status_t&&&&freeze();&&&&&&status_t&&&&unfreeze();&&&&&&status_t&&&&setFlags(uint32_t&flags,&uint32_t&mask);&&&&&&status_t&&&&setTransparentRegionHint(const&Region&&transparent);&&&&&&status_t&&&&setAlpha(float&alpha=1.0f);&&&&&&status_t&&&&setMatrix(float&dsdx,&float&dtdx,&float&dsdy,&float&dtdy);&&&&&&status_t&&&&setFreezeTint(uint32_t&tint);&&&&&&&&&&&&//把SurfaceControl中的mSurface和mIdentity写入parcel&&&&&&static&status_t&writeSurfaceToParcel(&&&&&&&&&&&&&&const&sp&SurfaceControl&&&control,&Parcel*&parcel);&&&&&&&&&&&&//以SurfaceControl为参数创建一个Surface返回,此Surface派生关系如下:&&&&&&//class&Surface&:&public&SurfaceTextureClient&&&&&&//class&SurfaceTextureClient:&public&ANativeWindow,&RefBase&&&&&&//struct&ANativeWindow&&&&&&sp&Surface&&getSurface()&&&&&private:&&&&&&SurfaceControl(&&&&&&&&&&&&&&const&sp&SurfaceComposerClient&&&client,&&&&&&&&&&&&&&const&sp&ISurface&&&surface,&&&&&&&&&&&&&&const&ISurfaceComposerClient::surface_data_t&&data);&&&&&&&&~SurfaceControl();&&&&&&&&void&destroy();&&&&&&&&&&&&sp&SurfaceComposerClient&&&&mC&&&&&&sp&ISurface&&&&&&&&&&&&&&&&&mS&&&&&&SurfaceID&&&&&&&&&&&&&&&&&&&mT&&//对应SurfaceID,在Client中单调递增&&&&&&uint32_t&&&&&&&&&&&&&&&&&&&&mI&&//Layer在系统中唯一的序列号,在系统中单调递增&&&&&&mutable&Mutex&&&&&&&&&&&&&&&mL&&&&&&&&&&&&mutable&sp&Surface&&&&&&&&&&mSurfaceD&&}&&
从其定义中可以看出,在getSurface中将有新花样,其它操作函数都是直接以mToken作为SurfaceID,直接调用 SurfaceComposerClient中对应方法。&经过这样一分析,SurfaceControl也没什么神秘的了。但它的getSurface 到有点神秘。 & &2.2.2 getSurface流程 &&&&&&getSurface在客户端返回Surface(派生于SurfaceTextureClient),并在Surface的mSurfaceTexture域中保存了BpSurfaceTexture。 &&&&& 前面Surface初始化之后,就可以getSurface了。getSurface流程如下图所示:
&&&&&&&&&& 有了Surface,且在Surface中又有了BpSurfaceTexture,下一步就操作GraphicBuffer了。 & &3. 画图流程 对于画图流程,可以从ViewRootImpl(ViewRootImpl.java)的draw函数看起,在画图之间,它要调用java层的surface.lockCanvas,画完图之后调用surface.unlockCanvasAndPost来提交显示。 surface.lockCanvas-& lockCanvasNative(Java)-& (C++)Surface_lockCanvas&android_view_Surface.cpp& surface.unlockCanvasAndPost(Java)-& (C++)Surface_unlockCanvasAndPost&android_view_Surface.cpp& 本章主要分析这两个函数到底做了些什么& &3.1 Surface_lockCanvas &&&&&&
Android图形系统中一个重要的概念是surface。View及其子类(如TextView,
Button)要画在surface上。每个surface创建一个Canvas对象(但属性时常改变),用来管理view在surface上的绘图操 作,如画点画线。每个canvas对象对应一个bitmap,存储画在surface上的内容。 3.1.1 相关数据结构定义 &3.1.1.1 ANativeWindow_Buffer [cpp] typedef&struct&ANativeWindow_Buffer&{&&&&&&//&The&number&of&pixels&that&are&show&horizontally.&&&&&&int32_t&&&&&&&&&//&The&number&of&pixels&that&are&shown&vertically.&&&&&&int32_t&&&&&&&&&//&The&number&of&*pixels*&that&a&line&in&the&buffer&takes&in&&&&&&//&memory.&&This&may&be&&=&width.&&&&&&int32_t&&&&&&&&&//&The&format&of&the&buffer.&&One&of&WINDOW_FORMAT_*&&&&&&int32_t&&&&&&&&&//&The&actual&bits.&&&&&&void*&&&//显示内存基地址,通过服务器端fd通过flat_binder_object传给客户端,&然后客户端通过mmap获取。&&&&&&&&&&&&//&Do¬&touch.&&&&&&uint32_t&reserved[6];&&}&ANativeWindow_B&& 3.1.1.2 SurfaceInfo
[cpp] struct&SurfaceInfo&{&&&&&&uint32_t&&&&w;&&&&&&uint32_t&&&&h;&&&&&&uint32_t&&&&s;&&&&&&uint32_t&&&&&&&&&&PixelFormat&&&&&&&void*&&&&&&&//显示内存基地址,通过服务器端fd通过flat_binder_object传给客户端,&然后客户端通过mmap获取。&&&&&&uint32_t&&&&reserved[2];&&};&&
3.1.1.3 二者对应关系 [cpp] SurfaceInfo*&&&ANativeWindow_Buffer&outB&&other-&w&=&uint32_t(outBuffer.width);&&other-&h&=&uint32_t(outBuffer.height);&&other-&s&=&uint32_t(outBuffer.stride);&&other-&usage&=&GRALLOC_USAGE_SW_READ_OFTEN&|&GRALLOC_USAGE_SW_WRITE_OFTEN;&&other-&format&=&uint32_t(outBuffer.format);&&other-&bits&=&outBuffer.&&
&3.1.1.4 GraphicBuffer &&&& 在分析下面的流程时, 不得不对GraphicBuffer进行深入了解,特别是其Flattenable interface,这是实现画图buffer的关键。其相关定义如下: [cpp] typedef&struct&native_handle&&{&&&&&&int&&&&&&&&&/*&sizeof(native_handle_t)&*/&&&&&&int&numF&&&&&&&&&/*&number&of&file-descriptors&at&&data[0]&*/&&&&&&int&numI&&&&&&&&/*&number&of&ints&at&&data[numFds]&*/&&&&&&int&data[0];&&&&&&&&/*&numFds&+&numInts&ints&*/&&}&native_handle_t;&&&&typedef&const&native_handle_t*&buffer_handle_t;&&&&class&GraphicBuffer&&&&&&:&public&EGLNativeBase&&&&&&&&&&&ANativeWindowBuffer,&&&&&&&&&&GraphicBuffer,&&&&&&&&&&&LightRefBase&GraphicBuffer&&&,&public&Flattenable&&{&&&&&&...&&&&&&//&Flattenable&interface&&&&&&size_t&getFlattenedSize()&&&&&&&size_t&getFdCount()&&&&&&&status_t&flatten(void*&buffer,&size_t&size,&&&&&&&&&&&&&&int&fds[],&size_t&count)&&&&&&&status_t&unflatten(void&const*&buffer,&size_t&size,&&&&&&&&&&&&&&int&fds[],&size_t&count);&&&&&&...&&&&&&buffer_handle_t&&//定义于基类ANativeWindowBuffer中&&};&& 3.1.1.5 Flattenable interface 下面看看每个Flattenable interface是如何实现的: 3.1.1.5.1 getFlattenedSize [cpp] size_t&GraphicBuffer::getFlattenedSize()&const&{&&&&&&return&(8&+&(handle&?&handle-&numInts&:&0))*sizeof(int);&&}&& 3.1.1.5.2 getFdCount [cpp] size_t&GraphicBuffer::getFdCount()&const&{&&&&&&return&handle&?&handle-&numFds&:&0;&&}&& 3.1.1.5.3 flatten [cpp] status_t&GraphicBuffer::flatten(void*&buffer,&size_t&size,&&&&&&&&&&int&fds[],&size_t&count)&const&&{&&&&&&size_t&sizeNeeded&=&GraphicBuffer::getFlattenedSize();&&&&&&if&(size&&&sizeNeeded)&return&NO_MEMORY;&&&&&&&&size_t&fdCountNeeded&=&GraphicBuffer::getFdCount();&&&&&&if&(count&&&fdCountNeeded)&return&NO_MEMORY;&&&&&&&&int*&buf&=&static_cast&int*&(buffer);&&&&&&buf[0]&=&'GBFR';&&&&&&buf[1]&=&&&&&&&buf[2]&=&&&&&&&buf[3]&=&&&&&&&buf[4]&=&&&&&&&buf[5]&=&&&&&&&buf[6]&=&0;&&&&&&buf[7]&=&0;&&&&&&&&if&(handle)&{&&&&&&&&&&buf[6]&=&handle-&numF&&&&&&&&&&buf[7]&=&handle-&numI&&&&&&&&&&native_handle_t&const*&const&h&=&&&&&&&&&&&memcpy(fds,&&&&&h-&data,&&&&&&&&&&&&&h-&numFds*sizeof(int));&&&&&&&&&&memcpy(&buf[8],&h-&data&+&h-&numFds,&h-&numInts*sizeof(int));&&&&&&}&&&&&&&&return&NO_ERROR;&&}&&
&&&& 把handle中的numFds拷贝到fds中,把handle中的numInts拷贝到buffer中。 &3.1.1.5.4 unflatten& [cpp] status_t&GraphicBuffer::unflatten(void&const*&buffer,&size_t&size,&&&&&&&&&&int&fds[],&size_t&count)&&{&&&&&&if&(size&&&8*sizeof(int))&return&NO_MEMORY;&&&&&&&&int&const*&buf&=&static_cast&int&const*&(buffer);&&&&&&if&(buf[0]&!=&'GBFR')&return&BAD_TYPE;&&&&&&&&const&size_t&numFds&&=&buf[6];&&&&&&const&size_t&numInts&=&buf[7];&&&&&&&&const&size_t&sizeNeeded&=&(8&+&numInts)&*&sizeof(int);&&&&&&if&(size&&&sizeNeeded)&return&NO_MEMORY;&&&&&&&&size_t&fdCountNeeded&=&0;&&&&&&if&(count&&&fdCountNeeded)&return&NO_MEMORY;&&&&&&&&if&(handle)&{&&&&&&&&&&//&free&previous&handle&if&any&&&&&&&&&&free_handle();&&&&&&}&&&&&&&&if&(numFds&||&numInts)&{&&&&&&&&&&width&&=&buf[1];&&&&&&&&&&height&=&buf[2];&&&&&&&&&&stride&=&buf[3];&&&&&&&&&&format&=&buf[4];&&&&&&&&&&usage&&=&buf[5];&&&&&&&&&&native_handle*&h&=&native_handle_create(numFds,&numInts);&&&&&&&&&&memcpy(h-&data,&&&&&&&&&&fds,&&&&&numFds*sizeof(int));&&&&&&&&&&memcpy(h-&data&+&numFds,&&buf[8],&numInts*sizeof(int));&&&&&&&&&&handle&=&h;&&&&&&}&else&{&&&&&&&&&&width&=&height&=&stride&=&format&=&usage&=&0;&&&&&&&&&&handle&=&NULL;&&&&&&}&&&&&&&&mOwner&=&ownH&&&&&&&&if&(handle&!=&0)&{&&&&&&&&&&mBufferMapper.registerBuffer(handle);&&&&&&}&&&&&&&&return&NO_ERROR;&&}&& &&&&&&
把width,height,stride,format和usage保存到成员变量中,并创建一个native_handle,然后把numFds和 numInts拷贝到handle的data中。同时把此handle注册到mBufferMapper中,mBufferMapper的注册函数实现代码如下: [cpp] status_t&GraphicBufferMapper::registerBuffer(buffer_handle_t&handle)&&{&&&&&&status_t&&&&&&&//gralloc_module_t&const&*mAllocM是一个硬件抽象层实现。通过hw_get_module(GRALLOC_HARDWARE_MODULE_ID,&&module)方式获取&&&&&&err&=&mAllocMod-®isterBuffer(mAllocMod,&handle);&&&&&&&&LOGW_IF(err,&"registerBuffer(%p)&failed&%d&(%s)",&&&&&&&&&&&&&&handle,&err,&strerror(-err));&&&&&&return&&&}&& & [cpp] GraphicBufferMapper::GraphicBufferMapper()&&&&&&:&mAllocMod(0)&&{&&&&&&hw_module_t&const*&&&&&&&int&err&=&hw_get_module(GRALLOC_HARDWARE_MODULE_ID,&&module);&&&&&&LOGE_IF(err,&"FATAL:&can't&find&the&%s&module",&GRALLOC_HARDWARE_MODULE_ID);&&&&&&if&(err&==&0)&{&&&&&&&&&&mAllocMod&=&(gralloc_module_t&const&*)&&&&&&}&&}&& &3.1.1.5.4& GRALLOC_HARDWARE_MODULE_ID实例 &&&&&
对于GRALLOC_HARDWARE_MODULE_ID,以hardware/msm7k/libgralloc/gralloc.cpp为例进行分 析。其registerBuffer实现函数:gralloc_register_buffer(hardware/msm7k/libgralloc /mapper.cpp),其相关代码如下: [cpp] int&gralloc_register_buffer(gralloc_module_t&const*&module,&&&&&&&&&&buffer_handle_t&handle)&&{&&&&&&if&(private_handle_t::validate(handle)&&&0)&&&&&&&&&&return&-EINVAL;&&&&&&&&//&if&this&handle&was&created&in&this&process,&then&we&keep&it&as&is.&&&&&&int&err&=&0;&&&&&&private_handle_t*&hnd&=&(private_handle_t*)&&&&&&if&(hnd-&pid&!=&getpid())&{&&&&&&&&&&hnd-&base&=&NULL;&&&&&&&&&&if&(!(hnd-&flags&&&private_handle_t::PRIV_FLAGS_USES_GPU))&{&&&&&&&&&&&&&&void&*&&&&&&&&&&&&&&err&=&gralloc_map(module,&handle,&&vaddr);&&&&&&&&&&}&&&&&&}&&&&&&return&&&}&&&&static&int&gralloc_map(gralloc_module_t&const*&module,&&&&&&&&&&buffer_handle_t&handle,&&&&&&&&&&void**&vaddr)&&{&&&&&&private_handle_t*&hnd&=&(private_handle_t*)&&&&&&if&(!(hnd-&flags&&&private_handle_t::PRIV_FLAGS_FRAMEBUFFER))&{&&&&&&&&&&size_t&size&=&hnd-&&&#if&PMEM_HACK&&&&&&&&&&size&+=&hnd-&&&#endif&&&&&&&&&&void*&mappedAddress&=&mmap(0,&size,&&&&&&&&&&&&&&&&&&PROT_READ|PROT_WRITE,&MAP_SHARED,&hnd-&fd,&0);&&&&&&&&&&if&(mappedAddress&==&MAP_FAILED)&{&&&&&&&&&&&&&&LOGE("Could¬&mmap&handle&%p,&fd=%d&(%s)",&&&&&&&&&&&&&&&&&&&&&&handle,&hnd-&fd,&strerror(errno));&&&&&&&&&&&&&&hnd-&base&=&0;&&&&&&&&&&&&&&return&-&&&&&&&&&&}&&&&&&&&&&hnd-&base&=&intptr_t(mappedAddress)&+&hnd-&&&&&&&&&&&//LOGD("gralloc_map()&succeeded&fd=%d,&off=%d,&size=%d,&vaddr=%p",&&&&&&&&&&&//&&&&&&&&hnd-&fd,&hnd-&offset,&hnd-&size,&mappedAddress);&&&&&&}&&&&&&*vaddr&=&(void*)hnd-&&&&&&&return&0;&&}&& &&& 从gralloc_map可以看出,这个registerBuffer主要做了一件事: &&& 1)根据handle中传过来的fd和size进行mmap映射(把kernel中的内存映射到用户空间),映射之后的地址再加上hnd-&offset便获得hnd-&base供后面使用。 &&&&& 从这里可以初步看出,这个图形buffer数据并不是真正的从client传递到server,而是在lock是从server把fd传递给client,由客户端进行mmap,然后进行使用。关于这个是怎么实现的,后面将详细分析其实现过程。 &&& 对于如何从native_handle转换为private_handle_t,且在private_handle_t中可以获取fd和offset? 看一下其数据结构和flatten的实现方式就可以得知: native_handle: [cpp] typedef&struct&native_handle&&{&&&&&&int&&&&&&&&&/*&sizeof(native_handle_t)&*/&&&&&&int&numF&&&&&&&&&/*&number&of&file-descriptors&at&&data[0]&*/&&&&&&int&numI&&&&&&&&/*&number&of&ints&at&&data[numFds]&*/&&&&&&int&data[0];&&&&&&&&/*&numFds&+&numInts&ints&*/&&}&native_handle_t;&& &&&& 这个data[0]是关键,虽然分配了哪么多buffer,但实质上native_handle只占了3个int.其它的数据由包含它的数据结构来解析。
private_handle_t: [cpp] struct&private_handle_t&{&&&&&&native_handle_t&nativeH&&#endif&&&&&&&&&&&&enum&{&&&&&&&&&&PRIV_FLAGS_FRAMEBUFFER&=&0x,&&&&&&&&&&PRIV_FLAGS_USES_PMEM&&&=&0x,&&&&&&&&&&PRIV_FLAGS_USES_GPU&&&&=&0x,&&&&&&};&&&&&&&&//&file-descriptors&&&&&&int&&&&&&&&&&&//&ints&&&&&&int&&&&&&&&&&&int&&&&&&&&&&&int&&&&&&&&&&&int&&&&&&&&&&&int&&&&&gpu_&//&stored&as&an&int,&b/c&we&don't&want&it&marshalled&&&&&&&&//&FIXME:&the&attributes&below&should&be&out-of-line&&&&&&int&&&&&&&&&&&int&&&&&map_&&&&&&int&&&&&&&&&#ifdef&__cplusplus&&&&&&static&const&int&sNumInts&=&8;&&//numInts在这儿明确指定&&&&&&static&const&int&sNumFds&=&1;&&&//numFds在这儿明确指定&&&&&&static&const&int&sMagic&=&'gmsm';&&&&&&&&private_handle_t(int&fd,&int&size,&int&flags)&:&&&&&&&&&&fd(fd),&magic(sMagic),&flags(flags),&size(size),&offset(0),&&&&&&&&&&base(0),&pid(getpid())&&&&&&{&&&&&&&&&&version&=&sizeof(native_handle);&&&&&&&&&&numInts&=&sNumI&&&&&&&&&&numFds&=&sNumF&&&&&&}&&&&&&~private_handle_t()&{&&&&&&&&&&magic&=&0;&&&&&&}&&&&&&&&static&int&validate(const&native_handle*&h)&{&&&&&&&&&&const&private_handle_t*&hnd&=&(const&private_handle_t*)h;&&&&&&&&&&if&(!h&||&h-&version&!=&sizeof(native_handle)&||&&&&&&&&&&&&&&&&&&h-&numInts&!=&sNumInts&||&h-&numFds&!=&sNumFds&||&&&&&&&&&&&&&&&&&&hnd-&magic&!=&sMagic)&&&&&&&&&&&{&&&&&&&&&&&&&&LOGE("invalid&gralloc&handle&(at&%p)",&h);&&&&&&&&&&&&&&return&-EINVAL;&&&&&&&&&&}&&&&&&&&&&return&0;&&&&&&}&&#endif&&}&& 3.1.2 Surface_lockCanvas执行流程
3.1.3 Surface_lockCanvas总结& 功能:Surface_lockCanvas获取显示buffer在本进程用户空间的地址,并据此创建一个SkBitmap给Java使用。 关键技术:BINDER_TYPE_FD类型的Binder、mmap、gralloc硬件抽象层 & 3.1.4 SurfaceTexture::dequeueBuffer如何创建GraphicBuffer &&&&&& 相关代码如下: [cpp] const&sp&GraphicBuffer&&&buffer(mSlots[buf].mGraphicBuffer);&&if&((buffer&==&NULL)&||&&&&&&(uint32_t(buffer-&width)&&!=&w)&||&&&&&&(uint32_t(buffer-&height)&!=&h)&||&&&&&&(uint32_t(buffer-&format)&!=&format)&||&&&&&&((uint32_t(buffer-&usage)&&&usage)&!=&usage))&&{&&&&&&usage&|=&GraphicBuffer::USAGE_HW_TEXTURE;&&&&&&status_t&&&&&&&sp&GraphicBuffer&&graphicBuffer(&//创建GraphicBuffer&&&&&&&&&&&&&&mGraphicBufferAlloc-&createGraphicBuffer(&&&&&&&&&&&&&&&&&&&&&&w,&h,&format,&usage,&&error));&&&&&&if&(graphicBuffer&==&0)&{&&&&&&&&&&ST_LOGE("dequeueBuffer:&SurfaceComposer::createGraphicBuffer&"&&&&&&&&&&&&&&&&&&"failed");&&&&&&&&&&return&&&&&&&}&&&&&&if&(updateFormat)&{&&&&&&&&&&mPixelFormat&=&&&&&&&}&&&&&&mSlots[buf].mGraphicBuffer&=&graphicB&&&&&&mSlots[buf].mRequestBufferCalled&=&&&&&&&if&(mSlots[buf].mEglImage&!=&EGL_NO_IMAGE_KHR)&{&&&&&&&&&&eglDestroyImageKHR(mSlots[buf].mEglDisplay,&mSlots[buf].mEglImage);&&&&&&&&&&mSlots[buf].mEglImage&=&EGL_NO_IMAGE_KHR;&&&&&&&&&&mSlots[buf].mEglDisplay&=&EGL_NO_DISPLAY;&&&&&&}&&&&&&returnFlags&|=&ISurfaceTexture::BUFFER_NEEDS_REALLOCATION;&&}&&
&&&& mGraphicBufferAlloc也是通过调用BpSurfaceComposer-&createGraphicBufferAlloc而获取,它对应的服务器为SufaceFlinger中的GraphicBufferAlloc。 &&&& mGraphicBufferAlloc实质为一个BpGraphicBufferAlloc,它真正创建GraphicBuffer的代码位于GraphicBufferAlloc::createGraphicBuffer中。代码关键调用流程如下: &&&& new GraphicBuffer(w, h, format, usage)-& &&&&&& initSize(w, h, reqFormat, reqUsage)-& &&&&&&&& GraphicBufferAllocator::get()-& &&&&&&&&&&& allocator.alloc(w, h, format, reqUsage, &handle, &stride)-& &&&&&&&&&&& 返回handle,此handle为ANativeWindowBuffer成员,类型为native_handle。 &&&&&&&&&&&&& GraphicBufferAllocator::alloc-& &&&&&&&&&&&&&&& mAllocDev-&alloc-& &&&&&&&&&&&&&&&& mAllocDev类型为alloc_device_t,它通过gralloc_open向 &&&&&&&&&&&&&&&& GRALLOC_HARDWARE_MODULE_ID获取,根据上面的实例msm7k, &&&&&&&&&&&&&&&& 它最终执行gralloc_device_open而获取gralloc_context_mon, &&&&&&&&&&&&&&&&&&alloc的实现函数为gralloc_alloc. &&&&&&&&&&&&&&&& & gralloc_alloc-& &&&&&&&&&&&&&&&&&&& gralloc_alloc_buffer-& &&&&&&&&&&&&&&&&&&&&&1)获取GPU内存(调用SimpleBestFitAllocator::allocate进行分配) &&&&&&&&&&&&&&&&&&&& 2)fd = open("/dev/null", O_RDONLY)获取fd &&&&&&&&&&&&&&&&&&&& 3)根据fd、size和flags创建private_handle_t,其相关代码如下: & [cpp] private_handle_t*&hnd&=&new&private_handle_t(fd,&size,&flags);&&if&(base&==&NULL)&{...&&&&&&}&&}&else&{&&&&&&private_module_t*&m&=&reinterpret_cast&private_module_t*&(&&&&&&&&&&&&&&dev-&common.module);&&&&&&hnd-&offset&=&&&&&&&hnd-&base&=&int(base)+&&&&&&hnd-&gpu_fd&=&gpu_&&&&&&hnd-&map_offset&=&m-&fb_map_&&&&&&*pHandle&=&&&}&&
3.2 Surface_unlockCanvasAndPost & & & & & & & & & &
阅读(1497)
阅读排行榜
评论排行榜

参考资料

 

随机推荐