summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAdy Abraham <adyabr@google.com>2020-10-05 17:59:09 -0700
committerAdy Abraham <adyabr@google.com>2020-10-09 11:17:32 -0700
commitdfb13985aff33cda393ffefc0db3103443f3be49 (patch)
tree25f497b88843c109e7ba08aa8a442d0a23336bc9
parent6057df4f9e36765965fa787c0670ed6ac964138e (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
-rw-r--r--core/java/android/view/Choreographer.java34
-rw-r--r--core/java/android/view/DisplayEventReceiver.java31
-rw-r--r--core/java/android/view/FrameMetrics.java15
-rw-r--r--core/jni/android_view_DisplayEventReceiver.cpp10
-rw-r--r--graphics/java/android/graphics/FrameInfo.java12
-rw-r--r--graphics/java/android/graphics/HardwareRenderer.java2
-rw-r--r--libs/hwui/FrameInfo.cpp3
-rw-r--r--libs/hwui/FrameInfo.h8
-rw-r--r--libs/hwui/jni/android_graphics_HardwareRenderer.cpp3
-rw-r--r--libs/hwui/renderthread/CanvasContext.cpp3
-rw-r--r--libs/hwui/renderthread/DrawFrameTask.cpp3
-rw-r--r--libs/hwui/renderthread/RenderThread.cpp3
-rw-r--r--libs/hwui/renderthread/TimeLord.cpp8
-rw-r--r--libs/hwui/renderthread/TimeLord.h5
-rw-r--r--libs/hwui/tests/macrobench/TestSceneRunner.cpp4
15 files changed, 104 insertions, 40 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
}
/*
diff --git a/core/jni/android_view_DisplayEventReceiver.cpp b/core/jni/android_view_DisplayEventReceiver.cpp
index 3acd15a8f340..e7e9c31ef90e 100644
--- a/core/jni/android_view_DisplayEventReceiver.cpp
+++ b/core/jni/android_view_DisplayEventReceiver.cpp
@@ -60,7 +60,7 @@ private:
sp<MessageQueue> mMessageQueue;
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 dispatchConfigChanged(nsecs_t timestamp, PhysicalDisplayId displayId,
int32_t configId, nsecs_t vsyncPeriod) override;
@@ -91,14 +91,15 @@ void NativeDisplayEventReceiver::dispose() {
}
void NativeDisplayEventReceiver::dispatchVsync(nsecs_t timestamp, PhysicalDisplayId displayId,
- uint32_t count, int64_t frameTimelineVsyncId) {
+ uint32_t count, VsyncEventData vsyncEventData) {
JNIEnv* env = AndroidRuntime::getJNIEnv();
ScopedLocalRef<jobject> receiverObj(env, jniGetReferent(env, mReceiverWeakGlobal));
if (receiverObj.get()) {
ALOGV("receiver %p ~ Invoking vsync handler.", this);
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);
}
@@ -198,7 +199,8 @@ int register_android_view_DisplayEventReceiver(JNIEnv* env) {
gDisplayEventReceiverClassInfo.clazz = MakeGlobalRefOrDie(env, clazz);
gDisplayEventReceiverClassInfo.dispatchVsync =
- GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz, "dispatchVsync", "(JJIJ)V");
+ GetMethodIDOrDie(env, gDisplayEventReceiverClassInfo.clazz, "dispatchVsync",
+ "(JJIJJ)V");
gDisplayEventReceiverClassInfo.dispatchHotplug = GetMethodIDOrDie(env,
gDisplayEventReceiverClassInfo.clazz, "dispatchHotplug", "(JJZ)V");
gDisplayEventReceiverClassInfo.dispatchConfigChanged = GetMethodIDOrDie(env,
diff --git a/graphics/java/android/graphics/FrameInfo.java b/graphics/java/android/graphics/FrameInfo.java
index f768bc741447..0061ea13f647 100644
--- a/graphics/java/android/graphics/FrameInfo.java
+++ b/graphics/java/android/graphics/FrameInfo.java
@@ -40,7 +40,7 @@ import java.lang.annotation.RetentionPolicy;
*/
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
private static final int FLAGS = 0;
@@ -87,14 +87,22 @@ public final class FrameInfo {
// When View:draw() started
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 */
- 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[INTENDED_VSYNC] = intendedVsync;
frameInfo[VSYNC] = usedVsync;
frameInfo[OLDEST_INPUT_EVENT] = Long.MAX_VALUE;
frameInfo[NEWEST_INPUT_EVENT] = 0;
frameInfo[FLAGS] = 0;
+ frameInfo[FRAME_DEADLINE] = frameDeadline;
}
/** checkstyle */
diff --git a/graphics/java/android/graphics/HardwareRenderer.java b/graphics/java/android/graphics/HardwareRenderer.java
index fd5916c2158d..a7f2739153e1 100644
--- a/graphics/java/android/graphics/HardwareRenderer.java
+++ b/graphics/java/android/graphics/HardwareRenderer.java
@@ -355,7 +355,7 @@ public class HardwareRenderer {
*/
public @NonNull FrameRenderRequest setVsyncTime(long vsyncTime) {
// TODO(b/168552873): populate vsync Id once available to Choreographer public API
- mFrameInfo.setVsync(vsyncTime, vsyncTime, FrameInfo.INVALID_VSYNC_ID);
+ mFrameInfo.setVsync(vsyncTime, vsyncTime, FrameInfo.INVALID_VSYNC_ID, Long.MAX_VALUE);
mFrameInfo.addFlags(FrameInfo.FLAG_SURFACE_CANVAS);
return this;
}
diff --git a/libs/hwui/FrameInfo.cpp b/libs/hwui/FrameInfo.cpp
index 30ce5370760d..fd18d2f9192d 100644
--- a/libs/hwui/FrameInfo.cpp
+++ b/libs/hwui/FrameInfo.cpp
@@ -31,6 +31,7 @@ const std::string FrameInfoNames[] = {
"AnimationStart",
"PerformTraversalsStart",
"DrawStart",
+ "FrameDeadline",
"SyncQueued",
"SyncStart",
"IssueDrawCommandsStart",
@@ -45,7 +46,7 @@ static_assert((sizeof(FrameInfoNames) / sizeof(FrameInfoNames[0])) ==
static_cast<int>(FrameInfoIndex::NumIndexes),
"size mismatch: FrameInfoNames doesn't match the enum!");
-static_assert(static_cast<int>(FrameInfoIndex::NumIndexes) == 18,
+static_assert(static_cast<int>(FrameInfoIndex::NumIndexes) == 19,
"Must update value in FrameMetrics.java#FRAME_STATS_COUNT (and here)");
void FrameInfo::importUiThreadInfo(int64_t* info) {
diff --git a/libs/hwui/FrameInfo.h b/libs/hwui/FrameInfo.h
index f5bfedde2f92..d24eca7d00c6 100644
--- a/libs/hwui/FrameInfo.h
+++ b/libs/hwui/FrameInfo.h
@@ -27,7 +27,7 @@
namespace android {
namespace uirenderer {
-#define UI_THREAD_FRAME_INFO_SIZE 10
+#define UI_THREAD_FRAME_INFO_SIZE 11
enum class FrameInfoIndex {
Flags = 0,
@@ -40,6 +40,7 @@ enum class FrameInfoIndex {
AnimationStart,
PerformTraversalsStart,
DrawStart,
+ FrameDeadline,
// End of UI frame info
SyncQueued,
@@ -77,9 +78,11 @@ public:
explicit UiFrameInfoBuilder(int64_t* buffer) : mBuffer(buffer) {
memset(mBuffer, 0, UI_THREAD_FRAME_INFO_SIZE * sizeof(int64_t));
set(FrameInfoIndex::FrameTimelineVsyncId) = INVALID_VSYNC_ID;
+ set(FrameInfoIndex::FrameDeadline) = std::numeric_limits<int64_t>::max();
}
- UiFrameInfoBuilder& setVsync(nsecs_t vsyncTime, nsecs_t intendedVsync, int64_t vsyncId) {
+ UiFrameInfoBuilder& setVsync(nsecs_t vsyncTime, nsecs_t intendedVsync,
+ int64_t vsyncId, int64_t frameDeadline) {
set(FrameInfoIndex::FrameTimelineVsyncId) = vsyncId;
set(FrameInfoIndex::Vsync) = vsyncTime;
set(FrameInfoIndex::IntendedVsync) = intendedVsync;
@@ -89,6 +92,7 @@ public:
set(FrameInfoIndex::AnimationStart) = vsyncTime;
set(FrameInfoIndex::PerformTraversalsStart) = vsyncTime;
set(FrameInfoIndex::DrawStart) = vsyncTime;
+ set(FrameInfoIndex::FrameDeadline) = frameDeadline;
return *this;
}
diff --git a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
index c89463bf3ab4..a146b64e29cc 100644
--- a/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
+++ b/libs/hwui/jni/android_graphics_HardwareRenderer.cpp
@@ -514,7 +514,8 @@ static jobject android_view_ThreadedRenderer_createHardwareBitmapFromRenderNode(
proxy.setLightGeometry((Vector3){0, 0, 0}, 0);
nsecs_t vsync = systemTime(SYSTEM_TIME_MONOTONIC);
UiFrameInfoBuilder(proxy.frameInfo())
- .setVsync(vsync, vsync, UiFrameInfoBuilder::INVALID_VSYNC_ID)
+ .setVsync(vsync, vsync, UiFrameInfoBuilder::INVALID_VSYNC_ID,
+ std::numeric_limits<int64_t>::max())
.addFlag(FrameInfoFlags::SurfaceCanvas);
proxy.syncAndDrawFrame();
}
diff --git a/libs/hwui/renderthread/CanvasContext.cpp b/libs/hwui/renderthread/CanvasContext.cpp
index 04359818e1b7..1ac99228c52c 100644
--- a/libs/hwui/renderthread/CanvasContext.cpp
+++ b/libs/hwui/renderthread/CanvasContext.cpp
@@ -629,10 +629,11 @@ void CanvasContext::prepareAndDraw(RenderNode* node) {
nsecs_t vsync = mRenderThread.timeLord().computeFrameTimeNanos();
int64_t vsyncId = mRenderThread.timeLord().lastVsyncId();
+ int64_t frameDeadline = mRenderThread.timeLord().lastFrameDeadline();
int64_t frameInfo[UI_THREAD_FRAME_INFO_SIZE];
UiFrameInfoBuilder(frameInfo)
.addFlag(FrameInfoFlags::RTAnimation)
- .setVsync(vsync, vsync, vsyncId);
+ .setVsync(vsync, vsync, vsyncId, frameDeadline);
TreeInfo info(TreeInfo::MODE_RT_ONLY, *this);
prepareTree(info, frameInfo, systemTime(SYSTEM_TIME_MONOTONIC), node);
diff --git a/libs/hwui/renderthread/DrawFrameTask.cpp b/libs/hwui/renderthread/DrawFrameTask.cpp
index 1ea595d6a30a..c9146b2fc2d1 100644
--- a/libs/hwui/renderthread/DrawFrameTask.cpp
+++ b/libs/hwui/renderthread/DrawFrameTask.cpp
@@ -130,7 +130,8 @@ bool DrawFrameTask::syncFrameState(TreeInfo& info) {
int64_t vsync = mFrameInfo[static_cast<int>(FrameInfoIndex::Vsync)];
int64_t intendedVsync = mFrameInfo[static_cast<int>(FrameInfoIndex::IntendedVsync)];
int64_t vsyncId = mFrameInfo[static_cast<int>(FrameInfoIndex::FrameTimelineVsyncId)];
- mRenderThread->timeLord().vsyncReceived(vsync, intendedVsync, vsyncId);
+ int64_t frameDeadline = mFrameInfo[static_cast<int>(FrameInfoIndex::FrameDeadline)];
+ mRenderThread->timeLord().vsyncReceived(vsync, intendedVsync, vsyncId, frameDeadline);
bool canDraw = mContext->makeCurrent();
mContext->unpinImages();
diff --git a/libs/hwui/renderthread/RenderThread.cpp b/libs/hwui/renderthread/RenderThread.cpp
index 9371656eda7f..a101d46f6da0 100644
--- a/libs/hwui/renderthread/RenderThread.cpp
+++ b/libs/hwui/renderthread/RenderThread.cpp
@@ -52,8 +52,9 @@ static JVMAttachHook gOnStartHook = nullptr;
void RenderThread::frameCallback(int64_t frameTimeNanos, void* data) {
RenderThread* rt = reinterpret_cast<RenderThread*>(data);
int64_t vsyncId = AChoreographer_getVsyncId(rt->mChoreographer);
+ int64_t frameDeadline = AChoreographer_getFrameDeadline(rt->mChoreographer);
rt->mVsyncRequested = false;
- if (rt->timeLord().vsyncReceived(frameTimeNanos, frameTimeNanos, vsyncId) &&
+ if (rt->timeLord().vsyncReceived(frameTimeNanos, frameTimeNanos, vsyncId, frameDeadline) &&
!rt->mFrameCallbackTaskPending) {
ATRACE_NAME("queue mFrameCallbackTask");
rt->mFrameCallbackTaskPending = true;
diff --git a/libs/hwui/renderthread/TimeLord.cpp b/libs/hwui/renderthread/TimeLord.cpp
index 7dc36c449568..abb633028363 100644
--- a/libs/hwui/renderthread/TimeLord.cpp
+++ b/libs/hwui/renderthread/TimeLord.cpp
@@ -14,6 +14,7 @@
* limitations under the License.
*/
#include "TimeLord.h"
+#include <limits>
namespace android {
namespace uirenderer {
@@ -22,12 +23,15 @@ namespace renderthread {
TimeLord::TimeLord() : mFrameIntervalNanos(milliseconds_to_nanoseconds(16)),
mFrameTimeNanos(0),
mFrameIntendedTimeNanos(0),
- mFrameVsyncId(-1) {}
+ mFrameVsyncId(-1),
+ mFrameDeadline(std::numeric_limits<int64_t>::max()){}
-bool TimeLord::vsyncReceived(nsecs_t vsync, nsecs_t intendedVsync, int64_t vsyncId) {
+bool TimeLord::vsyncReceived(nsecs_t vsync, nsecs_t intendedVsync, int64_t vsyncId,
+ int64_t frameDeadline) {
if (intendedVsync > mFrameIntendedTimeNanos) {
mFrameIntendedTimeNanos = intendedVsync;
mFrameVsyncId = vsyncId;
+ mFrameDeadline = frameDeadline;
}
if (vsync > mFrameTimeNanos) {
diff --git a/libs/hwui/renderthread/TimeLord.h b/libs/hwui/renderthread/TimeLord.h
index 23c1e51c427a..fa05c030fa0f 100644
--- a/libs/hwui/renderthread/TimeLord.h
+++ b/libs/hwui/renderthread/TimeLord.h
@@ -32,10 +32,12 @@ public:
nsecs_t frameIntervalNanos() const { return mFrameIntervalNanos; }
// returns true if the vsync is newer, false if it was rejected for staleness
- bool vsyncReceived(nsecs_t vsync, nsecs_t indendedVsync, int64_t vsyncId);
+ bool vsyncReceived(nsecs_t vsync, nsecs_t indendedVsync, int64_t vsyncId,
+ int64_t frameDeadline);
nsecs_t latestVsync() { return mFrameTimeNanos; }
nsecs_t computeFrameTimeNanos();
int64_t lastVsyncId() const { return mFrameVsyncId; }
+ int64_t lastFrameDeadline() const { return mFrameDeadline; }
private:
friend class RenderThread;
@@ -47,6 +49,7 @@ private:
nsecs_t mFrameTimeNanos;
nsecs_t mFrameIntendedTimeNanos;
int64_t mFrameVsyncId;
+ int64_t mFrameDeadline;
};
} /* namespace renderthread */
diff --git a/libs/hwui/tests/macrobench/TestSceneRunner.cpp b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
index ed89c590be10..eda5d2266dcf 100644
--- a/libs/hwui/tests/macrobench/TestSceneRunner.cpp
+++ b/libs/hwui/tests/macrobench/TestSceneRunner.cpp
@@ -146,7 +146,7 @@ void run(const TestScene::Info& info, const TestScene::Options& opts,
testContext.waitForVsync();
nsecs_t vsync = systemTime(SYSTEM_TIME_MONOTONIC);
UiFrameInfoBuilder(proxy->frameInfo())
- .setVsync(vsync, vsync, UiFrameInfoBuilder::INVALID_VSYNC_ID);
+ .setVsync(vsync, vsync, UiFrameInfoBuilder::INVALID_VSYNC_ID, std::numeric_limits<int64_t>::max());
proxy->syncAndDrawFrame();
}
@@ -167,7 +167,7 @@ void run(const TestScene::Info& info, const TestScene::Options& opts,
{
ATRACE_NAME("UI-Draw Frame");
UiFrameInfoBuilder(proxy->frameInfo())
- .setVsync(vsync, vsync, UiFrameInfoBuilder::INVALID_VSYNC_ID);
+ .setVsync(vsync, vsync, UiFrameInfoBuilder::INVALID_VSYNC_ID, std::numeric_limits<int64_t>::max());
scene->doFrame(i);
proxy->syncAndDrawFrame();
}