该函数是 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。