Android SurfaceFlinger 学习之路(九)----SurfaceFlinger事务处理

       荒废三个月,终于更新了~这期间事情巨多,一言难尽~不过对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
6
enum {
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
9
uint32_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
3
void SurfaceFlinger::signalTransaction() {
mEventQueue.invalidate();
}

       这个我们之前分析过,调用MessageQueue的invalidate函数,位于frameworks/native/services/surfaceflinger/MessageQueue.cpp中:

1
2
3
4
5
6
7
8
9
10
#define INVALIDATE_ON_VSYNC 1

void MessageQueue::invalidate() {
// INVALIDATE_ON_VSYNC宏默认为true
#if INVALIDATE_ON_VSYNC
mEvents->requestNextVsync();
#else
mHandler->dispatchInvalidate();
#endif
}

       mEvents就是EventThread类中的Connection类,第五篇分析vsync的时候介绍过,位于frameworks/native/services/surfaceflinger/EventThread.cpp中:

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
void 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
17
void 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
6
void 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
4
struct 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
30
void 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
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
void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
{
//获取当前所有Layer
const LayerVector& currentLayers(mCurrentState.layersSortedByZ);
const size_t count = currentLayers.size();

/*
* Traversal of the children
* (perform the transaction for each of them if needed)
*/

//先判断有没有eTraversalNeeded标志位
if (transactionFlags & eTraversalNeeded) {
//然后遍历所有Layer,让Layer去执行自己的事务
for (size_t i=0 ; i<count ; i++) {
const sp<Layer>& layer(currentLayers[i]);
//获取Layer的transaction flags
uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
if (!trFlags) continue;
// Layer处理自己的事务
const uint32_t flags = layer->doTransaction(0);
//如果Layer的可见区域改变了,则SurfaceFlinger就标注出当前可视区域改变了
if (flags & Layer::eVisibleRegion)
mVisibleRegionsDirty = true;
}
}

......
}

