diff options
Diffstat (limited to 'services/surfaceflinger/BufferQueueLayer.cpp')
| -rw-r--r-- | services/surfaceflinger/BufferQueueLayer.cpp | 119 |
1 files changed, 65 insertions, 54 deletions
diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp index 6e4235e409..6b6d43425d 100644 --- a/services/surfaceflinger/BufferQueueLayer.cpp +++ b/services/surfaceflinger/BufferQueueLayer.cpp @@ -17,6 +17,7 @@ // TODO(b/129481165): remove the #pragma below and fix conversion issues #pragma clang diagnostic push #pragma clang diagnostic ignored "-Wconversion" +#pragma clang diagnostic ignored "-Wextra" #undef LOG_TAG #define LOG_TAG "BufferQueueLayer" @@ -35,6 +36,7 @@ #include "TimeStats/TimeStats.h" namespace android { +using PresentState = frametimeline::SurfaceFrame::PresentState; BufferQueueLayer::BufferQueueLayer(const LayerCreationArgs& args) : BufferLayer(args) {} @@ -98,18 +100,10 @@ int32_t BufferQueueLayer::getQueuedFrameCount() const { return mQueuedFrames; } -bool BufferQueueLayer::shouldPresentNow(nsecs_t expectedPresentTime) const { - if (getSidebandStreamChanged() || getAutoRefresh()) { - return true; - } - - if (!hasFrameUpdate()) { - return false; - } - +bool BufferQueueLayer::isBufferDue(nsecs_t expectedPresentTime) const { Mutex::Autolock lock(mQueueItemLock); - const int64_t addedTime = mQueueItems[0].mTimestamp; + const int64_t addedTime = mQueueItems[0].item.mTimestamp; // Ignore timestamps more than a second in the future const bool isPlausible = addedTime < (expectedPresentTime + s2ns(1)); @@ -131,7 +125,9 @@ bool BufferQueueLayer::shouldPresentNow(nsecs_t expectedPresentTime) const { // ----------------------------------------------------------------------- bool BufferQueueLayer::fenceHasSignaled() const { - if (latchUnsignaledBuffers()) { + Mutex::Autolock lock(mQueueItemLock); + + if (SurfaceFlinger::enableLatchUnsignaled) { return true; } @@ -139,8 +135,7 @@ bool BufferQueueLayer::fenceHasSignaled() const { return true; } - Mutex::Autolock lock(mQueueItemLock); - if (mQueueItems[0].mIsDroppable) { + if (mQueueItems[0].item.mIsDroppable) { // Even though this buffer's fence may not have signaled yet, it could // be replaced by another buffer before it has a chance to, which means // that it's possible to get into a situation where a buffer is never @@ -148,7 +143,7 @@ bool BufferQueueLayer::fenceHasSignaled() const { return true; } const bool fenceSignaled = - mQueueItems[0].mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING; + mQueueItems[0].item.mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING; if (!fenceSignaled) { mFlinger->mTimeStats->incrementLatchSkipped(getSequence(), TimeStats::LatchSkipReason::LateAcquire); @@ -163,12 +158,12 @@ bool BufferQueueLayer::framePresentTimeIsCurrent(nsecs_t expectedPresentTime) co } Mutex::Autolock lock(mQueueItemLock); - return mQueueItems[0].mTimestamp <= expectedPresentTime; + return mQueueItems[0].item.mTimestamp <= expectedPresentTime; } uint64_t BufferQueueLayer::getFrameNumber(nsecs_t expectedPresentTime) const { Mutex::Autolock lock(mQueueItemLock); - uint64_t frameNumber = mQueueItems[0].mFrameNumber; + uint64_t frameNumber = mQueueItems[0].item.mFrameNumber; // The head of the queue will be dropped if there are signaled and timely frames behind it if (isRemovedFromCurrentState()) { @@ -177,39 +172,35 @@ uint64_t BufferQueueLayer::getFrameNumber(nsecs_t expectedPresentTime) const { for (int i = 1; i < mQueueItems.size(); i++) { const bool fenceSignaled = - mQueueItems[i].mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING; + mQueueItems[i].item.mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING; if (!fenceSignaled) { break; } // We don't drop frames without explicit timestamps - if (mQueueItems[i].mIsAutoTimestamp) { + if (mQueueItems[i].item.mIsAutoTimestamp) { break; } - const nsecs_t desiredPresent = mQueueItems[i].mTimestamp; + const nsecs_t desiredPresent = mQueueItems[i].item.mTimestamp; if (desiredPresent < expectedPresentTime - BufferQueueConsumer::MAX_REASONABLE_NSEC || desiredPresent > expectedPresentTime) { break; } - frameNumber = mQueueItems[i].mFrameNumber; + frameNumber = mQueueItems[i].item.mFrameNumber; } return frameNumber; } -bool BufferQueueLayer::getAutoRefresh() const { - return mAutoRefresh; -} - -bool BufferQueueLayer::getSidebandStreamChanged() const { - return mSidebandStreamChanged; -} - bool BufferQueueLayer::latchSidebandStream(bool& recomputeVisibleRegions) { + // We need to update the sideband stream if the layer has both a buffer and a sideband stream. + const bool updateSidebandStream = hasFrameUpdate() && mSidebandStream.get(); + bool sidebandStreamChanged = true; - if (mSidebandStreamChanged.compare_exchange_strong(sidebandStreamChanged, false)) { + if (mSidebandStreamChanged.compare_exchange_strong(sidebandStreamChanged, false) || + updateSidebandStream) { // mSidebandStreamChanged was changed to false mSidebandStream = mConsumer->getSidebandStream(); auto* layerCompositionState = editCompositionState(); @@ -229,10 +220,6 @@ bool BufferQueueLayer::hasFrameUpdate() const { return mQueuedFrames > 0; } -status_t BufferQueueLayer::bindTextureImage() { - return mConsumer->bindTextureImage(); -} - status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime, nsecs_t expectedPresentTime) { // This boolean is used to make sure that SurfaceFlinger's shadow copy @@ -241,8 +228,8 @@ status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t // buffer mode. bool queuedBuffer = false; const int32_t layerId = getSequence(); - LayerRejecter r(mDrawingState, getCurrentState(), recomputeVisibleRegions, - getProducerStickyTransform() != 0, mName, mOverrideScalingMode, + LayerRejecter r(mDrawingState, getDrawingState(), recomputeVisibleRegions, + getProducerStickyTransform() != 0, mName, getTransformToDisplayInverse()); if (isRemovedFromCurrentState()) { @@ -258,18 +245,20 @@ status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t Mutex::Autolock lock(mQueueItemLock); for (int i = 0; i < mQueueItems.size(); i++) { bool fenceSignaled = - mQueueItems[i].mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING; + mQueueItems[i].item.mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING; if (!fenceSignaled) { break; } - lastSignaledFrameNumber = mQueueItems[i].mFrameNumber; + lastSignaledFrameNumber = mQueueItems[i].item.mFrameNumber; } } const uint64_t maxFrameNumberToAcquire = std::min(mLastFrameNumberReceived.load(), lastSignaledFrameNumber); - status_t updateResult = mConsumer->updateTexImage(&r, expectedPresentTime, &mAutoRefresh, + bool autoRefresh; + status_t updateResult = mConsumer->updateTexImage(&r, expectedPresentTime, &autoRefresh, &queuedBuffer, maxFrameNumberToAcquire); + mAutoRefresh = autoRefresh; if (updateResult == BufferQueue::PRESENT_LATER) { // Producer doesn't want buffer to be displayed yet. Signal a // layer update so we check again at the next opportunity. @@ -280,9 +269,12 @@ status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t // and return early if (queuedBuffer) { Mutex::Autolock lock(mQueueItemLock); - mConsumer->mergeSurfaceDamage(mQueueItems[0].mSurfaceDamage); - mFlinger->mTimeStats->removeTimeRecord(layerId, mQueueItems[0].mFrameNumber); - mQueueItems.removeAt(0); + mConsumer->mergeSurfaceDamage(mQueueItems[0].item.mSurfaceDamage); + mFlinger->mTimeStats->removeTimeRecord(layerId, mQueueItems[0].item.mFrameNumber); + if (mQueueItems[0].surfaceFrame) { + addSurfaceFrameDroppedForBuffer(mQueueItems[0].surfaceFrame); + } + mQueueItems.erase(mQueueItems.begin()); mQueuedFrames--; } return BAD_VALUE; @@ -293,6 +285,11 @@ status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t // early. if (queuedBuffer) { Mutex::Autolock lock(mQueueItemLock); + for (auto& [item, surfaceFrame] : mQueueItems) { + if (surfaceFrame) { + addSurfaceFrameDroppedForBuffer(surfaceFrame); + } + } mQueueItems.clear(); mQueuedFrames = 0; mFlinger->mTimeStats->onDestroy(layerId); @@ -316,19 +313,27 @@ status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t // Remove any stale buffers that have been dropped during // updateTexImage - while (mQueueItems[0].mFrameNumber != currentFrameNumber) { - mConsumer->mergeSurfaceDamage(mQueueItems[0].mSurfaceDamage); - mFlinger->mTimeStats->removeTimeRecord(layerId, mQueueItems[0].mFrameNumber); - mQueueItems.removeAt(0); + while (mQueueItems[0].item.mFrameNumber != currentFrameNumber) { + mConsumer->mergeSurfaceDamage(mQueueItems[0].item.mSurfaceDamage); + mFlinger->mTimeStats->removeTimeRecord(layerId, mQueueItems[0].item.mFrameNumber); + if (mQueueItems[0].surfaceFrame) { + addSurfaceFrameDroppedForBuffer(mQueueItems[0].surfaceFrame); + } + mQueueItems.erase(mQueueItems.begin()); mQueuedFrames--; } - uint64_t bufferID = mQueueItems[0].mGraphicBuffer->getId(); + uint64_t bufferID = mQueueItems[0].item.mGraphicBuffer->getId(); mFlinger->mTimeStats->setLatchTime(layerId, currentFrameNumber, latchTime); mFlinger->mFrameTracer->traceTimestamp(layerId, bufferID, currentFrameNumber, latchTime, FrameTracer::FrameEvent::LATCH); - mQueueItems.removeAt(0); + if (mQueueItems[0].surfaceFrame) { + addSurfaceFramePresentedForBuffer(mQueueItems[0].surfaceFrame, + mQueueItems[0].item.mFenceTime->getSignalTime(), + latchTime); + } + mQueueItems.erase(mQueueItems.begin()); } // Decrement the queued-frames count. Signal another event if we @@ -364,6 +369,10 @@ status_t BufferQueueLayer::updateFrameNumber(nsecs_t latchTime) { return NO_ERROR; } +void BufferQueueLayer::setFrameTimelineInfoForBuffer(const FrameTimelineInfo& frameTimelineInfo) { + mFrameTimelineInfo = frameTimelineInfo; +} + // ----------------------------------------------------------------------- // Interface implementation for BufferLayerConsumer::ContentsChangedListener // ----------------------------------------------------------------------- @@ -420,7 +429,9 @@ void BufferQueueLayer::onFrameAvailable(const BufferItem& item) { } } - mQueueItems.push_back(item); + auto surfaceFrame = createSurfaceFrameForBuffer(mFrameTimelineInfo, systemTime(), mName); + + mQueueItems.push_back({item, surfaceFrame}); mQueuedFrames++; // Wake up any pending callbacks @@ -453,7 +464,10 @@ void BufferQueueLayer::onFrameReplaced(const BufferItem& item) { ALOGE("Can't replace a frame on an empty queue"); return; } - mQueueItems.editItemAt(mQueueItems.size() - 1) = item; + + auto surfaceFrame = createSurfaceFrameForBuffer(mFrameTimelineInfo, systemTime(), mName); + mQueueItems[mQueueItems.size() - 1].item = item; + mQueueItems[mQueueItems.size() - 1].surfaceFrame = std::move(surfaceFrame); // Wake up any pending callbacks mLastFrameNumberReceived = item.mFrameNumber; @@ -497,10 +511,7 @@ void BufferQueueLayer::onFirstRef() { mConsumer->setContentsChangedListener(mContentsChangedListener); mConsumer->setName(String8(mName.data(), mName.size())); - // BufferQueueCore::mMaxDequeuedBufferCount is default to 1 - if (!mFlinger->isLayerTripleBufferingDisabled()) { - mProducer->setMaxDequeuedBufferCount(2); - } + mProducer->setMaxDequeuedBufferCount(2); } status_t BufferQueueLayer::setDefaultBufferProperties(uint32_t w, uint32_t h, PixelFormat format) { @@ -617,4 +628,4 @@ void BufferQueueLayer::ContentsChangedListener::abandon() { } // namespace android // TODO(b/129481165): remove the #pragma below and fix conversion issues -#pragma clang diagnostic pop // ignored "-Wconversion" +#pragma clang diagnostic pop // ignored "-Wconversion -Wextra" |