Loading services/surfaceflinger/Scheduler/VsyncModulator.cpp +20 −4 Original line number Diff line number Diff line Loading @@ -134,15 +134,26 @@ VsyncModulator::VsyncConfig VsyncModulator::getVsyncConfig() const { return mVsyncConfig; } const VsyncModulator::VsyncConfig& VsyncModulator::getNextVsyncConfig() const { auto VsyncModulator::getNextVsyncConfigType() const -> VsyncConfigType { // Early offsets are used if we're in the middle of a refresh rate // change, or if we recently begin a transaction. if (!mEarlyWakeupRequests.empty() || mTransactionSchedule == Schedule::EarlyEnd || mEarlyTransactionFrames > 0 || mRefreshRateChangePending) { return mVsyncConfigSet.early; return VsyncConfigType::Early; } else if (mEarlyGpuFrames > 0) { return mVsyncConfigSet.earlyGpu; return VsyncConfigType::EarlyGpu; } else { return VsyncConfigType::Late; } } const VsyncModulator::VsyncConfig& VsyncModulator::getNextVsyncConfig() const { switch (getNextVsyncConfigType()) { case VsyncConfigType::Early: return mVsyncConfigSet.early; case VsyncConfigType::EarlyGpu: return mVsyncConfigSet.earlyGpu; case VsyncConfigType::Late: return mVsyncConfigSet.late; } } Loading Loading @@ -176,4 +187,9 @@ void VsyncModulator::binderDied(const wp<IBinder>& who) { static_cast<void>(updateVsyncConfigLocked()); } bool VsyncModulator::isVsyncConfigDefault() const { std::lock_guard<std::mutex> lock(mMutex); return getNextVsyncConfigType() == VsyncConfigType::Late; } } // namespace android::scheduler services/surfaceflinger/Scheduler/VsyncModulator.h +5 −0 Original line number Diff line number Diff line Loading @@ -109,11 +109,16 @@ public: [[nodiscard]] VsyncConfigOpt onDisplayRefresh(bool usedGpuComposition); [[nodiscard]] bool isVsyncConfigDefault() const; protected: // Called from unit tests as well void binderDied(const wp<IBinder>&) override EXCLUDES(mMutex); private: enum class VsyncConfigType { Early, EarlyGpu, Late }; VsyncConfigType getNextVsyncConfigType() const REQUIRES(mMutex); const VsyncConfig& getNextVsyncConfig() const REQUIRES(mMutex); [[nodiscard]] VsyncConfig updateVsyncConfig() EXCLUDES(mMutex); [[nodiscard]] VsyncConfig updateVsyncConfigLocked() REQUIRES(mMutex); Loading services/surfaceflinger/SurfaceFlinger.cpp +17 −6 Original line number Diff line number Diff line Loading @@ -3810,7 +3810,7 @@ bool SurfaceFlinger::frameIsEarly(nsecs_t expectedPresentTime, int64_t vsyncId) prediction->presentTime - expectedPresentTime >= earlyLatchVsyncThreshold; } bool SurfaceFlinger::shouldLatchUnsignaled(const sp<Layer>& layer, const layer_state_t& state, size_t numStates, size_t totalTXapplied) { size_t numStates, size_t totalTXapplied) const { if (enableLatchUnsignaledConfig == LatchUnsignaledConfig::Disabled) { ALOGV("%s: false (LatchUnsignaledConfig::Disabled)", __func__); return false; Loading @@ -3828,13 +3828,24 @@ bool SurfaceFlinger::shouldLatchUnsignaled(const sp<Layer>& layer, const layer_s return false; } if (enableLatchUnsignaledConfig == LatchUnsignaledConfig::AutoSingleLayer && totalTXapplied > 0) { ALOGV("%s: false (LatchUnsignaledConfig::AutoSingleLayer; totalTXapplied=%zu)", __func__, totalTXapplied); if (enableLatchUnsignaledConfig == LatchUnsignaledConfig::AutoSingleLayer) { if (totalTXapplied > 0) { ALOGV("%s: false (LatchUnsignaledConfig::AutoSingleLayer; totalTXapplied=%zu)", __func__, totalTXapplied); return false; } // We don't want to latch unsignaled if are in early / client composition // as it leads to jank due to RenderEngine waiting for unsignaled buffer // or window animations being slow. const auto isDefaultVsyncConfig = mVsyncModulator->isVsyncConfigDefault(); if (!isDefaultVsyncConfig) { ALOGV("%s: false (LatchUnsignaledConfig::AutoSingleLayer; !isDefaultVsyncConfig)", __func__); return false; } } if (!layer->simpleBufferUpdate(state)) { ALOGV("%s: false (!simpleBufferUpdate)", __func__); return false; Loading services/surfaceflinger/SurfaceFlinger.h +2 −2 Original line number Diff line number Diff line Loading @@ -782,8 +782,8 @@ private: const std::unordered_set<sp<IBinder>, SpHash<IBinder>>& bufferLayersReadyToPresent, size_t totalTXapplied) const REQUIRES(mStateLock); static LatchUnsignaledConfig getLatchUnsignaledConfig(); static bool shouldLatchUnsignaled(const sp<Layer>& layer, const layer_state_t&, size_t numStates, size_t totalTXapplied); bool shouldLatchUnsignaled(const sp<Layer>& layer, const layer_state_t&, size_t numStates, size_t totalTXapplied) const; bool stopTransactionProcessing(const std::unordered_set<sp<IBinder>, SpHash<IBinder>>& applyTokensWithUnsignaledTransactions) const; bool applyTransactions(std::vector<TransactionState>& transactions, int64_t vsyncId) Loading services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +2 −0 Original line number Diff line number Diff line Loading @@ -270,6 +270,8 @@ public: scheduler::TestableScheduler& mutableScheduler() { return *mScheduler; } scheduler::mock::SchedulerCallback& mockSchedulerCallback() { return mSchedulerCallback; } auto& mutableVsyncModulator() { return mFlinger->mVsyncModulator; } using CreateBufferQueueFunction = surfaceflinger::test::Factory::CreateBufferQueueFunction; void setCreateBufferQueueFunction(CreateBufferQueueFunction f) { mFactory.mCreateBufferQueue = f; Loading Loading
services/surfaceflinger/Scheduler/VsyncModulator.cpp +20 −4 Original line number Diff line number Diff line Loading @@ -134,15 +134,26 @@ VsyncModulator::VsyncConfig VsyncModulator::getVsyncConfig() const { return mVsyncConfig; } const VsyncModulator::VsyncConfig& VsyncModulator::getNextVsyncConfig() const { auto VsyncModulator::getNextVsyncConfigType() const -> VsyncConfigType { // Early offsets are used if we're in the middle of a refresh rate // change, or if we recently begin a transaction. if (!mEarlyWakeupRequests.empty() || mTransactionSchedule == Schedule::EarlyEnd || mEarlyTransactionFrames > 0 || mRefreshRateChangePending) { return mVsyncConfigSet.early; return VsyncConfigType::Early; } else if (mEarlyGpuFrames > 0) { return mVsyncConfigSet.earlyGpu; return VsyncConfigType::EarlyGpu; } else { return VsyncConfigType::Late; } } const VsyncModulator::VsyncConfig& VsyncModulator::getNextVsyncConfig() const { switch (getNextVsyncConfigType()) { case VsyncConfigType::Early: return mVsyncConfigSet.early; case VsyncConfigType::EarlyGpu: return mVsyncConfigSet.earlyGpu; case VsyncConfigType::Late: return mVsyncConfigSet.late; } } Loading Loading @@ -176,4 +187,9 @@ void VsyncModulator::binderDied(const wp<IBinder>& who) { static_cast<void>(updateVsyncConfigLocked()); } bool VsyncModulator::isVsyncConfigDefault() const { std::lock_guard<std::mutex> lock(mMutex); return getNextVsyncConfigType() == VsyncConfigType::Late; } } // namespace android::scheduler
services/surfaceflinger/Scheduler/VsyncModulator.h +5 −0 Original line number Diff line number Diff line Loading @@ -109,11 +109,16 @@ public: [[nodiscard]] VsyncConfigOpt onDisplayRefresh(bool usedGpuComposition); [[nodiscard]] bool isVsyncConfigDefault() const; protected: // Called from unit tests as well void binderDied(const wp<IBinder>&) override EXCLUDES(mMutex); private: enum class VsyncConfigType { Early, EarlyGpu, Late }; VsyncConfigType getNextVsyncConfigType() const REQUIRES(mMutex); const VsyncConfig& getNextVsyncConfig() const REQUIRES(mMutex); [[nodiscard]] VsyncConfig updateVsyncConfig() EXCLUDES(mMutex); [[nodiscard]] VsyncConfig updateVsyncConfigLocked() REQUIRES(mMutex); Loading
services/surfaceflinger/SurfaceFlinger.cpp +17 −6 Original line number Diff line number Diff line Loading @@ -3810,7 +3810,7 @@ bool SurfaceFlinger::frameIsEarly(nsecs_t expectedPresentTime, int64_t vsyncId) prediction->presentTime - expectedPresentTime >= earlyLatchVsyncThreshold; } bool SurfaceFlinger::shouldLatchUnsignaled(const sp<Layer>& layer, const layer_state_t& state, size_t numStates, size_t totalTXapplied) { size_t numStates, size_t totalTXapplied) const { if (enableLatchUnsignaledConfig == LatchUnsignaledConfig::Disabled) { ALOGV("%s: false (LatchUnsignaledConfig::Disabled)", __func__); return false; Loading @@ -3828,13 +3828,24 @@ bool SurfaceFlinger::shouldLatchUnsignaled(const sp<Layer>& layer, const layer_s return false; } if (enableLatchUnsignaledConfig == LatchUnsignaledConfig::AutoSingleLayer && totalTXapplied > 0) { ALOGV("%s: false (LatchUnsignaledConfig::AutoSingleLayer; totalTXapplied=%zu)", __func__, totalTXapplied); if (enableLatchUnsignaledConfig == LatchUnsignaledConfig::AutoSingleLayer) { if (totalTXapplied > 0) { ALOGV("%s: false (LatchUnsignaledConfig::AutoSingleLayer; totalTXapplied=%zu)", __func__, totalTXapplied); return false; } // We don't want to latch unsignaled if are in early / client composition // as it leads to jank due to RenderEngine waiting for unsignaled buffer // or window animations being slow. const auto isDefaultVsyncConfig = mVsyncModulator->isVsyncConfigDefault(); if (!isDefaultVsyncConfig) { ALOGV("%s: false (LatchUnsignaledConfig::AutoSingleLayer; !isDefaultVsyncConfig)", __func__); return false; } } if (!layer->simpleBufferUpdate(state)) { ALOGV("%s: false (!simpleBufferUpdate)", __func__); return false; Loading
services/surfaceflinger/SurfaceFlinger.h +2 −2 Original line number Diff line number Diff line Loading @@ -782,8 +782,8 @@ private: const std::unordered_set<sp<IBinder>, SpHash<IBinder>>& bufferLayersReadyToPresent, size_t totalTXapplied) const REQUIRES(mStateLock); static LatchUnsignaledConfig getLatchUnsignaledConfig(); static bool shouldLatchUnsignaled(const sp<Layer>& layer, const layer_state_t&, size_t numStates, size_t totalTXapplied); bool shouldLatchUnsignaled(const sp<Layer>& layer, const layer_state_t&, size_t numStates, size_t totalTXapplied) const; bool stopTransactionProcessing(const std::unordered_set<sp<IBinder>, SpHash<IBinder>>& applyTokensWithUnsignaledTransactions) const; bool applyTransactions(std::vector<TransactionState>& transactions, int64_t vsyncId) Loading
services/surfaceflinger/tests/unittests/TestableSurfaceFlinger.h +2 −0 Original line number Diff line number Diff line Loading @@ -270,6 +270,8 @@ public: scheduler::TestableScheduler& mutableScheduler() { return *mScheduler; } scheduler::mock::SchedulerCallback& mockSchedulerCallback() { return mSchedulerCallback; } auto& mutableVsyncModulator() { return mFlinger->mVsyncModulator; } using CreateBufferQueueFunction = surfaceflinger::test::Factory::CreateBufferQueueFunction; void setCreateBufferQueueFunction(CreateBufferQueueFunction f) { mFactory.mCreateBufferQueue = f; Loading