From 00feb50078fc971412667c0598f91144dd0aa645 Mon Sep 17 00:00:00 2001 From: Wei Wang Date: Tue, 18 Oct 2022 10:56:59 -0700 Subject: [PATCH] PerformanceHint: optimize rate limit Skip rate limit when first hit target. Also for 1st frame boost Bug: 254293108 Test: Build Signed-off-by: Wei Wang Change-Id: I0268de156ba2c34723c1593c76a64331016cc87c --- native/android/performance_hint.cpp | 45 ++++++++++++++++++++--------- 1 file changed, 31 insertions(+), 14 deletions(-) diff --git a/native/android/performance_hint.cpp b/native/android/performance_hint.cpp index 7863a7dba1a7c..40eb507a52139 100644 --- a/native/android/performance_hint.cpp +++ b/native/android/performance_hint.cpp @@ -71,8 +71,10 @@ private: const int64_t mPreferredRateNanos; // Target duration for choosing update rate int64_t mTargetDurationNanos; - // Last update timestamp - int64_t mLastUpdateTimestamp; + // First target hit timestamp + int64_t mFirstTargetMetTimestamp; + // Last target hit timestamp + int64_t mLastTargetMetTimestamp; // Cached samples std::vector mActualDurationsNanos; std::vector mTimestampsNanos; @@ -144,7 +146,8 @@ APerformanceHintSession::APerformanceHintSession(sp session, : mHintSession(std::move(session)), mPreferredRateNanos(preferredRateNanos), mTargetDurationNanos(targetDurationNanos), - mLastUpdateTimestamp(elapsedRealtimeNano()) {} + mFirstTargetMetTimestamp(0), + mLastTargetMetTimestamp(0) {} APerformanceHintSession::~APerformanceHintSession() { binder::Status ret = mHintSession->close(); @@ -171,7 +174,8 @@ int APerformanceHintSession::updateTargetWorkDuration(int64_t targetDurationNano */ mActualDurationsNanos.clear(); mTimestampsNanos.clear(); - mLastUpdateTimestamp = elapsedRealtimeNano(); + mFirstTargetMetTimestamp = 0; + mLastTargetMetTimestamp = 0; return 0; } @@ -184,25 +188,38 @@ int APerformanceHintSession::reportActualWorkDuration(int64_t actualDurationNano mActualDurationsNanos.push_back(actualDurationNanos); mTimestampsNanos.push_back(now); - /** - * Cache the hint if the hint is not overtime and the mLastUpdateTimestamp is - * still in the mPreferredRateNanos duration. - */ - if (actualDurationNanos < mTargetDurationNanos && - now - mLastUpdateTimestamp <= mPreferredRateNanos) { - return 0; + if (actualDurationNanos >= mTargetDurationNanos) { + // Reset timestamps if we are equal or over the target. + mFirstTargetMetTimestamp = 0; + } else { + // Set mFirstTargetMetTimestamp for first time meeting target. + if (!mFirstTargetMetTimestamp || !mLastTargetMetTimestamp || + (now - mLastTargetMetTimestamp > 2 * mPreferredRateNanos)) { + mFirstTargetMetTimestamp = now; + } + /** + * Rate limit the change if the update is over mPreferredRateNanos since first + * meeting target and less than mPreferredRateNanos since last meeting target. + */ + if (now - mFirstTargetMetTimestamp > mPreferredRateNanos && + now - mLastTargetMetTimestamp <= mPreferredRateNanos) { + return 0; + } + mLastTargetMetTimestamp = now; } binder::Status ret = mHintSession->reportActualWorkDuration(mActualDurationsNanos, mTimestampsNanos); - mActualDurationsNanos.clear(); - mTimestampsNanos.clear(); if (!ret.isOk()) { ALOGE("%s: HintSession reportActualWorkDuration failed: %s", __FUNCTION__, ret.exceptionMessage().c_str()); + mFirstTargetMetTimestamp = 0; + mLastTargetMetTimestamp = 0; return EPIPE; } - mLastUpdateTimestamp = now; + mActualDurationsNanos.clear(); + mTimestampsNanos.clear(); + return 0; }