Loading libs/gui/BufferQueueCore.cpp +48 −48 Original line number Diff line number Diff line Loading @@ -84,8 +84,8 @@ static status_t getProcessName(int pid, String8& name) { return INVALID_OPERATION; } BufferQueueCore::BufferQueueCore() : mMutex(), BufferQueueCore::BufferQueueCore() : mMutex(), mIsAbandoned(false), mConsumerControlledByApp(false), mConsumerName(getUniqueName()), Loading Loading @@ -130,8 +130,8 @@ BufferQueueCore::BufferQueueCore() : mLastQueuedSlot(INVALID_BUFFER_SLOT), mUniqueId(getUniqueId()), mAutoPrerotation(false), mTransformHintInUse(0) { mTransformHintInUse(0), mFrameRate(0) { int numStartingBuffers = getMaxBufferCountLocked(); for (int s = 0; s < numStartingBuffers; s++) { mFreeSlots.insert(s); Loading services/surfaceflinger/BufferQueueLayer.cpp +4 −2 Original line number Diff line number Diff line Loading @@ -130,8 +130,10 @@ bool BufferQueueLayer::setFrameRate(float frameRate) { } std::optional<float> BufferQueueLayer::getFrameRate() const { if (mLatchedFrameRate > 0.f || mLatchedFrameRate == FRAME_RATE_NO_VOTE) return mLatchedFrameRate; const auto frameRate = mLatchedFrameRate.load(); if (frameRate > 0.f || frameRate == FRAME_RATE_NO_VOTE) { return frameRate; } return {}; } Loading services/surfaceflinger/Scheduler/LayerInfoV2.cpp +2 −3 Original line number Diff line number Diff line Loading @@ -57,7 +57,7 @@ bool LayerInfoV2::isRecentlyActive(nsecs_t now) const { bool LayerInfoV2::isFrequent(nsecs_t now) const { // Assume layer is infrequent if too few present times have been recorded. if (mFrameTimes.size() < FREQUENT_LAYER_WINDOW_SIZE) { return true; return false; } // Layer is frequent if the earliest value in the window of most recent present times is Loading Loading @@ -100,8 +100,7 @@ std::optional<float> LayerInfoV2::calculateRefreshRateIfPossible() { static_cast<float>(totalPresentTimeDeltas) / (mFrameTimes.size() - 1); // Now once we calculated the refresh rate we need to make sure that all the frames we captured // are evenly distrubuted and we don't calculate the average across some burst of frames. // are evenly distributed and we don't calculate the average across some burst of frames. for (auto it = mFrameTimes.begin(); it != mFrameTimes.end() - 1; ++it) { const nsecs_t presentTimeDeltas = std::max(((it + 1)->presetTime - it->presetTime), mHighRefreshRatePeriod); Loading services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp +8 −5 Original line number Diff line number Diff line Loading @@ -125,12 +125,13 @@ const RefreshRate& RefreshRateConfigs::getRefreshRateForContentV2( } for (const auto& layer : layers) { ALOGV("Calculating score for %s (type: %d)", layer.name.c_str(), layer.vote); if (layer.vote == LayerVoteType::NoVote || layer.vote == LayerVoteType::Min || layer.vote == LayerVoteType::Max) { continue; } // If we have Explicit layers, ignore the Huristic ones // If we have Explicit layers, ignore the Hueristic ones if (explicitVoteLayers > 0 && layer.vote == LayerVoteType::Heuristic) { continue; } Loading @@ -148,24 +149,26 @@ const RefreshRate& RefreshRateConfigs::getRefreshRateForContentV2( } float layerScore; static constexpr size_t MAX_FRAMES_TO_FIT = 10; // Stop calculating when score < 0.1 if (displayFramesRem == 0) { // Layer desired refresh rate matches the display rate. layerScore = layer.weight * 1.0f; } else if (displayFramesQuot == 0) { // Layer desired refresh rate is higher the display rate. layerScore = layer.weight * layerPeriod / displayPeriod; layerScore = layer.weight * (static_cast<float>(layerPeriod) / static_cast<float>(displayPeriod)) * (1.0f / (MAX_FRAMES_TO_FIT + 1)); } else { // Layer desired refresh rate is lower the display rate. Check how well it fits the // cadence auto diff = std::abs(displayFramesRem - (displayPeriod - displayFramesRem)); int iter = 2; static constexpr size_t MAX_ITERATOR = 10; // Stop calculating when score < 0.1 while (diff > MARGIN && iter < MAX_ITERATOR) { while (diff > MARGIN && iter < MAX_FRAMES_TO_FIT) { diff = diff - (displayPeriod - diff); iter++; } layerScore = layer.weight * 1.0f / iter; layerScore = layer.weight * (1.0f / iter); } ALOGV("%s (weight %.2f) %.2fHz gives %s score of %.2f", layer.name.c_str(), Loading services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp +7 −2 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ namespace android::scheduler { class LayerHistoryTestV2 : public testing::Test { protected: static constexpr auto FREQUENT_LAYER_WINDOW_SIZE = LayerInfoV2::FREQUENT_LAYER_WINDOW_SIZE; static constexpr auto PRESENT_TIME_HISTORY_SIZE = LayerInfoV2::HISTORY_SIZE; static constexpr auto MAX_FREQUENT_LAYER_PERIOD_NS = LayerInfoV2::MAX_FREQUENT_LAYER_PERIOD_NS; Loading Loading @@ -105,7 +106,10 @@ TEST_F(LayerHistoryTestV2, oneLayer) { for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE - 1; i++) { history().record(layer.get(), 0, mTime); ASSERT_EQ(1, history().summarize(mTime).size()); EXPECT_EQ(LayerHistory::LayerVoteType::Max, history().summarize(mTime)[0].vote); const auto expectedType = (i + 1 < FREQUENT_LAYER_WINDOW_SIZE) ? LayerHistory::LayerVoteType::Min : LayerHistory::LayerVoteType::Max; EXPECT_EQ(expectedType, history().summarize(mTime)[0].vote); EXPECT_EQ(1, activeLayerCount()); } Loading @@ -129,7 +133,8 @@ TEST_F(LayerHistoryTestV2, oneInvisibleLayer) { history().record(layer.get(), 0, mTime); auto summary = history().summarize(mTime); ASSERT_EQ(1, history().summarize(mTime).size()); EXPECT_EQ(LayerHistory::LayerVoteType::Max, history().summarize(mTime)[0].vote); // Layer is still considered inactive so we expect to get Min EXPECT_EQ(LayerHistory::LayerVoteType::Min, history().summarize(mTime)[0].vote); EXPECT_EQ(1, activeLayerCount()); EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(false)); Loading Loading
libs/gui/BufferQueueCore.cpp +48 −48 Original line number Diff line number Diff line Loading @@ -84,8 +84,8 @@ static status_t getProcessName(int pid, String8& name) { return INVALID_OPERATION; } BufferQueueCore::BufferQueueCore() : mMutex(), BufferQueueCore::BufferQueueCore() : mMutex(), mIsAbandoned(false), mConsumerControlledByApp(false), mConsumerName(getUniqueName()), Loading Loading @@ -130,8 +130,8 @@ BufferQueueCore::BufferQueueCore() : mLastQueuedSlot(INVALID_BUFFER_SLOT), mUniqueId(getUniqueId()), mAutoPrerotation(false), mTransformHintInUse(0) { mTransformHintInUse(0), mFrameRate(0) { int numStartingBuffers = getMaxBufferCountLocked(); for (int s = 0; s < numStartingBuffers; s++) { mFreeSlots.insert(s); Loading
services/surfaceflinger/BufferQueueLayer.cpp +4 −2 Original line number Diff line number Diff line Loading @@ -130,8 +130,10 @@ bool BufferQueueLayer::setFrameRate(float frameRate) { } std::optional<float> BufferQueueLayer::getFrameRate() const { if (mLatchedFrameRate > 0.f || mLatchedFrameRate == FRAME_RATE_NO_VOTE) return mLatchedFrameRate; const auto frameRate = mLatchedFrameRate.load(); if (frameRate > 0.f || frameRate == FRAME_RATE_NO_VOTE) { return frameRate; } return {}; } Loading
services/surfaceflinger/Scheduler/LayerInfoV2.cpp +2 −3 Original line number Diff line number Diff line Loading @@ -57,7 +57,7 @@ bool LayerInfoV2::isRecentlyActive(nsecs_t now) const { bool LayerInfoV2::isFrequent(nsecs_t now) const { // Assume layer is infrequent if too few present times have been recorded. if (mFrameTimes.size() < FREQUENT_LAYER_WINDOW_SIZE) { return true; return false; } // Layer is frequent if the earliest value in the window of most recent present times is Loading Loading @@ -100,8 +100,7 @@ std::optional<float> LayerInfoV2::calculateRefreshRateIfPossible() { static_cast<float>(totalPresentTimeDeltas) / (mFrameTimes.size() - 1); // Now once we calculated the refresh rate we need to make sure that all the frames we captured // are evenly distrubuted and we don't calculate the average across some burst of frames. // are evenly distributed and we don't calculate the average across some burst of frames. for (auto it = mFrameTimes.begin(); it != mFrameTimes.end() - 1; ++it) { const nsecs_t presentTimeDeltas = std::max(((it + 1)->presetTime - it->presetTime), mHighRefreshRatePeriod); Loading
services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp +8 −5 Original line number Diff line number Diff line Loading @@ -125,12 +125,13 @@ const RefreshRate& RefreshRateConfigs::getRefreshRateForContentV2( } for (const auto& layer : layers) { ALOGV("Calculating score for %s (type: %d)", layer.name.c_str(), layer.vote); if (layer.vote == LayerVoteType::NoVote || layer.vote == LayerVoteType::Min || layer.vote == LayerVoteType::Max) { continue; } // If we have Explicit layers, ignore the Huristic ones // If we have Explicit layers, ignore the Hueristic ones if (explicitVoteLayers > 0 && layer.vote == LayerVoteType::Heuristic) { continue; } Loading @@ -148,24 +149,26 @@ const RefreshRate& RefreshRateConfigs::getRefreshRateForContentV2( } float layerScore; static constexpr size_t MAX_FRAMES_TO_FIT = 10; // Stop calculating when score < 0.1 if (displayFramesRem == 0) { // Layer desired refresh rate matches the display rate. layerScore = layer.weight * 1.0f; } else if (displayFramesQuot == 0) { // Layer desired refresh rate is higher the display rate. layerScore = layer.weight * layerPeriod / displayPeriod; layerScore = layer.weight * (static_cast<float>(layerPeriod) / static_cast<float>(displayPeriod)) * (1.0f / (MAX_FRAMES_TO_FIT + 1)); } else { // Layer desired refresh rate is lower the display rate. Check how well it fits the // cadence auto diff = std::abs(displayFramesRem - (displayPeriod - displayFramesRem)); int iter = 2; static constexpr size_t MAX_ITERATOR = 10; // Stop calculating when score < 0.1 while (diff > MARGIN && iter < MAX_ITERATOR) { while (diff > MARGIN && iter < MAX_FRAMES_TO_FIT) { diff = diff - (displayPeriod - diff); iter++; } layerScore = layer.weight * 1.0f / iter; layerScore = layer.weight * (1.0f / iter); } ALOGV("%s (weight %.2f) %.2fHz gives %s score of %.2f", layer.name.c_str(), Loading
services/surfaceflinger/tests/unittests/LayerHistoryTestV2.cpp +7 −2 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ namespace android::scheduler { class LayerHistoryTestV2 : public testing::Test { protected: static constexpr auto FREQUENT_LAYER_WINDOW_SIZE = LayerInfoV2::FREQUENT_LAYER_WINDOW_SIZE; static constexpr auto PRESENT_TIME_HISTORY_SIZE = LayerInfoV2::HISTORY_SIZE; static constexpr auto MAX_FREQUENT_LAYER_PERIOD_NS = LayerInfoV2::MAX_FREQUENT_LAYER_PERIOD_NS; Loading Loading @@ -105,7 +106,10 @@ TEST_F(LayerHistoryTestV2, oneLayer) { for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE - 1; i++) { history().record(layer.get(), 0, mTime); ASSERT_EQ(1, history().summarize(mTime).size()); EXPECT_EQ(LayerHistory::LayerVoteType::Max, history().summarize(mTime)[0].vote); const auto expectedType = (i + 1 < FREQUENT_LAYER_WINDOW_SIZE) ? LayerHistory::LayerVoteType::Min : LayerHistory::LayerVoteType::Max; EXPECT_EQ(expectedType, history().summarize(mTime)[0].vote); EXPECT_EQ(1, activeLayerCount()); } Loading @@ -129,7 +133,8 @@ TEST_F(LayerHistoryTestV2, oneInvisibleLayer) { history().record(layer.get(), 0, mTime); auto summary = history().summarize(mTime); ASSERT_EQ(1, history().summarize(mTime).size()); EXPECT_EQ(LayerHistory::LayerVoteType::Max, history().summarize(mTime)[0].vote); // Layer is still considered inactive so we expect to get Min EXPECT_EQ(LayerHistory::LayerVoteType::Min, history().summarize(mTime)[0].vote); EXPECT_EQ(1, activeLayerCount()); EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(false)); Loading