diff options
author | 2020-05-13 03:22:13 +0000 | |
---|---|---|
committer | 2020-05-13 03:22:13 +0000 | |
commit | ed9fb866a936d0ef5863981c5bd283670a8f3544 (patch) | |
tree | fdf8d0ae93da4696ed3a4a3b6bfa61359bcb9fd9 | |
parent | bec285a0d303275d7203a812df1130e8667233f0 (diff) | |
parent | c966483200cabe1a5e236e05c2493f58b24a40c7 (diff) |
SurfaceFlinger: refresh rate heuristic for TextureView am: c966483200
Change-Id: I762f096f351ca2ebb2fd5aee10205ef23e0d865f
-rw-r--r-- | services/surfaceflinger/Scheduler/LayerInfoV2.cpp | 33 | ||||
-rw-r--r-- | services/surfaceflinger/Scheduler/LayerInfoV2.h | 1 |
2 files changed, 29 insertions, 5 deletions
diff --git a/services/surfaceflinger/Scheduler/LayerInfoV2.cpp b/services/surfaceflinger/Scheduler/LayerInfoV2.cpp index bf1fb88de7..b7d0bdd101 100644 --- a/services/surfaceflinger/Scheduler/LayerInfoV2.cpp +++ b/services/surfaceflinger/Scheduler/LayerInfoV2.cpp @@ -111,23 +111,46 @@ std::optional<float> LayerInfoV2::calculateRefreshRateIfPossible() { // Calculate the refresh rate by finding the average delta between frames nsecs_t totalPresentTimeDeltas = 0; + nsecs_t totalQueueTimeDeltas = 0; + auto missingPresentTime = false; for (auto it = mFrameTimes.begin(); it != mFrameTimes.end() - 1; ++it) { - // If there are no presentation timestamp provided we can't calculate the refresh rate + totalQueueTimeDeltas += + std::max(((it + 1)->queueTime - it->queueTime), mHighRefreshRatePeriod); + if (it->presetTime == 0 || (it + 1)->presetTime == 0) { - return std::nullopt; + missingPresentTime = true; + continue; } totalPresentTimeDeltas += std::max(((it + 1)->presetTime - it->presetTime), mHighRefreshRatePeriod); } + + // If there are no presentation timestamps provided we can't calculate the refresh rate + if (missingPresentTime && mLastReportedRefreshRate == 0) { + return std::nullopt; + } + + // Calculate the average frame time based on presentation timestamps. If those + // doesn't exist, we look at the time the buffer was queued only. We can do that only if + // we calculated a refresh rate based on presentation timestamps in the past. The reason + // we look at the queue time is to handle cases where hwui attaches presentation timestamps + // when implementing render ahead for specific refresh rates. When hwui no longer provides + // presentation timestamps we look at the queue time to see if the current refresh rate still + // matches the content. const float averageFrameTime = - static_cast<float>(totalPresentTimeDeltas) / (mFrameTimes.size() - 1); + static_cast<float>(missingPresentTime ? totalQueueTimeDeltas : totalPresentTimeDeltas) / + (mFrameTimes.size() - 1); // Now once we calculated the refresh rate we need to make sure that all the frames we captured // 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); + const auto presentTimeDeltas = [&] { + const auto delta = missingPresentTime ? (it + 1)->queueTime - it->queueTime + : (it + 1)->presetTime - it->presetTime; + return std::max(delta, mHighRefreshRatePeriod); + }(); + if (std::abs(presentTimeDeltas - averageFrameTime) > 2 * averageFrameTime) { return std::nullopt; } diff --git a/services/surfaceflinger/Scheduler/LayerInfoV2.h b/services/surfaceflinger/Scheduler/LayerInfoV2.h index ad91f18fda..e36b7f709e 100644 --- a/services/surfaceflinger/Scheduler/LayerInfoV2.h +++ b/services/surfaceflinger/Scheduler/LayerInfoV2.h @@ -88,6 +88,7 @@ public: // buffer as Max as we don't know anything about this layer or Min as this layer is // posting infrequent updates. mFrameTimeValidSince = std::chrono::steady_clock::now(); + mLastReportedRefreshRate = 0.0f; } private: |