Loading services/surfaceflinger/BufferLayer.cpp +20 −0 Original line number Diff line number Diff line Loading @@ -389,6 +389,20 @@ void BufferLayer::gatherBufferInfo() { mBufferInfo.mFrameLatencyNeeded = true; } bool BufferLayer::frameIsEarly(nsecs_t expectedPresentTime) const { // TODO(b/169901895): kEarlyLatchVsyncThreshold should be based on the // vsync period. We can do this change as soon as ag/13100772 is merged. constexpr static std::chrono::nanoseconds kEarlyLatchVsyncThreshold = 5ms; const auto presentTime = nextPredictedPresentTime(); if (std::abs(presentTime - expectedPresentTime) >= kEarlyLatchMaxThreshold.count()) { return false; } return presentTime >= expectedPresentTime && presentTime - expectedPresentTime >= kEarlyLatchVsyncThreshold.count(); } bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime, nsecs_t expectedPresentTime) { ATRACE_CALL(); Loading Loading @@ -421,6 +435,12 @@ bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime, return false; } if (frameIsEarly(expectedPresentTime)) { ATRACE_NAME("frameIsEarly()"); mFlinger->signalLayerUpdate(); return false; } // If the head buffer's acquire fence hasn't signaled yet, return and // try again later if (!fenceHasSignaled()) { Loading services/surfaceflinger/BufferLayer.h +12 −0 Original line number Diff line number Diff line Loading @@ -224,6 +224,18 @@ private: std::unique_ptr<compositionengine::LayerFECompositionState> mCompositionState; FloatRect computeSourceBounds(const FloatRect& parentBounds) const override; // Returns true if the next frame is considered too early to present // at the given expectedPresentTime bool frameIsEarly(nsecs_t expectedPresentTime) const; // Returns the predicted present time of the next frame if available or // 0 otherwise. virtual nsecs_t nextPredictedPresentTime() const = 0; // The amount of time SF can delay a frame if it is considered early based // on the VsyncModulator::VsyncConfig::appWorkDuration static constexpr std::chrono::nanoseconds kEarlyLatchMaxThreshold = 100ms; }; } // namespace android services/surfaceflinger/BufferQueueLayer.cpp +15 −0 Original line number Diff line number Diff line Loading @@ -222,6 +222,21 @@ bool BufferQueueLayer::hasFrameUpdate() const { return mQueuedFrames > 0; } nsecs_t BufferQueueLayer::nextPredictedPresentTime() const { Mutex::Autolock lock(mQueueItemLock); if (mQueueItems.empty()) { return 0; } const auto& bufferData = mQueueItems[0]; if (!bufferData.item.mIsAutoTimestamp || !bufferData.surfaceFrame) { return 0; } return bufferData.surfaceFrame->getPredictions().presentTime; } status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime, nsecs_t expectedPresentTime) { // This boolean is used to make sure that SurfaceFlinger's shadow copy Loading services/surfaceflinger/BufferQueueLayer.h +2 −0 Original line number Diff line number Diff line Loading @@ -116,6 +116,8 @@ private: // Temporary - Used only for LEGACY camera mode. uint32_t getProducerStickyTransform() const; nsecs_t nextPredictedPresentTime() const override; sp<BufferLayerConsumer> mConsumer; sp<IGraphicBufferProducer> mProducer; Loading services/surfaceflinger/BufferStateLayer.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -601,6 +601,14 @@ bool BufferStateLayer::hasFrameUpdate() const { return mCurrentStateModified && (c.buffer != nullptr || c.bgColorLayer != nullptr); } nsecs_t BufferStateLayer::nextPredictedPresentTime() const { if (!getDrawingState().isAutoTimestamp || !mSurfaceFrame) { return 0; } return mSurfaceFrame->getPredictions().presentTime; } status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nsecs_t latchTime, nsecs_t /*expectedPresentTime*/) { const State& s(getDrawingState()); Loading Loading
services/surfaceflinger/BufferLayer.cpp +20 −0 Original line number Diff line number Diff line Loading @@ -389,6 +389,20 @@ void BufferLayer::gatherBufferInfo() { mBufferInfo.mFrameLatencyNeeded = true; } bool BufferLayer::frameIsEarly(nsecs_t expectedPresentTime) const { // TODO(b/169901895): kEarlyLatchVsyncThreshold should be based on the // vsync period. We can do this change as soon as ag/13100772 is merged. constexpr static std::chrono::nanoseconds kEarlyLatchVsyncThreshold = 5ms; const auto presentTime = nextPredictedPresentTime(); if (std::abs(presentTime - expectedPresentTime) >= kEarlyLatchMaxThreshold.count()) { return false; } return presentTime >= expectedPresentTime && presentTime - expectedPresentTime >= kEarlyLatchVsyncThreshold.count(); } bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime, nsecs_t expectedPresentTime) { ATRACE_CALL(); Loading Loading @@ -421,6 +435,12 @@ bool BufferLayer::latchBuffer(bool& recomputeVisibleRegions, nsecs_t latchTime, return false; } if (frameIsEarly(expectedPresentTime)) { ATRACE_NAME("frameIsEarly()"); mFlinger->signalLayerUpdate(); return false; } // If the head buffer's acquire fence hasn't signaled yet, return and // try again later if (!fenceHasSignaled()) { Loading
services/surfaceflinger/BufferLayer.h +12 −0 Original line number Diff line number Diff line Loading @@ -224,6 +224,18 @@ private: std::unique_ptr<compositionengine::LayerFECompositionState> mCompositionState; FloatRect computeSourceBounds(const FloatRect& parentBounds) const override; // Returns true if the next frame is considered too early to present // at the given expectedPresentTime bool frameIsEarly(nsecs_t expectedPresentTime) const; // Returns the predicted present time of the next frame if available or // 0 otherwise. virtual nsecs_t nextPredictedPresentTime() const = 0; // The amount of time SF can delay a frame if it is considered early based // on the VsyncModulator::VsyncConfig::appWorkDuration static constexpr std::chrono::nanoseconds kEarlyLatchMaxThreshold = 100ms; }; } // namespace android
services/surfaceflinger/BufferQueueLayer.cpp +15 −0 Original line number Diff line number Diff line Loading @@ -222,6 +222,21 @@ bool BufferQueueLayer::hasFrameUpdate() const { return mQueuedFrames > 0; } nsecs_t BufferQueueLayer::nextPredictedPresentTime() const { Mutex::Autolock lock(mQueueItemLock); if (mQueueItems.empty()) { return 0; } const auto& bufferData = mQueueItems[0]; if (!bufferData.item.mIsAutoTimestamp || !bufferData.surfaceFrame) { return 0; } return bufferData.surfaceFrame->getPredictions().presentTime; } status_t BufferQueueLayer::updateTexImage(bool& recomputeVisibleRegions, nsecs_t latchTime, nsecs_t expectedPresentTime) { // This boolean is used to make sure that SurfaceFlinger's shadow copy Loading
services/surfaceflinger/BufferQueueLayer.h +2 −0 Original line number Diff line number Diff line Loading @@ -116,6 +116,8 @@ private: // Temporary - Used only for LEGACY camera mode. uint32_t getProducerStickyTransform() const; nsecs_t nextPredictedPresentTime() const override; sp<BufferLayerConsumer> mConsumer; sp<IGraphicBufferProducer> mProducer; Loading
services/surfaceflinger/BufferStateLayer.cpp +8 −0 Original line number Diff line number Diff line Loading @@ -601,6 +601,14 @@ bool BufferStateLayer::hasFrameUpdate() const { return mCurrentStateModified && (c.buffer != nullptr || c.bgColorLayer != nullptr); } nsecs_t BufferStateLayer::nextPredictedPresentTime() const { if (!getDrawingState().isAutoTimestamp || !mSurfaceFrame) { return 0; } return mSurfaceFrame->getPredictions().presentTime; } status_t BufferStateLayer::updateTexImage(bool& /*recomputeVisibleRegions*/, nsecs_t latchTime, nsecs_t /*expectedPresentTime*/) { const State& s(getDrawingState()); Loading