SwallowJoe的博客

Be a real go-getter,
NEVER SETTLE!

0%

SurfaceFlinger(5)--composer

Andorid Q

接着上文,当我们接收到来自App RenderThread线程渲染后的Surface之后,会在SurfaceFlinger收到下一次Vsync时做合成。
前面我们也稍微分析了一下,直接看handleMessageRefresh方法:

图片

从上面trace上也可以看出收到Vsync后,sf首先调用handleMessageInvalidate检查时候需要进行合成。
如果需要就会调用方法handleMessageRefresh去做合成,最后将合成后的图像送入屏幕显示。

这里重点分析handleMessageRefresh.

一. handleMessageRefresh

1.1 SurfaceFlinger:handleMessageRefresh

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
void SurfaceFlinger::handleMessageRefresh() {
ATRACE_CALL();

mRefreshPending = false;

const bool repaintEverything = mRepaintEverything.exchange(false);
// 1.2 合成前再过一遍Layer是否被更新了
// 如果有则触发signalLayerUpdate(),通过EventThread安排一次invalidate sf vsync。
preComposition();

// 1.3 重建layer堆栈, 提取可见的Laye并计算可见区域
// 并将数据更新给对应的Display
rebuildLayerStacks();

// 1.4 hwcomposer的设定,将Layer数据更新给HWC
calculateWorkingSet();

// 遍历所有Display,依次合成处理
for (const auto& [token, display] : mDisplays) {
// 1.5 其实beginFrame和prepareFrame最终都是调用到FrameBufferSurface中,没有做特别的事情
beginFrame(display);
prepareFrame(display);
doDebugFlashRegions(display, repaintEverything);
// 1.6 正式的合成处理,简单来说就是申请GraphicBuffer,向其中填充帧数据
// 最终给到硬件帧缓冲区
doComposition(display, repaintEverything);
}

logLayerStats();

// 通知composer,即HWC
postFrame();

// 回调每个layer的onPostComposition
postComposition();

mHadClientComposition = false;
mHadDeviceComposition = false;
for (const auto& [token, displayDevice] : mDisplays) {
auto display = displayDevice->getCompositionDisplay();
const auto displayId = display->getId();
mHadClientComposition =
mHadClientComposition || getHwComposer().hasClientComposition(displayId);
mHadDeviceComposition =
mHadDeviceComposition || getHwComposer().hasDeviceComposition(displayId);
}

// 根据状况决定是否更新Vsync Offset
mVsyncModulator.onRefreshed(mHadClientComposition);

// 清空mLayersWithQueuedFrames,下一次vsync来到时,会在handlePageFlip中重新添加
mLayersWithQueuedFrames.clear();
}

1.2 SurfaceFlinger:perComposition

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
void SurfaceFlinger::preComposition()
{
ATRACE_CALL();
ALOGV("preComposition");
// 记录刷新时间
mRefreshStartTime = systemTime(SYSTEM_TIME_MONOTONIC);

bool needExtraInvalidate = false;
// 1.2.1 遍历所有layer, 处理处于Drawing状态的layer
// 这里使用了lambda函数
mDrawingState.traverseInZOrder([&](Layer* layer) {
// 1.2.3 判断Layer是否需要更新
if (layer->onPreComposition(mRefreshStartTime)) {
// 如果有layer有frame更新,则标记该值为true,表示需要下一个vsync
// 做合成
needExtraInvalidate = true;
}
});

if (needExtraInvalidate) {
signalLayerUpdate();
}
}

void SurfaceFlinger::State::traverseInZOrder(const LayerVector::Visitor& visitor) const {
// 这里的mDrawingState里面的stateSet为StateSet::Drawing
layersSortedByZ.traverseInZOrder(stateSet, visitor);
}

// SurfaceFlinger.h
State mDrawingState{LayerVector::StateSet::Drawing};

layersSortedByZ中存储的layer都是SurfaceFlinger.addClientLayer过程中添加的。

1.2.1 LayerVector:traverseInZOrder

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
void LayerVector::traverseInZOrder(StateSet stateSet, const Visitor& visitor) const {
for (size_t i = 0; i < size(); i++) {
const auto& layer = (*this)[i];
// 遍历所有layer,拿到合适State的Layer做处理
// 这里是拿所有Drawing状态的Layer
auto& state = (stateSet == StateSet::Current) ? layer->getCurrentState()
: layer->getDrawingState();
// zOrderRelativeOf中的layer是上层调用setRelativeLayer后添加的
// 如果为非null,则表示此Surface的Z顺序相对于此进行解释
// 默认是null的。
if (state.zOrderRelativeOf != nullptr) {
continue;
}
// 处理Layer
layer->traverseInZOrder(stateSet, visitor);
}
}

