SurfaceFlinger继承了Thread类,自然也继承了Thread类的threadLoop方法,SurfaceFlinger工作线
程的主代码都在threadLoop()方法中。工作线程启动后,基类Thread会循环地调用threadLoop方法,SurfaceFlinger
的threadLoop()主要是要完成系统中各个Layer(Surface)进行混合(compose),然后不停地把一帧帧混合好的图像数据传送到
显示设备中。
threadLoop的流程
图一 threadLoop流程
1. handleConsoleEvents
handleConsoleEvent目前没有深入了解,貌似只是处理显示设备进入休眠状态或者从休眠中唤醒时,改变SufaceFlinger的
状态,然后threadLoop的后续流程会根据相应的状态来决定是否继续给显示设备传送显示数据。
2.handleTransaction
因为Layer的混合是在线程中进行的,而混合的过程中,应用程序或者系统可能会改变Layer的状态,例如屏幕旋转、增加或删除Layer、某个
Layer可见或不可见,为了使这些变动不会破坏当前正在进行的混合动作,SurfaceFlinger维护着两个Layer列表:
- mCurrentState.layersSortedByZ ---- 当前系统最新的Layer列表
- mDrawingState.layersSortedByZ ---- 本次混合操作使用的Layer列表
handleTransaction就是根据Layer列表的这些状态的变化,计算是否有可见区域内需要更新,并设置状态变量
mVisibleRegionsDirty,然后把mCurrentState赋值给mDrawingState,最后释放已经被丢弃(ditch)的
Layer
-
上一次混合过程中,可能应用程序释放了一个Layer,可是mDrawingState正在使用,不能马上销毁,所以要等到本次混合前
才能做出销毁的动作。
-
如果Layer的大小有变化并且可见,Layer的handleTransaction将会重新分配缓冲区,并且冻结
SurfaceFlinger后续的混合操作,也就是屏幕的内容本次将不会刷新,直到下一个循环的handlePageFlip阶段才解除冻结。
3. handlePageFlip
该阶段会遍历各个Layer,在每个Layer中,取得并锁住该Layer的frontBuffer,然后利用frontBuffer中的图像数据
生成该Layer的2D贴图(Texture),并且计算更新区域,为后续的混合操作做准备。
图二 handlePageFlip处理流程
Layer的lockPageFlip()首先通过SharedBufferServer
类的成员变量lcblk
,调用retireAndLock取得该Layer当前可用的frontBuffer,然后通过
reloadTexture方法生成openGL
ES的纹理贴图,最后通过unlockPageFlip完成更新区域的Layer坐标到屏幕坐标的变换。
handleRepaint
handleRepaint真正实现Layer混合的阶段,下图是handleRepaint的处理流程:
图三
handleRepaint 的处理流程
handleRepaint首先重置了openGL的观察矩阵,然后遍历mDrawingState.layersSortedByZ中的
Layer列表,调用每个Layer的onDraw方法,在onDraw方法中,会调用drawWithOpenGL()方法,将在
handlePageFlip阶段生成的贴图混合到OpenGL的主表面,最后handleRepaint把需要刷新的区域清除。
unlockClients
unlockClients只是遍历各个Layer并调用各个Layer的finishPageFlip方法。finishPageFlip会进一
步调用SharedBufferServer的unlock()方法:(关
于SharedBufferSever,请参考本人以下博文的SharedClient 和 SharedBufferStack一节
)
-
void
Layer::finishPageFlip()
-
{
-
status_terr=lcblk->unlock(mFrontBufferIndex);
-
LOGE_IF(err!=NO_ERROR,
-
"layer%p,buffer=%dwasn'tlocked!"
,
-
this
,mFrontBufferIndex);
-
}
lcblk->unlock( mFrontBufferIndex )会把Layer的frontBuffer解除锁定。
postFramebuffer
进入postFramebuffer阶段,OpenGL主表面已经准备好了混合完成的图像数据,postFramebuffer只是简单地调用
hw.flip(),hw.flip()进一步调用了eglSwapBuffers完成主表面的切换,这样屏幕上的图像就会更新为新的数据。
分享到:
相关推荐
对Android SurfaceFlinger做介绍的PPT
Android SurfaceFlinger详解,评论时候不要忘了,评论星级阿,要不然拿不回下载积分了,呵呵
Android_Surfaceflinger研究-显示系统
Android系统Surface机制的SurfaceFlinger服务的线程模型分析.doc
Android图形系统分析-surfaceFlinger流程.欢迎研究surface 人员下载学习
Android系统Surface机制的SurfaceFlinger服务的线程模型分析报告.doc
Android 2.3.4 中SurfaceFlinger相关源码 Android 2.3.4 中SurfaceFlinger相关源码
自己单独写了一个jni来调用系统截屏接口 screencap ( frameworks/base/cmds/screencap/screencap.cpp),然后在源代码中编译jni成一个so文件(libscreencapjni.so),可是在真机上测试出现了SurfaceFlinger ...
SurfaceFlinger 视频教程 显示系统,内部机制,Vsync机制,HDMI系统
介绍了Android中SurfaceFlinger和应用程序之间共享显示缓冲区的机制, 阐明了surface, layer, buffer等概念以及相关C++ class之间的关系
Android源码中的SurfaceFlinger.cpp
在网络上找的几篇关于Android SurfaceFlinger的文章,写不非常不错,就拿来给大家分享
android SurfaceFlinger机制详解
andorid surfaceflinger概述
本例中简单运用了线程间通信原理,简单明了,适合初学线程通信
在Android手机上, 通过使用adb shell命令可以进入android系统的shell, 该shell除支持一些常用的标准命令之外,还支持一些和android系统相关的其他命令, 这些命令可以打印出系统当前的状态信息。 dumpsys就是这样...
详细的surfaceflinger说明文档,很详细很强大