该函数是 VSYNC 触发的。它调用 BufferLayer::latchBuffer() 尝试锁定一个 buffer,如果锁定成功则计算脏区域,返回值表示是否需要刷新。
/* handlePageFlip - latch a new buffer if available and compute the dirty
* region. Returns whether a new buffer has been latched, i.e., whether it
* is necessary to perform a refresh during this vsync.
*/
bool SurfaceFlinger::handlePageFlip() {
ATRACE_CALL();
ALOGV("handlePageFlip");
nsecs_t latchTime = systemTime();
bool visibleRegions = false;
bool frameQueued = false;
bool newDataLatched = false;
const nsecs_t expectedPresentTime = mExpectedPresentTime.load();
latchTime
,声明一些变量。 // Store the set of layers that need updates. This set must not change as
// buffers are being latched, as this could result in a deadlock.
// Example: Two producers share the same command stream and:
// 1.) Layer 0 is latched
// 2.) Layer 0 gets a new frame
// 2.) Layer 1 gets a new frame
// 3.) Layer 1 is latched.
// Display is now waiting on Layer 1's frame, which is behind layer 0's
// second frame. But layer 0's second frame could be waiting on display.
mDrawingState.traverse([&](Layer* layer) {
uint32_t trFlags = layer->getTransactionFlags(eTransactionNeeded);
if (trFlags || mForceTransactionDisplayChange) {
const uint32_t flags = layer->doTransaction(0);
if (flags & Layer::eVisibleRegion)
mVisibleRegionsDirty = true;
}
if (layer->hasReadyFrame()) {
frameQueued = true;
if (layer->shouldPresentNow(expectedPresentTime)) {
mLayersWithQueuedFrames.emplace(layer);
} else {
ATRACE_NAME("!layer->shouldPresentNow()");
layer->useEmptyDamage();
}
} else {
layer->useEmptyDamage();
}
});
mForceTransactionDisplayChange = false;
mDrawingState
中的 layer。eTransactionNeeded
或 mForceTransactionDisplayChange
是 true,则调用 Layer::doTransaction()
,它会重新计算 transform。如果 transform 有变更,则设置 eVisibleRegion
。
eVisibleRegion
,则设置 mVisibleRegionsDirty
为 true。hasReadyFrame()
返回 true,再调用 shouldPresentNow()
判断是否现在显示。
shouldPresentNow()
实现直接返回 true。否则,调用 useEmptyDamage()
清空 surfaceDamageRegion
。shouldPresentNow()
返回 true,把 layer 加入到 mLayersWithQueuedFrames
中,接下来会锁定 buffer。否则,调用 useEmptyDamage()
清空 surfaceDamageRegion
。mForceTransactionDisplayChange
为 false。 // 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) {
offscreenLayer->traverse(LayerVector::StateSet::Drawing,
[&](Layer* l) { l->latchAndReleaseBuffer(); });
}
mOffscreenLayers
,调用 BufferLayer::latchAndReleaseBuffer()。 if (!mLayersWithQueuedFrames.empty()) {
// mStateLock is needed for latchBuffer as LayerRejecter::reject()
// writes to Layer current state. See also b/119481871
Mutex::Autolock lock(mStateLock);
for (const auto& layer : mLayersWithQueuedFrames) {
if (layer->latchBuffer(visibleRegions, latchTime, expectedPresentTime)) {
mLayersPendingRefresh.push_back(layer);
}
layer->useSurfaceDamage();
if (layer->isBufferLatched()) {
newDataLatched = true;
}
}
}
mVisibleRegionsDirty |= visibleRegions;
mLayersWithQueuedFrames
,调用 BufferLayer::latchBuffer() 锁定 buffer,如果返回 true,则把 layer 加入到 mLayersPendingRefresh
,待被合成。useSurfaceDamage()
更新 surfaceDamageRegion
。newDataLatched
为 true。mVisibleRegionsDirty
或操作 visibleRegions
。