From f6a546afd6ed7591d622d8ce06822658d0b6816d Mon Sep 17 00:00:00 2001 From: Rachel Lee Date: Thu, 9 Mar 2023 20:41:53 +0000 Subject: [PATCH] Revert "Remove JNI per-frame allocations in Choreographer" This reverts commit 8c419c338a48e2ab9d09d361e2f6975839b504f8. Reason for revert: b/272536386 Test: ABTD Change-Id: Ib132c1e26822c7056186e8e57419ec97c94ad6a9 --- .../android/view/DisplayEventReceiver.java | 42 ++++----- .../jni/android_view_DisplayEventReceiver.cpp | 88 +++---------------- 2 files changed, 29 insertions(+), 101 deletions(-) diff --git a/core/java/android/view/DisplayEventReceiver.java b/core/java/android/view/DisplayEventReceiver.java index 2ab3bff485832..03074894b2ff6 100644 --- a/core/java/android/view/DisplayEventReceiver.java +++ b/core/java/android/view/DisplayEventReceiver.java @@ -81,10 +81,7 @@ 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 receiver, - WeakReference vsyncEventData, MessageQueue messageQueue, int vsyncSource, int eventRegistration, long layerHandle); private static native long nativeGetDisplayEventReceiverFinalizer(); @FastNative @@ -127,9 +124,7 @@ public abstract class DisplayEventReceiver { } mMessageQueue = looper.getQueue(); - mReceiverPtr = nativeInit(new WeakReference(this), - new WeakReference(mVsyncEventData), - mMessageQueue, + mReceiverPtr = nativeInit(new WeakReference(this), mMessageQueue, vsyncSource, eventRegistration, layerHandle); mFreeNativeResources = sNativeAllocationRegistry.registerNativeAllocation(this, mReceiverPtr); @@ -152,6 +147,9 @@ 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 @@ -159,10 +157,6 @@ 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; @@ -171,14 +165,14 @@ public abstract class DisplayEventReceiver { // The frame timeline vsync id, used to correlate a frame // produced by HWUI with the timeline data stored in Surface Flinger. - public long vsyncId = FrameInfo.INVALID_VSYNC_ID; + public final long vsyncId; // The frame timestamp for when the frame is expected to be presented. - public long expectedPresentationTime = Long.MAX_VALUE; + public final long expectedPresentationTime; // The frame deadline timestamp in {@link System#nanoTime()} timebase that it is // allotted for the frame to be completed. - public long deadline = Long.MAX_VALUE; + public final long deadline; } /** @@ -186,18 +180,11 @@ public abstract class DisplayEventReceiver { * {@link FrameInfo#VSYNC} to the current vsync in case Choreographer callback was heavily * delayed by the app. */ - public long frameInterval = -1; + public final long frameInterval; public final FrameTimeline[] frameTimelines; - public int preferredFrameTimelineIndex = 0; - - VsyncEventData() { - frameTimelines = new FrameTimeline[FRAME_TIMELINES_LENGTH]; - for (int i = 0; i < frameTimelines.length; i++) { - frameTimelines[i] = new FrameTimeline(); - } - } + public final int preferredFrameTimelineIndex; // Called from native code. @SuppressWarnings("unused") @@ -208,6 +195,12 @@ public abstract class DisplayEventReceiver { this.frameInterval = frameInterval; } + VsyncEventData() { + this.frameInterval = -1; + this.frameTimelines = INVALID_FRAME_TIMELINES; + this.preferredFrameTimelineIndex = 0; + } + public FrameTimeline preferredFrameTimeline() { return frameTimelines[preferredFrameTimelineIndex]; } @@ -311,8 +304,9 @@ public abstract class DisplayEventReceiver { // Called from native code. @SuppressWarnings("unused") - private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame) { - onVsync(timestampNanos, physicalDisplayId, frame, mVsyncEventData); + private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame, + VsyncEventData vsyncEventData) { + onVsync(timestampNanos, physicalDisplayId, frame, vsyncEventData); } // Called from native code. diff --git a/core/jni/android_view_DisplayEventReceiver.cpp b/core/jni/android_view_DisplayEventReceiver.cpp index 0c3ff6c28ea7d..b09a9c3a505de 100644 --- a/core/jni/android_view_DisplayEventReceiver.cpp +++ b/core/jni/android_view_DisplayEventReceiver.cpp @@ -50,22 +50,12 @@ 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; @@ -73,7 +63,7 @@ static struct { class NativeDisplayEventReceiver : public DisplayEventDispatcher { public: - NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak, jobject vsyncEventDataWeak, + NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak, const sp& messageQueue, jint vsyncSource, jint eventRegistration, jlong layerHandle); @@ -84,7 +74,6 @@ protected: private: jobject mReceiverWeakGlobal; - jobject mVsyncEventDataWeakGlobal; sp mMessageQueue; void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count, @@ -98,7 +87,6 @@ private: }; NativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak, - jobject vsyncEventDataWeak, const sp& messageQueue, jint vsyncSource, jint eventRegistration, jlong layerHandle) @@ -110,7 +98,6 @@ NativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env, jobject rece reinterpret_cast(layerHandle)) : nullptr), mReceiverWeakGlobal(env->NewGlobalRef(receiverWeak)), - mVsyncEventDataWeakGlobal(env->NewGlobalRef(vsyncEventDataWeak)), mMessageQueue(messageQueue) { ALOGV("receiver %p ~ Initializing display event receiver.", this); } @@ -157,43 +144,12 @@ void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDispla JNIEnv* env = AndroidRuntime::getJNIEnv(); ScopedLocalRef receiverObj(env, GetReferent(env, mReceiverWeakGlobal)); - ScopedLocalRef vsyncEventDataObj(env, GetReferent(env, mVsyncEventDataWeakGlobal)); - if (receiverObj.get() && vsyncEventDataObj.get()) { + if (receiverObj.get()) { ALOGV("receiver %p ~ Invoking vsync handler.", this); - env->SetIntField(vsyncEventDataObj.get(), - gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo - .preferredFrameTimelineIndex, - vsyncEventData.preferredFrameTimelineIndex); - env->SetLongField(vsyncEventDataObj.get(), - gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo.frameInterval, - vsyncEventData.frameInterval); - - ScopedLocalRef - frameTimelinesObj(env, - reinterpret_cast( - env->GetObjectField(vsyncEventDataObj.get(), - gDisplayEventReceiverClassInfo - .vsyncEventDataClassInfo - .frameTimelines))); - for (int i = 0; i < VsyncEventData::kFrameTimelinesLength; i++) { - VsyncEventData::FrameTimeline& frameTimeline = vsyncEventData.frameTimelines[i]; - ScopedLocalRef - 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); - } - + jobject javaVsyncEventData = createJavaVsyncEventData(env, vsyncEventData); env->CallVoidMethod(receiverObj.get(), gDisplayEventReceiverClassInfo.dispatchVsync, - timestamp, displayId.value, count); + timestamp, displayId.value, count, javaVsyncEventData); ALOGV("receiver %p ~ Returned from vsync handler.", this); } @@ -261,9 +217,8 @@ void NativeDisplayEventReceiver::dispatchFrameRateOverrides( mMessageQueue->raiseAndClearException(env, "dispatchModeChanged"); } -static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject vsyncEventDataWeak, - jobject messageQueueObj, jint vsyncSource, jint eventRegistration, - jlong layerHandle) { +static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject messageQueueObj, + jint vsyncSource, jint eventRegistration, jlong layerHandle) { sp messageQueue = android_os_MessageQueue_getMessageQueue(env, messageQueueObj); if (messageQueue == NULL) { jniThrowRuntimeException(env, "MessageQueue is not initialized."); @@ -271,8 +226,8 @@ static jlong nativeInit(JNIEnv* env, jclass clazz, jobject receiverWeak, jobject } sp receiver = - new NativeDisplayEventReceiver(env, receiverWeak, vsyncEventDataWeak, messageQueue, - vsyncSource, eventRegistration, layerHandle); + new NativeDisplayEventReceiver(env, receiverWeak, messageQueue, vsyncSource, + eventRegistration, layerHandle); status_t status = receiver->initialize(); if (status) { String8 message; @@ -319,9 +274,7 @@ static jobject nativeGetLatestVsyncEventData(JNIEnv* env, jclass clazz, jlong re static const JNINativeMethod gMethods[] = { /* name, signature, funcPtr */ - {"nativeInit", - "(Ljava/lang/ref/WeakReference;Ljava/lang/ref/WeakReference;Landroid/os/" - "MessageQueue;IIJ)J", + {"nativeInit", "(Ljava/lang/ref/WeakReference;Landroid/os/MessageQueue;IIJ)J", (void*)nativeInit}, {"nativeGetDisplayEventReceiverFinalizer", "()J", (void*)nativeGetDisplayEventReceiverFinalizer}, @@ -338,7 +291,8 @@ int register_android_view_DisplayEventReceiver(JNIEnv* env) { gDisplayEventReceiverClassInfo.clazz = MakeGlobalRefOrDie(env, clazz); gDisplayEventReceiverClassInfo.dispatchVsync = - GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz, "dispatchVsync", "(JJI)V"); + GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz, "dispatchVsync", + "(JJILandroid/view/DisplayEventReceiver$VsyncEventData;)V"); gDisplayEventReceiverClassInfo.dispatchHotplug = GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz, "dispatchHotplug", "(JJZ)V"); gDisplayEventReceiverClassInfo.dispatchModeChanged = @@ -364,15 +318,6 @@ int register_android_view_DisplayEventReceiver(JNIEnv* env) { gDisplayEventReceiverClassInfo.frameTimelineClassInfo.init = GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.frameTimelineClassInfo.clazz, "", "(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"); @@ -384,17 +329,6 @@ 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; }