上小节我们讲解了surface使用vsync的过程,并且分析了他的代码,我们下载来回顾一下:
假设我们的应用程序更新了一个界面,他会提交一个buffer给surfaceflinger,surfaceflinger发送一个Vsync请求给EventThread,EventThread又会把这个请求转发给DispSyncThread,DispSyncThread就会等待一个Vsync信号,当软件或者硬件的Vsync信号产生之后,他会唤醒DispSyncThread,DispSyncThread再去唤醒EventThread,然后EventThread给surfaceflinger发出一个Vsync信号,唤醒surfaceflinger。
EventThread是如何唤醒surfaceflinger的呢?实质是EventThread给surfaceflinger发送一个消息,surfaceflinger接收到这个消息之后,就会执行:
void SurfaceFlinger::onMessageReceived(int32_t what) { case MessageQueue::INVALIDATE: { bool refreshNeeded = handleMessageTransaction(); refreshNeeded |= handleMessageInvalidate(); signalRefresh();
进行处理,其发送的这个消息为MessageQueue::INVALIDATE类型。该小节我们就对
bool refreshNeeded = handleMessageTransaction(); refreshNeeded |= handleMessageInvalidate(); signalRefresh();
三个函数进行讲解。
前面提到,当应用程序提交数据给surfaceflinger,但是除了这种情况之外,他还要处理那些情况呢?如图:
一个android设备,其可能接有多个显示器(Dispaly),这些显示器有可能断开,也有可能接上。android设备也有多个APP,每个APP可能有多个surface,每个surface对应一个layer。这些layer会有内容更新,或者新的layer加入,老的layer移除,以及layer的属性变化(如:大小等等)与界面形状的改变。显然surfaceflinger对以上方式都能进行处理。
在讲解代码之前,我们先引入两个结构体,
打开surfaceflinger.h:
struct State { LayerVector layersSortedByZ; DefaultKeyedVector< wp<IBinder>, DisplayDeviceState> displays; }; /*定义了两个成员*/ State mDrawingState;//正在使用或者上次使用的状态 State mCurrentState;//当前或者被修改的状态
struct State 存在成员displays,State mDrawingState与State mCurrentState一做比较我们就知道displays是否发生了add或者remove。
打开layer.h
struct State { Geometry active; Geometry requested; uint32_t z; uint32_t layerStack; #ifdef USE_HWC2 float alpha; #else uint8_t alpha; #endif uint8_t flags; uint8_t mask; uint8_t reserved[2]; int32_t sequence; // changes when visible regions can change bool modified; Rect crop; Rect requestedCrop; Rect finalCrop; // If set, defers this state update until the Layer identified by handle // receives a frame with the given frameNumber wp<IBinder> handle; uint64_t frameNumber; // the transparentRegion hint is a bit special, it's latched only // when we receive a buffer -- this is because it's "content" // dependent. Region activeTransparentRegion; Region requestedTransparentRegion; android_dataspace dataSpace; }; /*定义了两个成员*/ State mDrawingState;//正在使用或者上次使用的状态 State mCurrentState;//当前或者被修改的状态
比如比较mDrawingState.sequence与mCurrentState.sequence即可知道其属性是否发生变化。
。
前面提到有多个layer,这些layer在哪个显示器上显示,由什么决定呢?在layer::State.displays与surfaceflinger::State中都存在成员layerStack,当他们中的layerStack相同时,这时才能在显示器上显示。
找到之前surfaceflinger.h
DefaultKeyedVector< wp<IBinder>, DisplayDeviceState> displays;
查看DisplayDeviceState定义:
struct DisplayDeviceState { DisplayDeviceState(); DisplayDeviceState(DisplayDevice::DisplayType type, bool isSecure); bool isValid() const { return type >= 0; } bool isMainDisplay() const { return type == DisplayDevice::DISPLAY_PRIMARY; } bool isVirtualDisplay() const { return type >= DisplayDevice::DISPLAY_VIRTUAL; } DisplayDevice::DisplayType type; sp<IGraphicBufferProducer> surface; uint32_t layerStack; Rect viewport; Rect frame; uint8_t orientation; uint32_t width, height; String8 displayName; bool isSecure; };
进入surfaceflinger.cpp找到void SurfaceFlinger::onMessageReceived(int32_t what) 函数:
void SurfaceFlinger::onMessageReceived(int32_t what) { case MessageQueue::INVALIDATE: { /*处理各种事物*/ bool refreshNeeded = handleMessageTransaction(); /*处理各layer的buffer的更换*/ refreshNeeded |= handleMessageInvalidate(); /*发出一个Refresh信号,最终到handleMessageRefresh();函数被调用,我们下小节进行详细的分析*/ signalRefresh();
其上的handleMessageTransaction与handleMessageInvalidate的时序图如下图所示:
先来看看handleMessageTransaction函数:
bool SurfaceFlinger::handleMessageTransaction() { handleTransaction(transactionFlags); /*其内部会遍历每个layer*/ handleTransactionLocked(transactionFlags); const LayerVector& currentLayers(mCurrentState.layersSortedByZ); const sp<Layer>& layer(currentLayers[i]); if (transactionFlags & eTraversalNeeded) /*如果trFlags ==0,则说明目前遍历的这个Layer没有变化*/ uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded); /*如果layer发生了变化,这调用其中的doTransaction*/ const uint32_t flags = layer->doTransaction(0); /*对Layer中的mDrawingState与mCurrentState进行比较看是否发生了变化*/ Layer::State c = getCurrentState(); Layer::State& s(getDrawingState()); /*代表尺寸是否发生了变化等等,如果发生改变都会去设置相应的标志位*/ const bool sizeChanged = (c.requested.w != s.requested.w) ||(c.requested.h != s.requested.h); const bool resizePending = (c.requested.w != c.active.w) ||(c.requested.h != c.active.h); /*该标志位最终返回给调用者const uint32_t flags = layer->doTransaction(0);*/ flags |= eDontUpdateGeometryState; /*表示这块区域脏了,以后需要更新他*/ mVisibleRegionsDirty = true; /*内部实现不在此进行粘贴*/ if (transactionFlags & eDisplayTransactionNeeded) { // find the displays that were remove, 查找显示器是否被移除 // (ie: in drawing state but not in current state),显示器在drawing state但是不在current state //................................... if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) { //Layer的角度发生了变化,如旋转了屏幕,Layer会发生一些变化 // The transform hint might have changed for some layers /*以下为处理surfaceflinger本身的事务*/ if (currentLayers.size() > layers.size()) mVisibleRegionsDirty = true; /*如果移除设备*/ if (mLayersRemoved) { mLayersRemoved = false; mVisibleRegionsDirty = true; /*Layer的层要相等*/ invalidateLayerStack(s.layerStack, visibleReg); if (hw->getLayerStack() == layerStack) { hw->dirtyRegion.orSelf(dirty);
handleMessageTransaction主要的工作是:
1.遍历每个Layer,执行layer->doTransaction(0),根据其返回值设置mVisibleRegionsDirty(可视区域是否脏,脏了后期需要更新)。
2.处理事务:add/reade/change
3.Layer的角度发生了变化,如旋转了屏幕,Layer会发生一些变化
4.处理surfaceflinger本身的事务,如Layer是否被添加或者删除
总的来看,handleMessageTransaction只是简单的设置了一些标志位。并内有做实质上的工作,下面我们分析handleMessageInvalidate
handleMessageInvalidate(使原来的界面数据无效,然后准备新数据),在分析代码的流程时,我们先了解一下buffer有那几种状态:
上面的生产者对应APP,surfaceflinger代表消费者:
APP需要更新数据的时候,需要从所有free状态的buffe中取出一个buffer,free状态的buffe被取出之后,就变成了DEQUEUED状态,构造好数据之后,在把这个数据放入到队列中,变成了QUEUED状态。
surfaceflinger逍遥消费的时候,就从队列中取出一个buffer,该buffer变成AQUEUED状态,然后进行处理,处理完成之后再把他释放。
bool SurfaceFlinger::handleMessageInvalidate() { /*页面切换*/ handlePageFlip(); /*首先手机一下需要更新的layer*/ for (size_t i = 0, count = layers.size(); i<count ; i++) { if (layer->hasQueuedFrame()) layersWithQueuedFrames.push_back(layer.get()); /*对所有需要更新的layer*/ for (size_t i = 0, count = layersWithQueuedFrames.size() ; i<count ; i++) { /*锁定buffer*/ const Region dirty(layer->latchBuffer(visibleRegions)); status_t updateResult = mSurfaceFlingerConsumer->updateTexImage(&r,mFlinger->mPrimaryDispSync, &mAutoRefresh, &queuedBuffer,mLastFrameNumberReceived); // Acquire the next buffer,对应前面提到buffer的AQUEUED状态 err = acquireBufferLocked(&item, computeExpectedPresent(dispSync),maxFrameNumber); // Release the previous buffer. updateAndReleaseLocked /*把bufer绑定到Texture(图形界面处理相关)之中*/ err = bindTextureImageLocked();
通过上面的流程,其主要工作为:
1.Acquire the next buffer
2.Release the previous buffer
3.bindTextureImageLocked
到这里,我们已经合成了新的数据,之后会通过signalRefresh发出一个信号,导致:
void SurfaceFlinger::onMessageReceived(int32_t what) { case MessageQueue::REFRESH: { handleMessageRefresh();
被执行,小小节在为大家进行讲解。