Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit f6a546af authored by Rachel Lee's avatar Rachel Lee
Browse files

Revert "Remove JNI per-frame allocations in Choreographer"

This reverts commit 8c419c33.

Reason for revert: b/272536386
Test: ABTD

Change-Id: Ib132c1e26822c7056186e8e57419ec97c94ad6a9
parent 912e1e49
Loading
Loading
Loading
Loading
+18 −24
Original line number Diff line number Diff line
@@ -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<DisplayEventReceiver> receiver,
            WeakReference<VsyncEventData> 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<DisplayEventReceiver>(this),
                new WeakReference<VsyncEventData>(mVsyncEventData),
                mMessageQueue,
        mReceiverPtr = nativeInit(new WeakReference<DisplayEventReceiver>(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.
+11 −77
Original line number Diff line number Diff line
@@ -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>& messageQueue, jint vsyncSource,
                               jint eventRegistration, jlong layerHandle);

@@ -84,7 +74,6 @@ protected:

private:
    jobject mReceiverWeakGlobal;
    jobject mVsyncEventDataWeakGlobal;
    sp<MessageQueue> 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>& messageQueue,
                                                       jint vsyncSource, jint eventRegistration,
                                                       jlong layerHandle)
@@ -110,7 +98,6 @@ 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);
}
@@ -157,43 +144,12 @@ void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDispla
    JNIEnv* env = AndroidRuntime::getJNIEnv();

    ScopedLocalRef<jobject> receiverObj(env, GetReferent(env, mReceiverWeakGlobal));
    ScopedLocalRef<jobject> 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<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);
        }

        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> 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<NativeDisplayEventReceiver> 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,
                             "<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");
@@ -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;
}