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

Commit 439b20b2 authored by Ady Abraham's avatar Ady Abraham Committed by Android (Google) Code Review
Browse files

Merge "pass frame deadline to Choreographer"

parents 7c4bea4b dfb13985
Loading
Loading
Loading
Loading
+24 −10
Original line number Original line Diff line number Diff line
@@ -181,7 +181,8 @@ public final class Choreographer {
    private long mFrameIntervalNanos;
    private long mFrameIntervalNanos;
    private boolean mDebugPrintNextFrameTimeDelta;
    private boolean mDebugPrintNextFrameTimeDelta;
    private int mFPSDivisor = 1;
    private int mFPSDivisor = 1;
    private long mLastVsyncId = FrameInfo.INVALID_VSYNC_ID;
    private DisplayEventReceiver.VsyncEventData mLastVsyncEventData =
            new DisplayEventReceiver.VsyncEventData();


    /**
    /**
     * Contains information about the current frame for jank-tracking,
     * Contains information about the current frame for jank-tracking,
@@ -664,7 +665,18 @@ public final class Choreographer {
     * @hide
     * @hide
     */
     */
    public long getVsyncId() {
    public long getVsyncId() {
        return mLastVsyncId;
        return mLastVsyncEventData.id;
    }

    /**
     * Returns the frame deadline in {@link System#nanoTime()} timebase that it is allotted for the
     * frame to be completed. Client are expected to call this function from their frame callback
     * function. Calling this function from anywhere else will return an undefined value.
     *
     * @hide
     */
    public long getFrameDeadline() {
        return mLastVsyncEventData.frameDeadline;
    }
    }


    void setFPSDivisor(int divisor) {
    void setFPSDivisor(int divisor) {
@@ -673,7 +685,8 @@ public final class Choreographer {
        ThreadedRenderer.setFPSDivisor(divisor);
        ThreadedRenderer.setFPSDivisor(divisor);
    }
    }


    void doFrame(long frameTimeNanos, int frame, long frameTimelineVsyncId) {
    void doFrame(long frameTimeNanos, int frame,
            DisplayEventReceiver.VsyncEventData vsyncEventData) {
        final long startNanos;
        final long startNanos;
        synchronized (mLock) {
        synchronized (mLock) {
            if (!mFrameScheduled) {
            if (!mFrameScheduled) {
@@ -723,10 +736,11 @@ public final class Choreographer {
                }
                }
            }
            }


            mFrameInfo.setVsync(intendedFrameTimeNanos, frameTimeNanos, frameTimelineVsyncId);
            mFrameInfo.setVsync(intendedFrameTimeNanos, frameTimeNanos, vsyncEventData.id,
                    vsyncEventData.frameDeadline);
            mFrameScheduled = false;
            mFrameScheduled = false;
            mLastFrameTimeNanos = frameTimeNanos;
            mLastFrameTimeNanos = frameTimeNanos;
            mLastVsyncId = frameTimelineVsyncId;
            mLastVsyncEventData = vsyncEventData;
        }
        }


        try {
        try {
@@ -910,7 +924,7 @@ public final class Choreographer {
        public void handleMessage(Message msg) {
        public void handleMessage(Message msg) {
            switch (msg.what) {
            switch (msg.what) {
                case MSG_DO_FRAME:
                case MSG_DO_FRAME:
                    doFrame(System.nanoTime(), 0, FrameInfo.INVALID_VSYNC_ID);
                    doFrame(System.nanoTime(), 0, new DisplayEventReceiver.VsyncEventData());
                    break;
                    break;
                case MSG_DO_SCHEDULE_VSYNC:
                case MSG_DO_SCHEDULE_VSYNC:
                    doScheduleVsync();
                    doScheduleVsync();
@@ -927,7 +941,7 @@ public final class Choreographer {
        private boolean mHavePendingVsync;
        private boolean mHavePendingVsync;
        private long mTimestampNanos;
        private long mTimestampNanos;
        private int mFrame;
        private int mFrame;
        private long mFrameTimelineVsyncId;
        private VsyncEventData mLastVsyncEventData = new VsyncEventData();


        public FrameDisplayEventReceiver(Looper looper, int vsyncSource) {
        public FrameDisplayEventReceiver(Looper looper, int vsyncSource) {
            super(looper, vsyncSource, CONFIG_CHANGED_EVENT_SUPPRESS);
            super(looper, vsyncSource, CONFIG_CHANGED_EVENT_SUPPRESS);
@@ -938,7 +952,7 @@ public final class Choreographer {
        // for the internal display implicitly.
        // for the internal display implicitly.
        @Override
        @Override
        public void onVsync(long timestampNanos, long physicalDisplayId, int frame,
        public void onVsync(long timestampNanos, long physicalDisplayId, int frame,
                long frameTimelineVsyncId) {
                VsyncEventData vsyncEventData) {
            // Post the vsync event to the Handler.
            // Post the vsync event to the Handler.
            // The idea is to prevent incoming vsync events from completely starving
            // The idea is to prevent incoming vsync events from completely starving
            // the message queue.  If there are no messages in the queue with timestamps
            // the message queue.  If there are no messages in the queue with timestamps
@@ -961,7 +975,7 @@ public final class Choreographer {


            mTimestampNanos = timestampNanos;
            mTimestampNanos = timestampNanos;
            mFrame = frame;
            mFrame = frame;
            mFrameTimelineVsyncId = frameTimelineVsyncId;
            mLastVsyncEventData = vsyncEventData;
            Message msg = Message.obtain(mHandler, this);
            Message msg = Message.obtain(mHandler, this);
            msg.setAsynchronous(true);
            msg.setAsynchronous(true);
            mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);
            mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS);
@@ -970,7 +984,7 @@ public final class Choreographer {
        @Override
        @Override
        public void run() {
        public void run() {
            mHavePendingVsync = false;
            mHavePendingVsync = false;
            doFrame(mTimestampNanos, mFrame, mFrameTimelineVsyncId);
            doFrame(mTimestampNanos, mFrame, mLastVsyncEventData);
        }
        }
    }
    }


+26 −5
Original line number Original line Diff line number Diff line
@@ -17,6 +17,7 @@
package android.view;
package android.view;


import android.compat.annotation.UnsupportedAppUsage;
import android.compat.annotation.UnsupportedAppUsage;
import android.graphics.FrameInfo;
import android.os.Looper;
import android.os.Looper;
import android.os.MessageQueue;
import android.os.MessageQueue;
import android.util.Log;
import android.util.Log;
@@ -145,6 +146,26 @@ public abstract class DisplayEventReceiver {
        mMessageQueue = null;
        mMessageQueue = null;
    }
    }


    static final class VsyncEventData {
        // The frame timeline vsync id, used to correlate a frame
        // produced by HWUI with the timeline data stored in Surface Flinger.
        public final long id;

        // The frame deadline timestamp in {@link System#nanoTime()} timebase that it is
        // allotted for the frame to be completed.
        public final long frameDeadline;

        VsyncEventData(long id, long frameDeadline) {
            this.id = id;
            this.frameDeadline = frameDeadline;
        }

        VsyncEventData() {
            this.id = FrameInfo.INVALID_VSYNC_ID;
            this.frameDeadline = Long.MAX_VALUE;
        }
    }

    /**
    /**
     * Called when a vertical sync pulse is received.
     * Called when a vertical sync pulse is received.
     * The recipient should render a frame and then call {@link #scheduleVsync}
     * The recipient should render a frame and then call {@link #scheduleVsync}
@@ -154,11 +175,10 @@ public abstract class DisplayEventReceiver {
     * timebase.
     * timebase.
     * @param physicalDisplayId Stable display ID that uniquely describes a (display, port) pair.
     * @param physicalDisplayId Stable display ID that uniquely describes a (display, port) pair.
     * @param frame The frame number.  Increases by one for each vertical sync interval.
     * @param frame The frame number.  Increases by one for each vertical sync interval.
     * @param frameTimelineVsyncId The frame timeline vsync id, used to correlate a frame
     * @param vsyncEventData The vsync event data.
     * produced by HWUI with the timeline data stored in Surface Flinger.
     */
     */
    public void onVsync(long timestampNanos, long physicalDisplayId, int frame,
    public void onVsync(long timestampNanos, long physicalDisplayId, int frame,
            long frameTimelineVsyncId) {
            VsyncEventData vsyncEventData) {
    }
    }


    /**
    /**
@@ -201,8 +221,9 @@ public abstract class DisplayEventReceiver {
    // 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,
            long frameTimelineVsyncId) {
            long frameTimelineVsyncId, long frameDeadline) {
        onVsync(timestampNanos, physicalDisplayId, frame, frameTimelineVsyncId);
        onVsync(timestampNanos, physicalDisplayId, frame,
                new VsyncEventData(frameTimelineVsyncId, frameDeadline));
    }
    }


    // Called from native code.
    // Called from native code.
+9 −6
Original line number Original line Diff line number Diff line
@@ -198,6 +198,7 @@ public final class FrameMetrics {
            Index.ANIMATION_START,
            Index.ANIMATION_START,
            Index.PERFORM_TRAVERSALS_START,
            Index.PERFORM_TRAVERSALS_START,
            Index.DRAW_START,
            Index.DRAW_START,
            Index.FRAME_DEADLINE,
            Index.SYNC_QUEUED,
            Index.SYNC_QUEUED,
            Index.SYNC_START,
            Index.SYNC_START,
            Index.ISSUE_DRAW_COMMANDS_START,
            Index.ISSUE_DRAW_COMMANDS_START,
@@ -216,13 +217,15 @@ public final class FrameMetrics {
        int ANIMATION_START = 7;
        int ANIMATION_START = 7;
        int PERFORM_TRAVERSALS_START = 8;
        int PERFORM_TRAVERSALS_START = 8;
        int DRAW_START = 9;
        int DRAW_START = 9;
        int SYNC_QUEUED = 10;
        int FRAME_DEADLINE = 10;
        int SYNC_START = 11;
        int SYNC_QUEUED = 11;
        int ISSUE_DRAW_COMMANDS_START = 12;
        int SYNC_START = 12;
        int SWAP_BUFFERS = 13;
        int ISSUE_DRAW_COMMANDS_START = 13;
        int FRAME_COMPLETED = 14;
        int SWAP_BUFFERS = 14;
        int FRAME_COMPLETED = 15;


        int FRAME_STATS_COUNT = 18; // must always be last
        int FRAME_STATS_COUNT = 19; // must always be last and in sync with
                                    // FrameInfoIndex::NumIndexes in libs/hwui/FrameInfo.h
    }
    }


    /*
    /*
+6 −4
Original line number Original line Diff line number Diff line
@@ -60,7 +60,7 @@ private:
    sp<MessageQueue> mMessageQueue;
    sp<MessageQueue> mMessageQueue;


    void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count,
    void dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId, uint32_t count,
                       int64_t sharedTimelineFrameCount) override;
                       VsyncEventData vsyncEventData) override;
    void dispatchHotplug(nsecs_t timestamp, PhysicalDisplayId displayId, bool connected) override;
    void dispatchHotplug(nsecs_t timestamp, PhysicalDisplayId displayId, bool connected) override;
    void dispatchConfigChanged(nsecs_t timestamp, PhysicalDisplayId displayId,
    void dispatchConfigChanged(nsecs_t timestamp, PhysicalDisplayId displayId,
                               int32_t configId, nsecs_t vsyncPeriod) override;
                               int32_t configId, nsecs_t vsyncPeriod) override;
@@ -91,14 +91,15 @@ void NativeDisplayEventReceiver::dispose() {
}
}


void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId,
void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId,
                                               uint32_t count, int64_t frameTimelineVsyncId) {
                                               uint32_t count, VsyncEventData vsyncEventData) {
    JNIEnv* env = AndroidRuntime::getJNIEnv();
    JNIEnv* env = AndroidRuntime::getJNIEnv();


    ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
    ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
    if (receiverObj.get()) {
    if (receiverObj.get()) {
        ALOGV("receiver %p ~ Invoking vsync handler.", this);
        ALOGV("receiver %p ~ Invoking vsync handler.", this);
        env->CallVoidMethod(receiverObj.get(), gDisplayEventReceiverClassInfo.dispatchVsync,
        env->CallVoidMethod(receiverObj.get(), gDisplayEventReceiverClassInfo.dispatchVsync,
                            timestamp, displayId.value, count, frameTimelineVsyncId);
                            timestamp, displayId.value, count, vsyncEventData.id,
                            vsyncEventData.deadlineTimestamp);
        ALOGV("receiver %p ~ Returned from vsync handler.", this);
        ALOGV("receiver %p ~ Returned from vsync handler.", this);
    }
    }


@@ -198,7 +199,8 @@ int register_android_view_DisplayEventReceiver(JNIEnv* env) {
    gDisplayEventReceiverClassInfo.clazz = MakeGlobalRefOrDie(env, clazz);
    gDisplayEventReceiverClassInfo.clazz = MakeGlobalRefOrDie(env, clazz);


    gDisplayEventReceiverClassInfo.dispatchVsync =
    gDisplayEventReceiverClassInfo.dispatchVsync =
            GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz, "dispatchVsync", "(JJIJ)V");
            GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz, "dispatchVsync",
                             "(JJIJJ)V");
    gDisplayEventReceiverClassInfo.dispatchHotplug = GetMethodIDOrDie(env,
    gDisplayEventReceiverClassInfo.dispatchHotplug = GetMethodIDOrDie(env,
            gDisplayEventReceiverClassInfo.clazz, "dispatchHotplug", "(JJZ)V");
            gDisplayEventReceiverClassInfo.clazz, "dispatchHotplug", "(JJZ)V");
    gDisplayEventReceiverClassInfo.dispatchConfigChanged = GetMethodIDOrDie(env,
    gDisplayEventReceiverClassInfo.dispatchConfigChanged = GetMethodIDOrDie(env,
+10 −2
Original line number Original line Diff line number Diff line
@@ -40,7 +40,7 @@ import java.lang.annotation.RetentionPolicy;
 */
 */
public final class FrameInfo {
public final class FrameInfo {


    public long[] frameInfo = new long[10];
    public long[] frameInfo = new long[FRAME_INFO_SIZE];


    // Various flags set to provide extra metadata about the current frame
    // Various flags set to provide extra metadata about the current frame
    private static final int FLAGS = 0;
    private static final int FLAGS = 0;
@@ -87,14 +87,22 @@ public final class FrameInfo {
    // When View:draw() started
    // When View:draw() started
    private static final int DRAW_START = 9;
    private static final int DRAW_START = 9;


    // When the frame needs to be ready by
    private static final int FRAME_DEADLINE = 10;

    // Must be the last one
    private static final int FRAME_INFO_SIZE = FRAME_DEADLINE + 1;

    /** checkstyle */
    /** checkstyle */
    public void setVsync(long intendedVsync, long usedVsync, long frameTimelineVsyncId) {
    public void setVsync(long intendedVsync, long usedVsync, long frameTimelineVsyncId,
            long frameDeadline) {
        frameInfo[FRAME_TIMELINE_VSYNC_ID] = frameTimelineVsyncId;
        frameInfo[FRAME_TIMELINE_VSYNC_ID] = frameTimelineVsyncId;
        frameInfo[INTENDED_VSYNC] = intendedVsync;
        frameInfo[INTENDED_VSYNC] = intendedVsync;
        frameInfo[VSYNC] = usedVsync;
        frameInfo[VSYNC] = usedVsync;
        frameInfo[OLDEST_INPUT_EVENT] = Long.MAX_VALUE;
        frameInfo[OLDEST_INPUT_EVENT] = Long.MAX_VALUE;
        frameInfo[NEWEST_INPUT_EVENT] = 0;
        frameInfo[NEWEST_INPUT_EVENT] = 0;
        frameInfo[FLAGS] = 0;
        frameInfo[FLAGS] = 0;
        frameInfo[FRAME_DEADLINE] = frameDeadline;
    }
    }


    /** checkstyle */
    /** checkstyle */
Loading