Avoid sync calls for unsupported/non-existant times

* Make sure not to do sync calls for present or retire
  if they aren't supported.

* Don't do sync calls for retire or release if they
  can not possibly exist.

Test: adb shell /data/nativetest/libgui_test/libgui_test
--gtest_filter=*GetFrameTimestamps*

Change-Id: I580409f01cbf07e9a6e00fbb05d914654f12a4a2
diff --git a/libs/gui/Surface.cpp b/libs/gui/Surface.cpp
index 1e79e06..a172c32 100644
--- a/libs/gui/Surface.cpp
+++ b/libs/gui/Surface.cpp
@@ -49,7 +49,6 @@
       mAutoRefresh(false),
       mSharedBufferSlot(BufferItem::INVALID_BUFFER_SLOT),
       mSharedBufferHasBeenQueued(false),
-      mNextFrameNumber(1),
       mQueriedSupportedTimestamps(false),
       mFrameTimestampsSupportsPresent(false),
       mFrameTimestampsSupportsRetire(false),
@@ -144,6 +143,31 @@
     mEnableFrameTimestamps = enable;
 }
 
+static bool checkConsumerForUpdates(
+        const FrameEvents* e, const uint64_t lastFrameNumber,
+        const nsecs_t* outRefreshStartTime,
+        const nsecs_t* outGlCompositionDoneTime,
+        const nsecs_t* outDisplayPresentTime,
+        const nsecs_t* outDisplayRetireTime,
+        const nsecs_t* outReleaseTime) {
+    bool checkForRefreshStart = (outRefreshStartTime != nullptr) &&
+            !e->hasFirstRefreshStartInfo();
+    bool checkForGlCompositionDone = (outGlCompositionDoneTime != nullptr) &&
+            !e->hasGpuCompositionDoneInfo();
+    bool checkForDisplayPresent = (outDisplayPresentTime != nullptr) &&
+            !e->hasDisplayPresentInfo();
+
+    // DisplayRetire and Release are never available for the last frame.
+    bool checkForDisplayRetire = (outDisplayRetireTime != nullptr) &&
+            !e->hasDisplayRetireInfo() && (e->frameNumber != lastFrameNumber);
+    bool checkForRelease = (outReleaseTime != nullptr) &&
+            !e->hasReleaseInfo() && (e->frameNumber != lastFrameNumber);
+
+    // RequestedPresent and Acquire info are always available producer-side.
+    return checkForRefreshStart || checkForGlCompositionDone ||
+            checkForDisplayPresent || checkForDisplayRetire || checkForRelease;
+}
+
 static void getFrameTimestamp(nsecs_t *dst, const nsecs_t& src) {
     if (dst != nullptr) {
         *dst = Fence::isValidTimestamp(src) ? src : 0;
@@ -180,24 +204,25 @@
     }
 
     FrameEvents* events = mFrameEventHistory.getFrame(frameNumber);
-
-    // Update our cache of events if the requested events are not available.
-    if (events == nullptr ||
-        (outRequestedPresentTime && !events->hasRequestedPresentInfo()) ||
-        (outAcquireTime && !events->hasAcquireInfo()) ||
-        (outRefreshStartTime && !events->hasFirstRefreshStartInfo()) ||
-        (outGlCompositionDoneTime && !events->hasGpuCompositionDoneInfo()) ||
-        (outDisplayPresentTime && !events->hasDisplayPresentInfo()) ||
-        (outDisplayRetireTime && !events->hasDisplayRetireInfo()) ||
-        (outReleaseTime && !events->hasReleaseInfo())) {
-            FrameEventHistoryDelta delta;
-            mGraphicBufferProducer->getFrameTimestamps(&delta);
-            mFrameEventHistory.applyDelta(delta);
-            events = mFrameEventHistory.getFrame(frameNumber);
+    if (events == nullptr) {
+        // If the entry isn't available in the producer, it's definitely not
+        // available in the consumer.
+        return NAME_NOT_FOUND;
     }
 
-    // A record for the requested frame does not exist.
+    // Update our cache of events if the requested events are not available.
+    if (checkConsumerForUpdates(events, mLastFrameNumber,
+            outRefreshStartTime, outGlCompositionDoneTime,
+            outDisplayPresentTime, outDisplayRetireTime, outReleaseTime)) {
+        FrameEventHistoryDelta delta;
+        mGraphicBufferProducer->getFrameTimestamps(&delta);
+        mFrameEventHistory.applyDelta(delta);
+        events = mFrameEventHistory.getFrame(frameNumber);
+    }
+
     if (events == nullptr) {
+        // The entry was available before the update, but was overwritten
+        // after the update. Make sure not to send the wrong frame's data.
         return NAME_NOT_FOUND;
     }
 
@@ -347,11 +372,9 @@
     nsecs_t now = systemTime();
 
     FrameEventHistoryDelta frameTimestamps;
-    FrameEventHistoryDelta* frameTimestampsOrNull =
-            enableFrameTimestamps ? &frameTimestamps : nullptr;
-
     status_t result = mGraphicBufferProducer->dequeueBuffer(&buf, &fence,
-            reqWidth, reqHeight, reqFormat, reqUsage, frameTimestampsOrNull);
+            reqWidth, reqHeight, reqFormat, reqUsage,
+            enableFrameTimestamps ? &frameTimestamps : nullptr);
     mLastDequeueDuration = systemTime() - now;
 
     if (result < 0) {
@@ -579,6 +602,8 @@
         mFrameEventHistory.updateSignalTimes();
     }
 
+    mLastFrameNumber = mNextFrameNumber;
+
     mDefaultWidth = output.width;
     mDefaultHeight = output.height;
     mNextFrameNumber = output.nextFrameNumber;