Merge "SF TimeStats: fix a display on time logic bug"
diff --git a/services/surfaceflinger/TimeStats/TimeStats.cpp b/services/surfaceflinger/TimeStats/TimeStats.cpp
index 43fa262..c219afd 100644
--- a/services/surfaceflinger/TimeStats/TimeStats.cpp
+++ b/services/surfaceflinger/TimeStats/TimeStats.cpp
@@ -451,6 +451,8 @@
 }
 
 void TimeStats::flushPowerTimeLocked() {
+    if (!mEnabled.load()) return;
+
     nsecs_t curTime = systemTime();
     // elapsedTime is in milliseconds.
     int64_t elapsedTime = (curTime - mPowerTime.prevTime) / 1000000;
@@ -500,10 +502,14 @@
         ALOGV("GlobalPresentFenceTime[%" PRId64 "]",
               mGlobalRecord.presentFences.front()->getSignalTime());
 
-        const int32_t presentToPresentMs = msBetween(mGlobalRecord.prevPresentTime, curPresentTime);
-        ALOGV("Global present2present[%d]", presentToPresentMs);
+        if (mGlobalRecord.prevPresentTime != 0) {
+            const int32_t presentToPresentMs =
+                    msBetween(mGlobalRecord.prevPresentTime, curPresentTime);
+            ALOGV("Global present2present[%d] prev[%" PRId64 "] curr[%" PRId64 "]",
+                  presentToPresentMs, mGlobalRecord.prevPresentTime, curPresentTime);
+            mTimeStats.presentToPresent.insert(presentToPresentMs);
+        }
 
-        mTimeStats.presentToPresent.insert(presentToPresentMs);
         mGlobalRecord.prevPresentTime = curPresentTime;
         mGlobalRecord.presentFences.pop_front();
     }
@@ -514,7 +520,15 @@
 
     ATRACE_CALL();
     std::lock_guard<std::mutex> lock(mMutex);
-    if (presentFence == nullptr) {
+    if (presentFence == nullptr || !presentFence->isValid()) {
+        mGlobalRecord.prevPresentTime = 0;
+        return;
+    }
+
+    if (mPowerTime.powerMode != HWC_POWER_MODE_NORMAL) {
+        // Try flushing the last present fence on HWC_POWER_MODE_NORMAL.
+        flushAvailableGlobalRecordsToStatsLocked();
+        mGlobalRecord.presentFences.clear();
         mGlobalRecord.prevPresentTime = 0;
         return;
     }
@@ -537,10 +551,10 @@
     ATRACE_CALL();
 
     std::lock_guard<std::mutex> lock(mMutex);
-    ALOGD("Enabled");
     mEnabled.store(true);
     mTimeStats.statsStart = static_cast<int64_t>(std::time(0));
     mPowerTime.prevTime = systemTime();
+    ALOGD("Enabled");
 }
 
 void TimeStats::disable() {
@@ -549,16 +563,17 @@
     ATRACE_CALL();
 
     std::lock_guard<std::mutex> lock(mMutex);
-    ALOGD("Disabled");
+    flushPowerTimeLocked();
     mEnabled.store(false);
     mTimeStats.statsEnd = static_cast<int64_t>(std::time(0));
+    ALOGD("Disabled");
 }
 
 void TimeStats::clear() {
     ATRACE_CALL();
 
     std::lock_guard<std::mutex> lock(mMutex);
-    ALOGD("Cleared");
+    mTimeStatsTracker.clear();
     mTimeStats.stats.clear();
     mTimeStats.statsStart = (mEnabled.load() ? static_cast<int64_t>(std::time(0)) : 0);
     mTimeStats.statsEnd = 0;
@@ -568,6 +583,9 @@
     mTimeStats.displayOnTime = 0;
     mTimeStats.presentToPresent.hist.clear();
     mPowerTime.prevTime = systemTime();
+    mGlobalRecord.prevPresentTime = 0;
+    mGlobalRecord.presentFences.clear();
+    ALOGD("Cleared");
 }
 
 bool TimeStats::isEnabled() {
diff --git a/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp b/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp
index c701224..599ff5c 100644
--- a/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp
+++ b/services/surfaceflinger/TimeStats/timestatsproto/TimeStatsHelper.cpp
@@ -39,7 +39,7 @@
     if (delta < 0) return;
     // std::lower_bound won't work on out of range values
     if (delta > histogramConfig[HISTOGRAM_SIZE - 1]) {
-        hist[histogramConfig[HISTOGRAM_SIZE - 1]]++;
+        hist[histogramConfig[HISTOGRAM_SIZE - 1]] += delta / histogramConfig[HISTOGRAM_SIZE - 1];
         return;
     }
     auto iter = std::lower_bound(histogramConfig.begin(), histogramConfig.end(), delta);