Loading core/java/android/view/Choreographer.java +24 −10 Original line number Original line Diff line number Diff line Loading @@ -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, Loading Loading @@ -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) { Loading @@ -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) { Loading Loading @@ -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 { Loading Loading @@ -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(); Loading @@ -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); Loading @@ -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 Loading @@ -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); Loading @@ -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); } } } } Loading core/java/android/view/DisplayEventReceiver.java +26 −5 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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} Loading @@ -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) { } } /** /** Loading Loading @@ -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. Loading core/java/android/view/FrameMetrics.java +9 −6 Original line number Original line Diff line number Diff line Loading @@ -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, Loading @@ -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 } } /* /* Loading core/jni/android_view_DisplayEventReceiver.cpp +6 −4 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } } Loading Loading @@ -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, Loading graphics/java/android/graphics/FrameInfo.java +10 −2 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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 Loading
core/java/android/view/Choreographer.java +24 −10 Original line number Original line Diff line number Diff line Loading @@ -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, Loading Loading @@ -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) { Loading @@ -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) { Loading Loading @@ -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 { Loading Loading @@ -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(); Loading @@ -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); Loading @@ -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 Loading @@ -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); Loading @@ -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); } } } } Loading
core/java/android/view/DisplayEventReceiver.java +26 −5 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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} Loading @@ -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) { } } /** /** Loading Loading @@ -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. Loading
core/java/android/view/FrameMetrics.java +9 −6 Original line number Original line Diff line number Diff line Loading @@ -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, Loading @@ -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 } } /* /* Loading
core/jni/android_view_DisplayEventReceiver.cpp +6 −4 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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); } } Loading Loading @@ -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, Loading
graphics/java/android/graphics/FrameInfo.java +10 −2 Original line number Original line Diff line number Diff line Loading @@ -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; Loading Loading @@ -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