diff options
| author | 2020-09-22 19:34:01 -0700 | |
|---|---|---|
| committer | 2020-09-29 12:15:22 -0700 | |
| commit | 2afd66e968d94ced15f563fb6b11c973bde135a1 (patch) | |
| tree | 38c1955c046cb5901614845b631eb19113a9ed78 | |
| parent | 2287185dd60c1537001e539223bc3ab1a03955d0 (diff) | |
Add vsyncId to transactions
This change is the first in a series of changes to add vsyncIds to
transactions so that SurfaceFlinger could identity jank related
to transactions. In this change we are sending the vsyncIds for
transactions originated by WindowAnimator.
Bug: 166302754
Test: manually see transactions in frame timeline
Change-Id: Ib0e9f4dcc873ab671c2bfded87868bfea2bf9366
| -rw-r--r-- | core/java/android/view/Choreographer.java | 14 | ||||
| -rw-r--r-- | core/java/android/view/SurfaceControl.java | 15 | ||||
| -rw-r--r-- | core/jni/android_view_SurfaceControl.cpp | 9 | ||||
| -rw-r--r-- | graphics/java/android/graphics/FrameInfo.java | 1 | ||||
| -rw-r--r-- | services/core/java/com/android/server/wm/WindowAnimator.java | 7 |
5 files changed, 44 insertions, 2 deletions
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java index 042808a4cad2..e520d7ccaa7a 100644 --- a/core/java/android/view/Choreographer.java +++ b/core/java/android/view/Choreographer.java @@ -181,6 +181,7 @@ public final class Choreographer { private long mFrameIntervalNanos; private boolean mDebugPrintNextFrameTimeDelta; private int mFPSDivisor = 1; + private long mLastVsyncId = FrameInfo.INVALID_VSYNC_ID; /** * Contains information about the current frame for jank-tracking, @@ -654,6 +655,18 @@ public final class Choreographer { } } + /** + * Returns the vsync id of the last frame callback. Client are expected to call + * this function from their frame callback function to get the vsyncId and pass + * it together with a buffer or transaction to the Surface Composer. Calling + * this function from anywhere else will return an undefined value. + * + * @hide + */ + public long getVsyncId() { + return mLastVsyncId; + } + void setFPSDivisor(int divisor) { if (divisor <= 0) divisor = 1; mFPSDivisor = divisor; @@ -713,6 +726,7 @@ public final class Choreographer { mFrameInfo.setVsync(intendedFrameTimeNanos, frameTimeNanos, frameTimelineVsyncId); mFrameScheduled = false; mLastFrameTimeNanos = frameTimeNanos; + mLastVsyncId = frameTimelineVsyncId; } try { diff --git a/core/java/android/view/SurfaceControl.java b/core/java/android/view/SurfaceControl.java index c698b926e233..44e603ea4900 100644 --- a/core/java/android/view/SurfaceControl.java +++ b/core/java/android/view/SurfaceControl.java @@ -225,6 +225,8 @@ public final class SurfaceControl implements Parcelable { int transformHint); private static native void nativeSetFocusedWindow(long transactionObj, IBinder toToken, IBinder focusedToken, int displayId); + private static native void nativeSetFrameTimelineVsync(long transactionObj, + long frameTimelineVsyncId); @Nullable @GuardedBy("mLock") @@ -3341,6 +3343,19 @@ public final class SurfaceControl implements Parcelable { } /** + * Sets the frame timeline vsync id received from choreographer + * {@link Choreographer#getVsyncId()} that corresponds to the transaction submitted on that + * surface control. + * + * @hide + */ + @NonNull + public Transaction setFrameTimelineVsync(long frameTimelineVsyncId) { + nativeSetFrameTimelineVsync(mNativeObject, frameTimelineVsyncId); + return this; + } + + /** * Writes the transaction to parcel, clearing the transaction as if it had been applied so * it can be used to store future transactions. It's the responsibility of the parcel * reader to apply the original transaction. diff --git a/core/jni/android_view_SurfaceControl.cpp b/core/jni/android_view_SurfaceControl.cpp index 9efe4b15ce7a..ba18b56156a4 100644 --- a/core/jni/android_view_SurfaceControl.cpp +++ b/core/jni/android_view_SurfaceControl.cpp @@ -1557,6 +1557,13 @@ static void nativeSetFocusedWindow(JNIEnv* env, jclass clazz, jlong transactionO displayId); } +static void nativeSetFrameTimelineVsync(JNIEnv* env, jclass clazz, jlong transactionObj, + jlong frameTimelineVsyncId) { + auto transaction = reinterpret_cast<SurfaceComposerClient::Transaction*>(transactionObj); + + transaction->setFrameTimelineVsync(frameTimelineVsyncId); +} + // ---------------------------------------------------------------------------- static const JNINativeMethod sSurfaceControlMethods[] = { @@ -1741,6 +1748,8 @@ static const JNINativeMethod sSurfaceControlMethods[] = { (void*)nativeSetFixedTransformHint}, {"nativeSetFocusedWindow", "(JLandroid/os/IBinder;Landroid/os/IBinder;I)V", (void*)nativeSetFocusedWindow}, + {"nativeSetFrameTimelineVsync", "(JJ)V", + (void*)nativeSetFrameTimelineVsync }, // clang-format on }; diff --git a/graphics/java/android/graphics/FrameInfo.java b/graphics/java/android/graphics/FrameInfo.java index 163823fde9f7..f768bc741447 100644 --- a/graphics/java/android/graphics/FrameInfo.java +++ b/graphics/java/android/graphics/FrameInfo.java @@ -52,6 +52,7 @@ public final class FrameInfo { public static final long FLAG_SURFACE_CANVAS = 1 << 2; // An invalid vsync id to be used when FRAME_TIMELINE_VSYNC_ID is unknown + // Needs to be in sync with android::ISurfaceComposer::INVALID_VSYNC_ID in native code public static final long INVALID_VSYNC_ID = -1; @LongDef(flag = true, value = { diff --git a/services/core/java/com/android/server/wm/WindowAnimator.java b/services/core/java/com/android/server/wm/WindowAnimator.java index 5c6266a2f8c4..ff5c17487413 100644 --- a/services/core/java/com/android/server/wm/WindowAnimator.java +++ b/services/core/java/com/android/server/wm/WindowAnimator.java @@ -103,7 +103,8 @@ public class WindowAnimator { mAnimationFrameCallback = frameTimeNs -> { synchronized (mService.mGlobalLock) { mAnimationFrameCallbackScheduled = false; - animate(frameTimeNs); + final long vsyncId = mChoreographer.getVsyncId(); + animate(frameTimeNs, vsyncId); if (mNotifyWhenNoAnimation && !mLastRootAnimating) { mService.mGlobalLock.notifyAll(); } @@ -125,7 +126,7 @@ public class WindowAnimator { mInitialized = true; } - private void animate(long frameTimeNs) { + private void animate(long frameTimeNs, long vsyncId) { if (!mInitialized) { return; } @@ -133,6 +134,8 @@ public class WindowAnimator { // Schedule next frame already such that back-pressure happens continuously. scheduleAnimation(); + mTransaction.setFrameTimelineVsync(vsyncId); + mCurrentTime = frameTimeNs / TimeUtils.NANOS_PER_MS; mBulkUpdateParams = SET_ORIENTATION_CHANGE_COMPLETE; if (DEBUG_WINDOW_TRACE) { |