1.2.2 Layer:traverseInZOrder

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
void Layer::traverseInZOrder(LayerVector::StateSet stateSet, const LayerVector::Visitor& visitor) {

bool skipRelativeZUsers = false;
// 1.2.2.1 按顺序将当前Layer所有z轴相关的layer和子layer添加至列表
const LayerVector list = makeTraversalList(stateSet, &skipRelativeZUsers);

// 也就是说首先遍历Z轴相关的Layer
size_t i = 0;
for (; i < list.size(); i++) {
const auto& relative = list[i];
if (skipRelativeZUsers && relative->usingRelativeZ(stateSet)) {
continue;
}

// 注意Layer的添加都是按照Z轴顺序插入排序的
// 这里的意思就是首先要遍历并对所有z轴小于0的Layer调用onPreComposition方法
// 所以需要理解z轴小于0的意义,什么时候z轴值才会小于0?
// 因为P/Q上Layer组合的数据结构是:树形结构+Z轴排序。现在Z轴的大小一般为 [-2, 2]
// Z轴小的在下面会被覆盖。现在可以理解了,这里为什么碰到z大于0就要退出循环了
if (relative->getZ() >= 0) {
break;
}
relative->traverseInZOrder(stateSet, visitor);
}

// 对本Layer做onPreComposition
visitor(this);

// 最后对所有Z轴不小于0的Layer做onPreComposition
for (; i < list.size(); i++) {
const auto& relative = list[i];

if (skipRelativeZUsers && relative->usingRelativeZ(stateSet)) {
continue;
}
relative->traverseInZOrder(stateSet, visitor);
}
}

visitor这个就是lambda表达式:

1
2
3
4
5
6
7
mDrawingState.traverseInZOrder([&](Layer* layer) {

// 1.2.3 调用onPreComposition
if (layer->onPreComposition(mRefreshStartTime)) {
needExtraInvalidate = true;
}
});

总的来说就是按顺序依次调用layer的onPreComposition方法,标记其mRefreshPending为false。

1.2.2.1 Layer:makeTraversalList

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
// __attribute__((no_sanitize("unsigned-integer-overflow")))的意思
// 是不进行无符号int溢出检测
__attribute__((no_sanitize("unsigned-integer-overflow"))) LayerVector Layer::makeTraversalList(
LayerVector::StateSet stateSet, bool* outSkipRelativeZUsers) {
LOG_ALWAYS_FATAL_IF(stateSet == LayerVector::StateSet::Invalid,
"makeTraversalList received invalid stateSet");
// 这里useDrawing为true
const bool useDrawing = stateSet == LayerVector::StateSet::Drawing;
const LayerVector& children = useDrawing ? mDrawingChildren : mCurrentChildren;
const State& state = useDrawing ? mDrawingState : mCurrentState;
// 假设没有zOrderRelatives,所以直接返回children
if (state.zOrderRelatives.size() == 0) {
*outSkipRelativeZUsers = true;
return children;
}
// 如果存在,则将相关的layer按照Z轴顺序加入stateSet.Drawing中
LayerVector traverse(stateSet);
for (const wp<Layer>& weakRelative : state.zOrderRelatives) {
sp<Layer> strongRelative = weakRelative.promote();
if (strongRelative != nullptr) {
traverse.add(strongRelative);
}
}
// 遍历所有children,将children的相关Layer添加至traverse
for (const sp<Layer>& child : children) {
const State& childState = useDrawing ? child->mDrawingState : child->mCurrentState;
if (childState.zOrderRelativeOf != nullptr) {
continue;
}
traverse.add(child);
}

return traverse;
}

回到1.2.2中。

1.2.3 Layer:BufferLayer::onPreComposition

1
2
3
4
5
6
7
8
bool BufferLayer::onPreComposition(nsecs_t refreshStartTime) {
if (mBufferLatched) {
Mutex::Autolock lock(mFrameEventHistoryMutex);
mFrameEventHistory.addPreComposition(mCurrentFrameNumber, refreshStartTime);
}
mRefreshPending = false;
return hasReadyFrame();
}

记录开始刷新的时间,并返回该Layer是否具有可被合成的条件。

1.2.3.1 Layer:BufferLayer::hasReadyFrame

1
2
3
bool BufferLayer::hasReadyFrame() const {
return hasFrameUpdate() || getSidebandStreamChanged() || getAutoRefresh();
}

1.2.3.2 Layer:BufferLayer:BufferQueueLayer

1
2
3
4
5
6
7
8
9
10
11
12
bool BufferQueueLayer::hasFrameUpdate() const {
// 是否具有绘制完成的frame
return mQueuedFrames > 0;
}

