Merge "Use getLatestVsyncEventData for late frame." into tm-dev

This commit is contained in:
TreeHugger Robot
2022-03-22 22:35:50 +00:00
committed by Android (Google) Code Review
3 changed files with 81 additions and 57 deletions

View File

@@ -779,7 +779,9 @@ public final class Choreographer {
+ "time to " + (lastFrameOffset * 0.000001f) + " ms in the past."); + "time to " + (lastFrameOffset * 0.000001f) + " ms in the past.");
} }
frameTimeNanos = startNanos - lastFrameOffset; frameTimeNanos = startNanos - lastFrameOffset;
frameData.setFrameTimeNanos(frameTimeNanos); DisplayEventReceiver.VsyncEventData latestVsyncEventData =
mDisplayEventReceiver.getLatestVsyncEventData();
frameData.updateFrameData(frameTimeNanos, latestVsyncEventData);
} }
if (frameTimeNanos < mLastFrameTimeNanos) { if (frameTimeNanos < mLastFrameTimeNanos) {
@@ -877,7 +879,9 @@ public final class Choreographer {
} }
frameTimeNanos = now - lastFrameOffset; frameTimeNanos = now - lastFrameOffset;
mLastFrameTimeNanos = frameTimeNanos; mLastFrameTimeNanos = frameTimeNanos;
frameData.setFrameTimeNanos(frameTimeNanos); DisplayEventReceiver.VsyncEventData latestVsyncEventData =
mDisplayEventReceiver.getLatestVsyncEventData();
frameData.updateFrameData(frameTimeNanos, latestVsyncEventData);
} }
} }
} }
@@ -1012,11 +1016,6 @@ public final class Choreographer {
return mVsyncId; return mVsyncId;
} }
/** Sets the vsync ID. */
void resetVsyncId() {
mVsyncId = FrameInfo.INVALID_VSYNC_ID;
}
/** /**
* The time in {@link System#nanoTime()} timebase which this frame is expected to be * The time in {@link System#nanoTime()} timebase which this frame is expected to be
* presented. * presented.
@@ -1061,17 +1060,15 @@ public final class Choreographer {
} }
private long mFrameTimeNanos; private long mFrameTimeNanos;
private final FrameTimeline[] mFrameTimelines; private FrameTimeline[] mFrameTimelines;
private final FrameTimeline mPreferredFrameTimeline; private FrameTimeline mPreferredFrameTimeline;
void setFrameTimeNanos(long frameTimeNanos) { void updateFrameData(long frameTimeNanos,
DisplayEventReceiver.VsyncEventData latestVsyncEventData) {
mFrameTimeNanos = frameTimeNanos; mFrameTimeNanos = frameTimeNanos;
for (FrameTimeline ft : mFrameTimelines) { mFrameTimelines = convertFrameTimelines(latestVsyncEventData);
// The ID is no longer valid because the frame time that was registered with the ID mPreferredFrameTimeline =
// no longer matches. mFrameTimelines[latestVsyncEventData.preferredFrameTimelineIndex];
// TODO(b/205721584): Ask SF for valid vsync information.
ft.resetVsyncId();
}
} }
/** The time in nanoseconds when the frame started being rendered. */ /** The time in nanoseconds when the frame started being rendered. */
@@ -1091,6 +1088,19 @@ public final class Choreographer {
public FrameTimeline getPreferredFrameTimeline() { public FrameTimeline getPreferredFrameTimeline() {
return mPreferredFrameTimeline; return mPreferredFrameTimeline;
} }
private FrameTimeline[] convertFrameTimelines(
DisplayEventReceiver.VsyncEventData vsyncEventData) {
FrameTimeline[] frameTimelines =
new FrameTimeline[vsyncEventData.frameTimelines.length];
for (int i = 0; i < vsyncEventData.frameTimelines.length; i++) {
DisplayEventReceiver.VsyncEventData.FrameTimeline frameTimeline =
vsyncEventData.frameTimelines[i];
frameTimelines[i] = new FrameTimeline(frameTimeline.vsyncId,
frameTimeline.expectedPresentTime, frameTimeline.deadline);
}
return frameTimelines;
}
} }
/** /**

View File

@@ -84,6 +84,7 @@ public abstract class DisplayEventReceiver {
private static native void nativeDispose(long receiverPtr); private static native void nativeDispose(long receiverPtr);
@FastNative @FastNative
private static native void nativeScheduleVsync(long receiverPtr); private static native void nativeScheduleVsync(long receiverPtr);
private static native VsyncEventData nativeGetLatestVsyncEventData(long receiverPtr);
/** /**
* Creates a display event receiver. * Creates a display event receiver.
@@ -279,6 +280,13 @@ public abstract class DisplayEventReceiver {
} }
} }
/**
* Gets the latest vsync event data from surface flinger.
*/
VsyncEventData getLatestVsyncEventData() {
return nativeGetLatestVsyncEventData(mReceiverPtr);
}
// Called from native code. // Called from native code.
@SuppressWarnings("unused") @SuppressWarnings("unused")
private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame, private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame,

View File

