下面就是SurfaceFlinger执行实际的数据合成,然后刷新到屏幕上。
voidSurfaceFlinger::onMessageReceived(int32_t what) {
switch(what) {
case MessageQueue::INVALIDATE: {
bool refreshNeeded =handleMessageTransaction();
refreshNeeded |=handleMessageInvalidate();
refreshNeeded |=mRepaintEverything;
if (refreshNeeded) { signalRefresh();}
Break;
}
case MessageQueue::REFRESH: {
handleMessageRefresh();
break;
}
}
}
上面是surfaceflinger收到vsync时的处理代码,signalRefresh跟handleMessageRefresh是一样的,所以INVALIDATE比REFRESH多了两个函数:handleMessageTransaction(对layer属性变更的处理)和handleMessageInvalidate(数据的刷新),在看handleMessageRefresh包含了那些工作:
void SurfaceFlinger::handleMessageRefresh(){
preComposition();//合成前的准备
rebuildLayerStacks();//重建layer堆栈
setUpHWComposer();//hwcomposer的设定
doComposition();//正式的合成处理
postComposition(refreshStartTime);//合成后期的处理
}
整个UI的就是上面handleMessageRefresh中几个函数,加上INVALIDATE中那两个函数。
Step1,handleMessageTransaction
handleMessageTransaction真正处理业务的地方是handleTransactionLocked。
voidSurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags){
if(transactionFlags & eTraversalNeeded) {
for(size_t i=0 ; i
const uint32_t flags = layer->doTransaction(0); }
}
commitTransaction();
}
transactionFlags有多个类别,这里以eTraversalNeeded为例,首先会循环判断每个layer是否要doTransaction,如果需要就调用layer->doTransaction由各layer做内部处理。
uint32_t Layer::doTransaction(uint32_tflags) {
//尺寸发生变化,调用setDefaultBufferSize使它生效,SurfaceFlingerConsumer,可以这样理解:surfaceflinger作为buffer的消费者,并没有直接管理Buffer,surfaceflinger直接拥有的是跟存储“图层数据”有关的layer,而layer也没有直接持有BufferQueue对象,而是通过SurfaceFlingerConsumer来管理,
if(sizeChanged) {
mSurfaceFlingerConsumer->setDefaultBufferSize(c.requested.w,c.requested.h); }
//重新计算可见区域,这个要作为flags传给surfaceflinger统一部署
if(s.active != c.active) {
flags |= Layer::eVisibleRegion; }
//当layer的position,z-order,transparentregion,crop等属性变化时,mCurrentState::Sequence的值就会递增,在doTransaction时,它和mDrawingState::sequence的值就不一样了,它在平时收集属性的变化,到vsync信号产生时做统一处理。mCurrentState和mDrawingState分别表示当前的状态和上一次drawing时的状态。Surfaceflinger中也有两个这样的变量,但是数据结构不同,surfaceflinger中的mCurrentState,内部包含了一个变量:LayerVector layersSortedByZ;记录了所有按Z-order顺序排列的layers。
if(c.sequence != s.sequence) {
this->contentDirty = true; }
//把mCurrentState赋值给mDrawingState,
commitTransaction(c);
}
完成所有layer的遍历后,返回到handleTransactionLocked,
voidSurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags){
//有新增的layer,可见区域要重新计算,同样还有移除layer的处理
if(currentLayers.size() > layers.size()) {
mVisibleRegionsDirty= true;}
//结束业务处理,会回调被移除layer的onRemoved(),最后通过mTransactionCV.broadcast();唤醒等待Transaction结束的线程,如应用进程中的处理surface跟新的线程、surfaceflinger中的显示线程。
commitTransaction();
}
Step2,handleMessageInvalidate--界面重新绘制,这个函数处理bufferQueue相关的工作。
bool SurfaceFlinger::handleMessageInvalidate(){
returnhandlePageFlip();
}
bool SurfaceFlinger::handlePageFlip(){
//锁定一个buffer,也就是每个layer当前要处理的缓冲区
const Regiondirty(layer->latchBuffer(visibleRegions));
//更新displayDevice中的脏区域
invalidateLayerStack(s.layerStack,dirty);
}
Region Layer::latchBuffer(bool&recomputeVisibleRegions){
if(mQueuedFrames > 0 || mAutoRefresh) {
status_t updateResult =mSurfaceFlingerConsumer->updateTexImage(&r,
mFlinger->mPrimaryDispSync, &mAutoRefresh, &queuedBuffer,
mLastFrameNumberReceived);
mFlinger->signalLayerUpdate();
mActiveBuffer= mSurfaceFlingerConsumer->getCurrentBuffer();
}
}
status_tSurfaceFlingerConsumer::updateTexImage(...){
err =acquireBufferLocked(&item, computeExpectedPresent(dispSync),...);
}
前面说过,当应用进程填充好一块buffer后,会通过BufferQueue的方法queue把这个bufferslot入队,同时BufferQueue会调用onFrameAvailable通知消费者有一帧数据准备好了,可以消费了,继承FrameAvailableListener这个监听的消费者--layer的方法onFrameAvailable就会被调用,这个函数会增加mQueuedFrames的计数,也会向surfaceflinger发去一个invalidate信号。Layer对BufferQueue的管理是通过SurfaceFlingerConsumer实现的,这个消费者想要操作一块buffer,要先accquire它,这个操作封装在mSurfaceFlingerConsumer->updateTexImage()中,accquire到的buffer封装在BufferItem中,如果有多个mQueuedFrames,还会通过signalLayerUpdate组织一次新的invalidate,最后更新当前活跃的缓冲区mActiveBuffer。
Step3,预合成--合成前的准备,preComposition
void SurfaceFlinger::preComposition(){
const LayerVector& layers(mDrawingState.layersSortedByZ);
for (size_t i=0 ; i
if (layers[i]->onPreComposition()) {
needExtraInvalidate = true;}
if (needExtraInvalidate) {
signalLayerUpdate();}
}
首先得到当前所有layer的集合,然后调用每个layer的预合成接口onPreComposition,只要有一个layer中存在被Queued的Frames,即mQueuedFrames>0,那么needExtraInvalidate就会变成true,最后触发signalLayerUpdate()调用,通过EventThread安排一次vsync。
Step4,计算可见layer及它们的可见区域—rebuildLayerStacks
void SurfaceFlinger::rebuildLayerStacks() {
//当前所有的layers都是通过mDrawingState.layersSortedByZ来记录的,每个layer都有一个layerStack来区别它属于哪个Display。
constLayerVector& layers(mDrawingState.layersSortedByZ);
//系统的Display可能不止一个,都存储在mDisplays中,逐个处理这些Display。
for(size_t dpy=0 ; dpy
if(hw->isDisplayOn()) {
//根据所有layers的当前状态,计算dirtyRegion—需要重新绘制的区域,opaqueRegion—不透明区域。
computeVisibleRegions(hw->getHwcDisplayId(),layers,
hw->getLayerStack(),dirtyRegion, opaqueRegion);}
for(size_t i=0 ; i
constsp
//把需要绘制的layer添加到layersSortedByZ中。
layersSortedByZ.add(layer);
}
}
Step5,为合成搭建环境—setUpHWComposer
把需要显示的那些layer的数据准备好,报给Hwc模块来决定由谁进行最终的合成工作。
void SurfaceFlinger::setUpHWComposer() {
//这个HWComposer并不是真正的Hal模块,而是surfaceflinger为管理HWComposer模块而设计的一个类,路径是:frameworks/native/service/surfaceflinger/displayhardware/。 HWComposer& hwc(getHwComposer());
//依次处理各个Display,构造WorkList,
for(size_t dpy=0 ; dpy
sp
const int32_t id = hw->getHwcDisplayId();
const Vector< sp
const size_t count = currentLayers.size();
if (hwc.createWorkList(id, count) == NO_ERROR) {…}
}
//填充各个layer的数据,由每个layer自己完成。
layer->setPerFrameData(hw,*cur);
//合成过程既可以有Hwc模块完成,也可以通过OpengGlEs来完成,具体用哪种方式是有prepare()中的compositionType来决定的。
status_t err =hwc.prepare();
}
Step6,执行合成、显示到屏幕上—doComposition
void SurfaceFlinger::doComposition() {
//逐个Display去处理,对每个DisplayDevice,需要单独调用doDisplayComposition。
for(size_t dpy=0 ; dpy
doDisplayComposition(hw,dirtyRegion);
//通知hwc合成已经完成。
hw->compositionComplete();
}
postFramebuffer();
}
void SurfaceFlinger::doDisplayComposition(…){
//相关layer的数据合成。
doComposeSurfaces(hw,dirtyRegion);
//交换前后台数据,将UI数据显示到屏幕上的关键是eglSwapBuffers。
hw->swapBuffers(getHwComposer());àeglSwapBuffers(mDisplay, mSurface);
}
bool SurfaceFlinger::doComposeSurfaces(…){
boolhasGlesComposition = hwc.hasGlesComposition(id);
//需要openglEs合成,通过makeCurrent设置当前的渲染环境。
if(hasGlesComposition) {
hw->makeCurrent(mEGLDisplay,mEGLContext);
//需要Hwc执行合成layer,hasHwcComposition跟hasGlesComposition不是互斥的,他们有可能同时为true,这种情况说明既有要OpengGlES处理的layer,也有要Hwc处理的layer。对layer的处理:layer->draw(hw, clip)àLayer::onDraw();
constbool hasHwcComposition = hwc.hasHwcComposition(id) ||
isS3DLayerPresent(hw);
if(hasHwcComposition) {
engine.clearWithColor(0,0, 0, 0);}
}
}
// doComposition的最后调用了这个函数,核心功能是调用Hwc模块的hal接口set,把那些需要hwc处理的layer的数据传给hwc做实际的处理,set的内部也调用了eglSwapBuffers。
void SurfaceFlinger::postFramebuffer(){
hwc.commit();àmHwc->set(mHwc, mNumDisplays, mLists);
}
到这里数据就送到了显示设备。