Plumbing for getting FenceTracker timestamps

Change-Id: I1ebee9e42e28658bd3a2b161fdaabb7da756d8f3
diff --git a/services/surfaceflinger/FenceTracker.cpp b/services/surfaceflinger/FenceTracker.cpp
index d415bd5..3ff9bbf 100644
--- a/services/surfaceflinger/FenceTracker.cpp
+++ b/services/surfaceflinger/FenceTracker.cpp
@@ -26,7 +26,9 @@
 FenceTracker::FenceTracker() :
         mFrameCounter(0),
         mOffset(0),
-        mFrames() {}
+        mFrames(),
+        mMutex() {
+}
 
 void FenceTracker::dump(String8* outString) {
     Mutex::Autolock lock(mMutex);
@@ -135,7 +137,7 @@
         nsecs_t postedTime;
         sp<Fence> acquireFence;
         sp<Fence> prevReleaseFence;
-        int32_t key = layers[i]->getSequence();
+        int32_t layerId = layers[i]->getSequence();
 
         layers[i]->getFenceData(&name, &frameNumber, &glesComposition,
                 &postedTime, &acquireFence, &prevReleaseFence);
@@ -144,13 +146,17 @@
             frame.layers.emplace(std::piecewise_construct,
                     std::forward_as_tuple(key),
                     std::forward_as_tuple(name, frameNumber, glesComposition,
-                    postedTime, 0, 0, acquireFence, prevReleaseFence));
+                    postedTime, FrameTimestamps::INVALID_TIME,
+                    FrameTimestamps::INVALID_TIME, acquireFence,
+                    prevReleaseFence));
             wasGlesCompositionDone = true;
         } else {
             frame.layers.emplace(std::piecewise_construct,
                     std::forward_as_tuple(key),
                     std::forward_as_tuple(name, frameNumber, glesComposition,
-                    postedTime, 0, 0, acquireFence, Fence::NO_FENCE));
+                    postedTime, FrameTimestamps::INVALID_TIME,
+                    FrameTimestamps::INVALID_TIME, acquireFence,
+                    Fence::NO_FENCE));
 
             auto prevLayer = prevFrame.layers.find(key);
             if (prevLayer != prevFrame.layers.end()) {
@@ -159,7 +165,7 @@
         }
 #else
         frame.layers.emplace(std::piecewise_construct,
-                std::forward_as_tuple(key),
+                std::forward_as_tuple(layerId),
                 std::forward_as_tuple(name, frameNumber, glesComposition,
                 postedTime, 0, 0, acquireFence,
                 glesComposition ? Fence::NO_FENCE : prevReleaseFence));
@@ -168,7 +174,7 @@
         }
 #endif
         frame.layers.emplace(std::piecewise_construct,
-                std::forward_as_tuple(key),
+                std::forward_as_tuple(layerId),
                 std::forward_as_tuple(name, frameNumber, glesComposition,
                 postedTime, 0, 0, acquireFence, prevReleaseFence));
     }
@@ -186,4 +192,33 @@
     mFrameCounter++;
 }
 
+bool FenceTracker::getFrameTimestamps(const Layer& layer,
+        uint64_t frameNumber, FrameTimestamps* outTimestamps) {
+    Mutex::Autolock lock(mMutex);
+    checkFencesForCompletion();
+    int32_t layerId = layer.getSequence();
+
+    size_t i = 0;
+    for (; i < MAX_FRAME_HISTORY; i++) {
+       if (mFrames[i].layers.count(layerId) &&
+               mFrames[i].layers[layerId].frameNumber == frameNumber) {
+           break;
+       }
+    }
+    if (i == MAX_FRAME_HISTORY) {
+        return false;
+    }
+
+    const FrameRecord& frameRecord = mFrames[i];
+    const LayerRecord& layerRecord = mFrames[i].layers[layerId];
+    outTimestamps->frameNumber = frameNumber;
+    outTimestamps->postedTime = layerRecord.postedTime;
+    outTimestamps->acquireTime = layerRecord.acquireTime;
+    outTimestamps->refreshStartTime = frameRecord.refreshStartTime;
+    outTimestamps->glCompositionDoneTime = frameRecord.glesCompositionDoneTime;
+    outTimestamps->displayRetireTime = frameRecord.retireTime;
+    outTimestamps->releaseTime = layerRecord.releaseTime;
+    return true;
+}
+
 } // namespace android
