当前位置:操作系统 > 安卓/Android >>

android surfaceflinger研究----显示系统

 

这周抽空研究了一下SurfaceFlinger,发现真正复杂的并不是SurfaceFlinger本身,而是android的display显示系统,网上关于这部分的介绍有不少,本不打算写的,但是发现还是记录一下研究代码的过程比较好,一是能够帮助自己理清思路,另一个原因就是以后当这块内容忘记的时候,能快速的通过这个记录捡起来。

 

    一.  android显示系统的建立

    我们看SurfaceFlinger的定义就知道,它其实是一个Thread, 因此SurfaceFlinger的初始化工作就理所当然的放在了SurfaceFlinger线程中,详见readyToRun()@SurfaceFlinger.cpp

    SurfaceFlinger对于显示的管理是通过一个或多个GraphicPlane对象(目前android只实现了一个)来管理的,

 

@SurfaceFlinger.h

 

 

GraphicPlane                mGraphicPlanes[1]; 

    其实,GraphicPlane类只是一个wrapper层,目的是当android支持多个显示系统时,通过该类来管里各自的图形系统,显示系统真正的初始化工作是通过DisplayHardware类来初始化底层图形系统的管理与显示的。真正的图形显示系统的初始化在init()@DisplayHardware.cpp

    目前,android支持一个图形系统,这个图形系统是全局的,surfaceflinger可以访问,其他不通过surfaceflinger进行图形处理的application也可以对其进行操作。

\

 

 

    1. FrameBuffer的建立

    framebuffer,确切的是说是linux下的framebuffer,,它是linux图形显示系统中一个与图形硬件无关的抽象层,user完全不用考虑我们的硬件设备,而仅仅使用framebuffer就可以实现对屏幕的操作。

 

    android的framebuffer并没有被SurfaceFlinger直接使用,而是在framebuffer外做了一层包装,这个包装就是FramebufferNativeWindow,我们来看一下FramebufferNativeWindow的创建过程。

 

   我们的framebuffer是由一个设备符fbDev来表示的,它是FramebufferNativeWindow的一个成员,我们来分析一下对fbDev的处理过程。

 

    1.1. fbDev设备符

    1.1.1 gralloc library

    在这之前,先介绍一下gralloc library,它的形态如grallocBOARDPLATFORM.so,BOARDPLATFORM可以从属性ro.board.platform中获得,这篇文章中我们以Qualcomm msmx7x30为例,也就是gralloc.msm7x30.so中,它的源路径在hardware/msm7k/libgralloc-qsd8k。

 

    framebuffer的初始化需要通过HAL gralloc.msm7x30.so 来完成与底层硬件驱动的适配,但是gralloc library并不是平台无关的,不同的vendor可能会实现自己的gralloc library,因此为了保证在创建framebuffer时能够平台无关,android只能是动态的判断并使用当前的gralloc library,android通过从gralloc library中再抽象出一个hw_module_t结构来供使用,它为framebuffer的初始化提供了需要的gralloc.msm7x30.so业务。因此通过这个hw_module_t结构我们就不需要知道当前系统使用的到底是哪个gralloc library。按规定,所有gralloc library中的这个结构体被命名为HAL_MODULE_INFO_SYM(HMI)。当前分析的系统中,HAL_MODULE_INFO_SYM在hardware/msm7k/libgralloc-qsd8k/galloc.cpp。

 

    1.1.2 打开fbDev设备符   

    下面看如何打开 打开fbDev设备符。通过HAL_MODULE_INFO_SYM提供的gralloc.msm7x30.so的接口我们调用到了fb_device_open()@hardware/msm7k/libgralloc-qsd8kframebuffer.cpp。

 

 

 

 

int fb_device_open(hw_module_t const* module, const char* name, 

        hw_device_t** device) 

    int status = -EINVAL; 

    if (!strcmp(name, GRALLOC_HARDWARE_FB0)) { 

        alloc_device_t* gralloc_device; 

        status = gralloc_open(module, &gralloc_device); 

 

        /* initialize our state here */ 

        fb_context_t *dev = (fb_context_t*)malloc(sizeof(*dev)); 

        memset(dev, 0, sizeof(*dev)); 

 

        /* initialize the procs */ 

        dev->device.common.tag = HARDWARE_DEVICE_TAG; 

 

        private_module_t* m = (private_module_t*)module; 

        status = mapFrameBuffer(m); 

 

 

在这个函数中,主要为fbDev设备符指定一个fb_context_t实例,并通过函数mapFrameBuffer()对设备节点/dev/graphics/fb0进行操作,操作的目的有:

 

1.获得屏幕设备的信息,并将屏幕信息保存在HAL_MODULE_INFO_SYM(上面代码中的module)中。

 

 2. 向/dev/graphics/fb0请求page flip模式,page

 flip模式需要至少2个屏幕大小的buffer,page flip模式在后面介绍。目前android系统中设置为2个屏幕大小的buffer。当然屏幕设备可能不支持page flip模式。

 

mapFrameBufferLocked()@hardware/msm7k/libgralloc-qsd8k/framebuffer.cpp

 

 

 

 

/*

 * Request NUM_BUFFERS screens (at lest 2 for page flipping)

 */ 

info.yres_virtual = info.yres * NUM_BUFFERS; 

 

 

uint32_t flags = PAGE_FLIP; 

if (ioctl(fd, FBIOPUT_VSCREENINFO, &info) == -1) { 

    info.yres_virtual = info.yres; 

    flags &= ~PAGE_FLIP; 

    LOGW("FBIOPUT_VSCREENINFO failed, page flipping not supported"); 

 

 

3. 映射屏幕设备缓存区给fbDev设备符。

 

 

mapFrameBufferLocked()@hardware/msm7k/libgralloc-qsd8k/framebuffer.cpp

 

 

 

 

/*

 * map the framebuffer

 */ 

 

int err; 

size_t fbSize = roundUpToPageSize(finfo.line_length * info.yres_virtual); 

module->framebuffer = new private_handle_t(dup(fd), fbSize, 

        private_handle_t::PRIV_FLAGS_USES_PMEM); 

 

module->numBuffers = info.yres_virtual / info.yres; 

module->bufferMask = 0; 

 

void* vaddr = mmap(0, fbSize, PROT_READ|PROT_WRITE, MAP_SHARED, fd, 0); 

if (vaddr == MAP_FAILED) { 

    LOGE("Error mapping the framebuffer (%s)", strerror(errno)); 

    return -errno; 

module->framebuffer->base = intptr_t(vaddr); 

memset(vaddr, 0, fbSize); 

 

 

 

1.2 grDev设备符

在为framebuffer,也就是FramebufferNativeWindow申请内存之前,我们还要介绍一个概念,就是grDev设备符。它虽然也叫设备符,但是它和具体的设备没有直接关系,我们看它的类型就是知道了alloc_device_t,没错,grDev设备符就是为了FramebufferNativeWindow管理内存使用的。为FramebufferNativeWindow提供了申请/释放内存的接口。

 

 

 

 

    1.3 FramebufferNativeWindow内存管理

    FramebufferNativeWindow维护了2个buffer,

 

sp<NativeBuffer> buffers[2]; 

补充:移动开发 , Android ,
CopyRight © 2012 站长网 编程知识问答 www.zzzyk.com All Rights Reserved
部份技术文章来自网络,