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

Commit 15b60b97 authored by Rachel Lee's avatar Rachel Lee Committed by Automerger Merge Worker
Browse files

Merge "Remove JNI per-frame allocations in Choreographer" into udc-dev am: a87cc2a3

parents 50467c8f a87cc2a3
Loading
Loading
Loading
Loading
+24 −18
Original line number Diff line number Diff line
@@ -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
@@ -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);
@@ -142,9 +147,6 @@ public abstract class DisplayEventReceiver {
    }

    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
@@ -152,6 +154,10 @@ 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;
@@ -160,14 +166,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 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;
        }

        /**
@@ -175,11 +181,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")
@@ -190,12 +203,6 @@ 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];
        }
@@ -299,9 +306,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.
+73 −11
Original line number Diff line number Diff line
@@ -50,12 +50,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;
@@ -63,7 +73,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);

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

private:
    jobject mReceiverWeakGlobal;
    jobject mVsyncEventDataWeakGlobal;
    sp<MessageQueue> mMessageQueue;

    void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count,
@@ -87,6 +98,7 @@ private:
};

NativeDisplayEventReceiver::NativeDisplayEventReceiver(JNIEnv* env, jobject receiverWeak,
                                                       jobject vsyncEventDataWeak,
                                                       const sp<MessageQueue>& messageQueue,
                                                       jint vsyncSource, jint eventRegistration,
                                                       jlong layerHandle)
@@ -98,6 +110,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);
}
@@ -144,12 +157,39 @@ 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);

        jobjectArray frameTimelinesObj = reinterpret_cast<jobjectArray>(
                env->GetObjectField(vsyncEventDataObj.get(),
                                    gDisplayEventReceiverClassInfo.vsyncEventDataClassInfo
                                            .frameTimelines));
        for (int i = 0; i < VsyncEventData::kFrameTimelinesLength; i++) {
            VsyncEventData::FrameTimeline& frameTimeline = vsyncEventData.frameTimelines[i];
            jobject frameTimelineObj = env->GetObjectArrayElement(frameTimelinesObj, i);
            env->SetLongField(frameTimelineObj,
                              gDisplayEventReceiverClassInfo.frameTimelineClassInfo.vsyncId,
                              frameTimeline.vsyncId);
            env->SetLongField(frameTimelineObj,
                              gDisplayEventReceiverClassInfo.frameTimelineClassInfo
                                      .expectedPresentationTime,
                              frameTimeline.expectedPresentationTime);
            env->SetLongField(frameTimelineObj,
                              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);
    }

@@ -217,8 +257,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.");
@@ -226,8 +267,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;
@@ -274,7 +315,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},
@@ -291,8 +334,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 =
@@ -318,6 +360,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");
@@ -329,6 +380,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;
}