Android下SF合成流程重学习之onMessageInvalidate
引言
虽然看了很多关于Android Graphics图形栈的文章和博客,但是都没有形成自己的知识点。每次学习了,仅仅是学习了而已,没有形成自己的知识体系,这次趁着有时间,这次必须把这个事情干透彻了!
本篇引用的代码,主要是Android R的。
并且Android下Graphics图形栈牵涉的点,太多了,这篇博客我们着重分析SF合成流程重学习之onMessageInvalidate的处理流程!
SurfaceFlinger layer之间的对应关系
先用一张图来看下各个部分之间layer的对应关系。接下来会根据这个图来解析是如何进行转换的,如下:

一. SF处理事务和处理Buffer
在SF的onMessageInvalidate主要是用来,处理事物和处理相关Buffer的,我们在下面的博客中详细分析!

1.1 onMessageInvalidate
文件: frameworks/native/services/surfaceflinger/Surfaceflinger.cpp
void SurfaceFlinger::onMessageInvalidate(nsecs_t expectedVSyncTime) {
ATRACE_CALL();
const nsecs_t frameStart = systemTime();
// expectedVSyncTime 是vsync回调带过来的时间戳,通过nextAnticipatedVSyncTimeFrom 计算得到
if (expectedVSyncTime >= frameStart) {
mExpectedPresentTime = expectedVSyncTime;
} else {
mExpectedPresentTime = mScheduler->getDispSyncExpectedPresentTime(frameStart);
}
// 存储上一帧的expectedVSyncTime
const nsecs_t lastScheduledPresentTime = mScheduledPresentTime;
mScheduledPresentTime = expectedVSyncTime;
...
// 根据上一帧的present fence判断当前这一帧是否pending
const TracedOrdinal<bool> framePending = {
"PrevFramePending",
previousFramePending(graceTimeForPresentFenceMs)};
// 若framePending 或者 上一帧present fence释放的时间 > 上一帧vsync计算的时间戳 + vsync周期的一半
// 则当前帧要丢掉
DisplayStatInfo stats;
mScheduler->getDisplayStatInfo(&stats);
const nsecs_t frameMissedSlop = stats.vsyncPeriod / 2;
const nsecs_t previousPresentTime = previousFramePresentTime();
const TracedOrdinal<bool> frameMissed = {
"PrevFrameMissed",
framePending ||
(previousPresentTime >= 0 &&
(lastScheduledPresentTime <
previousPresentTime - frameMissedSlop))};
// 根据合成类型判断丢帧的类型
const TracedOrdinal<bool> hwcFrameMissed = {
"PrevHwcFrameMissed",
mHadDeviceComposition && frameMissed};
const TracedOrdinal<bool> gpuFrameMissed = {
"PrevGpuFrameMissed",
mHadClientComposition && frameMissed};
...
// 这部分涉及帧率切换,先是通过performSetActiveConfig 将新的帧率给到hwc,然后下一帧再更新sf这边的状态
if (mSetActiveConfigPending) {
if (framePending) {
mEventQueue->invalidate();
return;
}
// We received the present fence from the HWC, so we assume it successfully updated
// the config, hence we update SF.
mSetActiveConfigPending = false;
ON_MAIN_THREAD(setActiveConfigInternal());
}
}
// mPropagateBackpressure 可以通过adb shell setprop debug.sf.disable_backpressure x 来控制,表示系统是否允许丢帧
// 若允许丢帧则skip这次刷帧
if (framePending && mPropagateBackpressure) {
if ((hwcFrameMissed && !gpuFrameMissed) || mPropagateBackpressureClientComposition) {
signalLayerUpdate();
return;
}
}
....
bool refreshNeeded;
{
ConditionalLockGuard<std::mutex> lock(mTracingLock, mTracingEnabled);
// 主要的逻辑在这两个函数,简单理解为处理layer或者display的事务和layer的buffer
refreshNeeded = handleMessageTransaction();
refreshNeeded |= handleMessageInvalidate();
...
}
// 帧率切换,SurfaceFlinger主线程执行
ON_MAIN_THREAD(performSetActiveConfig());
...
// 若layer的事务有变化或者有新的buffer,则触发refresh
signalRefresh();
}
上述onMessageInvalidate概括来说,其主要处理的事情如下:
- 判断当前帧是否丢掉
- handleMessageTr

本文详细解析了AndroidSurfaceFlinger中onMessageInvalidate的处理流程,涉及事务管理、Buffer获取、帧率切换以及图形合成的各个环节,重点讲解了事务处理、layer和display状态的变化、Buffer的latching过程以及与GPU合成的关系。
最低0.47元/天 解锁文章
1604