       先获取下一帧状态State所有的Layer,然后判断SF有没有eTraversalNeeded标志位,如果有,则遍历所有的Layer,让Layer去执行自己的事务,如果Layer的可见区域改变了,则SurfaceFlinger就标注出当前可视区域改变了,将mVisibleRegionsDirty 置为true。

Part.2 处理显示屏相关事务

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
{
...Part.1...

/*
* Perform display own transactions if needed
*/

//如果有eDisplayTransactionNeeded标志位
if (transactionFlags & eDisplayTransactionNeeded) {
// here we take advantage of Vector's copy-on-write semantics to
// improve performance by skipping the transaction entirely when
// know that the lists are identical
//当我们知道上一次绘制状态和当前需要去绘制状态的显示屏信息相同时,
//通过完全跳过事务,我们利用Vector的copy-on-write的特点去提高性能

//下一帧State的显示屏信息
const KeyedVector< wp<IBinder>, DisplayDeviceState>& curr(mCurrentState.displays);
//上一次绘制状态State的显示屏信息
const KeyedVector< wp<IBinder>, DisplayDeviceState>& draw(mDrawingState.displays);
//如果下一帧State的显示屏信息和上一次绘制状态State的显示屏信息不同
if (!curr.isIdenticalTo(draw)) {
//表示当前可见区域脏了
mVisibleRegionsDirty = true;
//下一帧需要显示状态
const size_t cc = curr.size();
//上一帧绘制状态
size_t dc = draw.size();

// find the displays that were removed
// (ie: in drawing state but not in current state)
// also handle displays that changed
// (ie: displays that are in both lists)
//对比上一帧绘制状态,找到我们移除的显示屏
for (size_t i=0 ; i<dc ; i++) {
const ssize_t j = curr.indexOfKey(draw.keyAt(i));
//移除显示屏的index
if (j < 0) {
// in drawing state but not in current state
//移除的不是主显示屏
if (!draw[i].isMainDisplay()) {
// Call makeCurrent() on the primary display so we can
// be sure that nothing associated with this display
// is current.
//主显示屏调用makeCurrent函数确保移除的显示屏和它没有联系了
const sp<const DisplayDevice> defaultDisplay(getDefaultDisplayDevice());
defaultDisplay->makeCurrent(mEGLDisplay, mEGLContext);
sp<DisplayDevice> hw(getDisplayDevice(draw.keyAt(i)));
//断开连接
if (hw != NULL)
hw->disconnect(getHwComposer());
if (draw[i].type < DisplayDevice::NUM_BUILTIN_DISPLAY_TYPES)
//并回调热插拔接口onHotplugReceived,用于触发下一次vsync信号相应事件
mEventThread->onHotplugReceived(draw[i].type, false);
mDisplays.removeItem(draw.keyAt(i));
} else {
ALOGW("trying to remove the main display");
}
} else {
//如果这个显示屏没有被移除,看看它是否改变了
// this display is in both lists. see if something changed.
const DisplayDeviceState& state(curr[j]);
const wp<IBinder>& display(curr.keyAt(j));
if (state.surface->asBinder() != draw[i].surface->asBinder()) {
// changing the surface is like destroying and
// recreating the DisplayDevice, so we just remove it
// from the drawing state, so that it get re-added
// below.
//如果显示屏是销毁又重建的,所以没有被移除,
//那么我们要移除并重新添加他
sp<DisplayDevice> hw(getDisplayDevice(display));
if (hw != NULL)
hw->disconnect(getHwComposer());
mDisplays.removeItem(display);
mDrawingState.displays.removeItemsAt(i);
dc--; i--;
// at this point we must loop to the next item
continue;
}

const sp<DisplayDevice> disp(getDisplayDevice(display));
//查看显示屏信息是否改变了,如果变了,
//就要重新将drawing信息赋值为current
if (disp != NULL) {
//z-order排布的layer层改变了
if (state.layerStack != draw[i].layerStack) {
disp->setLayerStack(state.layerStack);
}
//方向、视角、帧结构改变了
if ((state.orientation != draw[i].orientation)
|| (state.viewport != draw[i].viewport)
|| (state.frame != draw[i].frame))
{
disp->setProjection(state.orientation,
state.viewport, state.frame);
}
//大小改变了
if (state.width != draw[i].width || state.height != draw[i].height) {
disp->setDisplaySize(state.width, state.height);
}
}
}
}

// find displays that were added
// (ie: in current state but not in drawing state)
//找到我们新增加的显示屏信息
for (size_t i=0 ; i<cc ; i++) {
if (draw.indexOfKey(curr.keyAt(i)) < 0) {
const DisplayDeviceState& state(curr[i]);
//新增显示屏,需要一些变量属性:
//FrameBufferSurface、BufferQueueProducer、
//BufferQueueConsumer等
sp<DisplaySurface> dispSurface;
sp<IGraphicBufferProducer> producer;
sp<IGraphicBufferProducer> bqProducer;
sp<IGraphicBufferConsumer> bqConsumer;
BufferQueue::createBufferQueue(&bqProducer, &bqConsumer,
new GraphicBufferAlloc());

int32_t hwcDisplayId = -1;
//如果是虚拟设备
if (state.isVirtualDisplay()) {
// Virtual displays without a surface are dormant:
// they have external state (layer stack, projection,
// etc.) but no internal state (i.e. a DisplayDevice).
if (state.surface != NULL) {

hwcDisplayId = allocateHwcDisplayId(state.type);
sp<VirtualDisplaySurface> vds = new VirtualDisplaySurface(
*mHwc, hwcDisplayId, state.surface,
bqProducer, bqConsumer, state.displayName);

dispSurface = vds;
producer = vds;
}
} else {
//如果不是虚拟设备
ALOGE_IF(state.surface!=NULL,
"adding a supported display, but rendering "
"surface is provided (%p), ignoring it",
state.surface.get());
//申请设备id
hwcDisplayId = allocateHwcDisplayId(state.type);
// for supported (by hwc) displays we provide our
// own rendering surface
//创建FrameBufferSurface用于渲染显示
dispSurface = new FramebufferSurface(*mHwc, state.type,
bqConsumer);
producer = bqProducer;
}

const wp<IBinder>& display(curr.keyAt(i));
//设置显示屏相关属性
if (dispSurface != NULL) {
//创建显示屏信息
sp<DisplayDevice> hw = new DisplayDevice(this,
state.type, hwcDisplayId,
mHwc->getFormat(hwcDisplayId), state.isSecure,
display, dispSurface, producer,
mRenderEngine->getEGLConfig());
hw->setLayerStack(state.layerStack);
hw->setProjection(state.orientation,
state.viewport, state.frame);
hw->setDisplayName(state.displayName);
mDisplays.add(display, hw);
if (state.isVirtualDisplay()) {
if (hwcDisplayId >= 0) {
mHwc->setVirtualDisplayProperties(hwcDisplayId,
hw->getWidth(), hw->getHeight(),
hw->getFormat());
}
} else {
mEventThread->onHotplugReceived(state.type, true);
}
}
}
}
}
}

......

}