diff --git a/services/surfaceflinger/FenceTracker.h b/services/surfaceflinger/FenceTracker.h
index 2fcc314..4cb14a5 100644
--- a/services/surfaceflinger/FenceTracker.h
+++ b/services/surfaceflinger/FenceTracker.h
@@ -29,7 +29,7 @@
 namespace android {
 
 class Layer;
-
+struct FrameTimestamps;
 /*
  * Keeps a circular buffer of fence/timestamp data for the last N frames in
  * SurfaceFlinger. Gets timestamps for fences after they have signaled.
@@ -40,6 +40,8 @@
      void dump(String8* outString);
      void addFrame(nsecs_t refreshStartTime, sp<Fence> retireFence,
              const Vector<sp<Layer>>& layers, sp<Fence> glDoneFence);
+     bool getFrameTimestamps(const Layer& layer, uint64_t frameNumber,
+             FrameTimestamps* outTimestamps);
 
 protected:
      static constexpr size_t MAX_FRAME_HISTORY = 8;
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index abf0e6c..15e5615 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -154,7 +154,8 @@
     sp<IGraphicBufferConsumer> consumer;
     BufferQueue::createBufferQueue(&producer, &consumer);
     mProducer = new MonitoredProducer(producer, mFlinger);
-    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName);
+    mSurfaceFlingerConsumer = new SurfaceFlingerConsumer(consumer, mTextureName,
+            this);
     mSurfaceFlingerConsumer->setConsumerUsageBits(getEffectiveUsage(0));
     mSurfaceFlingerConsumer->setContentsChangedListener(this);
     mSurfaceFlingerConsumer->setName(mName);
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 79750a6..fef2d98 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -409,6 +409,11 @@
 
     std::vector<OccupancyTracker::Segment> getOccupancyHistory(bool forceFlush);
 
+    bool getFrameTimestamps(uint64_t frameNumber,
+            FrameTimestamps* outTimestamps) const {
+        return mFlinger->getFrameTimestamps(*this, frameNumber, outTimestamps);
+    }
+
 protected:
     // constant
     sp<SurfaceFlinger> mFlinger;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index 0276d38..0dc04eb 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -3606,6 +3606,11 @@
     }
 }
 
+bool SurfaceFlinger::getFrameTimestamps(const Layer& layer,
+        uint64_t frameNumber, FrameTimestamps* outTimestamps) {
+    return mFenceTracker.getFrameTimestamps(layer, frameNumber, outTimestamps);
+}
+
 // ---------------------------------------------------------------------------
 
 SurfaceFlinger::LayerVector::LayerVector() {
diff --git a/services/surfaceflinger/SurfaceFlinger.h b/services/surfaceflinger/SurfaceFlinger.h
index 8263994..28666e2 100644
--- a/services/surfaceflinger/SurfaceFlinger.h
+++ b/services/surfaceflinger/SurfaceFlinger.h
@@ -440,6 +440,9 @@
             std::vector<OccupancyTracker::Segment>&& history);
     void dumpBufferingStats(String8& result) const;
 
+    bool getFrameTimestamps(const Layer& layer, uint64_t frameNumber,
+            FrameTimestamps* outTimestamps);
+
     /* ------------------------------------------------------------------------
      * Attributes
      */
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.cpp b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
index c71b3bc..ba0a527 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.cpp
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.cpp
@@ -18,6 +18,7 @@
 //#define LOG_NDEBUG 0
 
 #include "SurfaceFlingerConsumer.h"
+#include "Layer.h"
 
 #include <private/gui/SyncFeatures.h>
 
@@ -251,6 +252,12 @@
     }
 }
 
+bool SurfaceFlingerConsumer::getFrameTimestamps(uint64_t frameNumber,
+        FrameTimestamps* outTimestamps) const {
+    sp<const Layer> l = mLayer.promote();
+    return l.get() ? l->getFrameTimestamps(frameNumber, outTimestamps) : false;
+}
+
 // ---------------------------------------------------------------------------
 }; // namespace android
 
diff --git a/services/surfaceflinger/SurfaceFlingerConsumer.h b/services/surfaceflinger/SurfaceFlingerConsumer.h
index 51b002f..3762659 100644
--- a/services/surfaceflinger/SurfaceFlingerConsumer.h
+++ b/services/surfaceflinger/SurfaceFlingerConsumer.h
@@ -23,6 +23,8 @@
 namespace android {
 // ----------------------------------------------------------------------------
 
+class Layer;
+
 /*
  * This is a thin wrapper around GLConsumer.
  */
@@ -35,10 +37,10 @@
     };
 
     SurfaceFlingerConsumer(const sp<IGraphicBufferConsumer>& consumer,
-            uint32_t tex)
+            uint32_t tex, const Layer* layer)
         : GLConsumer(consumer, tex, GLConsumer::TEXTURE_EXTERNAL, false, false),
           mTransformToDisplayInverse(false), mSurfaceDamage(),
-          mPrevReleaseFence(Fence::NO_FENCE)
+          mPrevReleaseFence(Fence::NO_FENCE), mLayer(layer)
     {}
 
     class BufferRejecter {
@@ -82,6 +84,9 @@
     void releasePendingBuffer();
 #endif
 
+    virtual bool getFrameTimestamps(uint64_t frameNumber,
+            FrameTimestamps* outTimestamps) const override;
+
 private:
     virtual void onSidebandStreamChanged();
 
@@ -103,6 +108,9 @@
 
     // The release fence of the already displayed buffer (previous frame).
     sp<Fence> mPrevReleaseFence;
+
+    // The layer for this SurfaceFlingerConsumer
+    wp<const Layer> mLayer;
 };
 
 // ----------------------------------------------------------------------------
diff --git a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
index 71d7cf9..f4061e7 100644
--- a/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
+++ b/services/surfaceflinger/SurfaceFlinger_hwc1.cpp
@@ -3593,6 +3593,11 @@
     return result;
 }
 
+bool SurfaceFlinger::getFrameTimestamps(const Layer& layer,
+        uint64_t frameNumber, FrameTimestamps* outTimestamps) {
+    return mFenceTracker.getFrameTimestamps(layer, frameNumber, outTimestamps);
+}
+
 void SurfaceFlinger::checkScreenshot(size_t w, size_t s, size_t h, void const* vaddr,
         const sp<const DisplayDevice>& hw, uint32_t minLayerZ, uint32_t maxLayerZ) {
     if (DEBUG_SCREENSHOTS) {