荒废三个月,终于更新了~这期间事情巨多,一言难尽~不过对SurfaceFlinger的研究不能停啊,还是要一点一点钻研。
这次继续顺着上次末尾,分析一下SurfaceFlinger事务处理。
事务概述
Transaction是“事务”的意思。在我脑海中,关于事务的知识来自于数据库。在数据库操作中,事务意味着一次可以提交多个SQL语句,然后一个commit就可让它们集中执行,而且数据库中的事务还可以回滚,即恢复到事务提交前的状态。
SurfaceFlinger为什么需要事务呢?从上面对数据库事务的描述来看,是不是意味着一次执行多个请求呢?我们从数据库事务概念大致可以看出一点端倪, 它的其中一个很重要的信息就是说”将一组相关操作组合成一个单元去处理“。这个思路也运用在了SurfaceFlinger中。我们先举个没有事务的例子,再一个Vsync周期里,Layer的属性改变了很多,比如有大小、位置、透明度、z-order都改变了,并且还不是一个Layer变了,如果每个都改变了,那么如果我们没改变一个属性就去触发相关操作,让SurfaceFlinger去重新合成,这样他岂不是累死了?所以正确的做法是,每当Layer属性改变,先记下来,将所有改变何如一条事务当中,最后在合成前handleTransaction 一次处理掉,这样就省事多了。
事务标志
我们之前分析java层Surface创建的时候,使用过SurfaceControl这个类,它里面有两个方法,openTransaction和closeTransaction,这就是对Surface操作开事务的方法。不过我们这里先不分析这个,我们先看看C++层这一侧的事务。
事务的标志有以下几种,位于frameworks/native/services/surfaceflinger/SurfaceFlinger.h中:1
2
3
4
5
6enum {
eTransactionNeeded = 0x01,//Layer的属性发生变化了,表示需要处理事务
eTraversalNeeded = 0x02,//遍历的是SurfaceFlinger中所有的Layer
eDisplayTransactionNeeded = 0x04,//这个是显示器相关的事务,如显示器hotplug
eTransactionMask = 0x07//掩码
};
事务标志也可以是多种组合,也很好理解,十六进制位,每种标志占一位,掩码占全位。
每种的意义在注释写的比较清楚。
设置和处理flags
mTransactionFlags是surface flinger中的一个成员,注意在layer中也存在一个同名的mTransactionFlags,通过下面的函数设置该flag,位于frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp中:1
2
3
4
5
6
7
8
9uint32_t SurfaceFlinger::setTransactionFlags(uint32_t flags) {
//或返回的是mTransactionFlags旧的值
uint32_t old = android_atomic_or(flags, &mTransactionFlags);
//如果旧值和flags没有bit是相同的?
if ((old & flags)==0) { // wake the server up,触发一次invalidate
signalTransaction();
}
return old;
}
在surfaceflinger中,
- createLayer(),removeLayer(),setClientStateLocked都会去设置事务flag为eTransactionNeeded;
- setClientStateLocked()会去设置eTraversalNeeded;
- createDisplay(),destroyDisplay(),onHotplugReceived(),setDisplayStateLocked()会去设置eDisplayTransactionNeeded。
然后就是调用SurfaceFlinger的signalTransaction,我们看看它:1
2
3void SurfaceFlinger::signalTransaction() {
mEventQueue.invalidate();
}
这个我们之前分析过,调用MessageQueue的invalidate函数,位于frameworks/native/services/surfaceflinger/MessageQueue.cpp中:1
2
3
4
5
6
7
8
9
10
void MessageQueue::invalidate() {
// INVALIDATE_ON_VSYNC宏默认为true
mEvents->requestNextVsync();
mHandler->dispatchInvalidate();
}
mEvents就是EventThread类中的Connection类,第五篇分析vsync的时候介绍过,位于frameworks/native/services/surfaceflinger/EventThread.cpp中:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15void EventThread::Connection::requestNextVsync() {
mEventThread->requestNextVsync(this);
}
// 关于Connection中的count,当为0时为一次性的事件,即触发一次sync信号
// count >= 1 : continuous event. count is the vsync rate
// count == 0 : one-shot event that has not fired
// count ==-1 : one-shot event that fired this round / disabled
void EventThread::requestNextVsync(
const sp<EventThread::Connection>& connection) {
Mutex::Autolock _l(mLock);
if (connection->count < 0) {
connection->count = 0;
mCondition.broadcast();
}
}
这里将mCondition wait的地方释放,在Android SurfaceFlinger 学习之路(五)—-VSync 工作原理我们分析过,各种事务都会去触发一次vsync,前面文章分析过,在每次vsync信号到来时,处理这个vsync事件会去调用SurfaceFlinger的onMessageReceived函数,我们看看它的实现:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17void SurfaceFlinger::onMessageReceived(int32_t what) {
ATRACE_CALL();
switch (what) {
case MessageQueue::TRANSACTION:
handleMessageTransaction();
break;
//我们走的是这个case
case MessageQueue::INVALIDATE:
handleMessageTransaction();
handleMessageInvalidate();
signalRefresh();
break;
case MessageQueue::REFRESH:
handleMessageRefresh();
break;
}
}
我们走的是第二个case。这里先分析这个case第一个函数调用,后面的部分是SurfaceFlinger合成步骤,我们后续在分析。进而调用handleMessageTransaction,根据mTransactionFlags中设置的bit值做相应的处理。1
2
3
4
5
6void SurfaceFlinger::handleMessageTransaction() {
uint32_t transactionFlags = peekTransactionFlags(eTransactionMask);
if (transactionFlags) {
handleTransaction(transactionFlags);
}
}
这样就回到我们今天的主题了,对事务的处理,我们接下来会逐步分析。
SurfaceFlinger处理事务
我们首先要看SurfaceFlinger几个重要的变量:
- State mCurrentState
SurfaceFlinger下一帧的状态,即表示即将绘制的下一帧的状态。 - State mDrawingState
当前正在绘制的状态,即表示上一帧处理完事务后更新出来的状态,是最终的状态。 - mVisibleRegionsDirty
表示当前可见区域是否脏了,如果脏了的话,比如(layer added/removed, Display added/remove相关)在最后合成的时候会对每个屏幕重建layer stack, 但是一般都为false。
这两个状态是SurfaceFlinger中的State,在Layer当中也有一个State,我们后面会讲到,我们看看这个State的定义,位于frameworks/native/services/surfaceflinger/SurfaceFlinger.h:1
2
3
4struct State {
LayerVector layersSortedByZ;//SurfaceFlinger中所有的按照Z order排序的 Layer
DefaultKeyedVector< wp<IBinder>, DisplayDeviceState> displays;//外接的显示屏
};
前者是上一次“drawing”时的状态,而后者则是当前状态。这样我们只要通过对比这两个State,就知道系统中发生了什么变化,然后采取相应的措施。它们内部都包含了一个LayerVector类型的layersSortedByZ成员变量,从变量名可以看出是所有layers按照Z-order顺序排列的Vector。
所以我们可以从mCurrentState.layersSortedByZ来访问到所有layer,然后对有需要执行transaction的图层再调用内部的doTransaction()。显然,并不是每个layer在每次handleTransactionLocked中都需要调用doTransaction,判断的标准就是Layer::getTransactionFlags返回的标志中是否要求了eTransactionNeeded。大家要注意SurfaceFlinger和各Layer都有一个mTransactionFlags变量,不过含义不同。另外,Layer中也同样有mCurrentState和mDrawingState,虽然它们也分别表示上一次和当前的状态,但所属的State结构体是完全不同的。
handleTransaction
我们顺着上一节末位,处理vsync信号之后要去合成,之前先处理事务。因此走到了SurfaceFlinger的handleTransaction函数:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30void SurfaceFlinger::handleTransaction(uint32_t transactionFlags)
{
ATRACE_CALL();
// here we keep a copy of the drawing state (that is the state that's
// going to be overwritten by handleTransactionLocked()) outside of
// mStateLock so that the side-effects of the State assignment
// don't happen with mStateLock held (which can cause deadlocks).
//保存mDrawingState,但是却没有使用,are you kidding me?
State drawingState(mDrawingState);
Mutex::Autolock _l(mStateLock);
const nsecs_t now = systemTime();
mDebugInTransaction = now;
// Here we're guaranteed that some transaction flags are set
// so we can call handleTransactionLocked() unconditionally.
// We call getTransactionFlags(), which will also clear the flags,
// with mStateLock held to guarantee that mCurrentState won't change
// until the transaction is committed.
////获得SurfaceFlinger中的Transaction标志位
transactionFlags = getTransactionFlags(eTransactionMask);
//在这里处理Transaction
handleTransactionLocked(transactionFlags);
mLastTransactionTime = systemTime() - now;
mDebugInTransaction = 0;
invalidateHwcGeometry();
// here the transaction has been committed
}
先获取了SurfaceFlinger的transactionFlags ,然后调用handleTransactionLocked处理这些事务。这个函数很长,我们需要分步查看。
Part.1 遍历所有的Layer, 让Layer去执行自己的事务
1 | void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) |
先获取下一帧状态State所有的Layer,然后判断SF有没有eTraversalNeeded标志位,如果有,则遍历所有的Layer,让Layer去执行自己的事务,如果Layer的可见区域改变了,则SurfaceFlinger就标注出当前可视区域改变了,将mVisibleRegionsDirty 置为true。
Part.2 处理显示屏相关事务
1 | void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) |
代码虽然多,但是逻辑很清晰,做的事情主要如下:
1)对比上一帧绘制状态,找到我们移除的显示屏。如果找到移除的就要断开连接,并且remove;如果没有移除,则判断是否为destroy-recreate的,如果是,则要移除重新add进来,如果不是,则看看是否状态发生改变,然后设置current状态;
2)找到我们新增加的显示屏信息。新增显示屏,则要创建DisplayDevice描述对象,构建这个对象又需要FrameBufferSurface用于渲染显示,构建FrameBufferSurface又需要BufferQueue一套对象,因此一一创建。
Part.3 找到Layer所在显示屏并更新旋转方向
1 | void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) |
Part3做的事情主要是找到Layer所在显示屏并更新旋转方向,也是layer的事务。
Part.4 处理Layer移除逻辑
1 | void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags) |
这一段主要处理Layer的移除逻辑。如果需要合成的layer小于上一次绘制状态的layer个数,则有layer需要去移除。找到需要移除的Layer,获得可见区域,然后更新Display的dirty区域,也就是对region做或运算。
提交事务
剩下就是提交事务和更新显示屏的光标了,我们看看提交事务。1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24void SurfaceFlinger::commitTransaction()
{
//mLayersPendingRemoval是保存的是pending 着需要移除的Layer.
//比如APP调用destroySurface
if (!mLayersPendingRemoval.isEmpty()) {
// Notify removed layers now that they can't be drawn from
for (size_t i = 0; i < mLayersPendingRemoval.size(); i++) {
mLayersPendingRemoval[i]->onRemoved();
}
mLayersPendingRemoval.clear();
}
// If this transaction is part of a window animation then the next frame
// we composite should be considered an animation as well.
mAnimCompositionPending = mAnimTransactionPending;
//更新 mDrawingState
mDrawingState = mCurrentState;
mTransactionPending = false;
mAnimTransactionPending = false;
//释放mTransactionCV, 如果SurfaceFlinger正在处理事务,
//而这时如果调用setTransactionState就可能会一直等着mTransactionCV,
//因为setTransactionState可能会改变SurfaceFlinger的Transaction标志位,导致前后不一致
mTransactionCV.broadcast();
}
这就是提交事务的操作,先处理pendingRemove的layer,回调onRemove接口;然后更新mDrawingState状态;最后释放mTransactionCV条件锁。
以上就是SurfaceFlinger处理事务的流程,接下来我们分析Layer怎么处理事务。
Layer处理事务
在handleTransactionLocked函数中的Part1中,我们我们简要分析了layer处理自己事务的流程,接下来我们详细分析这个过程。
Layer的重要变量
我们在Android SurfaceFlinger 学习之路(六)—-SurfaceFlinger创建Surface中提到过,每一个Layer都有很多属性。
Each Layer has:
- Z-order
- Alpha value from 0 to 255
- visibleRegion
- crop region
- transformation: rotate 0, 90, 180, 270: flip H, V: scale
当多个Layer进行合成的时候,并不是整个Layer的空间都会被完全显示,根据这个Layer最终的显示效果,一个Layer可以被划分成很多的Region, Android SurfaceFlinger 定义了以下一些Region类型:
- TransparantRegion: 完全透明的区域,在它之下的区域将被显示出来。
- OpaqueRegion: 完全不透明的区域,是否显示取决于它上面是否有遮挡或是否透明。
- VisibleRegion: 可见区域,包括完全不透明无遮挡区域或半透明区域。
- visibleRegion = Region - above OpaqueRegion.
- CoveredRegion: 被遮挡区域,在它之上,有不透明或半透明区域。
- DirtyRegion: 可见部分改变区域,包括新的被遮挡区域,和新的露出区域。
我们这里先看看以下几个重要属性:
State mCurrentState;
表示Layer下一帧的属性状态,当某个属性变化时,直接操作该变量State mDrawingState;
表示当前正在绘制的帧的属性状态。Layer处理完事务后,最终的用于绘制的状态
我们再次看看Layer::State结构体的定义:1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18struct State {
Geometry active;//当前Layer的可见区域
Geometry requested;//请求的Layer的可见区域, 在Layer做doTransaction时会将 requested赋值给active. setSize/setMatrix/setPosition
uint32_t z;//z-order
uint32_t layerStack;//layerStack指明当前Layer属于哪个Display,Display的layer stack可以用 hw->getLayerStack获得
uint8_t alpha;
uint8_t flags;
uint8_t reserved[2];
////当Layer的属性变化时, sequence就会加1
int32_t sequence; // changes when visible regions can change
//更新region的传输矩阵
Transform transform;
// 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;
};
doTransaction
我们继续分析Layer处理事务的逻辑,看看Layer的doTransaction函数。
1 | uint32_t Layer::doTransaction(uint32_t flags) {// 0 |
这个函数长度还行,看着也不负责,流程如下:
1)如果requested的可见区域与旧的可见区域不同了,则size changed。如果size changed, 把新的 w|h 设置到 BufferQueueCore中的 mDefaultWidth|mDefaultHeight中去。
这里mSurfaceFlingerConsumer->setDefaultBufferSize去设置变化后的大小,我们在Android SurfaceFlinger 学习之路(六)—-SurfaceFlinger创建Surface分析过mSurfaceFlingerConsumer的创建,位于Layer的onFirstRef函数中。
2)如果可见区域发生改变,刷新并重新计算可见区域。
3)sequence发生改变,重新获取大小。Sequence是个什么东西?当Layer的position,Zorder,alpha,matrix,transparent region,flags,crops.等发生变化的时候,sequence就会自增。也就是,当这些属性发生变化是,页面在Vsync信号触发的时候,根据sequence来判断是否需要属性页面。
4)提交事务。主要就是同步2个state,将current state赋值给drawing state。看看代码如下:1
2
3void Layer::commitTransaction() {
mDrawingState = mCurrentState;
}
以上就是SurfaceFlinger和Layer处理事务的逻辑。通俗的奖就是三句话:
- 新增layer,对比2个state中的layer队列,就可以知道新增的layer。
- 移除layer,也是比较2个layer队列,就可以找到移除的layer。
- 提交transaction,主要就是同步2个state。然后currentstate继续跟踪layer变化,如此往复。
贴个时序图就是下面的逻辑。
小结
以上就是SurfaceFlinger处理事务的简要流程。回顾开始的内容,我们说过SurfaceControl的openTransation和closeTransaction底层实现也是SurfaceFlinger处理事务的操作,不过这个我们以后在分析。下一篇就应该去讲Layer的合成了,也是个十分复杂的过程。
断更三个月,期间也是尝尽辛酸苦辣,痛苦和悔恨只能自己默默下咽。只希望以后能够少点折腾,多一些安逸。