Loading core/java/android/view/Choreographer.java +4 −4 Original line number Diff line number Diff line Loading @@ -195,7 +195,7 @@ public final class Choreographer { private boolean mDebugPrintNextFrameTimeDelta; private int mFPSDivisor = 1; private DisplayEventReceiver.VsyncEventData mLastVsyncEventData = private final DisplayEventReceiver.VsyncEventData mLastVsyncEventData = new DisplayEventReceiver.VsyncEventData(); private final FrameData mFrameData = new FrameData(); Loading Loading @@ -860,7 +860,7 @@ public final class Choreographer { mFrameScheduled = false; mLastFrameTimeNanos = frameTimeNanos; mLastFrameIntervalNanos = frameIntervalNanos; mLastVsyncEventData = vsyncEventData; mLastVsyncEventData.copyFrom(vsyncEventData); } if (resynced && Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { Loading Loading @@ -1262,7 +1262,7 @@ public final class Choreographer { private boolean mHavePendingVsync; private long mTimestampNanos; private int mFrame; private VsyncEventData mLastVsyncEventData = new VsyncEventData(); private final VsyncEventData mLastVsyncEventData = new VsyncEventData(); FrameDisplayEventReceiver(Looper looper, int vsyncSource, long layerHandle) { super(looper, vsyncSource, /* eventRegistration */ 0, layerHandle); Loading Loading @@ -1302,7 +1302,7 @@ public final class Choreographer { mTimestampNanos = timestampNanos; mFrame = frame; mLastVsyncEventData = vsyncEventData; mLastVsyncEventData.copyFrom(vsyncEventData); Message msg = Message.obtain(mHandler, this); msg.setAsynchronous(true); mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS); Loading core/java/android/view/DisplayEventReceiver.java +36 −16 Original line number Diff line number Diff line Loading @@ -81,7 +81,10 @@ public abstract class DisplayEventReceiver { // GC'd while the native peer of the receiver is using them. private MessageQueue mMessageQueue; private final VsyncEventData mVsyncEventData = new VsyncEventData(); private static native long nativeInit(WeakReference<DisplayEventReceiver> receiver, WeakReference<VsyncEventData> vsyncEventData, MessageQueue messageQueue, int vsyncSource, int eventRegistration, long layerHandle); private static native long nativeGetDisplayEventReceiverFinalizer(); @FastNative Loading Loading @@ -124,7 +127,9 @@ public abstract class DisplayEventReceiver { } mMessageQueue = looper.getQueue(); mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this), mMessageQueue, mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this), new WeakReference<VsyncEventData>(mVsyncEventData), mMessageQueue, vsyncSource, eventRegistration, layerHandle); mFreeNativeResources = sNativeAllocationRegistry.registerNativeAllocation(this, mReceiverPtr); Loading @@ -147,9 +152,6 @@ public abstract class DisplayEventReceiver { * @hide */ public static final class VsyncEventData { static final FrameTimeline[] INVALID_FRAME_TIMELINES = {new FrameTimeline(FrameInfo.INVALID_VSYNC_ID, Long.MAX_VALUE, Long.MAX_VALUE)}; // The amount of frame timeline choices. // Must be in sync with VsyncEventData::kFrameTimelinesLength in // frameworks/native/libs/gui/include/gui/VsyncEventData.h. If they do not match, a runtime Loading @@ -157,22 +159,32 @@ public abstract class DisplayEventReceiver { static final int FRAME_TIMELINES_LENGTH = 7; public static class FrameTimeline { FrameTimeline() {} // Called from native code. @SuppressWarnings("unused") FrameTimeline(long vsyncId, long expectedPresentationTime, long deadline) { this.vsyncId = vsyncId; this.expectedPresentationTime = expectedPresentationTime; this.deadline = deadline; } void copyFrom(FrameTimeline other) { vsyncId = other.vsyncId; expectedPresentationTime = other.expectedPresentationTime; deadline = other.deadline; } // The frame timeline vsync id, used to correlate a frame // produced by HWUI with the timeline data stored in Surface Flinger. public final long vsyncId; public long vsyncId = FrameInfo.INVALID_VSYNC_ID; // The frame timestamp for when the frame is expected to be presented. public final long expectedPresentationTime; public long expectedPresentationTime = Long.MAX_VALUE; // The frame deadline timestamp in {@link System#nanoTime()} timebase that it is // allotted for the frame to be completed. public final long deadline; public long deadline = Long.MAX_VALUE; } /** Loading @@ -180,11 +192,18 @@ public abstract class DisplayEventReceiver { * {@link FrameInfo#VSYNC} to the current vsync in case Choreographer callback was heavily * delayed by the app. */ public final long frameInterval; public long frameInterval = -1; public final FrameTimeline[] frameTimelines; public final int preferredFrameTimelineIndex; public int preferredFrameTimelineIndex = 0; VsyncEventData() { frameTimelines = new FrameTimeline[FRAME_TIMELINES_LENGTH]; for (int i = 0; i < frameTimelines.length; i++) { frameTimelines[i] = new FrameTimeline(); } } // Called from native code. @SuppressWarnings("unused") Loading @@ -195,10 +214,12 @@ public abstract class DisplayEventReceiver { this.frameInterval = frameInterval; } VsyncEventData() { this.frameInterval = -1; this.frameTimelines = INVALID_FRAME_TIMELINES; this.preferredFrameTimelineIndex = 0; void copyFrom(VsyncEventData other) { preferredFrameTimelineIndex = other.preferredFrameTimelineIndex; frameInterval = other.frameInterval; for (int i = 0; i < frameTimelines.length; i++) { frameTimelines[i].copyFrom(other.frameTimelines[i]); } } public FrameTimeline preferredFrameTimeline() { Loading Loading @@ -304,9 +325,8 @@ public abstract class DisplayEventReceiver { // Called from native code. @SuppressWarnings("unused") private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame, VsyncEventData vsyncEventData) { onVsync(timestampNanos, physicalDisplayId, frame, vsyncEventData); private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame) { onVsync(timestampNanos, physicalDisplayId, frame, mVsyncEventData); } // Called from native code. Loading core/jni/android_view_DisplayEventReceiver.cpp +77 −11 Original line number Diff line number Diff line Loading @@ -48,12 +48,22 @@ static struct { struct { jclass clazz; jmethodID init; jfieldID vsyncId; jfieldID expectedPresentationTime; jfieldID deadline; } frameTimelineClassInfo; struct { jclass clazz; jmethodID init; jfieldID frameInterval; jfieldID preferredFrameTimelineIndex; jfieldID frameTimelines; } vsyncEventDataClassInfo; } gDisplayEventReceiverClassInfo; Loading @@ -61,7 +71,7 @@ static struct { class NativeDisplayEventReceiver : public DisplayEventDispatcher { public: NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak, NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak, jobject vsyncEventDataWeak, const sp<MessageQueue>& messageQueue, jint vsyncSource, jint eventRegistration, jlong layerHandle); Loading @@ -72,6 +82,7 @@ protected: private: jobject mReceiverWeakGlobal; jobject mVsyncEventDataWeakGlobal; sp<MessageQueue> mMessageQueue; void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count, Loading @@ -85,6 +96,7 @@ private: }; NativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak, jobject vsyncEventDataWeak, const sp<MessageQueue>& messageQueue, jint vsyncSource, jint eventRegistration, jlong layerHandle) Loading @@ -96,6 +108,7 @@ NativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env, jobject rece reinterpret_cast<IBinder*>(layerHandle)) : nullptr), mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)), mVsyncEventDataWeakGlobal(env->NewGlobalRef(vsyncEventDataWeak)), mMessageQueue(messageQueue) { ALOGV("receiver %p ~ Initializing display event receiver.", this); } Loading Loading @@ -154,12 +167,43 @@ void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDispla JNIEnv* env = AndroidRuntime::getJNIEnv(); ScopedLocalRef<jobject> receiverObj(env, GetReferent(env, mReceiverWeakGlobal)); if (receiverObj.get()) { ScopedLocalRef<jobject> vsyncEventDataObj(env, GetReferent(env, mVsyncEventDataWeakGlobal)); if (receiverObj.get() && vsyncEventDataObj.get()) { ALOGV("receiver %p ~ Invoking vsync handler.", this); jobject javaVsyncEventData = createJavaVsyncEventData(env, vsyncEventData); env->SetIntField(vsyncEventDataObj.get(), gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo .preferredFrameTimelineIndex, vsyncEventData.preferredFrameTimelineIndex); env->SetLongField(vsyncEventDataObj.get(), gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.frameInterval, vsyncEventData.frameInterval); ScopedLocalRef<jobjectArray> frameTimelinesObj(env, reinterpret_cast<jobjectArray>( env->GetObjectField(vsyncEventDataObj.get(), gDisplayEventReceiverClassInfo .vsyncEventDataClassInfo .frameTimelines))); for (int i = 0; i < VsyncEventData::kFrameTimelinesLength; i++) { VsyncEventData::FrameTimeline& frameTimeline = vsyncEventData.frameTimelines[i]; ScopedLocalRef<jobject> frameTimelineObj(env, env->GetObjectArrayElement(frameTimelinesObj.get(), i)); env->SetLongField(frameTimelineObj.get(), gDisplayEventReceiverClassInfo.frameTimelineClassInfo.vsyncId, frameTimeline.vsyncId); env->SetLongField(frameTimelineObj.get(), gDisplayEventReceiverClassInfo.frameTimelineClassInfo .expectedPresentationTime, frameTimeline.expectedPresentationTime); env->SetLongField(frameTimelineObj.get(), gDisplayEventReceiverClassInfo.frameTimelineClassInfo.deadline, frameTimeline.deadlineTimestamp); } env->CallVoidMethod(receiverObj.get(), gDisplayEventReceiverClassInfo.dispatchVsync, timestamp, displayId.value, count, javaVsyncEventData); timestamp, displayId.value, count); ALOGV("receiver %p ~ Returned from vsync handler.", this); } Loading Loading @@ -227,8 +271,9 @@ void NativeDisplayEventReceiver::dispatchFrameRateOverrides( mMessageQueue->raiseAndClearException(env, "dispatchModeChanged"); } static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject messageQueueObj, jint vsyncSource, jint eventRegistration, jlong layerHandle) { static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject vsyncEventDataWeak, jobject messageQueueObj, jint vsyncSource, jint eventRegistration, jlong layerHandle) { sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj); if (messageQueue == NULL) { jniThrowRuntimeException(env, "MessageQueue is not initialized."); Loading @@ -236,8 +281,8 @@ static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject } sp<NativeDisplayEventReceiver> receiver = new NativeDisplayEventReceiver(env, receiverWeak, messageQueue, vsyncSource, eventRegistration, layerHandle); new NativeDisplayEventReceiver(env, receiverWeak, vsyncEventDataWeak, messageQueue, vsyncSource, eventRegistration, layerHandle); status_t status = receiver->initialize(); if (status) { String8 message; Loading Loading @@ -284,7 +329,9 @@ static jobject nativeGetLatestVsyncEventData(JNIEnv* env, jclass clazz, jlong re static const JNINativeMethod gMethods[] = { /* name, signature, funcPtr */ {"nativeInit", "(Ljava/lang/ref/WeakReference;Landroid/os/MessageQueue;IIJ)J", {"nativeInit", "(Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;Landroid/os/" "MessageQueue;IIJ)J", (void*)nativeInit}, {"nativeGetDisplayEventReceiverFinalizer", "()J", (void*)nativeGetDisplayEventReceiverFinalizer}, Loading @@ -301,8 +348,7 @@ int register_android_view_DisplayEventReceiver(JNIEnv* env) { gDisplayEventReceiverClassInfo.clazz = MakeGlobalRefOrDie(env, clazz); gDisplayEventReceiverClassInfo.dispatchVsync = GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz, "dispatchVsync", "(JJILandroid/view/DisplayEventReceiver$VsyncEventData;)V"); GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz, "dispatchVsync", "(JJI)V"); gDisplayEventReceiverClassInfo.dispatchHotplug = GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz, "dispatchHotplug", "(JJZ)V"); gDisplayEventReceiverClassInfo.dispatchModeChanged = Loading @@ -328,6 +374,15 @@ int register_android_view_DisplayEventReceiver(JNIEnv* env) { gDisplayEventReceiverClassInfo.frameTimelineClassInfo.init = GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.frameTimelineClassInfo.clazz, "<init>", "(JJJ)V"); gDisplayEventReceiverClassInfo.frameTimelineClassInfo.vsyncId = GetFieldIDOrDie(env, gDisplayEventReceiverClassInfo.frameTimelineClassInfo.clazz, "vsyncId", "J"); gDisplayEventReceiverClassInfo.frameTimelineClassInfo.expectedPresentationTime = GetFieldIDOrDie(env, gDisplayEventReceiverClassInfo.frameTimelineClassInfo.clazz, "expectedPresentationTime", "J"); gDisplayEventReceiverClassInfo.frameTimelineClassInfo.deadline = GetFieldIDOrDie(env, gDisplayEventReceiverClassInfo.frameTimelineClassInfo.clazz, "deadline", "J"); jclass vsyncEventDataClazz = FindClassOrDie(env, "android/view/DisplayEventReceiver$VsyncEventData"); Loading @@ -339,6 +394,17 @@ int register_android_view_DisplayEventReceiver(JNIEnv* env) { "([Landroid/view/" "DisplayEventReceiver$VsyncEventData$FrameTimeline;IJ)V"); gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.preferredFrameTimelineIndex = GetFieldIDOrDie(env, gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.clazz, "preferredFrameTimelineIndex", "I"); gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.frameInterval = GetFieldIDOrDie(env, gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.clazz, "frameInterval", "J"); gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.frameTimelines = GetFieldIDOrDie(env, gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.clazz, "frameTimelines", "[Landroid/view/DisplayEventReceiver$VsyncEventData$FrameTimeline;"); return res; } Loading Loading
core/java/android/view/Choreographer.java +4 −4 Original line number Diff line number Diff line Loading @@ -195,7 +195,7 @@ public final class Choreographer { private boolean mDebugPrintNextFrameTimeDelta; private int mFPSDivisor = 1; private DisplayEventReceiver.VsyncEventData mLastVsyncEventData = private final DisplayEventReceiver.VsyncEventData mLastVsyncEventData = new DisplayEventReceiver.VsyncEventData(); private final FrameData mFrameData = new FrameData(); Loading Loading @@ -860,7 +860,7 @@ public final class Choreographer { mFrameScheduled = false; mLastFrameTimeNanos = frameTimeNanos; mLastFrameIntervalNanos = frameIntervalNanos; mLastVsyncEventData = vsyncEventData; mLastVsyncEventData.copyFrom(vsyncEventData); } if (resynced && Trace.isTagEnabled(Trace.TRACE_TAG_VIEW)) { Loading Loading @@ -1262,7 +1262,7 @@ public final class Choreographer { private boolean mHavePendingVsync; private long mTimestampNanos; private int mFrame; private VsyncEventData mLastVsyncEventData = new VsyncEventData(); private final VsyncEventData mLastVsyncEventData = new VsyncEventData(); FrameDisplayEventReceiver(Looper looper, int vsyncSource, long layerHandle) { super(looper, vsyncSource, /* eventRegistration */ 0, layerHandle); Loading Loading @@ -1302,7 +1302,7 @@ public final class Choreographer { mTimestampNanos = timestampNanos; mFrame = frame; mLastVsyncEventData = vsyncEventData; mLastVsyncEventData.copyFrom(vsyncEventData); Message msg = Message.obtain(mHandler, this); msg.setAsynchronous(true); mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS); Loading
core/java/android/view/DisplayEventReceiver.java +36 −16 Original line number Diff line number Diff line Loading @@ -81,7 +81,10 @@ public abstract class DisplayEventReceiver { // GC'd while the native peer of the receiver is using them. private MessageQueue mMessageQueue; private final VsyncEventData mVsyncEventData = new VsyncEventData(); private static native long nativeInit(WeakReference<DisplayEventReceiver> receiver, WeakReference<VsyncEventData> vsyncEventData, MessageQueue messageQueue, int vsyncSource, int eventRegistration, long layerHandle); private static native long nativeGetDisplayEventReceiverFinalizer(); @FastNative Loading Loading @@ -124,7 +127,9 @@ public abstract class DisplayEventReceiver { } mMessageQueue = looper.getQueue(); mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this), mMessageQueue, mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(this), new WeakReference<VsyncEventData>(mVsyncEventData), mMessageQueue, vsyncSource, eventRegistration, layerHandle); mFreeNativeResources = sNativeAllocationRegistry.registerNativeAllocation(this, mReceiverPtr); Loading @@ -147,9 +152,6 @@ public abstract class DisplayEventReceiver { * @hide */ public static final class VsyncEventData { static final FrameTimeline[] INVALID_FRAME_TIMELINES = {new FrameTimeline(FrameInfo.INVALID_VSYNC_ID, Long.MAX_VALUE, Long.MAX_VALUE)}; // The amount of frame timeline choices. // Must be in sync with VsyncEventData::kFrameTimelinesLength in // frameworks/native/libs/gui/include/gui/VsyncEventData.h. If they do not match, a runtime Loading @@ -157,22 +159,32 @@ public abstract class DisplayEventReceiver { static final int FRAME_TIMELINES_LENGTH = 7; public static class FrameTimeline { FrameTimeline() {} // Called from native code. @SuppressWarnings("unused") FrameTimeline(long vsyncId, long expectedPresentationTime, long deadline) { this.vsyncId = vsyncId; this.expectedPresentationTime = expectedPresentationTime; this.deadline = deadline; } void copyFrom(FrameTimeline other) { vsyncId = other.vsyncId; expectedPresentationTime = other.expectedPresentationTime; deadline = other.deadline; } // The frame timeline vsync id, used to correlate a frame // produced by HWUI with the timeline data stored in Surface Flinger. public final long vsyncId; public long vsyncId = FrameInfo.INVALID_VSYNC_ID; // The frame timestamp for when the frame is expected to be presented. public final long expectedPresentationTime; public long expectedPresentationTime = Long.MAX_VALUE; // The frame deadline timestamp in {@link System#nanoTime()} timebase that it is // allotted for the frame to be completed. public final long deadline; public long deadline = Long.MAX_VALUE; } /** Loading @@ -180,11 +192,18 @@ public abstract class DisplayEventReceiver { * {@link FrameInfo#VSYNC} to the current vsync in case Choreographer callback was heavily * delayed by the app. */ public final long frameInterval; public long frameInterval = -1; public final FrameTimeline[] frameTimelines; public final int preferredFrameTimelineIndex; public int preferredFrameTimelineIndex = 0; VsyncEventData() { frameTimelines = new FrameTimeline[FRAME_TIMELINES_LENGTH]; for (int i = 0; i < frameTimelines.length; i++) { frameTimelines[i] = new FrameTimeline(); } } // Called from native code. @SuppressWarnings("unused") Loading @@ -195,10 +214,12 @@ public abstract class DisplayEventReceiver { this.frameInterval = frameInterval; } VsyncEventData() { this.frameInterval = -1; this.frameTimelines = INVALID_FRAME_TIMELINES; this.preferredFrameTimelineIndex = 0; void copyFrom(VsyncEventData other) { preferredFrameTimelineIndex = other.preferredFrameTimelineIndex; frameInterval = other.frameInterval; for (int i = 0; i < frameTimelines.length; i++) { frameTimelines[i].copyFrom(other.frameTimelines[i]); } } public FrameTimeline preferredFrameTimeline() { Loading Loading @@ -304,9 +325,8 @@ public abstract class DisplayEventReceiver { // Called from native code. @SuppressWarnings("unused") private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame, VsyncEventData vsyncEventData) { onVsync(timestampNanos, physicalDisplayId, frame, vsyncEventData); private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame) { onVsync(timestampNanos, physicalDisplayId, frame, mVsyncEventData); } // Called from native code. Loading
core/jni/android_view_DisplayEventReceiver.cpp +77 −11 Original line number Diff line number Diff line Loading @@ -48,12 +48,22 @@ static struct { struct { jclass clazz; jmethodID init; jfieldID vsyncId; jfieldID expectedPresentationTime; jfieldID deadline; } frameTimelineClassInfo; struct { jclass clazz; jmethodID init; jfieldID frameInterval; jfieldID preferredFrameTimelineIndex; jfieldID frameTimelines; } vsyncEventDataClassInfo; } gDisplayEventReceiverClassInfo; Loading @@ -61,7 +71,7 @@ static struct { class NativeDisplayEventReceiver : public DisplayEventDispatcher { public: NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak, NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak, jobject vsyncEventDataWeak, const sp<MessageQueue>& messageQueue, jint vsyncSource, jint eventRegistration, jlong layerHandle); Loading @@ -72,6 +82,7 @@ protected: private: jobject mReceiverWeakGlobal; jobject mVsyncEventDataWeakGlobal; sp<MessageQueue> mMessageQueue; void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count, Loading @@ -85,6 +96,7 @@ private: }; NativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak, jobject vsyncEventDataWeak, const sp<MessageQueue>& messageQueue, jint vsyncSource, jint eventRegistration, jlong layerHandle) Loading @@ -96,6 +108,7 @@ NativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env, jobject rece reinterpret_cast<IBinder*>(layerHandle)) : nullptr), mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)), mVsyncEventDataWeakGlobal(env->NewGlobalRef(vsyncEventDataWeak)), mMessageQueue(messageQueue) { ALOGV("receiver %p ~ Initializing display event receiver.", this); } Loading Loading @@ -154,12 +167,43 @@ void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDispla JNIEnv* env = AndroidRuntime::getJNIEnv(); ScopedLocalRef<jobject> receiverObj(env, GetReferent(env, mReceiverWeakGlobal)); if (receiverObj.get()) { ScopedLocalRef<jobject> vsyncEventDataObj(env, GetReferent(env, mVsyncEventDataWeakGlobal)); if (receiverObj.get() && vsyncEventDataObj.get()) { ALOGV("receiver %p ~ Invoking vsync handler.", this); jobject javaVsyncEventData = createJavaVsyncEventData(env, vsyncEventData); env->SetIntField(vsyncEventDataObj.get(), gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo .preferredFrameTimelineIndex, vsyncEventData.preferredFrameTimelineIndex); env->SetLongField(vsyncEventDataObj.get(), gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.frameInterval, vsyncEventData.frameInterval); ScopedLocalRef<jobjectArray> frameTimelinesObj(env, reinterpret_cast<jobjectArray>( env->GetObjectField(vsyncEventDataObj.get(), gDisplayEventReceiverClassInfo .vsyncEventDataClassInfo .frameTimelines))); for (int i = 0; i < VsyncEventData::kFrameTimelinesLength; i++) { VsyncEventData::FrameTimeline& frameTimeline = vsyncEventData.frameTimelines[i]; ScopedLocalRef<jobject> frameTimelineObj(env, env->GetObjectArrayElement(frameTimelinesObj.get(), i)); env->SetLongField(frameTimelineObj.get(), gDisplayEventReceiverClassInfo.frameTimelineClassInfo.vsyncId, frameTimeline.vsyncId); env->SetLongField(frameTimelineObj.get(), gDisplayEventReceiverClassInfo.frameTimelineClassInfo .expectedPresentationTime, frameTimeline.expectedPresentationTime); env->SetLongField(frameTimelineObj.get(), gDisplayEventReceiverClassInfo.frameTimelineClassInfo.deadline, frameTimeline.deadlineTimestamp); } env->CallVoidMethod(receiverObj.get(), gDisplayEventReceiverClassInfo.dispatchVsync, timestamp, displayId.value, count, javaVsyncEventData); timestamp, displayId.value, count); ALOGV("receiver %p ~ Returned from vsync handler.", this); } Loading Loading @@ -227,8 +271,9 @@ void NativeDisplayEventReceiver::dispatchFrameRateOverrides( mMessageQueue->raiseAndClearException(env, "dispatchModeChanged"); } static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject messageQueueObj, jint vsyncSource, jint eventRegistration, jlong layerHandle) { static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject vsyncEventDataWeak, jobject messageQueueObj, jint vsyncSource, jint eventRegistration, jlong layerHandle) { sp<MessageQueue> messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj); if (messageQueue == NULL) { jniThrowRuntimeException(env, "MessageQueue is not initialized."); Loading @@ -236,8 +281,8 @@ static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject } sp<NativeDisplayEventReceiver> receiver = new NativeDisplayEventReceiver(env, receiverWeak, messageQueue, vsyncSource, eventRegistration, layerHandle); new NativeDisplayEventReceiver(env, receiverWeak, vsyncEventDataWeak, messageQueue, vsyncSource, eventRegistration, layerHandle); status_t status = receiver->initialize(); if (status) { String8 message; Loading Loading @@ -284,7 +329,9 @@ static jobject nativeGetLatestVsyncEventData(JNIEnv* env, jclass clazz, jlong re static const JNINativeMethod gMethods[] = { /* name, signature, funcPtr */ {"nativeInit", "(Ljava/lang/ref/WeakReference;Landroid/os/MessageQueue;IIJ)J", {"nativeInit", "(Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;Landroid/os/" "MessageQueue;IIJ)J", (void*)nativeInit}, {"nativeGetDisplayEventReceiverFinalizer", "()J", (void*)nativeGetDisplayEventReceiverFinalizer}, Loading @@ -301,8 +348,7 @@ int register_android_view_DisplayEventReceiver(JNIEnv* env) { gDisplayEventReceiverClassInfo.clazz = MakeGlobalRefOrDie(env, clazz); gDisplayEventReceiverClassInfo.dispatchVsync = GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz, "dispatchVsync", "(JJILandroid/view/DisplayEventReceiver$VsyncEventData;)V"); GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz, "dispatchVsync", "(JJI)V"); gDisplayEventReceiverClassInfo.dispatchHotplug = GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz, "dispatchHotplug", "(JJZ)V"); gDisplayEventReceiverClassInfo.dispatchModeChanged = Loading @@ -328,6 +374,15 @@ int register_android_view_DisplayEventReceiver(JNIEnv* env) { gDisplayEventReceiverClassInfo.frameTimelineClassInfo.init = GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.frameTimelineClassInfo.clazz, "<init>", "(JJJ)V"); gDisplayEventReceiverClassInfo.frameTimelineClassInfo.vsyncId = GetFieldIDOrDie(env, gDisplayEventReceiverClassInfo.frameTimelineClassInfo.clazz, "vsyncId", "J"); gDisplayEventReceiverClassInfo.frameTimelineClassInfo.expectedPresentationTime = GetFieldIDOrDie(env, gDisplayEventReceiverClassInfo.frameTimelineClassInfo.clazz, "expectedPresentationTime", "J"); gDisplayEventReceiverClassInfo.frameTimelineClassInfo.deadline = GetFieldIDOrDie(env, gDisplayEventReceiverClassInfo.frameTimelineClassInfo.clazz, "deadline", "J"); jclass vsyncEventDataClazz = FindClassOrDie(env, "android/view/DisplayEventReceiver$VsyncEventData"); Loading @@ -339,6 +394,17 @@ int register_android_view_DisplayEventReceiver(JNIEnv* env) { "([Landroid/view/" "DisplayEventReceiver$VsyncEventData$FrameTimeline;IJ)V"); gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.preferredFrameTimelineIndex = GetFieldIDOrDie(env, gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.clazz, "preferredFrameTimelineIndex", "I"); gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.frameInterval = GetFieldIDOrDie(env, gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.clazz, "frameInterval", "J"); gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.frameTimelines = GetFieldIDOrDie(env, gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.clazz, "frameTimelines", "[Landroid/view/DisplayEventReceiver$VsyncEventData$FrameTimeline;"); return res; } Loading