bool BufferQueueLayer::getAutoRefresh() const {
return mAutoRefresh;
}

bool BufferQueueLayer::getSidebandStreamChanged() const {
return mSidebandStreamChanged;
}

1.3 SurfaceFlinger:rebuildLayerStacks

这个方法比较长,慢慢看。

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
void SurfaceFlinger::rebuildLayerStacks() {
ATRACE_CALL();
ALOGV("rebuildLayerStacks");
Mutex::Autolock lock(mDolphinStateLock);

// 对每个display重建其layer列表
// mVisibleRegionsDirty的这个变量在如下条件会被置为true:
// 1. 有layer的增删时
// 2. layer可视化面积发生变化
// 3. display显示设备变化
// 4. set power mode on - 即亮屏时
if (CC_UNLIKELY(mVisibleRegionsDirty)) {
ATRACE_NAME("rebuildLayerStacks VR Dirty");
mVisibleRegionsDirty = false;

// 就是将mGeometryInvalid置为true
// 这个值影响后续是否需要hwc合成
invalidateHwcGeometry();

// 对每一个Display做处理,适配多屏场景
// mDisplays的类型是:std::map<wp<IBinder>, sp<DisplayDevice>>
for (const auto& pair : mDisplays) {
const auto& displayDevice = pair.second;
auto display = displayDevice->getCompositionDisplay();
const auto& displayState = display->getState();
Region opaqueRegion;
Region dirtyRegion;
compositionengine::Output::OutputLayers layersSortedByZ;
Vector<sp<Layer>> deprecated_layersSortedByZ;
Vector<sp<Layer>> layersNeedingFences;
const ui::Transform& tr = displayState.transform;
const Rect bounds = displayState.bounds;
if (displayState.isEnabled) {
// 2.1 计算可视区域
computeVisibleRegions(displayDevice, dirtyRegion, opaqueRegion);

// 顺序遍历Z轴Layer
mDrawingState.traverseInZOrder([&](Layer* layer) {
auto compositionLayer = layer->getCompositionLayer();
if (compositionLayer == nullptr) {
return;
}

const auto displayId = displayDevice->getId();
sp<compositionengine::LayerFE> layerFE = compositionLayer->getLayerFE();
LOG_ALWAYS_FATAL_IF(layerFE.get() == nullptr);

bool needsOutputLayer = false;

// 对属于给定图层堆栈上的layer, 将其可视区域与其所在Display相交
// 相交结果不为空,则说明其在或者其一部分在显示屏幕上
// needsOutputLayer标记为true
if (display->belongsInOutput(layer->getLayerStack(),
layer->getPrimaryDisplayOnly())) {
Region drawRegion(tr.transform(
layer->visibleNonTransparentRegion));
drawRegion.andSelf(bounds);
if (!drawRegion.isEmpty()) {
needsOutputLayer = true;
}
}

// Layer有内容在屏幕上
if (needsOutputLayer) {
layersSortedByZ.emplace_back(
display->getOrCreateOutputLayer(displayId, compositionLayer,
layerFE));
deprecated_layersSortedByZ.add(layer);

auto& outputLayerState = layersSortedByZ.back()->editState();
outputLayerState.visibleRegion =
tr.transform(layer->visibleRegion.intersect(displayState.viewport));
} else if (displayId) {
// 到这个分支里说明Layer之前有内容显示,但现在没有内容显示在屏幕上
// 此时我们需要清理该Layer对应的Fence,销毁HWC Layer
bool hasExistingOutputLayer =
display->getOutputLayerForLayer(compositionLayer.get()) != nullptr;

// mLayersWithQueuedFrames 这个变量还记不,是在handlePageFlip方法中,顺序
// 遍历Z轴Layer时添加进入的。
bool hasQueuedFrames = std::find(mLayersWithQueuedFrames.cbegin(),
mLayersWithQueuedFrames.cend(),
layer) != mLayersWithQueuedFrames.cend();

if (hasExistingOutputLayer && hasQueuedFrames) {
layersNeedingFences.add(layer);
}
}
});
}

// 将数据更新到Display中
display->setOutputLayersOrderedByZ(std::move(layersSortedByZ));

displayDevice->setVisibleLayersSortedByZ(deprecated_layersSortedByZ);
displayDevice->setLayersNeedingFences(layersNeedingFences);

// 未定义的区域。也就是屏幕的大小减去屏幕的非透明区域opaqueRegion余下的部分。
Region undefinedRegion{bounds};
undefinedRegion.subtractSelf(tr.transform(opaqueRegion));

display->editState().undefinedRegion = undefinedRegion;
display->editState().dirtyRegion.orSelf(dirtyRegion);
}
}
}

