diff options
| author | Jamie Gennis <jgennis@google.com> | 2012-01-15 18:54:57 -0800 |
|---|---|---|
| committer | Mathias Agopian <mathias@google.com> | 2012-01-24 15:41:50 -0800 |
| commit | b335fad4705348ff78d764fb4be53dcbe6b67abe (patch) | |
| tree | 0ead32dd0e0e2c74b4e2539a93deacf485f99901 | |
| parent | fa1a91628a706bbe51d91e0ccb9144df8b8529e6 (diff) | |
| download | frameworks_base-b335fad4705348ff78d764fb4be53dcbe6b67abe.zip frameworks_base-b335fad4705348ff78d764fb4be53dcbe6b67abe.tar.gz frameworks_base-b335fad4705348ff78d764fb4be53dcbe6b67abe.tar.bz2 | |
hack up frame latency measurement
Change-Id: I6d9a466a23285304f0e229a5649815636ab5d6af
| -rw-r--r-- | core/java/android/view/HardwareRenderer.java | 12 | ||||
| -rw-r--r-- | core/jni/android_view_HardwareRenderer.cpp | 10 | ||||
| -rw-r--r-- | opengl/libs/EGL/eglApi.cpp | 20 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.cpp | 29 | ||||
| -rw-r--r-- | services/surfaceflinger/Layer.h | 5 | ||||
| -rw-r--r-- | services/surfaceflinger/LayerBase.h | 4 | ||||
| -rw-r--r-- | services/surfaceflinger/SurfaceFlinger.cpp | 6 |
7 files changed, 85 insertions, 1 deletions
diff --git a/core/java/android/view/HardwareRenderer.java b/core/java/android/view/HardwareRenderer.java index 4592ae6..1c9cbbf 100644 --- a/core/java/android/view/HardwareRenderer.java +++ b/core/java/android/view/HardwareRenderer.java @@ -238,6 +238,15 @@ public abstract class HardwareRenderer { private static native void nSetupShadersDiskCache(String cacheFile); /** + * Notifies EGL that the frame is about to be rendered. + */ + private static void beginFrame() { + nBeginFrame(); + } + + private static native void nBeginFrame(); + + /** * Interface used to receive callbacks whenever a view is drawn by * a hardware renderer instance. */ @@ -808,6 +817,7 @@ public abstract class HardwareRenderer { } void onPreDraw(Rect dirty) { + } void onPostDraw() { @@ -832,6 +842,8 @@ public abstract class HardwareRenderer { dirty = null; } + beginFrame(); + onPreDraw(dirty); HardwareCanvas canvas = mCanvas; diff --git a/core/jni/android_view_HardwareRenderer.cpp b/core/jni/android_view_HardwareRenderer.cpp index 09809ec..cdcde51 100644 --- a/core/jni/android_view_HardwareRenderer.cpp +++ b/core/jni/android_view_HardwareRenderer.cpp @@ -22,6 +22,8 @@ #include <EGL/egl_cache.h> +EGLAPI void EGLAPIENTRY eglBeginFrame(EGLDisplay dpy, EGLSurface surface); + namespace android { // ---------------------------------------------------------------------------- @@ -36,6 +38,12 @@ static void android_view_HardwareRenderer_setupShadersDiskCache(JNIEnv* env, job env->ReleaseStringUTFChars(diskCachePath, cacheArray); } +static void android_view_HardwareRenderer_beginFrame(JNIEnv* env, jobject clazz) { + EGLDisplay dpy = eglGetCurrentDisplay(); + EGLSurface surf = eglGetCurrentSurface(EGL_DRAW); + eglBeginFrame(dpy, surf); +} + // ---------------------------------------------------------------------------- // JNI Glue // ---------------------------------------------------------------------------- @@ -45,6 +53,8 @@ const char* const kClassPathName = "android/view/HardwareRenderer"; static JNINativeMethod gMethods[] = { { "nSetupShadersDiskCache", "(Ljava/lang/String;)V", (void*) android_view_HardwareRenderer_setupShadersDiskCache }, + { "nBeginFrame", "()V", + (void*) android_view_HardwareRenderer_beginFrame }, }; int register_android_view_HardwareRenderer(JNIEnv* env) { 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 @@ EGLBoolean eglQuerySurface( EGLDisplay dpy, EGLSurface surface, 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 @@ Layer::Layer(SurfaceFlinger* flinger, { 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 @@ void Layer::lockPageFlip(bool& recomputeVisibleRegions) // update the active buffer mActiveBuffer = mSurfaceTexture->getCurrentBuffer(); + mFrameLatencyNeeded = true; const Rect crop(mSurfaceTexture->getCurrentCrop()); const uint32_t transform(mSurfaceTexture->getCurrentTransform()); @@ -538,6 +555,18 @@ void Layer::dump(String8& result, char* buffer, size_t SIZE) const 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 @@ public: // 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 @@ private: 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 @@ public: /** 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 @@ void SurfaceFlinger::postFramebuffer() 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(); |