@@ -108,6 +108,32 @@ void NativeDisplayEventReceiver::dispose() {
DisplayEventDispatcher::dispose(); DisplayEventDispatcher::dispose();
} }
static jobject createJavaVsyncEventData(JNIEnv* env, VsyncEventData vsyncEventData) {
ScopedLocalRef<jobjectArray>
frameTimelineObjs(env,
env->NewObjectArray(VsyncEventData::kFrameTimelinesLength,
gDisplayEventReceiverClassInfo
.frameTimelineClassInfo.clazz,
/*initial element*/ NULL));
for (int i = 0; i < VsyncEventData::kFrameTimelinesLength; i++) {
VsyncEventData::FrameTimeline frameTimeline = vsyncEventData.frameTimelines[i];
ScopedLocalRef<jobject>
frameTimelineObj(env,
env->NewObject(gDisplayEventReceiverClassInfo
.frameTimelineClassInfo.clazz,
gDisplayEventReceiverClassInfo
.frameTimelineClassInfo.init,
frameTimeline.vsyncId,
frameTimeline.expectedPresentationTime,
frameTimeline.deadlineTimestamp));
env->SetObjectArrayElement(frameTimelineObjs.get(), i, frameTimelineObj.get());
}
return env->NewObject(gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.clazz,
gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.init,
frameTimelineObjs.get(), vsyncEventData.preferredFrameTimelineIndex,
vsyncEventData.frameInterval);
}
void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId,
uint32_t count, VsyncEventData vsyncEventData) { uint32_t count, VsyncEventData vsyncEventData) {
JNIEnv* env = AndroidRuntime::getJNIEnv(); JNIEnv* env = AndroidRuntime::getJNIEnv();
@@ -116,37 +142,9 @@ void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDispla
if (receiverObj.get()) { if (receiverObj.get()) {
ALOGV("receiver %p ~ Invoking vsync handler.", this); ALOGV("receiver %p ~ Invoking vsync handler.", this);
ScopedLocalRef<jobjectArray> jobject javaVsyncEventData = createJavaVsyncEventData(env, vsyncEventData);
frameTimelineObjs(env,
env->NewObjectArray(VsyncEventData::kFrameTimelinesLength,
gDisplayEventReceiverClassInfo
.frameTimelineClassInfo.clazz,
/*initial element*/ NULL));
for (int i = 0; i < VsyncEventData::kFrameTimelinesLength; i++) {
VsyncEventData::FrameTimeline frameTimeline = vsyncEventData.frameTimelines[i];
ScopedLocalRef<jobject>
frameTimelineObj(env,
env->NewObject(gDisplayEventReceiverClassInfo
.frameTimelineClassInfo.clazz,
gDisplayEventReceiverClassInfo
.frameTimelineClassInfo.init,
frameTimeline.vsyncId,
frameTimeline.expectedPresentationTime,
frameTimeline.deadlineTimestamp));
env->SetObjectArrayElement(frameTimelineObjs.get(), i, frameTimelineObj.get());
}
ScopedLocalRef<jobject>
vsyncEventDataJava(env,
env->NewObject(gDisplayEventReceiverClassInfo
.vsyncEventDataClassInfo.clazz,
gDisplayEventReceiverClassInfo
.vsyncEventDataClassInfo.init,
frameTimelineObjs.get(),
vsyncEventData.preferredFrameTimelineIndex,
vsyncEventData.frameInterval));
env->CallVoidMethod(receiverObj.get(), gDisplayEventReceiverClassInfo.dispatchVsync, env->CallVoidMethod(receiverObj.get(), gDisplayEventReceiverClassInfo.dispatchVsync,
timestamp, displayId.value, count, vsyncEventDataJava.get()); timestamp, displayId.value, count, javaVsyncEventData);
ALOGV("receiver %p ~ Returned from vsync handler.", this); ALOGV("receiver %p ~ Returned from vsync handler.", this);
} }
@@ -255,19 +253,27 @@ static void nativeScheduleVsync(JNIEnv* env, jclass clazz, jlong receiverPtr) {
} }
} }
static jobject nativeGetLatestVsyncEventData(JNIEnv* env, jclass clazz, jlong receiverPtr) {
sp<NativeDisplayEventReceiver> receiver =
reinterpret_cast<NativeDisplayEventReceiver*>(receiverPtr);
gui::ParcelableVsyncEventData parcelableVsyncEventData;
status_t status = receiver->getLatestVsyncEventData(&parcelableVsyncEventData);
if (status) {
ALOGW("Failed to get latest vsync event data from surface flinger");
return NULL;
}
return createJavaVsyncEventData(env, parcelableVsyncEventData.vsync);
}
static const JNINativeMethod gMethods[] = { static const JNINativeMethod gMethods[] = {
/* name, signature, funcPtr */ /* name, signature, funcPtr */
{ "nativeInit", {"nativeInit", "(Ljava/lang/ref/WeakReference;Landroid/os/MessageQueue;II)J",
"(Ljava/lang/ref/WeakReference;Landroid/os/MessageQueue;II)J", (void*)nativeInit},
(void*)nativeInit }, {"nativeDispose", "(J)V", (void*)nativeDispose},
{ "nativeDispose", // @FastNative
"(J)V", {"nativeScheduleVsync", "(J)V", (void*)nativeScheduleVsync},
(void*)nativeDispose }, {"nativeGetLatestVsyncEventData", "(J)Landroid/view/DisplayEventReceiver$VsyncEventData;",
// @FastNative (void*)nativeGetLatestVsyncEventData}};
{ "nativeScheduleVsync", "(J)V",
(void*)nativeScheduleVsync }
};
int register_android_view_DisplayEventReceiver(JNIEnv* env) { int register_android_view_DisplayEventReceiver(JNIEnv* env) {
int res = RegisterMethodsOrDie(env, "android/view/DisplayEventReceiver", gMethods, int res = RegisterMethodsOrDie(env, "android/view/DisplayEventReceiver", gMethods,