总的来说,rebuildLayerStacks就是反向遍历Z轴计算各个Layer的可视区域,之后 顺序遍历Z轴Layer将相关信息更新到对应Diplay中。

1.4 SurfaceFlinger::calculateWorkingSet

再看这个方法之前先瞄一眼各个Layer之前的关系:

图片

上图中标红的appId就是在此方法内的latchCompositionState方法中赋值的。

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
void SurfaceFlinger::calculateWorkingSet() {
ATRACE_CALL();
ALOGV(__FUNCTION__);

// 建立HWC中的Layer列表
if (CC_UNLIKELY(mGeometryInvalid)) {
mGeometryInvalid = false;
// 同样需要针对各个Display做处理
for (const auto& [token, displayDevice] : mDisplays) {
auto display = displayDevice->getCompositionDisplay();

uint32_t zOrder = 0;

// 按照Z轴的顺序,依次给可见OutputLayer在HWC中建立映射
for (auto& layer : display->getOutputLayersOrderedByZ()) {
auto& compositionState = layer->editState();
compositionState.forceClientComposition = false;
if (!compositionState.hwc || mDebugDisableHWC || mDebugRegion) {
compositionState.forceClientComposition = true;
}

// Z轴顺序依次递增
compositionState.z = zOrder++;

// 更新与显示无关的合成状态,其实就是将Layer的状态信息放在CompositionState中了。
// 也就是frontEnd(LayerFECompositionState)中
layer->getLayerFE().latchCompositionState(layer->getLayer().editState().frontEnd,
true);

// 重新计算OutputLayer的几何状态
// 比如根据显示屏全局矩阵调整该Layer的DisplayFrame、
// 变换窗口裁剪以匹配缓冲区坐标系等等。
layer->updateCompositionState(true);

// 将Layer更新完毕的几何状态写入HWC
layer->writeStateToHWC(true);
}
}
}

// 设置每帧的数据
for (const auto& [token, displayDevice] : mDisplays) {
auto display = displayDevice->getCompositionDisplay();
const auto displayId = display->getId();
if (!displayId) {
continue;
}
auto* profile = display->getDisplayColorProfile();

if (mDrawingState.colorMatrixChanged) {
display->setColorTransform(mDrawingState.colorMatrix);
}
Dataspace targetDataspace = Dataspace::UNKNOWN;
if (useColorManagement) {
ColorMode colorMode;
RenderIntent renderIntent;
pickColorMode(displayDevice, &colorMode, &targetDataspace, &renderIntent);
display->setColorMode(colorMode, targetDataspace, renderIntent);
}
for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
......
const auto& displayState = display->getState();

// 将Layer的mActiveBuffer设置到HWComposer中
layer->setPerFrameData(displayDevice, displayState.transform, displayState.viewport,
displayDevice->getSupportedPerFrameMetadata(),
isHdrColorMode(displayState.colorMode) ? Dataspace::UNKNOWN
: targetDataspace);
}
}

mDrawingState.colorMatrixChanged = false;

for (const auto& [token, displayDevice] : mDisplays) {
auto display = displayDevice->getCompositionDisplay();
for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
auto& layerState = layer->getCompositionLayer()->editState().frontEnd;
layerState.compositionType = static_cast<Hwc2::IComposerClient::Composition>(
layer->getCompositionType(displayDevice));
}
}
}

这里建立HWC中的Layer列表:

  1. 按照Z轴的顺序,依次给可见OutputLayer在HWC中建立映射也就是将Layer的状态信息放在CompositionState中,并重新计算OutputLayer的几何状态,写入HWC
  2. 将Layer的mActiveBuffer设置到HWComposer中

1.5 SurfaceFlinger::beginFrame

开始合成前的准备。

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::beginFrame(const sp<DisplayDevice>& displayDevice) {
auto display = displayDevice->getCompositionDisplay();
const auto& displayState = display->getState();

// 是否有待更新的区域
bool dirty = !display->getDirtyRegion(false).isEmpty();
// 可见Layer数量是否为0
bool empty = displayDevice->getVisibleLayersSortedByZ().size() == 0;
// 上次合成是否有可见Layer
bool wasEmpty = !displayState.lastCompositionHadVisibleLayers;

// 没有变化时或者有变化但此时没有可见Layer且上次合成时也没有就跳过
bool mustRecompose = dirty && !(empty && wasEmpty);

const char flagPrefix[] = {'-', '+'};
static_cast<void>(flagPrefix);
ALOGV_IF(displayDevice->isVirtual(), "%s: %s composition for %s (%cdirty %cempty %cwasEmpty)",
__FUNCTION__, mustRecompose ? "doing" : "skipping",
displayDevice->getDebugName().c_str(), flagPrefix[dirty], flagPrefix[empty],
flagPrefix[wasEmpty]);

// 这里面其实没有做什么特殊的操作,我们看一下DisplayDevice相关的类
display->getRenderSurface()->beginFrame(mustRecompose);

if (mustRecompose) {
display->editState().lastCompositionHadVisibleLayers = !empty;
}
}