       代码虽然多,但是逻辑很清晰,做的事情主要如下:
       1)对比上一帧绘制状态,找到我们移除的显示屏。如果找到移除的就要断开连接,并且remove;如果没有移除,则判断是否为destroy-recreate的,如果是,则要移除重新add进来,如果不是,则看看是否状态发生改变,然后设置current状态;
       2)找到我们新增加的显示屏信息。新增显示屏,则要创建DisplayDevice描述对象,构建这个对象又需要FrameBufferSurface用于渲染显示,构建FrameBufferSurface又需要BufferQueue一套对象,因此一一创建。

Part.3 找到Layer所在显示屏并更新旋转方向

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
{
...Part.1...
...Part.2...

if (transactionFlags & (eTraversalNeeded|eDisplayTransactionNeeded)) {
// The transform hint might have changed for some layers
// (either because a display has changed, or because a layer
// as changed).
//
// Walk through all the layers in currentLayers,
// and update their transform hint.
//
// If a layer is visible only on a single display, then that
// display is used to calculate the hint, otherwise we use the
// default display.
//
// NOTE: we do this here, rather than in rebuildLayerStacks() so that
// the hint is set before we acquire a buffer from the surface texture.
//
// NOTE: layer transactions have taken place already, so we use their
// drawing state. However, SurfaceFlinger's own transaction has not
// happened yet, so we must use the current state layer list
// (soon to become the drawing state list).
//
sp<const DisplayDevice> disp;
uint32_t currentlayerStack = 0;
for (size_t i=0; i<count; i++) {
// NOTE: we rely on the fact that layers are sorted by
// layerStack first (so we don't have to traverse the list
// of displays for every layer).
const sp<Layer>& layer(currentLayers[i]);
uint32_t layerStack = layer->getDrawingState().layerStack;

//通过遍历所有的Display来找到Layer所在的显示屏
if (i==0 || currentlayerStack != layerStack) {
currentlayerStack = layerStack;
// figure out if this layerstack is mirrored
// (more than one display) if so, pick the default display,
// if not, pick the only display it's on.
disp.clear();
for (size_t dpy=0 ; dpy<mDisplays.size() ; dpy++) {
sp<const DisplayDevice> hw(mDisplays[dpy]);
if (hw->getLayerStack() == currentlayerStack) {
if (disp == NULL) {
disp = hw;
} else {
disp = NULL;
break;
}
}
}
}
if (disp == NULL) {
// NOTE: TEMPORARY FIX ONLY. Real fix should cause layers to
// redraw after transform hint changes. See bug 8508397.

// could be null when this layer is using a layerStack
// that is not visible on any display. Also can occur at
// screen off/on times.
disp = getDefaultDisplayDevice();
}
//更新Layer的旋转方向,最终会体现在 BufferQueueCore中的mTransformHint变量
layer->updateTransformHint(disp);
}
}

......

}

       Part3做的事情主要是找到Layer所在显示屏并更新旋转方向,也是layer的事务。

Part.4 处理Layer移除逻辑

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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
{
...Part.1...
...Part.2...
...Part.3...

/*
* Perform our own transaction if needed
*/
//如果需要合成的layer小于上一次绘制状态的layer个数,
//则有Layer需要去移除
const LayerVector& layers(mDrawingState.layersSortedByZ);
if (currentLayers.size() > layers.size()) {
// layers have been added
mVisibleRegionsDirty = true;
}

// some layers might have been removed, so
// we need to update the regions they're exposing.
//下面有layer移除的情况
if (mLayersRemoved) {
mLayersRemoved = false;
mVisibleRegionsDirty = true;
const size_t count = layers.size();
for (size_t i=0 ; i<count ; i++) {
const sp<Layer>& layer(layers[i]);
//找到移除的layer
if (currentLayers.indexOf(layer) < 0) {
// this layer is not visible anymore
// TODO: we could traverse the tree from front to back and
// compute the actual visible region
// TODO: we could cache the transformed region
const Layer::State& s(layer->getDrawingState());
//获得移除的Layer的可见区域, 这块可见区域就是dirty的
Region visibleReg = s.transform.transform(
Region(Rect(s.active.w, s.active.h)));
//找到被移除掉的Layer所在的Display, 然后更新Diplay的dirty 区域,也就是对region做或运算
invalidateLayerStack(s.layerStack, visibleReg);
}
}
}
//提交事务
commitTransaction();
//更新显示屏中的光标
updateCursorAsync();
}

       这一段主要处理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
