summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
author Ady Abraham <adyabr@google.com> 2020-09-22 19:34:01 -0700
committer Ady Abraham <adyabr@google.com> 2020-09-29 12:15:22 -0700
commit2afd66e968d94ced15f563fb6b11c973bde135a1 (patch)
tree38c1955c046cb5901614845b631eb19113a9ed78
parent2287185dd60c1537001e539223bc3ab1a03955d0 (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.java14
-rw-r--r--core/java/android/view/SurfaceControl.java15
-rw-r--r--core/jni/android_view_SurfaceControl.cpp9
-rw-r--r--graphics/java/android/graphics/FrameInfo.java1
-rw-r--r--services/core/java/com/android/server/wm/WindowAnimator.java7
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) {