图片

这个DiplayDevice是怎么初始化的呢,后续再看。

1.6 SurfaceFlinger::doComposition

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
void SurfaceFlinger::doComposition(const sp<DisplayDevice>& displayDevice, bool repaintEverything) {
ATRACE_CALL();
ALOGV("doComposition");

auto display = displayDevice->getCompositionDisplay();
const auto& displayState = display->getState();

if (displayState.isEnabled) {
// 将脏区转换为该屏幕的坐标空间
const Region dirtyRegion = display->getDirtyRegion(repaintEverything);

// 1.6.1 请求buffer,做合成操作
doDisplayComposition(displayDevice, dirtyRegion);

display->editState().dirtyRegion.clear();
display->getRenderSurface()->flip();
}

// Fence同步相关处理,暂时忽略
postFramebuffer(displayDevice);
}

1.6.1 SurfaceFlinger::doDisplayComposition

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
void SurfaceFlinger::doDisplayComposition(const sp<DisplayDevice>& displayDevice,
const Region& inDirtyRegion) {
auto display = displayDevice->getCompositionDisplay();

// 仅在以下情况下才需要实际构成显示:
    // 1)由HWC处理,它可能需要此操作以使其虚拟显示状态机保持同步
    // 2)有工作要做(脏区不为空)
if (!displayDevice->getId() && inDirtyRegion.isEmpty()) {
ALOGV("Skipping display composition");
return;
}

ALOGV("doDisplayComposition");
base::unique_fd readyFence;

// 1.6.2 合成Surface
if (!doComposeSurfaces(displayDevice, Region::INVALID_REGION, &readyFence)) return;

// 交换缓冲区,buffer已经被填充了合成所有Layer后的帧数据。
// 将FrameBuffer发送给HWC, 也就是将内容渲染到硬件帧缓冲区中去
display->getRenderSurface()->queueBuffer(std::move(readyFence));
}

