参考资料
- Android Synchronization Fences – An Introduction
- Android 4.0.3 显示系统深入理解
- Clang 10 documentation ATTRIBUTES IN CLANG
- 「Android」SurfaceFlinger分析
- 显示系统:第005课_Vsync机制:第007节_rebuildLayerStacks源码分析
- Android系统Surface机制的SurfaceFlinger服务渲染应用程序UI的过程分析
- Android Region代码分析
Andorid Q
接着上文,当我们接收到来自App RenderThread线程渲染后的Surface之后,会在SurfaceFlinger收到下一次Vsync时做合成。
前面我们也稍微分析了一下,直接看handleMessageRefresh方法:
![[外链图片转存失败,源站可能有防盗链机制,建议将图片保存下来直接上传(img-LAd0wxbT-1592309583800)(picture/5_1_sf_onVsync.png)]](https://i-blog.csdnimg.cn/blog_migrate/fefb38ec97867f6e589fad9c7f1a7f9f.png)
从上面trace上也可以看出收到Vsync后,sf首先调用handleMessageInvalidate检查时候需要进行合成。
如果需要就会调用方法handleMessageRefresh去做合成,最后将合成后的图像送入屏幕显示。
这里重点分析handleMessageRefresh.
一. handleMessageRefresh
1.1 SurfaceFlinger:handleMessageRefresh
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
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
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
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表达式:
mDrawingState.traverseInZOrder([&](Layer* layer) {
// 1.2.3 调用onPreComposition
if (layer->onPreComposition(mRefreshStartTime)) {
needExtraInvalidate = true;
}
});
总的来说就是按顺序依次调用layer的onPreComposition方法,标记其mRefreshPending为false。
1.2.2.1 Layer:makeTraversalList
// __attribute__((no_sanitize("unsigned-integer-overflow")))的意思
// 是不进行无符号int溢出检测
__attribute__((no_sanitize("unsigned-integer-o
本文详细探讨了Android系统中SurfaceFlinger在接收到Vsync信号后的处理过程,包括handleMessageRefresh方法的执行、Layer的遍历、可视区域的计算以及合成阶段的关键步骤。通过对handleMessageRefresh、rebuildLayerStacks、calculateWorkingSet和doComposition等方法的分析,揭示了Android UI的刷新动力机制。
最低0.47元/天 解锁文章
689

被折叠的 条评论
为什么被折叠?



