diff options
| -rw-r--r-- | libs/gui/BufferQueueConsumer.cpp | 2 | ||||
| -rw-r--r-- | libs/gui/include/gui/BufferQueueConsumer.h | 3 | ||||
| -rw-r--r-- | services/surfaceflinger/BufferLayer.cpp | 8 | ||||
| -rw-r--r-- | services/surfaceflinger/BufferLayer.h | 1 | ||||
| -rw-r--r-- | services/surfaceflinger/BufferQueueLayer.cpp | 42 | ||||
| -rw-r--r-- | services/surfaceflinger/BufferQueueLayer.h | 1 | ||||
| -rw-r--r-- | services/surfaceflinger/BufferStateLayer.cpp | 8 | ||||
| -rw-r--r-- | services/surfaceflinger/BufferStateLayer.h | 1 |
8 files changed, 60 insertions, 6 deletions
diff --git a/libs/gui/BufferQueueConsumer.cpp b/libs/gui/BufferQueueConsumer.cpp index e2261360b6..528bfb194e 100644 --- a/libs/gui/BufferQueueConsumer.cpp +++ b/libs/gui/BufferQueueConsumer.cpp @@ -94,8 +94,6 @@ status_t BufferQueueConsumer::acquireBuffer(BufferItem* outBuffer, // Skip this if we're in shared buffer mode and the queue is empty, // since in that case we'll just return the shared buffer. if (expectedPresent != 0 && !mCore->mQueue.empty()) { - const int MAX_REASONABLE_NSEC = 1000000000ULL; // 1 second - // The 'expectedPresent' argument indicates when the buffer is expected // to be presented on-screen. If the buffer's desired present time is // earlier (less) than expectedPresent -- meaning it will be displayed diff --git a/libs/gui/include/gui/BufferQueueConsumer.h b/libs/gui/include/gui/BufferQueueConsumer.h index aa13c0cf13..7db69eca9d 100644 --- a/libs/gui/include/gui/BufferQueueConsumer.h +++ b/libs/gui/include/gui/BufferQueueConsumer.h @@ -171,6 +171,9 @@ public: // End functions required for backwards compatibility + // Value used to determine if present time is valid. + constexpr static int MAX_REASONABLE_NSEC = 1'000'000'000ULL; // 1 second + private: sp<BufferQueueCore> mCore; diff --git a/services/surfaceflinger/BufferLayer.cpp b/services/surfaceflinger/BufferLayer.cpp index 4ea587dbba..06caf1e2dc 100644 --- a/services/surfaceflinger/BufferLayer.cpp +++ b/services/surfaceflinger/BufferLayer.cpp @@ -534,11 +534,13 @@ bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime) // transaction void BufferLayer::notifyAvailableFrames() { - auto headFrameNumber = getHeadFrameNumber(); - bool headFenceSignaled = fenceHasSignaled(); + const auto headFrameNumber = getHeadFrameNumber(); + const bool headFenceSignaled = fenceHasSignaled(); + const bool presentTimeIsCurrent = framePresentTimeIsCurrent(); Mutex::Autolock lock(mLocalSyncPointMutex); for (auto& point : mLocalSyncPoints) { - if (headFrameNumber >= point->getFrameNumber() && headFenceSignaled) { + if (headFrameNumber >= point->getFrameNumber() && headFenceSignaled && + presentTimeIsCurrent) { point->setFrameAvailable(); } } diff --git a/services/surfaceflinger/BufferLayer.h b/services/surfaceflinger/BufferLayer.h index dc103cbada..b679380b79 100644 --- a/services/surfaceflinger/BufferLayer.h +++ b/services/surfaceflinger/BufferLayer.h @@ -114,6 +114,7 @@ public: // ----------------------------------------------------------------------- private: virtual bool fenceHasSignaled() const = 0; + virtual bool framePresentTimeIsCurrent() const = 0; virtual nsecs_t getDesiredPresentTime() = 0; virtual std::shared_ptr<FenceTime> getCurrentFenceTime() const = 0; diff --git a/services/surfaceflinger/BufferQueueLayer.cpp b/services/surfaceflinger/BufferQueueLayer.cpp index ff5f271960..5d729f5b4f 100644 --- a/services/surfaceflinger/BufferQueueLayer.cpp +++ b/services/surfaceflinger/BufferQueueLayer.cpp @@ -19,6 +19,7 @@ #include <compositionengine/OutputLayer.h> #include <compositionengine/impl/LayerCompositionState.h> #include <compositionengine/impl/OutputLayerCompositionState.h> +#include <gui/BufferQueueConsumer.h> #include <system/window.h> #include "BufferQueueLayer.h" @@ -133,6 +134,15 @@ bool BufferQueueLayer::fenceHasSignaled() const { return mQueueItems[0].mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING; } +bool BufferQueueLayer::framePresentTimeIsCurrent() const { + if (!hasFrameUpdate() || isRemovedFromCurrentState()) { + return true; + } + + Mutex::Autolock lock(mQueueItemLock); + return mQueueItems[0].mTimestamp <= mFlinger->mScheduler->expectedPresentTime(); +} + nsecs_t BufferQueueLayer::getDesiredPresentTime() { return mConsumer->getTimestamp(); } @@ -185,7 +195,37 @@ PixelFormat BufferQueueLayer::getPixelFormat() const { uint64_t BufferQueueLayer::getFrameNumber() const { Mutex::Autolock lock(mQueueItemLock); - return mQueueItems[0].mFrameNumber; + uint64_t frameNumber = mQueueItems[0].mFrameNumber; + + // The head of the queue will be dropped if there are signaled and timely frames behind it + nsecs_t expectedPresentTime = mFlinger->mScheduler->expectedPresentTime(); + + if (isRemovedFromCurrentState()) { + expectedPresentTime = 0; + } + + for (int i = 1; i < mQueueItems.size(); i++) { + const bool fenceSignaled = + mQueueItems[i].mFenceTime->getSignalTime() != Fence::SIGNAL_TIME_PENDING; + if (!fenceSignaled) { + break; + } + + // We don't drop frames without explicit timestamps + if (mQueueItems[i].mIsAutoTimestamp) { + break; + } + + const nsecs_t desiredPresent = mQueueItems[i].mTimestamp; + if (desiredPresent < expectedPresentTime - BufferQueueConsumer::MAX_REASONABLE_NSEC || + desiredPresent > expectedPresentTime) { + break; + } + + frameNumber = mQueueItems[i].mFrameNumber; + } + + return frameNumber; } bool BufferQueueLayer::getAutoRefresh() const { diff --git a/services/surfaceflinger/BufferQueueLayer.h b/services/surfaceflinger/BufferQueueLayer.h index a2aad17497..7def33ad78 100644 --- a/services/surfaceflinger/BufferQueueLayer.h +++ b/services/surfaceflinger/BufferQueueLayer.h @@ -61,6 +61,7 @@ public: // ----------------------------------------------------------------------- public: bool fenceHasSignaled() const override; + bool framePresentTimeIsCurrent() const override; private: nsecs_t getDesiredPresentTime() override; diff --git a/services/surfaceflinger/BufferStateLayer.cpp b/services/surfaceflinger/BufferStateLayer.cpp index dabc683aa9..30848d6eb5 100644 --- a/services/surfaceflinger/BufferStateLayer.cpp +++ b/services/surfaceflinger/BufferStateLayer.cpp @@ -374,6 +374,14 @@ bool BufferStateLayer::fenceHasSignaled() const { return getDrawingState().acquireFence->getStatus() == Fence::Status::Signaled; } +bool BufferStateLayer::framePresentTimeIsCurrent() const { + if (!hasFrameUpdate() || isRemovedFromCurrentState()) { + return true; + } + + return mDesiredPresentTime <= mFlinger->mScheduler->expectedPresentTime(); +} + nsecs_t BufferStateLayer::getDesiredPresentTime() { return mDesiredPresentTime; } diff --git a/services/surfaceflinger/BufferStateLayer.h b/services/surfaceflinger/BufferStateLayer.h index 13186dd343..4e2bc45287 100644 --- a/services/surfaceflinger/BufferStateLayer.h +++ b/services/surfaceflinger/BufferStateLayer.h @@ -101,6 +101,7 @@ public: // Interface implementation for BufferLayer // ----------------------------------------------------------------------- bool fenceHasSignaled() const override; + bool framePresentTimeIsCurrent() const override; private: nsecs_t getDesiredPresentTime() override; |