Merge "Use getLatestVsyncEventData for late frame." into tm-dev
This commit is contained in:
committed by
Android (Google) Code Review
commit
77fbf6f1d0
@@ -779,7 +779,9 @@ public final class Choreographer {
|
||||
+ "time to " + (lastFrameOffset * 0.000001f) + " ms in the past.");
|
||||
}
|
||||
frameTimeNanos = startNanos - lastFrameOffset;
|
||||
frameData.setFrameTimeNanos(frameTimeNanos);
|
||||
DisplayEventReceiver.VsyncEventData latestVsyncEventData =
|
||||
mDisplayEventReceiver.getLatestVsyncEventData();
|
||||
frameData.updateFrameData(frameTimeNanos, latestVsyncEventData);
|
||||
}
|
||||
|
||||
if (frameTimeNanos < mLastFrameTimeNanos) {
|
||||
@@ -877,7 +879,9 @@ public final class Choreographer {
|
||||
}
|
||||
frameTimeNanos = now - lastFrameOffset;
|
||||
mLastFrameTimeNanos = frameTimeNanos;
|
||||
frameData.setFrameTimeNanos(frameTimeNanos);
|
||||
DisplayEventReceiver.VsyncEventData latestVsyncEventData =
|
||||
mDisplayEventReceiver.getLatestVsyncEventData();
|
||||
frameData.updateFrameData(frameTimeNanos, latestVsyncEventData);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1012,11 +1016,6 @@ public final class Choreographer {
|
||||
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
|
||||
* presented.
|
||||
@@ -1061,17 +1060,15 @@ public final class Choreographer {
|
||||
}
|
||||
|
||||
private long mFrameTimeNanos;
|
||||
private final FrameTimeline[] mFrameTimelines;
|
||||
private final FrameTimeline mPreferredFrameTimeline;
|
||||
private FrameTimeline[] mFrameTimelines;
|
||||
private FrameTimeline mPreferredFrameTimeline;
|
||||
|
||||
void setFrameTimeNanos(long frameTimeNanos) {
|
||||
void updateFrameData(long frameTimeNanos,
|
||||
DisplayEventReceiver.VsyncEventData latestVsyncEventData) {
|
||||
mFrameTimeNanos = frameTimeNanos;
|
||||
for (FrameTimeline ft : mFrameTimelines) {
|
||||
// The ID is no longer valid because the frame time that was registered with the ID
|
||||
// no longer matches.
|
||||
// TODO(b/205721584): Ask SF for valid vsync information.
|
||||
ft.resetVsyncId();
|
||||
}
|
||||
mFrameTimelines = convertFrameTimelines(latestVsyncEventData);
|
||||
mPreferredFrameTimeline =
|
||||
mFrameTimelines[latestVsyncEventData.preferredFrameTimelineIndex];
|
||||
}
|
||||
|
||||
/** The time in nanoseconds when the frame started being rendered. */
|
||||
@@ -1091,6 +1088,19 @@ public final class Choreographer {
|
||||
public FrameTimeline getPreferredFrameTimeline() {
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -84,6 +84,7 @@ public abstract class DisplayEventReceiver {
|
||||
private static native void nativeDispose(long receiverPtr);
|
||||
@FastNative
|
||||
private static native void nativeScheduleVsync(long receiverPtr);
|
||||
private static native VsyncEventData nativeGetLatestVsyncEventData(long receiverPtr);
|
||||
|
||||
/**
|
||||
* 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.
|
||||
@SuppressWarnings("unused")
|
||||
private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame,
|
||||
|
||||
@@ -108,6 +108,32 @@ void NativeDisplayEventReceiver::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,
|
||||
uint32_t count, VsyncEventData vsyncEventData) {
|
||||
JNIEnv* env = AndroidRuntime::getJNIEnv();
|
||||
@@ -116,37 +142,9 @@ void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDispla
|
||||
if (receiverObj.get()) {
|
||||
ALOGV("receiver %p ~ Invoking vsync handler.", this);
|
||||
|
||||
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());
|
||||
}
|
||||
ScopedLocalRef<jobject>
|
||||
vsyncEventDataJava(env,
|
||||
env->NewObject(gDisplayEventReceiverClassInfo
|
||||
.vsyncEventDataClassInfo.clazz,
|
||||
gDisplayEventReceiverClassInfo
|
||||
.vsyncEventDataClassInfo.init,
|
||||
frameTimelineObjs.get(),
|
||||
vsyncEventData.preferredFrameTimelineIndex,
|
||||
vsyncEventData.frameInterval));
|
||||
|
||||
jobject javaVsyncEventData = createJavaVsyncEventData(env, vsyncEventData);
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -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[] = {
|
||||
/* name, signature, funcPtr */
|
||||
{ "nativeInit",
|
||||
"(Ljava/lang/ref/WeakReference;Landroid/os/MessageQueue;II)J",
|
||||
(void*)nativeInit },
|
||||
{ "nativeDispose",
|
||||
"(J)V",
|
||||
(void*)nativeDispose },
|
||||
// @FastNative
|
||||
{ "nativeScheduleVsync", "(J)V",
|
||||
(void*)nativeScheduleVsync }
|
||||
};
|
||||
/* name, signature, funcPtr */
|
||||
{"nativeInit", "(Ljava/lang/ref/WeakReference;Landroid/os/MessageQueue;II)J",
|
||||
(void*)nativeInit},
|
||||
{"nativeDispose", "(J)V", (void*)nativeDispose},
|
||||
// @FastNative
|
||||
{"nativeScheduleVsync", "(J)V", (void*)nativeScheduleVsync},
|
||||
{"nativeGetLatestVsyncEventData", "(J)Landroid/view/DisplayEventReceiver$VsyncEventData;",
|
||||
(void*)nativeGetLatestVsyncEventData}};
|
||||
|
||||
int register_android_view_DisplayEventReceiver(JNIEnv* env) {
|
||||
int res = RegisterMethodsOrDie(env, "android/view/DisplayEventReceiver", gMethods,
|
||||
|
||||
Reference in New Issue
Block a user