Loading core/java/android/view/Choreographer.java +14 −0 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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; Loading Loading @@ -715,6 +728,7 @@ public final class Choreographer { mFrameInfo.setVsync(intendedFrameTimeNanos, frameTimeNanos, frameTimelineVsyncId); mFrameScheduled = false; mLastFrameTimeNanos = frameTimeNanos; mLastVsyncId = frameTimelineVsyncId; } try { Loading core/java/android/view/SurfaceControl.java +15 −0 Original line number Diff line number Diff line Loading @@ -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") Loading Loading @@ -3340,6 +3342,19 @@ public final class SurfaceControl implements Parcelable { return this; } /** * 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 Loading core/jni/android_view_SurfaceControl.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -1558,6 +1558,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[] = { Loading Loading @@ -1742,6 +1749,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 }; Loading graphics/java/android/graphics/FrameInfo.java +1 −0 Original line number Diff line number Diff line Loading @@ -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 = { Loading services/core/java/com/android/server/wm/WindowAnimator.java +5 −2 Original line number Diff line number Diff line Loading @@ -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(); } Loading @@ -125,7 +126,7 @@ public class WindowAnimator { mInitialized = true; } private void animate(long frameTimeNs) { private void animate(long frameTimeNs, long vsyncId) { if (!mInitialized) { return; } Loading @@ -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) { Loading Loading
core/java/android/view/Choreographer.java +14 −0 Original line number Diff line number Diff line Loading @@ -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, Loading Loading @@ -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; Loading Loading @@ -715,6 +728,7 @@ public final class Choreographer { mFrameInfo.setVsync(intendedFrameTimeNanos, frameTimeNanos, frameTimelineVsyncId); mFrameScheduled = false; mLastFrameTimeNanos = frameTimeNanos; mLastVsyncId = frameTimelineVsyncId; } try { Loading
core/java/android/view/SurfaceControl.java +15 −0 Original line number Diff line number Diff line Loading @@ -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") Loading Loading @@ -3340,6 +3342,19 @@ public final class SurfaceControl implements Parcelable { return this; } /** * 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 Loading
core/jni/android_view_SurfaceControl.cpp +9 −0 Original line number Diff line number Diff line Loading @@ -1558,6 +1558,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[] = { Loading Loading @@ -1742,6 +1749,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 }; Loading
graphics/java/android/graphics/FrameInfo.java +1 −0 Original line number Diff line number Diff line Loading @@ -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 = { Loading
services/core/java/com/android/server/wm/WindowAnimator.java +5 −2 Original line number Diff line number Diff line Loading @@ -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(); } Loading @@ -125,7 +126,7 @@ public class WindowAnimator { mInitialized = true; } private void animate(long frameTimeNs) { private void animate(long frameTimeNs, long vsyncId) { if (!mInitialized) { return; } Loading @@ -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) { Loading