SurfaceFlinger简介

来源:互联网 发布:保卫萝卜安卓数据同步 编辑:程序博客网 时间:2024/06/08 13:34

1. SurfaceFlinger背景知识

 

        SurfaceFlinger 是一个独立的Service, 它接收所有Window的Surface作为输入,根据ZOrder, 透明度,大小,位置等参数,计算出每个Surface在最终合成图像中的位置,然后交由HWComposer或OpenGL生成最终的显示Buffer, 然后显示到特定的显示设备上。


下面首先介绍下相关概念:
        Surface——在Android中,Window与Surface一一对应。 如果说Window关心的是层次和布局,是从设计者角度定义的类,Surface则从实现角度出发,是工程师关心和考虑的类。Window的内容是变化 的,Surface需要有空间来记录每个时刻Window的内容。在android的SurfaceFlinger实现里,通常一个Surface有两块 Buffer, 一块用于绘画,一块用于显示,两个Buffer按照固定的频率进行交换,从而实现Window的动态刷新。


        Layer——Layer是SurfaceFlinger 进行合成的基本操作单元。Layer在应用请求创建Surface的时候在SurfaceFlinger内部创建,因此一个Surface对应一个 Layer, 但注意,Surface不一定对应于Window,Android中有些Surface并不跟某个Window相关,而是有程序直接创建,比如说 SurfaceView, 用于显示有硬件输出的视频内容等。
当多个Layer进行合成的时候,并不是整个Layer的空间都会被完全显示,根据这个Layer最终的显示效果,一个Layer可以被划分成很多的Region, Android SurfaceFlinger 定义了以下一些Region类型:
        TransparantRegion: 完全透明的区域,在它之下的区域将被显示出来。
        OpaqueRegion:  完全不透明的区域,是否显示取决于它上面是否有遮挡或是否透明。
        VisibleRegion:  可见区域,包括完全不透明无遮挡区域或半透明区域 
                                  visibleRegion = Region - above   OpaqueRegion.
        CoveredRegion:  被遮挡区域,在它之上,有不透明或半透明区域。
        DirtyRegion:  可见部分改变区域,包括新的被遮挡区域,和新的露出区域。

 

 

 

       如上图所示,应用程序的每个Surface都对应一个SurfaceFlinger端的Layer,每个Layer都有两个buffer可以用(Android4.1后有三个buffer可以用,此处以两个buffer举例说明),一个前端buffer,一个后端buffer,前端buffer用于显示,后端buffer用于绘制,SurfaceFlinger所要做的事情就是把后端buffer绘制完成后需要显示的buffer进行合成,合成到framebuffer上,然后丢给Display去显示。

 

 

2. surfaceflinger的工作流程

 

 

       当Surface绘制完成后会发出一个Invalidate的消息给Surfaceflinger的等待线程,当waitForEvent接收到消息后就会交给onMessageReceivered去处理,处理过程中会依次调用handleMessageTransactionhandleMessageInvalidatehandleMessageRefresh接口。

        handleMessageTransaction——主要处理之前对屏幕和应用程序窗口的改动。窗口状态的改变只能在一个Transaction中进行。因为窗口状态的改变可能造成本窗口和其他窗口的可见区域变化,所以就必须重新来计算窗口的可见区域。在这个处理子过程中Android会根据标志位来对所有layer进行遍历,一旦发现哪个窗口的状态发生了变化就设置标志位以在将来重新计算这个窗口的可见区域。

        handleMessageInvalidate——主要调用handlePageFlip()函数,该函数主要是从各Layer对应的BufferQueue中拿图形缓冲区数据,并根据内容更新脏区域。

        handleMessageRefresh——就是合并和渲染输出了。作为重头戏,这步步骤多一些,大体框架如下:

 

        合并渲染完成后,该线程继续等待下一个invalidate消息。

原创粉丝点击