当BufferQueueLayer有新的buffer到来时,会调用之前在SurfaceFlinger中Layer的创建时注册的ContentsChangedListener的onFrameAvailable方法(frameworks/native/services/surfaceflinger/BufferQueueLayer.cpp):
void BufferQueueLayer::ContentsChangedListener::onFrameAvailable(const BufferItem& item) {
Mutex::Autolock lock(mMutex);
if (mBufferQueueLayer != nullptr) {
mBufferQueueLayer->onFrameAvailable(item);
}
}
直接调用了BufferQueueLayer的onFrameAvailable方法:
void BufferQueueLayer::onFrameAvailable(const BufferItem& item) {
const int32_t layerId = getSequence();
const uint64_t bufferId = item.mGraphicBuffer->getId();
mFlinger->mFrameTracer->traceTimestamp(layerId, bufferId, item.mFrameNumber, systemTime(),
FrameTracer::FrameEvent::QUEUE);
mFlinger->mFrameTracer->traceFence(layerId, bufferId, item.mFrameNumber,
std::make_shared<FenceTime>(item.mFence),
FrameTracer::FrameEvent::ACQUIRE_FENCE);
ATRACE_CALL();
// Add this buffer from our internal queue tracker
{
// Autolock scope
const nsecs_t presentTime = item.mIsAutoTimestamp ? 0 : item.mTimestamp;
mFlinger->mScheduler->recordLayerHistory(this, presentTime,
LayerHistory::LayerUpdateType::Buffer);
Mutex::Autolock lock(mQueueItemLock);
// Reset the frame number tracker when we receive the first buffer after
// a frame number reset
if (item.mFrameNumber == 1) {
mLastFrameNumberReceived = 0;
}
// Ensure that callbacks are handled in order
while (item.mFrameNumber != mLastFrameNumberReceived + 1) {
status_t result = mQueueItemCondition.waitRelative(mQueueItemLock, ms2ns(500));
if (result != NO_ERROR) {
ALOGE("[%s] Timed out waiting on callback", getDebugName());
break;
}
}
mQueueItems.push_back(item);
mQueuedFrames++;
// Wake up any pending callbacks
mLastFrameNumberReceived = item.mFrameNumber;
mQueueItemCondition.broadcast();
}
mFlinger->mInterceptor->saveBufferUpdate(layerId, item.mGraphicBuffer->getWidth(),
item.mGraphicBuffer->getHeight(), item.mFrameNumber);
mFlinger->signalLayerUpdate();
mConsumer->onBufferAvailable(item);
}
最后调用了frameworks/native/services/surfaceflinger/SurfaceFlinger.cpp的signalLayerUpdate方法:
void SurfaceFlinger::signalLayerUpdate() {
mScheduler->resetIdleTimer();
mPowerAdvisor.notifyDisplayUpdateImminent();
mEventQueue->invalidate();
}
EventQueue的invalidate方法会导致SurfaceFlinger的onMessageInvalidate方法被调用:
void SurfaceFlinger::onMessageInvalidate(nsecs_t expectedVSyncTime) {
ATRACE_CALL();
const nsecs_t frameStart = systemTime();
// calculate the expected present time once and use the cached
// value throughout this frame to make sure all layers are
// seeing this same value.
if (expectedVSyncTime >= frameStart) {
mExpectedPresentTime = expectedVSyncTime;
} else {
mExpectedPresentTime = mScheduler->getDispSyncExpectedPresentTime(frameStart);
}
const nsecs_t lastScheduledPresentTime = mScheduledPresentTime;
mScheduledPresentTime = expectedVSyncTime;
// When Backpressure propagation is enabled we want to give a small grace period
// for the present fence to fire instead of just giving up on this frame to handle cases
// where present fence is just about to get signaled.
const int graceTimeForPresentFenceMs =
(mPropagateBackpressure &&
(mPropagateBackpressureClientComposition || !mHadClientComposition))
? 1
: 0;
// Pending frames may trigger backpressure propagation.
const TracedOrdinal<bool> framePending = {
"PrevFramePending",
previousFramePending(graceTimeForPresentFenceMs)};
// Frame missed counts for metrics tracking.
// A frame is missed if the prior frame is still pending. If no longer pending,
// then we still count the frame as missed if the predicted present time
// was further in the past than when the fence actually fired.
// Add some slop to correct for drift. This should generally be
// smaller than a typical frame duration, but should not be so small
// that it reports reasonable drift as a missed frame.
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};
if (frameMissed) {
mFrameMissedCount++;
mTimeStats->incrementMissedFrames();
if (mMissedFrameJankCount == 0) {
mMissedFrameJankStart = systemTime();
}
mMissedFrameJankCount++;
}
if (hwcFrameMissed) {
mHwcFrameMissedCount++;
}
if (gpuFrameMissed) {
mGpuFrameMissedCount++;
}
// If we are in the middle of a config change and the fence hasn't
// fired yet just wait for the next invalidate
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());
}
if (framePending && mPropagateBackpressure) {
if ((hwcFrameMissed && !gpuFrameMissed) || mPropagateBackpressureClientComposition) {
signalLayerUpdate();
return;
}
}
// Our jank window is always at least 100ms since we missed a
// frame...
static constexpr nsecs_t kMinJankyDuration =
std::chrono::duration_cast<std::chrono::nanoseconds>(100ms).count();
// ...but if it's larger than 1s then we missed the trace cutoff.
static constexpr nsecs_t kMaxJankyDuration =
std::chrono::duration_cast<std::chrono::nanoseconds>(1s).count();
nsecs_t jankDurationToUpload = -1;
// If we're in a user build then don't push any atoms
if (!mIsUserBuild && mMissedFrameJankCount > 0) {
const auto display = ON_MAIN_THREAD(getDefaultDisplayDeviceLocked());
// Only report jank when the display is on, as displays in DOZE
// power mode may operate at a different frame rate than is
// reported in their config, which causes noticeable (but less
// severe) jank.
if (display && display->getPowerMode() == hal::PowerMode::ON) {
const nsecs_t currentTime = systemTime();
const nsecs_t jankDuration = currentTime - mMissedFrameJankStart;
if (jankDuration > kMinJankyDuration && jankDuration < kMaxJankyDuration) {
jankDurationToUpload = jankDuration;
}
// We either reported a jank event or we missed the trace
// window, so clear counters here.
if (jankDuration > kMinJankyDuration) {
mMissedFrameJankCount = 0;
mMissedFrameJankStart = 0;
}
}
}
if (mTracingEnabledChanged) {
mTracingEnabled = mTracing.isEnabled();
mTracingEnabledChanged = false;
}
bool refreshNeeded;
{
ConditionalLockGuard<std::mutex> lock(mTracingLock, mTracingEnabled);
refreshNeeded = handleMessageTransaction();
refreshNeeded |= handleMessageInvalidate();
if (mTracingEnabled) {
mAddCompositionStateToTrace =
mTracing.flagIsSetLocked(SurfaceTracing::TRACE_COMPOSITION);
if (mVisibleRegionsDirty && !mAddCompositionStateToTrace) {
mTracing.notifyLocked("visibleRegionsDirty");
}
}
}
// Layers need to get updated (in the previous line) before we can use them for
// choosing the refresh rate.
// Hold mStateLock as chooseRefreshRateForContent promotes wp to sp
// and may eventually call to ~Layer() if it holds the last reference
{
Mutex::Autolock _l(mStateLock);
mScheduler->chooseRefreshRateForContent();
}
ON_MAIN_THREAD(performSetActiveConfig());
updateCursorAsync();
updateInputFlinger();
refreshNeeded |= mRepaintEverything;
if (refreshNeeded && CC_LIKELY(mBootStage != BootStage::BOOTLOADER)) {
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();
}
}
其中调用了SurfaceFlinger的handleMessageInvalidate方法:
bool SurfaceFlinger::handleMessageInvalidate() {
ATRACE_CALL();
bool refreshNeeded = handlePageFlip();
if (mVisibleRegionsDirty) {
computeLayerBounds();
}
for (auto& layer : mLayersPendingRefresh) {
Region visibleReg;
visibleReg.set(layer->getScreenBounds());
invalidateLayerStack(layer, visibleReg);
}
mLayersPendingRefresh.clear();
return refreshNeeded;
}
调用了SurfaceFlinger的handlePageFlip方法:
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();
// 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) {
if (layer->hasReadyFrame()) {
frameQueued = true;
if (layer->shouldPresentNow(expectedPresentTime)) {
mLayersWithQueuedFrames.push_back(layer);
} 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) {
offscreenLayer->traverse(LayerVector::StateSet::Drawing,
[&](Layer* l) {
l->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 (auto& layer : mLayersWithQueuedFrames) {
if (layer->latchBuffer(visibleRegions, latchTime, expectedPresentTime)) {
mLayersPendingRefresh.push_back(layer);
}
layer->useSurfaceDamage();
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(); });
// Only continue with the refresh if there is actually new work to do
return !mLayersWithQueuedFrames.empty() && newDataLatched;
}
对所有有准备好了的buffer的Layer调用了latchBuffer方法,具体是调用了frameworks/native/services/surfaceflinger/BufferLayer.cpp的latchBuffer方法:
bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime,
nsecs_t expectedPresentTime) {
ATRACE_CALL();
bool refreshRequired = latchSidebandStream(recomputeVisibleRegions);
if (refreshRequired) {
return refreshRequired;
}
if (!hasReadyFrame()) {
return false;
}
// if we've already called updateTexImage() without going through
// a composition step, we have to skip this layer at this point
// because we cannot call updateTeximage() without a corresponding
// compositionComplete() call.
// we'll trigger an update in onPreComposition().
if (mRefreshPending) {
return false;
}
// If the head buffer's acquire fence hasn't signaled yet, return and
// try again later
if (!fenceHasSignaled()) {
ATRACE_NAME("!fenceHasSignaled()");
mFlinger->signalLayerUpdate();
return false;
}
// Capture the old state of the layer for comparisons later
const State& s(getDrawingState());
const bool oldOpacity = isOpaque(s);
BufferInfo oldBufferInfo = mBufferInfo;
if (!allTransactionsSignaled(expectedPresentTime))