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.");
|
+ "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;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|||||||
@@ -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,
|
||||||
|
|||||||
@@ -108,14 +108,7 @@ void NativeDisplayEventReceiver::dispose() {
|
|||||||
DisplayEventDispatcher::dispose();
|
DisplayEventDispatcher::dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId,
|
static jobject createJavaVsyncEventData(JNIEnv* env, VsyncEventData vsyncEventData) {
|
||||||
uint32_t count, VsyncEventData vsyncEventData) {
|
|
||||||
JNIEnv* env = AndroidRuntime::getJNIEnv();
|
|
||||||
|
|
||||||
ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
|
|
||||||
if (receiverObj.get()) {
|
|
||||||
ALOGV("receiver %p ~ Invoking vsync handler.", this);
|
|
||||||
|
|
||||||
ScopedLocalRef<jobjectArray>
|
ScopedLocalRef<jobjectArray>
|
||||||
frameTimelineObjs(env,
|
frameTimelineObjs(env,
|
||||||
env->NewObjectArray(VsyncEventData::kFrameTimelinesLength,
|
env->NewObjectArray(VsyncEventData::kFrameTimelinesLength,
|
||||||
@@ -135,18 +128,23 @@ void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDispla
|
|||||||
frameTimeline.deadlineTimestamp));
|
frameTimeline.deadlineTimestamp));
|
||||||
env->SetObjectArrayElement(frameTimelineObjs.get(), i, frameTimelineObj.get());
|
env->SetObjectArrayElement(frameTimelineObjs.get(), i, frameTimelineObj.get());
|
||||||
}
|
}
|
||||||
ScopedLocalRef<jobject>
|
return env->NewObject(gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.clazz,
|
||||||
vsyncEventDataJava(env,
|
gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.init,
|
||||||
env->NewObject(gDisplayEventReceiverClassInfo
|
frameTimelineObjs.get(), vsyncEventData.preferredFrameTimelineIndex,
|
||||||
.vsyncEventDataClassInfo.clazz,
|
vsyncEventData.frameInterval);
|
||||||
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();
|
||||||
|
|
||||||
|
ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
|
||||||
|
if (receiverObj.get()) {
|
||||||
|
ALOGV("receiver %p ~ Invoking vsync handler.", this);
|
||||||
|
|
||||||
|
jobject javaVsyncEventData = createJavaVsyncEventData(env, vsyncEventData);
|
||||||
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",
|
{"nativeDispose", "(J)V", (void*)nativeDispose},
|
||||||
"(J)V",
|
|
||||||
(void*)nativeDispose },
|
|
||||||
// @FastNative
|
// @FastNative
|
||||||
{ "nativeScheduleVsync", "(J)V",
|
{"nativeScheduleVsync", "(J)V", (void*)nativeScheduleVsync},
|
||||||
(void*)nativeScheduleVsync }
|
{"nativeGetLatestVsyncEventData", "(J)Landroid/view/DisplayEventReceiver$VsyncEventData;",
|
||||||
};
|
(void*)nativeGetLatestVsyncEventData}};
|
||||||
|
|
||||||
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,
|
||||||
|
|||||||
Reference in New Issue
Block a user