SurfaceFlinger合成二
onMessageInvalidate过程
/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
void SurfaceFlinger::onMessageInvalidate(nsecs_t expectedVSyncTime) {
......
bool refreshNeeded;//@1
{
ConditionalLockGuard<std::mutex> lock(mTracingLock, mTracingEnabled);
refreshNeeded = handleMessageTransaction();//@2
refreshNeeded |= handleMessageInvalidate();//@3
if (mTracingEnabled) {
mAddCompositionStateToTrace =
mTracing.flagIsSetLocked(SurfaceTracing::TRACE_COMPOSITION);
if (mVisibleRegionsDirty && !mAddCompositionStateToTrace) {
mTracing.notifyLocked("visibleRegionsDirty");
}
}
}
......
refreshNeeded |= mRepaintEverything; //@4
if (refreshNeeded && CC_LIKELY(mBootStage != BootStage::BOOTLOADER)) { //@5
mLastJankDuration = jankDurationToUpload;
// Signal a refresh if a transaction modified the window state,
// a new buffer was latched, or if HWC has requested a full
// repaint
if (mFrameStartTime <= 0) {
// We should only use the time of the first invalidate
// message that signals a refresh as the beginning of the
// frame. Otherwise the real frame time will be
// underestimated.
mFrameStartTime = frameStart;
}
signalRefresh(); //@6
}
}
@1处refreshNeeded这个变量的值最后会用来判定是否执行 @6处,是否需要刷新
@2处handleMessageTransaction 有要处理的transaction则返回true;
@3处handleMessageInvalidate 总体意思就是layer latch到了buffer,则返回true,且结果和之前的refreshNeeded进行或操作。
@4 refreshNeeded 和mRepaintEverything 进行或操作,mRepaintEverything在updateVrFlinger的时候会置为true。
@5处进行判断符合条件后执行到@6处
@6处就会申请再一次的刷新最后执行到SurfaceFlinger.cpp的onMessageRefresh。
主要关心一下 handleMessageTransaction、handleMessageInvalidate,其他内容先忽略。
一、handleMessageTransaction处理
bool SurfaceFlinger::handleMessageTransaction() {
ATRACE_CALL();
uint32_t transactionFlags = peekTransactionFlags();
bool flushedATransaction = flushTransactionQueues();
bool runHandleTransaction =
(transactionFlags && (transactionFlags != eTransactionFlushNeeded)) ||
flushedATransaction ||
mForceTraversal;
if (runHandleTransaction) {
handleTransaction(eTransactionMask);\\@1
} else {
getTransactionFlags(eTransactionFlushNeeded);
}
if (transactionFlushNeeded()) {
setTransactionFlags(eTransactionFlushNeeded);
}
return runHandleTransaction;
}
这个过程就是处理应用传过来的各种Transition。
@1处 handleTransaction处理
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).
State drawingState(mDrawingState);
Mutex::Autolock _l(mStateLock);@1
mDebugInTransaction = systemTime();
// 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.
mVSyncModulator->onTransactionHandled();
transactionFlags = getTransactionFlags(eTransactionMask);@2
handleTransactionLocked(transactionFlags);@3
mDebugInTransaction = 0;
invalidateHwcGeometry();
// here the transaction has been committed
}
@1处 获取mStateLock锁,才能继续执行。
@2处会获取一个transactionFlags, 分为以下几种类别
enum {
eTransactionNeeded = 0x01,
eTraversalNeeded = 0x02,
eDisplayTransactionNeeded = 0x04,
eTransformHintUpdateNeeded = 0x08,
eTransactionFlushNeeded = 0x10,
eTransactionMask = 0x1f,
};
各个Flag处理过程基本上相似,我们会看下eTraversalNeeded的处理。
@3处会执行 handleTransactionLocked(transactionFlags);
void SurfaceFlinger::handleTransactionLocked(uint32_t transactionFlags)
{
......
if ((transactionFlags & eTraversalNeeded) || mForceTraversal) { @1
mForceTraversal = false;
mCurrentState.traverse([&](Layer* layer) {
uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);@2
if (!trFlags) return; @3
const uint32_t flags = layer->doTransaction(0);@4
if (flags & Layer::eVisibleRegion) @5
mVisibleRegionsDirty = true; @6
if (flags & Layer::eInputInfoChanged) {
mInputInfoChanged = true;
}
});
}
@1处满足条件,@2处遍历所有的layer,看这个layer是否需要doTransaction。
@3处如果不需要的话,进入到下一个循环,
@4处执行layer的doTransaction
@5个layer计算可见区域是否发生变化
@6可见区域发生变化
执行getTransactionFlags, trFlags不为0则会继续执行。
显然,不是每个Layer在每次handleTransactionLocked中都需要调用doTransaction,判断标准就是Layer::getTransactionFlags返回的标志中是否指明了eTransactionNeeded
二、handleMessageInvalidate
bool SurfaceFlinger::handleMessageInvalidate() {
ATRACE_CALL();
bool refreshNeeded = handlePageFlip();//@1
if (mVisibleRegionsDirty) {
computeLayerBounds();
}
for (auto& layer : mLayersPendingRefresh) {
Region visibleReg;
visibleReg.set(layer->getScreenBounds());
invalidateLayerStack(layer, visibleReg);
}
mLayersPendingRefresh.clear();
return refreshNeeded;
}
handlePageFlip
/frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp
bool SurfaceFlinger::handlePageFlip()
{
ATRACE_CALL();
......
mDrawingState.traverse([&](Layer* layer) { @1
if (layer->hasReadyFrame()) { @2
frameQueued = true;
if (layer->shouldPresentNow(expectedPresentTime)) { @3
mLayersWithQueuedFrames.push_back(layer); @4
} else {
ATRACE_NAME("!layer->shouldPresentNow()");
layer->useEmptyDamage();
}
} else {
layer->useEmptyDamage();
}
});
// The client can continue submitting buffers for offscreen layers, but they will not
// be shown on screen. Therefore, we need to latch and release buffers of offscreen
// layers to ensure dequeueBuffer doesn't block indefinitely.
for (Layer* offscreenLayer : mOffscreenLayers) { @5
offscreenLayer->traverse(LayerVector::StateSet::Drawing,
[&](Layer* l) { l->latchAndReleaseBuffer(); });
}
if (!mLayersWithQueuedFrames.empty()) { @6
// mStateLock is needed for latchBuffer as LayerRejecter::reject()
// writes to Layer current state. See also b/119481871
Mutex::Autolock lock(mStateLock);
for (auto& layer : mLayersWithQueuedFrames) {
if (layer->latchBuffer(visibleRegions, latchTime, expectedPresentTime)) { @7
mLayersPendingRefresh.push_back(layer);
}
layer->useSurfaceDamage(); @8
if (layer->isBufferLatched()) {
newDataLatched = true;
}
}
}
mVisibleRegionsDirty |= visibleRegions;
// If we will need to wake up at some time in the future to deal with a
// queued frame that shouldn't be displayed during this vsync period, wake
// up during the next vsync period to check again.
if (frameQueued && (mLayersWithQueuedFrames.empty() || !newDataLatched)) {
signalLayerUpdate();
}
// enter boot animation on first buffer latch
if (CC_UNLIKELY(mBootStage == BootStage::BOOTLOADER && newDataLatched)) {
ALOGI("Enter boot animation");
mBootStage = BootStage::BOOTANIMATION;
}
mDrawingState.traverse([&](Layer* layer) { layer->updateCloneBufferInfo(); }); @9
// Only continue with the refresh if there is actually new work to do
return !mLayersWithQueuedFrames.empty() && newDataLatched;
}
@1处 需要进行合成的数据保存在mDrawingState中。遍历获取到的Layer列表,并且把layer作为参数传给语句块。
@2处 判断layer是不是有Queued的Frame,
@3处 如果shouldPresentNow返回true,@4该Layer标记为mLayersWithQueuedFrames;否则,Layer使用空的DamageRegion。
@5处遍历mOffscreenLayers(mOffscreenLayers是一组没有父层的图层,不在屏幕上面绘制,只被主线程访问)。主要是调用layer的latchAndReleaseBuffer方法,作用注释描述很明确。
@6 mLayersWithQueuedFrames不为空,说明存有适合的layer,接下来获取mStateLock锁,进行遍历mLayersWithQueuedFrames。
@7处 latchBuffer,获取buffer成功后,把此layer 存入mLayersPendingRefresh中,注意传入了一个visibleRegions参数。
@8处 Layer使用空的DamageRegion。DamageRegion后面研究。
@9处 保存此layer的BufferInfo,下一次BufferLayer latchBuffer时候会比较上次buffer的状态,那个时候会用到。
接着看一下handlePageFlip中重要子方法:shouldPresentNow 和latchBuffer
1、shouldPresentNow
/frameworks/native/services/surfaceflinger/BufferQueueLayer.cpp
bool BufferQueueLayer::shouldPresentNow(nsecs_t expectedPresentTime) const {
if (getSidebandStreamChanged() || getAutoRefresh()) {
return true;
}
if (!hasFrameUpdate()) {
return false;
}
Mutex::Autolock lock(mQueueItemLock);
const int64_t addedTime = mQueueItems[0].mTimestamp; //@1
// Ignore timestamps more than a second in the future
const bool isPlausible = addedTime < (expectedPresentTime + s2ns(1)); @2
ALOGW_IF(!isPlausible,
"[%s] Timestamp %" PRId64 " seems implausible "
"relative to expectedPresent %" PRId64,
getDebugName(), addedTime, expectedPresentTime);
if (!isPlausible) {
mFlinger->mTimeStats->incrementBadDesiredPresent(getSequence());
}
const bool isDue = addedTime < expectedPresentTime; @3
return isDue || !isPlausible;
}
可以看到影响返回值的就是isDue 和 isPlausible两个值
@1处获取Buffer的时间戳,
@2处判断 Buffer的时间戳 和 期望显示时间再加1秒 之间的关系。注释很明确,忽略超过一秒的时间戳。
@3处 如果Buffer的时间戳小于期望的时间,则为true。