Android系统Surface机制的SurfaceFlinger服务对帧缓冲区(FrameBuff

整理文档很辛苦,赏杯茶钱您下走!

免费阅读已结束,点击下载阅读编辑剩下 ...

阅读已结束,您可以下载文档离线阅读编辑

资源描述

Android系统Surface机制的SurfaceFlinger服务对帧缓冲区(FrameBuffer)的管理分析在前文中,我们分析了SurfaceFlinger服务的启动过程。SurfaceFlinger服务在启动的过程中,会对系统的硬件帧缓冲区进行初始化。由于系统的硬件帧缓冲区一般只有一个,并且不是谁都可以随便访问的,因此,它就需要由一个服务来统一管理。在Android系统中,这个服务便是SurfaceFlinger。在本文中,我们就详细分析SurfaceFlinger服务是如何管理系统的硬件帧缓冲区的。从前面一文可以知道,SurfaceFlinger服务通过一个GraphicPlane对象来描述系统的显示屏,即系统的硬件帧缓冲区。GraphicPlane类内部聚合了一个DisplayHardware对象,通过这个DisplayHardware对象就可以访问系统的硬件帧缓冲区。DisplayHardware类内部又包含了一个FramebufferNativeWindow对象,这个FramebufferNativeWindow对象才是真正用来描述系统的硬件帧缓冲区的。FramebufferNativeWindow类的作用类似于在前面一文中所介绍的Surface类,它是连接OpenGL库和Android的UI系统的一个桥梁,OpenGL库就是通过这个桥梁来将Android系统的UI渲染到硬件帧缓冲区中去的。GraphicPlane、DisplayHardware和FramebufferNativeWindow这三个类的关系如图1所示。接下来,我们就分别介绍GraphicPlane、DisplayHardware和FramebufferNativeWindow这三个类的实现,以便可以理解SurfaceFlinger服务是如何通过它们来管理系统的硬件帧缓冲区的。从前面一文可以知道,SurfaceFlinger服务在启动的过程中,会对系统的硬件帧缓冲区进行初始化,如下所示:[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片status_tSurfaceFlinger::readyToRun(){......//weonlysupportonedisplaycurrentlyintdpy=0;{//initializethemaindisplayGraphicPlane&plane(graphicPlane(dpy));DisplayHardware*consthw=newDisplayHardware(this,dpy);plane.setDisplayHardware(hw);}......//initializeprimaryscreen//(otherdisplayshouldbeinitializedinthesamemanner,but//asynchronously,astheycouldcomeandgo.Noneofthisissupported//yet).constGraphicPlane&plane(graphicPlane(dpy));constDisplayHardware&hw=plane.displayHardware();......hw.makeCurrent();......}这个函数定义在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp文件中。这个代码段首先创建了一个DisplayHardware对象,用来初始化编号为0的GraphicPlane对象,接着再将这个DisplayHardware对象设置为系统当前活动的DisplayHardware对象,这就相当于是将编号为0的GraphicPlane对象所描述的显示屏设置为系统当前活动的显示屏。接下来,我们就首先分析编号为0的GraphicPlane对象的初始化过程,接着再分析DisplayHardware对象的创建过程。编号为0的GraphicPlane对象的初始化过程主要是调用GraphicPlane类的成员函数setDisplayHardware来实现的,如下所示:[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片voidGraphicPlane::setDisplayHardware(DisplayHardware*hw){mHw=hw;//initializethedisplayorientationtransform.//it'saconstantthatshouldcomefromthedisplaydriver.intdisplayOrientation=ISurfaceComposer::eOrientationDefault;charproperty[PROPERTY_VALUE_MAX];if(property_get(ro.sf.hwrotation,property,NULL)0){//displayOrientationswitch(atoi(property)){case90:displayOrientation=ISurfaceComposer::eOrientation90;break;case270:displayOrientation=ISurfaceComposer::eOrientation270;break;}}constfloatw=hw-getWidth();constfloath=hw-getHeight();GraphicPlane::orientationToTransfrom(displayOrientation,w,h,&mDisplayTransform);if(displayOrientation&ISurfaceComposer::eOrientationSwapMask){mDisplayWidth=h;mDisplayHeight=w;}else{mDisplayWidth=w;mDisplayHeight=h;}setOrientation(ISurfaceComposer::eOrientationDefault);}这个函数定义在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp文件中。函数首先设置显示屏的初始大小和旋转方向。GraphicPlane类有三个成员变量mDisplayWidth、mDisplayHeight和mDisplayTransform,前两者的类型为float,分别用描述显示屏的初始宽度和高度,而后者的类型为Transform,用来描述显示屏的初始旋转矩阵。Transform类的作用是来描述变换矩阵,以便后面在渲染UI时可以用来动态地计算显示屏的大小和旋转方向等。显示屏的初始化宽度和高度是由参数hw所描述的一个DisplayHardware对象来描述的,而显示屏的初始旋转方向则是由名称为“ro.sf.hwrotation”的系统属性来决定的。如果没有设置名称为“ro.sf.hwrotation”的系统属性,那么显示屏的旋转方向就为默认方向,即ISurfaceComposer::eOrientationDefault。获得了显示屏的初始化宽度w、高度h和旋转方向displayOrientation之后,函数接着就调用GraphicPlane类的静态成员函数orientationToTransfrom来将它们构造成一个变换矩阵,并且保存在GraphicPlane类的成员变量mDisplayTransform中。函数接下来继续判断显示屏的初始化旋转方向是否将初始化宽度和高度值翻转了。如果翻转了,那么就需要相互调换GraphicPlane类的成员变量mDisplayWidth和mDisplayHeight的值,以便可以正确地反映显示屏的初始化宽度和高度。注意,显示屏的初始宽度、高度和旋转方向一经初始化之后,就会保持不变,以后显示屏的实际旋转方向计算都是要在此基础上进行计算的,即要在变换矩阵mDisplayTransform的基础上进行计算。从这里还可以看出,通过设置名称为“ro.sf.hwrotation”的系统属性的值,就可以设置系统显示屏的初始化旋转方向,以便匹配实际的硬件帧缓冲区的旋转方向。函数最后调用GraphicPlane类的成员函数setOrientation来设备显示屏的实际度度、高度以及旋转方向,如下所示:[cpp]viewplaincopy在CODE上查看代码片派生到我的代码片status_tGraphicPlane::setOrientation(intorientation){//Iftherotationcanbehandledinhardware,thisiswhere//themagicshouldhappen.constDisplayHardware&hw(displayHardware());constfloatw=mDisplayWidth;constfloath=mDisplayHeight;mWidth=int(w);mHeight=int(h);TransformorientationTransform;GraphicPlane::orientationToTransfrom(orientation,w,h,&orientationTransform);if(orientation&ISurfaceComposer::eOrientationSwapMask){mWidth=int(h);mHeight=int(w);}mOrientation=orientation;mGlobalTransform=mDisplayTransform*orientationTransform;returnNO_ERROR;}这个函数定义在文件frameworks/base/services/surfaceflinger/SurfaceFlinger.cpp文件中。参数orientation的值等于ISurfaceComposer::eOrientationDefault,即SurfaceFlinger服务在初始化系统显示屏时,会将它的旋转方向设置为默认值,以后再根据实际情况来做调整。GraphicPlane类有三个成员变量mWidth、mHeight和mOrientation,它们的类型均为int,分别用来描述显示屏的实际宽度、高度和旋转方向。与成员变量mDisplayWidth、mDisplayHeight和mDisplayTransform所描述的显示屏初始化宽度、高度和旋转矩阵一经初始化后就保持不变不同,mWidth、mHeight和mOrientation这三个成员变量是会动态变化的。例如,当显示屏由LANDSCAPE变为PORTRAIT模式时,mWidth、mHeight和mOrientation这三个成员变量就会相应地发生改变。函数首先将显示屏的实际宽度mWidth、高度mHeight和旋转方向mOrientation设置为显示屏的初始宽度mDisplayWidth、高度mDisplayHeight以及参数orientation所描述的旋转方向,接着再调用GraphicPlane类的静态成员函数orientationToTransfrom来将它们构造成一个变换矩阵orientationTransform。函数接着判断显示屏的实际旋转方向orientation是否将原来的实际宽度和高度值翻转了。如果翻转了,那么就需要相互调换GraphicPlane类的成员变量mWidth和mHeight的值,以便可以正确地反映显示屏的实际宽度和高度。函数最后将用来描述显示屏的初始化旋转方向的变换矩阵mDisplayTransform和用来描述显示屏的实际旋转方向的变换矩阵orientationTransform相乘,就可以得到一

1 / 24
下载文档,编辑使用

©2015-2020 m.777doc.com 三七文档.

备案号:鲁ICP备2024069028号-1 客服联系 QQ:2149211541

×
保存成功