hack up frame latency measurement

Change-Id: I6d9a466a23285304f0e229a5649815636ab5d6af
diff --git a/opengl/libs/EGL/eglApi.cpp b/opengl/libs/EGL/eglApi.cpp
index 664f258..8b37da5 100644
--- a/opengl/libs/EGL/eglApi.cpp
+++ b/opengl/libs/EGL/eglApi.cpp
@@ -477,6 +477,26 @@
     return result;
 }
 
+void EGLAPI eglBeginFrame(EGLDisplay dpy, EGLSurface surface) {
+    clearError();
+
+    egl_display_t const * const dp = validate_display(dpy);
+    if (!dp) {
+        return;
+    }
+
+    SurfaceRef _s(dp, surface);
+    if (!_s.get()) {
+        setError(EGL_BAD_SURFACE, EGL_FALSE);
+        return;
+    }
+
+    int64_t timestamp = systemTime(SYSTEM_TIME_MONOTONIC);
+
+    egl_surface_t const * const s = get_surface(surface);
+    native_window_set_buffers_timestamp(s->win.get(), timestamp);
+}
+
 // ----------------------------------------------------------------------------
 // Contexts
 // ----------------------------------------------------------------------------
diff --git a/services/surfaceflinger/Layer.cpp b/services/surfaceflinger/Layer.cpp
index d4c4b1f..51efdc2 100644
--- a/services/surfaceflinger/Layer.cpp
+++ b/services/surfaceflinger/Layer.cpp
@@ -63,6 +63,22 @@
 {
     mCurrentCrop.makeInvalid();
     glGenTextures(1, &mTextureName);
+
+    mFrameLatencyNeeded = false;
+    mFrameLatencyOffset = 0;
+    for (int i = 0; i < 128; i++) {
+        mFrameLatencies[i] = 0;
+    }
+}
+
+void Layer::onLayerDisplayed() {
+    if (mFrameLatencyNeeded) {
+        int64_t now = systemTime(SYSTEM_TIME_MONOTONIC);
+        mFrameLatencies[mFrameLatencyOffset] = now -
+                mSurfaceTexture->getTimestamp();
+        mFrameLatencyOffset = (mFrameLatencyOffset + 1) % 128;
+        mFrameLatencyNeeded = false;
+    }
 }
 
 void Layer::onFirstRef()
@@ -408,6 +424,7 @@
 
         // update the active buffer
         mActiveBuffer = mSurfaceTexture->getCurrentBuffer();
+        mFrameLatencyNeeded = true;
 
         const Rect crop(mSurfaceTexture->getCurrentCrop());
         const uint32_t transform(mSurfaceTexture->getCurrentTransform());
@@ -538,6 +555,18 @@
 
     result.append(buffer);
 
+    const int64_t* l = mFrameLatencies;
+    int o = mFrameLatencyOffset;
+    for (int i = 0; i < 128; i += 8) {
+        snprintf(buffer, SIZE,
+                "      "
+                "% 12lld % 12lld % 12lld % 12lld "
+                "% 12lld % 12lld % 12lld % 12lld\n",
+                l[(o+i+0)%128], l[(o+i+1)%128], l[(o+i+2)%128], l[(o+i+3)%128],
+                l[(o+i+4)%128], l[(o+i+5)%128], l[(o+i+6)%128], l[(o+i+7)%128]);
+        result.append(buffer);
+    }
+
     if (mSurfaceTexture != 0) {
         mSurfaceTexture->dump(result, "            ", buffer, SIZE);
     }
diff --git a/services/surfaceflinger/Layer.h b/services/surfaceflinger/Layer.h
index 2b9471b..9686259 100644
--- a/services/surfaceflinger/Layer.h
+++ b/services/surfaceflinger/Layer.h
@@ -78,6 +78,8 @@
     // LayerBaseClient interface
     virtual wp<IBinder> getSurfaceTextureBinder() const;
 
+    virtual void onLayerDisplayed();
+
     // only for debugging
     inline const sp<GraphicBuffer>& getActiveBuffer() const { return mActiveBuffer; }
 
@@ -110,6 +112,9 @@
     uint32_t mCurrentTransform;
     uint32_t mCurrentScalingMode;
     bool mCurrentOpacity;
+    bool mFrameLatencyNeeded;
+    int mFrameLatencyOffset;
+    int64_t mFrameLatencies[128];
 
     // constants
     PixelFormat mFormat;
diff --git a/services/surfaceflinger/LayerBase.h b/services/surfaceflinger/LayerBase.h
index 7f62145..0c1b228 100644
--- a/services/surfaceflinger/LayerBase.h
+++ b/services/surfaceflinger/LayerBase.h
@@ -205,7 +205,9 @@
     /** called with the state lock when the surface is removed from the
      *  current list */
     virtual void onRemoved() { };
-    
+
+    virtual void onLayerDisplayed() { };
+
     /** always call base class first */
     virtual void dump(String8& result, char* scratch, size_t size) const;
     virtual void shortDump(String8& result, char* scratch, size_t size) const;
diff --git a/services/surfaceflinger/SurfaceFlinger.cpp b/services/surfaceflinger/SurfaceFlinger.cpp
index af47402..b295201 100644
--- a/services/surfaceflinger/SurfaceFlinger.cpp
+++ b/services/surfaceflinger/SurfaceFlinger.cpp
@@ -445,6 +445,12 @@
     const nsecs_t now = systemTime();
     mDebugInSwapBuffers = now;
     hw.flip(mSwapRegion);
+
+    size_t numLayers = mVisibleLayersSortedByZ.size();
+    for (size_t i = 0; i < numLayers; i++) {
+        mVisibleLayersSortedByZ[i]->onLayerDisplayed();
+    }
+
     mLastSwapBufferTime = systemTime() - now;
     mDebugInSwapBuffers = 0;
     mSwapRegion.clear();