Loading services/surfaceflinger/Scheduler/LayerInfo.cpp +23 −12 Original line number Diff line number Diff line Loading @@ -276,17 +276,16 @@ std::optional<Fps> LayerInfo::calculateRefreshRateIfPossible(const RefreshRateSe if (const auto averageFrameTime = calculateAverageFrameTime()) { const auto refreshRate = Fps::fromPeriodNsecs(*averageFrameTime); const bool refreshRateConsistent = mRefreshRateHistory.add(refreshRate, now); if (refreshRateConsistent) { const auto knownRefreshRate = selector.findClosestKnownFrameRate(refreshRate); const auto closestKnownRefreshRate = mRefreshRateHistory.add(refreshRate, now, selector); if (closestKnownRefreshRate.isValid()) { using fps_approx_ops::operator!=; // To avoid oscillation, use the last calculated refresh rate if it is close enough. if (std::abs(mLastRefreshRate.calculated.getValue() - refreshRate.getValue()) > MARGIN && mLastRefreshRate.reported != knownRefreshRate) { mLastRefreshRate.reported != closestKnownRefreshRate) { mLastRefreshRate.calculated = refreshRate; mLastRefreshRate.reported = knownRefreshRate; mLastRefreshRate.reported = closestKnownRefreshRate; } ALOGV("%s %s rounded to nearest known frame rate %s", mName.c_str(), Loading Loading @@ -432,7 +431,8 @@ void LayerInfo::RefreshRateHistory::clear() { mRefreshRates.clear(); } bool LayerInfo::RefreshRateHistory::add(Fps refreshRate, nsecs_t now) { Fps LayerInfo::RefreshRateHistory::add(Fps refreshRate, nsecs_t now, const RefreshRateSelector& selector) { mRefreshRates.push_back({refreshRate, now}); while (mRefreshRates.size() >= HISTORY_SIZE || now - mRefreshRates.front().timestamp > HISTORY_DURATION.count()) { Loading @@ -447,11 +447,11 @@ bool LayerInfo::RefreshRateHistory::add(Fps refreshRate, nsecs_t now) { ATRACE_INT(mHeuristicTraceTagData->average.c_str(), refreshRate.getIntValue()); } return isConsistent(); return selectRefreshRate(selector); } bool LayerInfo::RefreshRateHistory::isConsistent() const { if (mRefreshRates.empty()) return true; Fps LayerInfo::RefreshRateHistory::selectRefreshRate(const RefreshRateSelector& selector) const { if (mRefreshRates.empty()) return Fps(); const auto [min, max] = std::minmax_element(mRefreshRates.begin(), mRefreshRates.end(), Loading @@ -459,8 +459,19 @@ bool LayerInfo::RefreshRateHistory::isConsistent() const { return isStrictlyLess(lhs.refreshRate, rhs.refreshRate); }); const bool consistent = max->refreshRate.getValue() - min->refreshRate.getValue() < MARGIN_CONSISTENT_FPS; const auto maxClosestRate = selector.findClosestKnownFrameRate(max->refreshRate); const bool consistent = [&](Fps maxFps, Fps minFps) { if (FlagManager::getInstance().use_known_refresh_rate_for_fps_consistency()) { if (maxFps.getValue() - minFps.getValue() < MARGIN_CONSISTENT_FPS_FOR_CLOSEST_REFRESH_RATE) { const auto minClosestRate = selector.findClosestKnownFrameRate(minFps); using fps_approx_ops::operator==; return maxClosestRate == minClosestRate; } return false; } return maxFps.getValue() - minFps.getValue() < MARGIN_CONSISTENT_FPS; }(max->refreshRate, min->refreshRate); if (CC_UNLIKELY(sTraceEnabled)) { if (!mHeuristicTraceTagData.has_value()) { Loading @@ -472,7 +483,7 @@ bool LayerInfo::RefreshRateHistory::isConsistent() const { ATRACE_INT(mHeuristicTraceTagData->consistent.c_str(), consistent); } return consistent; return consistent ? maxClosestRate : Fps(); } FrameRateCompatibility LayerInfo::FrameRate::convertCompatibility(int8_t compatibility) { Loading services/surfaceflinger/Scheduler/LayerInfo.h +4 −3 Original line number Diff line number Diff line Loading @@ -265,8 +265,8 @@ private: // Clears History void clear(); // Adds a new refresh rate and returns true if it is consistent bool add(Fps refreshRate, nsecs_t now); // Adds a new refresh rate and returns valid refresh rate if it is consistent enough Fps add(Fps refreshRate, nsecs_t now, const RefreshRateSelector&); private: friend class LayerHistoryTest; Loading @@ -286,13 +286,14 @@ private: std::string average; }; bool isConsistent() const; Fps selectRefreshRate(const RefreshRateSelector&) const; HeuristicTraceTagData makeHeuristicTraceTagData() const; const std::string mName; mutable std::optional<HeuristicTraceTagData> mHeuristicTraceTagData; std::deque<RefreshRateData> mRefreshRates; static constexpr float MARGIN_CONSISTENT_FPS = 1.0; static constexpr float MARGIN_CONSISTENT_FPS_FOR_CLOSEST_REFRESH_RATE = 5.0; }; // Represents whether we were able to determine either layer is frequent or infrequent Loading services/surfaceflinger/common/FlagManager.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -121,6 +121,7 @@ void FlagManager::dump(std::string& result) const { DUMP_READ_ONLY_FLAG(hdcp_level_hal); DUMP_READ_ONLY_FLAG(multithreaded_present); DUMP_READ_ONLY_FLAG(add_sf_skipped_frames_to_trace); DUMP_READ_ONLY_FLAG(use_known_refresh_rate_for_fps_consistency); #undef DUMP_READ_ONLY_FLAG #undef DUMP_SERVER_FLAG Loading Loading @@ -190,6 +191,7 @@ FLAG_MANAGER_READ_ONLY_FLAG(hotplug2, "") FLAG_MANAGER_READ_ONLY_FLAG(hdcp_level_hal, "") FLAG_MANAGER_READ_ONLY_FLAG(multithreaded_present, "debug.sf.multithreaded_present") FLAG_MANAGER_READ_ONLY_FLAG(add_sf_skipped_frames_to_trace, "") FLAG_MANAGER_READ_ONLY_FLAG(use_known_refresh_rate_for_fps_consistency, "") /// Trunk stable server flags /// FLAG_MANAGER_SERVER_FLAG(late_boot_misc2, "") Loading services/surfaceflinger/common/include/common/FlagManager.h +1 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ public: bool hdcp_level_hal() const; bool multithreaded_present() const; bool add_sf_skipped_frames_to_trace() const; bool use_known_refresh_rate_for_fps_consistency() const; protected: // overridden for unit tests Loading services/surfaceflinger/surfaceflinger_flags.aconfig +8 −0 Original line number Diff line number Diff line Loading @@ -84,3 +84,11 @@ flag { description: "enable refresh rate indicator on the external display" bug: "301647974" } flag { name: "use_known_refresh_rate_for_fps_consistency" namespace: "core_graphics" description: "Whether to use the closest known refresh rate to determine the fps consistency." bug: "299201319" is_fixed_read_only: true } Loading
services/surfaceflinger/Scheduler/LayerInfo.cpp +23 −12 Original line number Diff line number Diff line Loading @@ -276,17 +276,16 @@ std::optional<Fps> LayerInfo::calculateRefreshRateIfPossible(const RefreshRateSe if (const auto averageFrameTime = calculateAverageFrameTime()) { const auto refreshRate = Fps::fromPeriodNsecs(*averageFrameTime); const bool refreshRateConsistent = mRefreshRateHistory.add(refreshRate, now); if (refreshRateConsistent) { const auto knownRefreshRate = selector.findClosestKnownFrameRate(refreshRate); const auto closestKnownRefreshRate = mRefreshRateHistory.add(refreshRate, now, selector); if (closestKnownRefreshRate.isValid()) { using fps_approx_ops::operator!=; // To avoid oscillation, use the last calculated refresh rate if it is close enough. if (std::abs(mLastRefreshRate.calculated.getValue() - refreshRate.getValue()) > MARGIN && mLastRefreshRate.reported != knownRefreshRate) { mLastRefreshRate.reported != closestKnownRefreshRate) { mLastRefreshRate.calculated = refreshRate; mLastRefreshRate.reported = knownRefreshRate; mLastRefreshRate.reported = closestKnownRefreshRate; } ALOGV("%s %s rounded to nearest known frame rate %s", mName.c_str(), Loading Loading @@ -432,7 +431,8 @@ void LayerInfo::RefreshRateHistory::clear() { mRefreshRates.clear(); } bool LayerInfo::RefreshRateHistory::add(Fps refreshRate, nsecs_t now) { Fps LayerInfo::RefreshRateHistory::add(Fps refreshRate, nsecs_t now, const RefreshRateSelector& selector) { mRefreshRates.push_back({refreshRate, now}); while (mRefreshRates.size() >= HISTORY_SIZE || now - mRefreshRates.front().timestamp > HISTORY_DURATION.count()) { Loading @@ -447,11 +447,11 @@ bool LayerInfo::RefreshRateHistory::add(Fps refreshRate, nsecs_t now) { ATRACE_INT(mHeuristicTraceTagData->average.c_str(), refreshRate.getIntValue()); } return isConsistent(); return selectRefreshRate(selector); } bool LayerInfo::RefreshRateHistory::isConsistent() const { if (mRefreshRates.empty()) return true; Fps LayerInfo::RefreshRateHistory::selectRefreshRate(const RefreshRateSelector& selector) const { if (mRefreshRates.empty()) return Fps(); const auto [min, max] = std::minmax_element(mRefreshRates.begin(), mRefreshRates.end(), Loading @@ -459,8 +459,19 @@ bool LayerInfo::RefreshRateHistory::isConsistent() const { return isStrictlyLess(lhs.refreshRate, rhs.refreshRate); }); const bool consistent = max->refreshRate.getValue() - min->refreshRate.getValue() < MARGIN_CONSISTENT_FPS; const auto maxClosestRate = selector.findClosestKnownFrameRate(max->refreshRate); const bool consistent = [&](Fps maxFps, Fps minFps) { if (FlagManager::getInstance().use_known_refresh_rate_for_fps_consistency()) { if (maxFps.getValue() - minFps.getValue() < MARGIN_CONSISTENT_FPS_FOR_CLOSEST_REFRESH_RATE) { const auto minClosestRate = selector.findClosestKnownFrameRate(minFps); using fps_approx_ops::operator==; return maxClosestRate == minClosestRate; } return false; } return maxFps.getValue() - minFps.getValue() < MARGIN_CONSISTENT_FPS; }(max->refreshRate, min->refreshRate); if (CC_UNLIKELY(sTraceEnabled)) { if (!mHeuristicTraceTagData.has_value()) { Loading @@ -472,7 +483,7 @@ bool LayerInfo::RefreshRateHistory::isConsistent() const { ATRACE_INT(mHeuristicTraceTagData->consistent.c_str(), consistent); } return consistent; return consistent ? maxClosestRate : Fps(); } FrameRateCompatibility LayerInfo::FrameRate::convertCompatibility(int8_t compatibility) { Loading
services/surfaceflinger/Scheduler/LayerInfo.h +4 −3 Original line number Diff line number Diff line Loading @@ -265,8 +265,8 @@ private: // Clears History void clear(); // Adds a new refresh rate and returns true if it is consistent bool add(Fps refreshRate, nsecs_t now); // Adds a new refresh rate and returns valid refresh rate if it is consistent enough Fps add(Fps refreshRate, nsecs_t now, const RefreshRateSelector&); private: friend class LayerHistoryTest; Loading @@ -286,13 +286,14 @@ private: std::string average; }; bool isConsistent() const; Fps selectRefreshRate(const RefreshRateSelector&) const; HeuristicTraceTagData makeHeuristicTraceTagData() const; const std::string mName; mutable std::optional<HeuristicTraceTagData> mHeuristicTraceTagData; std::deque<RefreshRateData> mRefreshRates; static constexpr float MARGIN_CONSISTENT_FPS = 1.0; static constexpr float MARGIN_CONSISTENT_FPS_FOR_CLOSEST_REFRESH_RATE = 5.0; }; // Represents whether we were able to determine either layer is frequent or infrequent Loading
services/surfaceflinger/common/FlagManager.cpp +2 −0 Original line number Diff line number Diff line Loading @@ -121,6 +121,7 @@ void FlagManager::dump(std::string& result) const { DUMP_READ_ONLY_FLAG(hdcp_level_hal); DUMP_READ_ONLY_FLAG(multithreaded_present); DUMP_READ_ONLY_FLAG(add_sf_skipped_frames_to_trace); DUMP_READ_ONLY_FLAG(use_known_refresh_rate_for_fps_consistency); #undef DUMP_READ_ONLY_FLAG #undef DUMP_SERVER_FLAG Loading Loading @@ -190,6 +191,7 @@ FLAG_MANAGER_READ_ONLY_FLAG(hotplug2, "") FLAG_MANAGER_READ_ONLY_FLAG(hdcp_level_hal, "") FLAG_MANAGER_READ_ONLY_FLAG(multithreaded_present, "debug.sf.multithreaded_present") FLAG_MANAGER_READ_ONLY_FLAG(add_sf_skipped_frames_to_trace, "") FLAG_MANAGER_READ_ONLY_FLAG(use_known_refresh_rate_for_fps_consistency, "") /// Trunk stable server flags /// FLAG_MANAGER_SERVER_FLAG(late_boot_misc2, "") Loading
services/surfaceflinger/common/include/common/FlagManager.h +1 −0 Original line number Diff line number Diff line Loading @@ -60,6 +60,7 @@ public: bool hdcp_level_hal() const; bool multithreaded_present() const; bool add_sf_skipped_frames_to_trace() const; bool use_known_refresh_rate_for_fps_consistency() const; protected: // overridden for unit tests Loading
services/surfaceflinger/surfaceflinger_flags.aconfig +8 −0 Original line number Diff line number Diff line Loading @@ -84,3 +84,11 @@ flag { description: "enable refresh rate indicator on the external display" bug: "301647974" } flag { name: "use_known_refresh_rate_for_fps_consistency" namespace: "core_graphics" description: "Whether to use the closest known refresh rate to determine the fps consistency." bug: "299201319" is_fixed_read_only: true }