1.6.2 SurfaceFlinger::doComposeSurfaces

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
bool SurfaceFlinger::doComposeSurfaces(const sp<DisplayDevice>& displayDevice,
const Region& debugRegion, base::unique_fd* readyFence) {
ATRACE_CALL();
ALOGV("doComposeSurfaces");

auto display = displayDevice->getCompositionDisplay();
const auto& displayState = display->getState();
const auto displayId = display->getId();
auto& renderEngine = getRenderEngine();
const bool supportProtectedContent = renderEngine.supportsProtectedContent();

const Region bounds(displayState.bounds);
const DisplayRenderArea renderArea(displayDevice);
const bool hasClientComposition = getHwComposer().hasClientComposition(displayId);
ATRACE_INT("hasClientComposition", hasClientComposition);

bool applyColorMatrix = false;

renderengine::DisplaySettings clientCompositionDisplay;
std::vector<renderengine::LayerSettings> clientCompositionLayers;
sp<GraphicBuffer> buf;
base::unique_fd fd;

if (hasClientComposition) {
ALOGV("hasClientComposition");

......

// 请求GraphicBuffer, 通过ANativeWindow向GPU申请
buf = display->getRenderSurface()->dequeueBuffer(&fd);

if (buf == nullptr) {
ALOGW("Dequeuing buffer for display [%s] failed, bailing out of "
"client composition for this frame",
displayDevice->getDisplayName().c_str());
return false;
}

// 将DisplayState相关信息赋值给clientCompositionDisplay,以供HWC使用
clientCompositionDisplay.physicalDisplay = displayState.scissor;
clientCompositionDisplay.clip = displayState.scissor;
const ui::Transform& displayTransform = displayState.transform;
clientCompositionDisplay.globalTransform = displayTransform.asMatrix4();
clientCompositionDisplay.orientation = displayState.orientation;

const auto* profile = display->getDisplayColorProfile();
Dataspace outputDataspace = Dataspace::UNKNOWN;
if (profile->hasWideColorGamut()) {
outputDataspace = displayState.dataspace;
}
clientCompositionDisplay.outputDataspace = outputDataspace;
clientCompositionDisplay.maxLuminance =
profile->getHdrCapabilities().getDesiredMaxLuminance();

const bool hasDeviceComposition = getHwComposer().hasDeviceComposition(displayId);
const bool skipClientColorTransform =
getHwComposer()
.hasDisplayCapability(displayId,
HWC2::DisplayCapability::SkipClientColorTransform);

// Compute the global color transform matrix.
applyColorMatrix = !hasDeviceComposition && !skipClientColorTransform;
if (applyColorMatrix) {
clientCompositionDisplay.colorTransform = displayState.colorTransformMat;
}
}

/*
* 现在渲染以帧缓冲区为目标的图层
*/

ALOGV("Rendering client layers");
bool firstLayer = true;
Region clearRegion = Region::INVALID_REGION;

// 遍历所有可见Layer
for (auto& layer : displayDevice->getVisibleLayersSortedByZ()) {
const Region viewportRegion(displayState.viewport);
const Region clip(viewportRegion.intersect(layer->visibleRegion));
ALOGV("Layer: %s", layer->getName().string());
ALOGV(" Composition type: %s", toString(layer->getCompositionType(displayDevice)).c_str());
if (!clip.isEmpty()) {
switch (layer->getCompositionType(displayDevice)) {
......
case Hwc2::IComposerClient::Composition::CLIENT: {
renderengine::LayerSettings layerSettings;
// 根据相关配置设置Layer状态:渲染区域、alpha通道、颜色变换等等
bool prepared =
layer->prepareClientLayer(renderArea, clip, clearRegion,
supportProtectedContent, layerSettings);
if (prepared) {
// 放入clientCompositionLayers中备用
clientCompositionLayers.push_back(layerSettings);
}
break;
}
default:
break;
}
} else {
ALOGV(" Skipping for empty clip");
}
firstLayer = false;
}

// hasClientComposition为true说明使用GPU合成
if (hasClientComposition) {
clientCompositionDisplay.clearRegion = clearRegion;

// 在这里提高GPU频率,因为会进行色彩空间转换,比较耗时。
// 提高了GPU频率,以便GPU合成可以及时完成。
// 之后必须重新设置GPU频率,因为高频率会消耗额外的电池。
const bool expensiveRenderingExpected =
clientCompositionDisplay.outputDataspace == Dataspace::DISPLAY_P3;
if (expensiveRenderingExpected && displayId) {
mPowerAdvisor.setExpensiveRenderingExpected(*displayId, true);
}
.......

// 使用渲染引擎(renderengine/gl/GLESRenderEngine.cpp)合成所有Layer
renderEngine.drawLayers(clientCompositionDisplay, clientCompositionLayers,
buf->getNativeBuffer(), /*useFramebufferCache=*/true, std::move(fd),
readyFence);
} else if (displayId) {
mPowerAdvisor.setExpensiveRenderingExpected(*displayId, false);
}
return true;
}

先请求GraphicBuffer,然后通过GLESRenderEngine合成所有Layer.

二. 计算Layer可视区域

一般来讲,我们手机App Layer如下:
图片

计算可视区域的时候,从Z轴大的开始遍历计算。这样做的好处是,如果计算到某一层Layer时,完全不透明的可视化区域已经占满整个屏幕,那么这之下的Layer可视化区域就可以不用计算了。

在开始阅读代码之前,还是有必要理清楚:

  1. 可见区域(Visible Region)
  2. 透明区域(Transparent Region)
  3. 半透明区域(Translucent Region)
  4. 完全不透明区域(Opaque Region)
  5. 被覆盖区域(Covered Region)

如下图:

图片

如果A1为W2中半透明区域,A2在W1中全透明,W2中不透明,A3为W1中完全不透明区域。
则对于Surface W2而言,可见区域为W2-A1-A3.

2.1 SurfaceFlinger:computeVisibleRegions

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
void SurfaceFlinger::computeVisibleRegions(const sp<const DisplayDevice>& displayDevice,
Region& outDirtyRegion, Region& outOpaqueRegion) {
ATRACE_CALL();
ALOGV("computeVisibleRegions");

auto display = displayDevice->getCompositionDisplay();

Region aboveOpaqueLayers;
Region aboveCoveredLayers;
Region dirty;

outDirtyRegion.clear();

// 先找到“感兴趣的”Layer,也就是这个layer是属于SecureDisplay的
// 暂时没有找到相关的说明,忽略好了
Layer* layerOfInterest = NULL;
bool bIgnoreLayer = false;
mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
if (layer->isSecureDisplay()) {
bIgnoreLayer = true;
if (displayDevice->isPrimary()) {
layerOfInterest = layer;
}
return;
}
});

