Loading libs/gui/BufferQueueCore.cpp +48 −48 Original line number Original line Diff line number Diff line Loading @@ -84,8 +84,8 @@ static status_t getProcessName(int pid, String8& name) { return INVALID_OPERATION; return INVALID_OPERATION; } } BufferQueueCore::BufferQueueCore() : BufferQueueCore::BufferQueueCore() mMutex(), : mMutex(), mIsAbandoned(false), mIsAbandoned(false), mConsumerControlledByApp(false), mConsumerControlledByApp(false), mConsumerName(getUniqueName()), mConsumerName(getUniqueName()), Loading Loading @@ -130,8 +130,8 @@ BufferQueueCore::BufferQueueCore() : mLastQueuedSlot(INVALID_BUFFER_SLOT), mLastQueuedSlot(INVALID_BUFFER_SLOT), mUniqueId(getUniqueId()), mUniqueId(getUniqueId()), mAutoPrerotation(false), mAutoPrerotation(false), mTransformHintInUse(0) mTransformHintInUse(0), { mFrameRate(0) { int numStartingBuffers = getMaxBufferCountLocked(); int numStartingBuffers = getMaxBufferCountLocked(); for (int s = 0; s < numStartingBuffers; s++) { for (int s = 0; s < numStartingBuffers; s++) { mFreeSlots.insert(s); mFreeSlots.insert(s); Loading services/surfaceflinger/BufferQueueLayer.cpp +4 −2 Original line number Original line Diff line number Diff line Loading @@ -130,8 +130,10 @@ bool BufferQueueLayer::setFrameRate(float frameRate) { } } std::optional<float> BufferQueueLayer::getFrameRate() const { std::optional<float> BufferQueueLayer::getFrameRate() const { if (mLatchedFrameRate > 0.f || mLatchedFrameRate == FRAME_RATE_NO_VOTE) const auto frameRate = mLatchedFrameRate.load(); return mLatchedFrameRate; if (frameRate > 0.f || frameRate == FRAME_RATE_NO_VOTE) { return frameRate; } return {}; return {}; } } Loading services/surfaceflinger/Scheduler/LayerInfoV2.cpp +2 −3 Original line number Original line Diff line number Diff line Loading @@ -57,7 +57,7 @@ bool LayerInfoV2::isRecentlyActive(nsecs_t now) const { bool LayerInfoV2::isFrequent(nsecs_t now) const { bool LayerInfoV2::isFrequent(nsecs_t now) const { // Assume layer is infrequent if too few present times have been recorded. // Assume layer is infrequent if too few present times have been recorded. if (mFrameTimes.size() < FREQUENT_LAYER_WINDOW_SIZE) { 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 // 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); 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 // 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) { for (auto it = mFrameTimes.begin(); it != mFrameTimes.end() - 1; ++it) { const nsecs_t presentTimeDeltas = const nsecs_t presentTimeDeltas = std::max(((it + 1)->presetTime - it->presetTime), mHighRefreshRatePeriod); std::max(((it + 1)->presetTime - it->presetTime), mHighRefreshRatePeriod); Loading services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp +8 −5 Original line number Original line Diff line number Diff line Loading @@ -125,12 +125,13 @@ const RefreshRate& RefreshRateConfigs::getRefreshRateForContentV2( } } for (const auto& layer : layers) { 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 || if (layer.vote == LayerVoteType::NoVote || layer.vote == LayerVoteType::Min || layer.vote == LayerVoteType::Max) { layer.vote == LayerVoteType::Max) { continue; 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) { if (explicitVoteLayers > 0 && layer.vote == LayerVoteType::Heuristic) { continue; continue; } } Loading @@ -148,24 +149,26 @@ const RefreshRate& RefreshRateConfigs::getRefreshRateForContentV2( } } float layerScore; float layerScore; static constexpr size_t MAX_FRAMES_TO_FIT = 10; // Stop calculating when score < 0.1 if (displayFramesRem == 0) { if (displayFramesRem == 0) { // Layer desired refresh rate matches the display rate. // Layer desired refresh rate matches the display rate. layerScore = layer.weight * 1.0f; layerScore = layer.weight * 1.0f; } else if (displayFramesQuot == 0) { } else if (displayFramesQuot == 0) { // Layer desired refresh rate is higher the display rate. // 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 { } else { // Layer desired refresh rate is lower the display rate. Check how well it fits the // Layer desired refresh rate is lower the display rate. Check how well it fits the // cadence // cadence auto diff = std::abs(displayFramesRem - (displayPeriod - displayFramesRem)); auto diff = std::abs(displayFramesRem - (displayPeriod - displayFramesRem)); int iter = 2; int iter = 2; static constexpr size_t MAX_ITERATOR = 10; // Stop calculating when score < 0.1 while (diff > MARGIN && iter < MAX_FRAMES_TO_FIT) { while (diff > MARGIN && iter < MAX_ITERATOR) { diff = diff - (displayPeriod - diff); diff = diff - (displayPeriod - diff); iter++; 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(), 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 Original line Diff line number Diff line Loading @@ -34,6 +34,7 @@ namespace android::scheduler { class LayerHistoryTestV2 : public testing::Test { class LayerHistoryTestV2 : public testing::Test { protected: 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 PRESENT_TIME_HISTORY_SIZE = LayerInfoV2::HISTORY_SIZE; static constexpr auto MAX_FREQUENT_LAYER_PERIOD_NS = LayerInfoV2::MAX_FREQUENT_LAYER_PERIOD_NS; 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++) { for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE - 1; i++) { history().record(layer.get(), 0, mTime); history().record(layer.get(), 0, mTime); ASSERT_EQ(1, history().summarize(mTime).size()); 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()); EXPECT_EQ(1, activeLayerCount()); } } Loading @@ -129,7 +133,8 @@ TEST_F(LayerHistoryTestV2, oneInvisibleLayer) { history().record(layer.get(), 0, mTime); history().record(layer.get(), 0, mTime); auto summary = history().summarize(mTime); auto summary = history().summarize(mTime); ASSERT_EQ(1, history().summarize(mTime).size()); 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_EQ(1, activeLayerCount()); EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(false)); EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(false)); Loading Loading
libs/gui/BufferQueueCore.cpp +48 −48 Original line number Original line Diff line number Diff line Loading @@ -84,8 +84,8 @@ static status_t getProcessName(int pid, String8& name) { return INVALID_OPERATION; return INVALID_OPERATION; } } BufferQueueCore::BufferQueueCore() : BufferQueueCore::BufferQueueCore() mMutex(), : mMutex(), mIsAbandoned(false), mIsAbandoned(false), mConsumerControlledByApp(false), mConsumerControlledByApp(false), mConsumerName(getUniqueName()), mConsumerName(getUniqueName()), Loading Loading @@ -130,8 +130,8 @@ BufferQueueCore::BufferQueueCore() : mLastQueuedSlot(INVALID_BUFFER_SLOT), mLastQueuedSlot(INVALID_BUFFER_SLOT), mUniqueId(getUniqueId()), mUniqueId(getUniqueId()), mAutoPrerotation(false), mAutoPrerotation(false), mTransformHintInUse(0) mTransformHintInUse(0), { mFrameRate(0) { int numStartingBuffers = getMaxBufferCountLocked(); int numStartingBuffers = getMaxBufferCountLocked(); for (int s = 0; s < numStartingBuffers; s++) { for (int s = 0; s < numStartingBuffers; s++) { mFreeSlots.insert(s); mFreeSlots.insert(s); Loading
services/surfaceflinger/BufferQueueLayer.cpp +4 −2 Original line number Original line Diff line number Diff line Loading @@ -130,8 +130,10 @@ bool BufferQueueLayer::setFrameRate(float frameRate) { } } std::optional<float> BufferQueueLayer::getFrameRate() const { std::optional<float> BufferQueueLayer::getFrameRate() const { if (mLatchedFrameRate > 0.f || mLatchedFrameRate == FRAME_RATE_NO_VOTE) const auto frameRate = mLatchedFrameRate.load(); return mLatchedFrameRate; if (frameRate > 0.f || frameRate == FRAME_RATE_NO_VOTE) { return frameRate; } return {}; return {}; } } Loading
services/surfaceflinger/Scheduler/LayerInfoV2.cpp +2 −3 Original line number Original line Diff line number Diff line Loading @@ -57,7 +57,7 @@ bool LayerInfoV2::isRecentlyActive(nsecs_t now) const { bool LayerInfoV2::isFrequent(nsecs_t now) const { bool LayerInfoV2::isFrequent(nsecs_t now) const { // Assume layer is infrequent if too few present times have been recorded. // Assume layer is infrequent if too few present times have been recorded. if (mFrameTimes.size() < FREQUENT_LAYER_WINDOW_SIZE) { 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 // 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); 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 // 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) { for (auto it = mFrameTimes.begin(); it != mFrameTimes.end() - 1; ++it) { const nsecs_t presentTimeDeltas = const nsecs_t presentTimeDeltas = std::max(((it + 1)->presetTime - it->presetTime), mHighRefreshRatePeriod); std::max(((it + 1)->presetTime - it->presetTime), mHighRefreshRatePeriod); Loading
services/surfaceflinger/Scheduler/RefreshRateConfigs.cpp +8 −5 Original line number Original line Diff line number Diff line Loading @@ -125,12 +125,13 @@ const RefreshRate& RefreshRateConfigs::getRefreshRateForContentV2( } } for (const auto& layer : layers) { 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 || if (layer.vote == LayerVoteType::NoVote || layer.vote == LayerVoteType::Min || layer.vote == LayerVoteType::Max) { layer.vote == LayerVoteType::Max) { continue; 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) { if (explicitVoteLayers > 0 && layer.vote == LayerVoteType::Heuristic) { continue; continue; } } Loading @@ -148,24 +149,26 @@ const RefreshRate& RefreshRateConfigs::getRefreshRateForContentV2( } } float layerScore; float layerScore; static constexpr size_t MAX_FRAMES_TO_FIT = 10; // Stop calculating when score < 0.1 if (displayFramesRem == 0) { if (displayFramesRem == 0) { // Layer desired refresh rate matches the display rate. // Layer desired refresh rate matches the display rate. layerScore = layer.weight * 1.0f; layerScore = layer.weight * 1.0f; } else if (displayFramesQuot == 0) { } else if (displayFramesQuot == 0) { // Layer desired refresh rate is higher the display rate. // 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 { } else { // Layer desired refresh rate is lower the display rate. Check how well it fits the // Layer desired refresh rate is lower the display rate. Check how well it fits the // cadence // cadence auto diff = std::abs(displayFramesRem - (displayPeriod - displayFramesRem)); auto diff = std::abs(displayFramesRem - (displayPeriod - displayFramesRem)); int iter = 2; int iter = 2; static constexpr size_t MAX_ITERATOR = 10; // Stop calculating when score < 0.1 while (diff > MARGIN && iter < MAX_FRAMES_TO_FIT) { while (diff > MARGIN && iter < MAX_ITERATOR) { diff = diff - (displayPeriod - diff); diff = diff - (displayPeriod - diff); iter++; 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(), 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 Original line Diff line number Diff line Loading @@ -34,6 +34,7 @@ namespace android::scheduler { class LayerHistoryTestV2 : public testing::Test { class LayerHistoryTestV2 : public testing::Test { protected: 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 PRESENT_TIME_HISTORY_SIZE = LayerInfoV2::HISTORY_SIZE; static constexpr auto MAX_FREQUENT_LAYER_PERIOD_NS = LayerInfoV2::MAX_FREQUENT_LAYER_PERIOD_NS; 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++) { for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE - 1; i++) { history().record(layer.get(), 0, mTime); history().record(layer.get(), 0, mTime); ASSERT_EQ(1, history().summarize(mTime).size()); 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()); EXPECT_EQ(1, activeLayerCount()); } } Loading @@ -129,7 +133,8 @@ TEST_F(LayerHistoryTestV2, oneInvisibleLayer) { history().record(layer.get(), 0, mTime); history().record(layer.get(), 0, mTime); auto summary = history().summarize(mTime); auto summary = history().summarize(mTime); ASSERT_EQ(1, history().summarize(mTime).size()); 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_EQ(1, activeLayerCount()); EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(false)); EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(false)); Loading