Add displayPresentTime to getFrameTimestamps

Makes HWC1 use displayRetireTime and HWC2 use
displayPresentTime.

Properly takes into account if HWC2On1Adapter is used.

Returns whether present or retire is supported via
eglQueryTimestampSupportedANDROID, which uses a
cached answer in Surface.

Surface::getFrameTimestamps returns with an error
if the caller requests an unsupported timestamp.

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

Change-Id: Ib91c2d05d7fb5cbf307e2dec1e20e79bcc19d90b
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.cpp b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
index bb2e45a..b4d698f 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.cpp
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.cpp
@@ -601,6 +601,10 @@
     return mDisplayData[displayId].lastRetireFence;
 }
 
+bool HWComposer::retireFenceRepresentsStartOfScanout() const {
+    return mAdapter ? false : true;
+}
+
 sp<Fence> HWComposer::getLayerReleaseFence(int32_t displayId,
         const std::shared_ptr<HWC2::Layer>& layer) const {
     if (!isValidDisplay(displayId)) {
diff --git a/services/surfaceflinger/DisplayHardware/HWComposer.h b/services/surfaceflinger/DisplayHardware/HWComposer.h
index 41671f6..64c0d1b 100644
--- a/services/surfaceflinger/DisplayHardware/HWComposer.h
+++ b/services/surfaceflinger/DisplayHardware/HWComposer.h
@@ -122,6 +122,11 @@
     // last call to presentDisplay
     sp<Fence> getRetireFence(int32_t displayId) const;
 
+    // Returns true if the retire fence represents the start of the display
+    // controller's scan out. This should be true for all HWC2 implementations,
+    // except for the wrapper around HWC1 implementations.
+    bool retireFenceRepresentsStartOfScanout() const;
+
     // Get last release fence for the given layer
     sp<Fence> getLayerReleaseFence(int32_t displayId,
             const std::shared_ptr<HWC2::Layer>& layer) const;
diff --git a/services/surfaceflinger/FenceTracker.cpp b/services/surfaceflinger/FenceTracker.cpp
index 276890d..742c00d 100644
--- a/services/surfaceflinger/FenceTracker.cpp
+++ b/services/surfaceflinger/FenceTracker.cpp
@@ -48,12 +48,21 @@
         } else if (frame.glesCompositionDoneFence != Fence::NO_FENCE) {
             outString->append("- GLES done\tNot signaled\n");
         }
+
+        if (frame.presentTime) {
+            outString->appendFormat("- Present\t%" PRId64 "\n",
+                    frame.presentTime);
+        } else if (frame.presentFence != Fence::NO_FENCE) {
+            outString->append("- Present\tNot signaled\n");
+        }
+
         if (frame.retireTime) {
             outString->appendFormat("- Retire\t%" PRId64 "\n",
                     frame.retireTime);
-        } else {
+        } else if (frame.retireFence != Fence::NO_FENCE) {
             outString->append("- Retire\tNot signaled\n");
         }
+
         for (const auto& kv : frame.layers) {
             const LayerRecord& layer = kv.second;
             outString->appendFormat("-- %s\n", layer.name.string());
@@ -85,6 +94,13 @@
 void FenceTracker::checkFencesForCompletion() {
     ATRACE_CALL();
     for (auto& frame : mFrames) {
+        if (frame.presentFence != Fence::NO_FENCE) {
+            nsecs_t time = frame.presentFence->getSignalTime();
+            if (isValidTimestamp(time)) {
+                frame.presentTime = time;
+                frame.presentFence = Fence::NO_FENCE;
+            }
+        }
         if (frame.retireFence != Fence::NO_FENCE) {
             nsecs_t time = frame.retireFence->getSignalTime();
             if (isValidTimestamp(time)) {
@@ -119,8 +135,9 @@
     }
 }
 
-void FenceTracker::addFrame(nsecs_t refreshStartTime, sp<Fence> retireFence,
-        const Vector<sp<Layer>>& layers, sp<Fence> glDoneFence) {
+void FenceTracker::addFrame(nsecs_t refreshStartTime, sp<Fence> presentFence,
+        sp<Fence> retireFence, const Vector<sp<Layer>>& layers,
+        sp<Fence> glDoneFence) {
     ATRACE_CALL();
     Mutex::Autolock lock(mMutex);
     FrameRecord& frame = mFrames[mOffset];
@@ -177,8 +194,10 @@
 
     frame.frameId = mFrameCounter;
     frame.refreshStartTime = refreshStartTime;
+    frame.presentTime = 0;
     frame.retireTime = 0;
     frame.glesCompositionDoneTime = 0;
+    frame.presentFence = presentFence;
     prevFrame.retireFence = retireFence;
     frame.retireFence = Fence::NO_FENCE;
     frame.glesCompositionDoneFence = wasGlesCompositionDone ? glDoneFence :
@@ -212,6 +231,7 @@
     outTimestamps->acquireTime = layerRecord.acquireTime;
     outTimestamps->refreshStartTime = frameRecord.refreshStartTime;
     outTimestamps->glCompositionDoneTime = frameRecord.glesCompositionDoneTime;
+    outTimestamps->displayPresentTime = frameRecord.presentTime;
     outTimestamps->displayRetireTime = frameRecord.retireTime;
     outTimestamps->releaseTime = layerRecord.releaseTime;
     return true;
diff --git a/services/surfaceflinger/FenceTracker.h b/services/surfaceflinger/FenceTracker.h
index 385c970..3b429d1 100644
--- a/services/surfaceflinger/FenceTracker.h
+++ b/services/surfaceflinger/FenceTracker.h
@@ -38,8 +38,9 @@
 public:
      FenceTracker();
      void dump(String8* outString);
-     void addFrame(nsecs_t refreshStartTime, sp<Fence> retireFence,
-             const Vector<sp<Layer>>& layers, sp<Fence> glDoneFence);
+     void addFrame(nsecs_t refreshStartTime, sp<Fence> presentFence,
+             sp<Fence> retireFence, const Vector<sp<Layer>>& layers,
+             sp<Fence> glDoneFence);
      bool getFrameTimestamps(const Layer& layer, uint64_t frameNumber,
              FrameTimestamps* outTimestamps);
 
@@ -79,18 +80,22 @@
          std::unordered_map<int32_t, LayerRecord> layers;
          // timestamp for when SurfaceFlinger::handleMessageRefresh() was called
          nsecs_t refreshStartTime;
+         // timestamp from the present fence
+         nsecs_t presentTime;
          // timestamp from the retire fence
          nsecs_t retireTime;
          // timestamp from the GLES composition completion fence
          nsecs_t glesCompositionDoneTime;
+         // primary display present fence for this frame
+         sp<Fence> presentFence;
          // primary display retire fence for this frame
          sp<Fence> retireFence;
          // if GLES composition was done, the fence for its completion
          sp<Fence> glesCompositionDoneFence;
 
          FrameRecord() : frameId(0), layers(), refreshStartTime(0),
-                 retireTime(0), glesCompositionDoneTime(0),
-                 retireFence(Fence::NO_FENCE),
+                 presentTime(0), retireTime(0), glesCompositionDoneTime(0),
+                 presentFence(Fence::NO_FENCE), retireFence(Fence::NO_FENCE),
                  glesCompositionDoneFence(Fence::NO_FENCE) {}
      };
 
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 37fd70d..1697540 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -566,6 +566,21 @@
     return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0;
 }
 
+status_t SurfaceFlinger::getSupportedFrameTimestamps(
+        std::vector<SupportableFrameTimestamps>* outSupported) const {
+    *outSupported = {
+        SupportableFrameTimestamps::REQUESTED_PRESENT,
+        SupportableFrameTimestamps::ACQUIRE,
+        SupportableFrameTimestamps::REFRESH_START,
+        SupportableFrameTimestamps::GL_COMPOSITION_DONE_TIME,
+        getHwComposer().retireFenceRepresentsStartOfScanout() ?
+                SupportableFrameTimestamps::DISPLAY_PRESENT_TIME :
+                SupportableFrameTimestamps::DISPLAY_RETIRE_TIME,
+        SupportableFrameTimestamps::RELEASE_TIME,
+    };
+    return NO_ERROR;
+}
+
 status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
         Vector<DisplayInfo>* configs) {
     if ((configs == NULL) || (display.get() == NULL)) {
@@ -1234,7 +1249,17 @@
         }
     }
 
-    mFenceTracker.addFrame(refreshStartTime, presentFence,
+    sp<Fence> fenceTrackerPresentFence;
+    sp<Fence> fenceTrackerRetireFence;
+    if (mHwc->retireFenceRepresentsStartOfScanout()) {
+        fenceTrackerPresentFence = presentFence;
+        fenceTrackerRetireFence = Fence::NO_FENCE;
+    } else {
+        fenceTrackerPresentFence = Fence::NO_FENCE;
+        fenceTrackerRetireFence = presentFence;
+    }
+    mFenceTracker.addFrame(refreshStartTime,
+            fenceTrackerPresentFence, fenceTrackerRetireFence,
             hw->getVisibleLayersSortedByZ(), hw->getClientTargetAcquireFence());
 
     if (mAnimCompositionPending) {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 3af1754..bdb2614 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -200,6 +200,8 @@
     virtual void bootFinished();
     virtual bool authenticateSurfaceTexture(
         const sp<IGraphicBufferProducer>& bufferProducer) const;
+    virtual status_t getSupportedFrameTimestamps(
+            std::vector<SupportableFrameTimestamps>* outSupported) const;
     virtual sp<IDisplayEventConnection> createDisplayEventConnection();
     virtual status_t captureScreen(const sp<IBinder>& display,
             const sp<IGraphicBufferProducer>& producer,
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index 8e5c565..0143d99 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -599,6 +599,19 @@
     return mGraphicBufferProducerList.indexOf(surfaceTextureBinder) >= 0;
 }
 
+status_t SurfaceFlinger::getSupportedFrameTimestamps(
+        std::vector<SupportableFrameTimestamps>* outSupported) const {
+    *outSupported = {
+        SupportableFrameTimestamps::REQUESTED_PRESENT,
+        SupportableFrameTimestamps::ACQUIRE,
+        SupportableFrameTimestamps::REFRESH_START,
+        SupportableFrameTimestamps::GL_COMPOSITION_DONE_TIME,
+        SupportableFrameTimestamps::DISPLAY_RETIRE_TIME,
+        SupportableFrameTimestamps::RELEASE_TIME,
+    };
+    return NO_ERROR;
+}
+
 status_t SurfaceFlinger::getDisplayConfigs(const sp<IBinder>& display,
         Vector<DisplayInfo>* configs) {
     if ((configs == NULL) || (display.get() == NULL)) {
@@ -1148,7 +1161,8 @@
         }
     }
 
-    mFenceTracker.addFrame(refreshStartTime, presentFence,
+    // The present fence is actually a retire fence in HWC1.
+    mFenceTracker.addFrame(refreshStartTime, Fence::NO_FENCE, presentFence,
             hw->getVisibleLayersSortedByZ(), hw->getClientTargetAcquireFence());
 
     if (mAnimCompositionPending) {