上小节我们讲解了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 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 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 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 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(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
handleMessageInvalidatehandleMessageInvalidate(使原来的界面数据无效,然后准备新数据),在分析代码的流程时,我们先了解一下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(); ihasQueuedFrame())
layersWithQueuedFrames.push_back(layer.get());
/*对所有需要更新的layer*/
for (size_t i = 0, count = layersWithQueuedFrames.size() ; ilatchBuffer(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();
被执行,小小节在为大家进行讲解。