// 反向遍历Z轴计算可视化区域
mDrawingState.traverseInReverseZOrder([&](Layer* layer) {
// 获取当前绘制中的Surface
const Layer::State& s(layer->getDrawingState());

// 只考虑给定图层堆栈上的layer
if (!display->belongsInOutput(layer->getLayerStack(), layer->getPrimaryDisplayOnly())) {
return;
}

// 忽略SecureDisplay中的layer
if (bIgnoreLayer && layerOfInterest != layer) {
Region visibleNonTransRegion;
visibleNonTransRegion.set(Rect(0, 0));
layer->setVisibleNonTransparentRegion(visibleNonTransRegion);
return;
}

// 完全不透明的Surface区域
Region opaqueRegion;

// 在屏幕上可见且不完全透明的Surface区域。
// 这实际上是该层的足迹减去其上方的不透明区域。
// 半透明Surface覆盖的区域被认为是可见的。
Region visibleRegion;

// 被其上方所有可见区域覆盖的Surface区域(包括半透明区域)。
Region coveredRegion;

// 暗示完全透明的表面区域。 这仅用于告诉图层何时没有可见的非透明区域,可以将其从图层列表中删除。
// 它不会影响此层或它下面的任何层的visibleRegion。
// 如果应用程序不遵守SurfaceView限制(不幸的是,有些不遵守),则提示可能不正确。
Region transparentRegion;

// 处理不可见或者被隐藏的Surface的方式就是将其可视化的区域设置为空
if (CC_LIKELY(layer->isVisible())) {
// 如果该Surface不是完全不透明的,则视为半透明
const bool translucent = !layer->isOpaque(s);
Rect bounds(layer->getScreenBounds());

// 当前Surface的可视区域默认为屏幕大小或者Surface在屏幕中的大小
visibleRegion.set(bounds);
ui::Transform tr = layer->getTransform();

// Region为空则说明没有可视区域
// 注意 Region 是一个矩形(Rect)集合
if (!visibleRegion.isEmpty()) {
// 首先从可见区域移除透明区域
if (translucent) {
// 函数preserveRects的返回值为false
// 说明需要忽略掉当前正在处理的应用程序窗口的透明区域
if (tr.preserveRects()) {
// 标记透明区域,这个透明区域就是transparentRegionHint遍历
// 在 SurfaceFlinger.setClientStateLocked过程中设置的
transparentRegion = tr.transform(layer->getActiveTransparentRegion(s));
} else {
// 转换太复杂,无法进行透明区域优化。
transparentRegion.clear();
}
}

// 计算不透明区域
const int32_t layerOrientation = tr.getOrientation();
if (layer->getAlpha() == 1.0f && !translucent &&
layer->getRoundedCornerState().radius == 0.0f &&
((layerOrientation & ui::Transform::ROT_INVALID) == false)) {

// 当当前正在处理的应用程序窗口是完全不透明,并且旋转方向也是规则时
// 那么它的完全不透明区域opaqueRegion就等于计算所得到的可见区域visibleRegion
opaqueRegion = visibleRegion;
}
}
}

// 该Surface没有可视区域,则清空相关变量,直接返回
if (visibleRegion.isEmpty()) {
layer->clearVisibilityRegions();
return;
}

// 将覆盖区域裁剪到可见区域
// aboveCoveredLayers用来描述当前正在处理的应用程序窗口的所有上层应用程序窗口所组成的可见区域
// 将这个区域与当前正在处理的应用程序窗口的可见区域visibleRegion相交,就可以得到当前正在处理的应用程序窗口的被覆盖区域coveredRegion
// 而将这个区域与当前正在处理的应用程序窗口的可见区域visibleRegion相或一下,就可以得到下一个应用程序窗口的所有上层应用程序窗口所组成的可见区域aboveCoveredLayers。
coveredRegion = aboveCoveredLayers.intersect(visibleRegion);

// aboveOpaqueLayers用来描述当前正在处理的应用程序窗口的所有上层应用程序窗口所组成的完全不透明区域
aboveCoveredLayers.orSelf(visibleRegion);

// 这个区域从当前正在处理的应用程序窗口的可见区域visibleRegion减去后,就可以得到当前正在处理的应用程序窗口的最终可见区域visibleRegion。
visibleRegion.subtractSelf(aboveOpaqueLayers);

// 计算Layer的脏区域,所谓脏区域就是需要重新执行渲染操作的
if (layer->contentDirty) {
// 成员变量contentDirty的值为true,则说明当前正在处理的Layer上一次的状态还未来得及处理
// 即它当前的内容是脏的。在这个状况下,只需要将此次的可见区域与上一次的可见区域合并即可
dirty = visibleRegion;
// as well, as the old visible region
dirty.orSelf(layer->visibleRegion);
layer->contentDirty = false;
} else {

// 当上一次状态已经处理了,也就是显示内容没有更新,则无需重新渲染所有区域。
// 现在只需要处理一下两种情况:
// 1. 之前是被覆盖的区域,但现在不被覆盖了
// 2. 由于窗口大小变化而引发的新增不被覆盖区域

// 针对第一种情况:
// 将当前可见区域visibleRegion与它的上一次被覆盖区域oldCoveredRegion相交
// 就可以得到之前是被覆盖的而现在不被覆盖了的区域,即可以得到第一部分需要重新渲染的区域
// 上一次可见区域和被覆盖区域分别oldVisibleRegion, oldCoveredRegion

// 针对第二种情况:
// 由于将一个应用程序窗口的当前可见区域减去被覆盖区域即为它的当前不被覆盖的区域newExposed
// 同理上一次不被覆盖的区域oldExposed就是上一次可见区域减去上一次被覆盖区域
// 那么将一个应用程序窗口的当前不被覆盖的区域newExposed减去它的上一次不被覆盖的区域oldExposed,就可以得到新增的不被覆盖区域
const Region newExposed = visibleRegion - coveredRegion;
const Region oldVisibleRegion = layer->visibleRegion;
const Region oldCoveredRegion = layer->coveredRegion;
const Region oldExposed = oldVisibleRegion - oldCoveredRegion;

// 将第一部分和第二部分需要重新渲染的区域组合起来,就可以得到当前Layer的脏区域dirty。
dirty = (visibleRegion&oldCoveredRegion) | (newExposed-oldExposed);
}

// 从该脏区域dirty减去上层的完全不透明区域
// 因为后者的渲染不需要当前Layer参与
dirty.subtractSelf(aboveOpaqueLayers);

// 新的脏区域dirty累计到输出参数dirtyRegion中.
outDirtyRegion.orSelf(dirty);

// 更新计算到目前为止所得到的Layer的完全不透明区域
// 这个是方便下一层Layer的计算
aboveOpaqueLayers.orSelf(opaqueRegion);

// 保存当前正在处理的Layer的可见区域和被覆盖区域以及可见非透明区域.
layer->setVisibleRegion(visibleRegion);
layer->setCoveredRegion(coveredRegion);
layer->setVisibleNonTransparentRegion(
visibleRegion.subtract(transparentRegion));
});

