App的启动过程(10)surfaceflinger对数据合成,送显

下面就是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时的处理代码,signalRefreshhandleMessageRefresh是一样的,所以INVALIDATEREFRESH多了两个函数:handleMessageTransaction(对layer属性变更的处理)和handleMessageInvalidate(数据的刷新),在看handleMessageRefresh包含了那些工作:

void SurfaceFlinger::handleMessageRefresh(){

         preComposition();//合成前的准备

         rebuildLayerStacks();//重建layer堆栈

         setUpHWComposer();//hwcomposer的设定

         doComposition();//正式的合成处理

         postComposition(refreshStartTime);//合成后期的处理

}

         整个UI的就是上面handleMessageRefresh中几个函数,加上INVALIDATE中那两个函数。

Step1handleMessageTransaction

         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的消费者,并没有直接管理Buffersurfaceflinger直接拥有的是跟存储图层数据有关的layer,而layer也没有直接持有BufferQueue对象,而是通过SurfaceFlingerConsumer来管理,

         if(sizeChanged) {

mSurfaceFlingerConsumer->setDefaultBufferSize(c.requested.w,c.requested.h); }

//重新计算可见区域,这个要作为flags传给surfaceflinger统一部署

         if(s.active != c.active) {

flags |= Layer::eVisibleRegion; }

//layerpositionz-ordertransparentregioncrop等属性变化时,mCurrentState::Sequence的值就会递增,在doTransaction时,它和mDrawingState::sequence的值就不一样了,它在平时收集属性的变化,到vsync信号产生时做统一处理。mCurrentStatemDrawingState分别表示当前的状态和上一次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;}

//结束业务处理,会回调被移除layeronRemoved(),最后通过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信号。LayerBufferQueue的管理是通过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中存在被QueuedFrames,即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(layers[i]);

//把需要绘制的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 hw(mDisplays[dpy]);

const int32_t id = hw->getHwcDisplayId();

const Vector< sp >¤tLayers(hw->getVisibleLayersSortedByZ());

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执行合成layerhasHwcCompositionhasGlesComposition不是互斥的,他们有可能同时为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);

}

到这里数据就送到了显示设备。

你可能感兴趣的:(Android,app的启动到显示)