24
void 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
18
struct 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
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
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
uint32_t Layer::doTransaction(uint32_t flags) {// 0
ATRACE_CALL();
//上一次绘制状态
const Layer::State& s(getDrawingState());
//下一帧状态
const Layer::State& c(getCurrentState());
//如果requested的可见区域与旧的可见区域不同了,则size changed
const bool sizeChanged = (c.requested.w != s.requested.w) ||
(c.requested.h != s.requested.h);

if (sizeChanged) {
// the size changed, we need to ask our client to request a new buffer

//省略一些log信息

// record the new size, form this point on, when the client request
// a buffer, it'll get the new size.
// 如果size changed, 把新的 w|h 设置到 BufferQueueCore中的 mDefaultWidth|mDefaultHeight中去
mSurfaceFlingerConsumer->setDefaultBufferSize(
c.requested.w, c.requested.h);
}

//如果新的请求的 w|h 与新的原本要显示的区域不同,表明是 resize了
if (!isFixedSize()) {

const bool resizePending = (c.requested.w != c.active.w) ||
(c.requested.h != c.active.h);

if (resizePending) {
//resize只发生在非固定模式下
// don't let Layer::doTransaction update the drawing state
// if we have a pending resize, unless we are in fixed-size mode.
// the drawing state will be updated only once we receive a buffer
// with the correct size.
//
// in particular, we want to make sure the clip (which is part
// of the geometry state) is latched together with the size but is
// latched immediately when no resizing is involved.
//如果resize了,则打上eDontUpdateGeometryState的flag
flags |= eDontUpdateGeometryState;
}
}

// always set active to requested, unless we're asked not to
// this is used by Layer, which special cases resizes.
if (flags & eDontUpdateGeometryState) {//skip
} else {
//这里是允许更新 可见区域
Layer::State& editCurrentState(getCurrentState());
editCurrentState.active = c.requested;
}
//如果可见区域发生改变,刷新并重新计算可见区域
if (s.active != c.active) {
// invalidate and recompute the visible regions if needed
flags |= Layer::eVisibleRegion;
}

// 只要Layer有属性发生变化了,sequence就会加1,
//这样可以很直观判断是否当前的state和旧的state是否发生变化了
// 但是这样并不能保证sequence相同,但是属性变化的这种情况
if (c.sequence != s.sequence) {
// invalidate and recompute the visible regions if needed
flags |= eVisibleRegion;
this->contentDirty = true;

// we may use linear filtering, if the matrix scales us
const uint8_t type = c.transform.getType();
mNeedsFiltering = (!c.transform.preserveRects() ||
(type >= Transform::SCALE));
}

// Commit the transaction
//提交事务
commitTransaction();
return flags;
}

       这个函数长度还行,看着也不负责,流程如下:
       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
3
void Layer::commitTransaction() {
mDrawingState = mCurrentState;
}

       以上就是SurfaceFlinger和Layer处理事务的逻辑。通俗的奖就是三句话:

  • 新增layer,对比2个state中的layer队列,就可以知道新增的layer。
  • 移除layer,也是比较2个layer队列,就可以找到移除的layer。
  • 提交transaction,主要就是同步2个state。然后currentstate继续跟踪layer变化,如此往复。

       贴个时序图就是下面的逻辑。

transation

小结

       以上就是SurfaceFlinger处理事务的简要流程。回顾开始的内容,我们说过SurfaceControl的openTransation和closeTransaction底层实现也是SurfaceFlinger处理事务的操作,不过这个我们以后在分析。下一篇就应该去讲Layer的合成了,也是个十分复杂的过程。
       断更三个月,期间也是尝尽辛酸苦辣,痛苦和悔恨只能自己默默下咽。只希望以后能够少点折腾,多一些安逸。

meizi

坚持技术分享,您的支持将鼓励我继续创作!