// 将前面所有的Layer组成的完全不透明区域aboveOpaqueLayers保存在输出参数opaqueRegion中
outOpaqueRegion = aboveOpaqueLayers;
}

三. 小结

handleMessageRefresh – SF合成所有Layer大概步骤如下:

  1. preComposition
    合成前遍历所有layer, 处理处于Drawing状态的Layer是否被更新了
  2. rebuildLayerStacks
    反向遍历Z轴计算各个Layer的可视区域,之后 顺序遍历Z轴Layer将相关信息更新到对应Diplay中。
  3. calculateWorkingSet
    这里建立HWC中的Layer列表:
  4. 按照Z轴的顺序,依次给可见OutputLayer在HWC中建立映射也就是将Layer的状态信息放在CompositionState中,并重新计算OutputLayer的几何状态,写入HWC
  5. 将Layer的mActiveBuffer设置到HWComposer中
  6. doComposition
    正式的合成处理,使用渲染引擎合成所有layer,然后就是申请GraphicBuffer,向其中填充帧数据, 最终给到硬件帧缓冲区
  7. postComposition && clear mLayersWithQueuedFrames
    回调每个layer的onPostComposition并清空mLayersWithQueuedFrames,下一次vsync来到时,会在handlePageFlip中重新添加

大概流程搞清楚了,接下来细细分析比如GraphicBuffer和Fence机制的工作原理, 等等,HWC好像还没有了解,先看看这个是怎么工作的。

参考资料

  1. [Android Synchronization Fences – An Introduction]http://netaz.blogspot.com/2013/10/android-fences-introduction-in-any.html
  2. [Android 4.0.3 显示系统深入理解]https://www.linuxidc.com/Linux/2012-03/55898p4.htm
  3. [Clang 10 documentation ATTRIBUTES IN CLANG]https://clang.llvm.org/docs/AttributeReference.html
  4. [「Android」SurfaceFlinger分析]https://www.cnblogs.com/1996swg/p/9790209.html
  5. [显示系统:第005课_Vsync机制:第007节_rebuildLayerStacks源码分析]http://www.pianshen.com/article/8541345041/
  6. [Android系统Surface机制的SurfaceFlinger服务渲染应用程序UI的过程分析]https://blog.csdn.net/luoshengyang/article/details/8079456
  7. [Android Region代码分析]https://blog.csdn.net/fuyajun01/article/details/25551717?_t=t

欢迎关注我的其它发布渠道