diff options
| author | Ady Abraham <adyabr@google.com> | 2020-10-05 17:59:09 -0700 |
|---|---|---|
| committer | Ady Abraham <adyabr@google.com> | 2020-10-09 11:17:32 -0700 |
| commit | dfb13985aff33cda393ffefc0db3103443f3be49 (patch) | |
| tree | 25f497b88843c109e7ba08aa8a442d0a23336bc9 /core/java | |
| parent | 6057df4f9e36765965fa787c0670ed6ac964138e (diff) | |
pass frame deadline to Choreographer
Pass the frame deadline calculated by SF to Choreographer so
hwui would be able to improve its stats by knowing if a frame is
likely to be late.
Bug: 169858174
Test: manual
Change-Id: Ib9fd93638b54f08d8dc72fa6b023e2dd7c276dc7
Diffstat (limited to 'core/java')
| -rw-r--r-- | core/java/android/view/Choreographer.java | 34 | ||||
| -rw-r--r-- | core/java/android/view/DisplayEventReceiver.java | 31 | ||||
| -rw-r--r-- | core/java/android/view/FrameMetrics.java | 15 |
3 files changed, 59 insertions, 21 deletions
diff --git a/core/java/android/view/Choreographer.java b/core/java/android/view/Choreographer.java index e520d7ccaa7a..b5080cdb37aa 100644 --- a/core/java/android/view/Choreographer.java +++ b/core/java/android/view/Choreographer.java @@ -181,7 +181,8 @@ public final class Choreographer { private long mFrameIntervalNanos; private boolean mDebugPrintNextFrameTimeDelta; 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, @@ -664,7 +665,18 @@ public final class Choreographer { * @hide */ 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) { @@ -673,7 +685,8 @@ public final class Choreographer { ThreadedRenderer.setFPSDivisor(divisor); } - void doFrame(long frameTimeNanos, int frame, long frameTimelineVsyncId) { + void doFrame(long frameTimeNanos, int frame, + DisplayEventReceiver.VsyncEventData vsyncEventData) { final long startNanos; synchronized (mLock) { 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; mLastFrameTimeNanos = frameTimeNanos; - mLastVsyncId = frameTimelineVsyncId; + mLastVsyncEventData = vsyncEventData; } try { @@ -910,7 +924,7 @@ public final class Choreographer { public void handleMessage(Message msg) { switch (msg.what) { case MSG_DO_FRAME: - doFrame(System.nanoTime(), 0, FrameInfo.INVALID_VSYNC_ID); + doFrame(System.nanoTime(), 0, new DisplayEventReceiver.VsyncEventData()); break; case MSG_DO_SCHEDULE_VSYNC: doScheduleVsync(); @@ -927,7 +941,7 @@ public final class Choreographer { private boolean mHavePendingVsync; private long mTimestampNanos; private int mFrame; - private long mFrameTimelineVsyncId; + private VsyncEventData mLastVsyncEventData = new VsyncEventData(); public FrameDisplayEventReceiver(Looper looper, int vsyncSource) { super(looper, vsyncSource, CONFIG_CHANGED_EVENT_SUPPRESS); @@ -938,7 +952,7 @@ public final class Choreographer { // for the internal display implicitly. @Override public void onVsync(long timestampNanos, long physicalDisplayId, int frame, - long frameTimelineVsyncId) { + VsyncEventData vsyncEventData) { // Post the vsync event to the Handler. // The idea is to prevent incoming vsync events from completely starving // the message queue. If there are no messages in the queue with timestamps @@ -961,7 +975,7 @@ public final class Choreographer { mTimestampNanos = timestampNanos; mFrame = frame; - mFrameTimelineVsyncId = frameTimelineVsyncId; + mLastVsyncEventData = vsyncEventData; Message msg = Message.obtain(mHandler, this); msg.setAsynchronous(true); mHandler.sendMessageAtTime(msg, timestampNanos / TimeUtils.NANOS_PER_MS); @@ -970,7 +984,7 @@ public final class Choreographer { @Override public void run() { mHavePendingVsync = false; - doFrame(mTimestampNanos, mFrame, mFrameTimelineVsyncId); + doFrame(mTimestampNanos, mFrame, mLastVsyncEventData); } } diff --git a/core/java/android/view/DisplayEventReceiver.java b/core/java/android/view/DisplayEventReceiver.java index 51474d3c39c8..467d93ef3aaf 100644 --- a/core/java/android/view/DisplayEventReceiver.java +++ b/core/java/android/view/DisplayEventReceiver.java @@ -17,6 +17,7 @@ package android.view; import android.compat.annotation.UnsupportedAppUsage; +import android.graphics.FrameInfo; import android.os.Looper; import android.os.MessageQueue; import android.util.Log; @@ -145,6 +146,26 @@ public abstract class DisplayEventReceiver { 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. * The recipient should render a frame and then call {@link #scheduleVsync} @@ -154,11 +175,10 @@ public abstract class DisplayEventReceiver { * timebase. * @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 frameTimelineVsyncId The frame timeline vsync id, used to correlate a frame - * produced by HWUI with the timeline data stored in Surface Flinger. + * @param vsyncEventData The vsync event data. */ 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. @SuppressWarnings("unused") private void dispatchVsync(long timestampNanos, long physicalDisplayId, int frame, - long frameTimelineVsyncId) { - onVsync(timestampNanos, physicalDisplayId, frame, frameTimelineVsyncId); + long frameTimelineVsyncId, long frameDeadline) { + onVsync(timestampNanos, physicalDisplayId, frame, + new VsyncEventData(frameTimelineVsyncId, frameDeadline)); } // Called from native code. diff --git a/core/java/android/view/FrameMetrics.java b/core/java/android/view/FrameMetrics.java index 280a1c0d95d2..387787e3b0be 100644 --- a/core/java/android/view/FrameMetrics.java +++ b/core/java/android/view/FrameMetrics.java @@ -198,6 +198,7 @@ public final class FrameMetrics { Index.ANIMATION_START, Index.PERFORM_TRAVERSALS_START, Index.DRAW_START, + Index.FRAME_DEADLINE, Index.SYNC_QUEUED, Index.SYNC_START, Index.ISSUE_DRAW_COMMANDS_START, @@ -216,13 +217,15 @@ public final class FrameMetrics { int ANIMATION_START = 7; int PERFORM_TRAVERSALS_START = 8; int DRAW_START = 9; - int SYNC_QUEUED = 10; - int SYNC_START = 11; - int ISSUE_DRAW_COMMANDS_START = 12; - int SWAP_BUFFERS = 13; - int FRAME_COMPLETED = 14; + int FRAME_DEADLINE = 10; + int SYNC_QUEUED = 11; + int SYNC_START = 12; + int ISSUE_DRAW_COMMANDS_START = 13; + 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 } /* |
