Fix SF jank classification
In a buffer stuffed state, there is no way the app frame will be
presented on time. It will be at least one vsync late even if the app
frame finished much earlier than expected. The current system wrongly
classifies this as SF Scheduling jank when in reality, the only jank is
that the app is now in a buffer stuffed state.
The other case can also happen, the app could have presented only one
vsync late in a stuffed scenario, but it could have spent some time
waiting on dequeue. To consider this case and give some room for the
app, we try to adjust the deadline within which the app should be ready
to be presented on the next vsync. This way, we can find frames that are
truly long in a buffer stuffed state.
Bug: 180423820
Test: libsurfaceflinger_unittest
Change-Id: I6ff35d018cfab1ef1e96d010165ed7bce013a98e
diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
index ff000c9..75229e9 100644
--- a/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
+++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.cpp
@@ -504,6 +504,17 @@
if (mLastLatchTime != 0 && mPredictions.endTime <= mLastLatchTime) {
// Buffer Stuffing.
mJankType |= JankType::BufferStuffing;
+ // In a stuffed state, the frame could be stuck on a dequeue wait for quite some time.
+ // Because of this dequeue wait, it can be hard to tell if a frame was genuinely late.
+ // We try to do this by moving the deadline. Since the queue could be stuffed by more
+ // than one buffer, we take the last latch time as reference and give one vsync
+ // worth of time for the frame to be ready.
+ nsecs_t adjustedDeadline = mLastLatchTime + refreshRate.getPeriodNsecs();
+ if (adjustedDeadline > mActuals.endTime) {
+ mFrameReadyMetadata = FrameReadyMetadata::OnTimeFinish;
+ } else {
+ mFrameReadyMetadata = FrameReadyMetadata::LateFinish;
+ }
}
if (mFrameReadyMetadata == FrameReadyMetadata::OnTimeFinish) {
// Finish on time, Present late
@@ -511,14 +522,18 @@
// Propagate displayFrame's jank if it exists
mJankType |= displayFrameJankType;
} else {
- if (deltaToVsync < mJankClassificationThresholds.presentThreshold ||
- deltaToVsync >= refreshRate.getPeriodNsecs() -
- mJankClassificationThresholds.presentThreshold) {
- // Delta factor of vsync
- mJankType |= JankType::SurfaceFlingerScheduling;
- } else {
- // Delta not a factor of vsync
- mJankType |= JankType::PredictionError;
+ if (!(mJankType & JankType::BufferStuffing)) {
+ // In a stuffed state, if the app finishes on time and there is no display frame
+ // jank, only buffer stuffing is the root cause of the jank.
+ if (deltaToVsync < mJankClassificationThresholds.presentThreshold ||
+ deltaToVsync >= refreshRate.getPeriodNsecs() -
+ mJankClassificationThresholds.presentThreshold) {
+ // Delta factor of vsync
+ mJankType |= JankType::SurfaceFlingerScheduling;
+ } else {
+ // Delta not a factor of vsync
+ mJankType |= JankType::PredictionError;
+ }
}
}
} else if (mFrameReadyMetadata == FrameReadyMetadata::LateFinish) {
@@ -683,13 +698,14 @@
}
FrameTimeline::FrameTimeline(std::shared_ptr<TimeStats> timeStats, pid_t surfaceFlingerPid,
- JankClassificationThresholds thresholds)
+ JankClassificationThresholds thresholds, nsecs_t hwcDuration)
: mMaxDisplayFrames(kDefaultMaxDisplayFrames),
mTimeStats(std::move(timeStats)),
mSurfaceFlingerPid(surfaceFlingerPid),
- mJankClassificationThresholds(thresholds) {
- mCurrentDisplayFrame =
- std::make_shared<DisplayFrame>(mTimeStats, thresholds, &mTraceCookieCounter);
+ mJankClassificationThresholds(thresholds),
+ mHwcDuration(hwcDuration) {
+ mCurrentDisplayFrame = std::make_shared<DisplayFrame>(mTimeStats, thresholds, hwcDuration,
+ &mTraceCookieCounter);
}
void FrameTimeline::onBootFinished() {
@@ -732,11 +748,13 @@
FrameTimeline::DisplayFrame::DisplayFrame(std::shared_ptr<TimeStats> timeStats,
JankClassificationThresholds thresholds,
+ nsecs_t hwcDuration,
TraceCookieCounter* traceCookieCounter)
: mSurfaceFlingerPredictions(TimelineItem()),
mSurfaceFlingerActuals(TimelineItem()),
mTimeStats(timeStats),
mJankClassificationThresholds(thresholds),
+ mHwcDuration(hwcDuration),
mTraceCookieCounter(*traceCookieCounter) {
mSurfaceFrames.reserve(kNumSurfaceFramesInitial);
}
@@ -808,7 +826,7 @@
const nsecs_t presentDelta =
mSurfaceFlingerActuals.presentTime - mSurfaceFlingerPredictions.presentTime;
const nsecs_t deadlineDelta =
- mSurfaceFlingerActuals.endTime - mSurfaceFlingerPredictions.endTime;
+ mSurfaceFlingerActuals.endTime - (mSurfaceFlingerPredictions.endTime - mHwcDuration);
// How far off was the presentDelta when compared to the vsyncPeriod. Used in checking if there
// was a prediction error or not.
@@ -822,8 +840,9 @@
mFramePresentMetadata = FramePresentMetadata::OnTimePresent;
}
- if (mSurfaceFlingerActuals.endTime - mSurfaceFlingerPredictions.endTime >
- mJankClassificationThresholds.deadlineThreshold) {
+ if (mSurfaceFlingerActuals.endTime > mSurfaceFlingerPredictions.endTime - mHwcDuration) {
+ // SF needs to have finished at least mHwcDuration ahead of the deadline for it to be
+ // on time.
mFrameReadyMetadata = FrameReadyMetadata::LateFinish;
} else {
mFrameReadyMetadata = FrameReadyMetadata::OnTimeFinish;
@@ -875,8 +894,13 @@
mJankType = JankType::PredictionError;
}
} else if (mFrameReadyMetadata == FrameReadyMetadata::LateFinish) {
- // Finish late, Present late
- mJankType = JankType::SurfaceFlingerCpuDeadlineMissed;
+ if (mFrameStartMetadata == FrameStartMetadata::LateStart) {
+ // Late start, Late finish, Late Present
+ mJankType = JankType::SurfaceFlingerScheduling;
+ } else {
+ // OnTime start, Finish late, Present late
+ mJankType = JankType::SurfaceFlingerCpuDeadlineMissed;
+ }
} else {
// Finish time unknown
mJankType = JankType::Unknown;
@@ -1066,7 +1090,7 @@
mDisplayFrames.push_back(mCurrentDisplayFrame);
mCurrentDisplayFrame.reset();
mCurrentDisplayFrame = std::make_shared<DisplayFrame>(mTimeStats, mJankClassificationThresholds,
- &mTraceCookieCounter);
+ mHwcDuration, &mTraceCookieCounter);
}
nsecs_t FrameTimeline::DisplayFrame::getBaseTime() const {
diff --git a/services/surfaceflinger/FrameTimeline/FrameTimeline.h b/services/surfaceflinger/FrameTimeline/FrameTimeline.h
index d65769b..7c6a0cc 100644
--- a/services/surfaceflinger/FrameTimeline/FrameTimeline.h
+++ b/services/surfaceflinger/FrameTimeline/FrameTimeline.h
@@ -342,7 +342,7 @@
class DisplayFrame {
public:
DisplayFrame(std::shared_ptr<TimeStats> timeStats, JankClassificationThresholds thresholds,
- TraceCookieCounter* traceCookieCounter);
+ nsecs_t hwcDuration, TraceCookieCounter* traceCookieCounter);
virtual ~DisplayFrame() = default;
// Dumpsys interface - dumps only if the DisplayFrame itself is janky or is at least one
// SurfaceFrame is janky.
@@ -371,6 +371,7 @@
// Functions to be used only in testing.
TimelineItem getActuals() const { return mSurfaceFlingerActuals; };
TimelineItem getPredictions() const { return mSurfaceFlingerPredictions; };
+ FrameStartMetadata getFrameStartMetadata() const { return mFrameStartMetadata; };
FramePresentMetadata getFramePresentMetadata() const { return mFramePresentMetadata; };
FrameReadyMetadata getFrameReadyMetadata() const { return mFrameReadyMetadata; };
int32_t getJankType() const { return mJankType; }
@@ -394,6 +395,7 @@
TimelineItem mSurfaceFlingerActuals;
std::shared_ptr<TimeStats> mTimeStats;
const JankClassificationThresholds mJankClassificationThresholds;
+ const nsecs_t mHwcDuration;
// Collection of predictions and actual values sent over by Layers
std::vector<std::shared_ptr<SurfaceFrame>> mSurfaceFrames;
@@ -419,7 +421,8 @@
};
FrameTimeline(std::shared_ptr<TimeStats> timeStats, pid_t surfaceFlingerPid,
- JankClassificationThresholds thresholds = {});
+ JankClassificationThresholds thresholds = {},
+ nsecs_t hwcDuration = kDefaultHwcDuration);
~FrameTimeline() = default;
frametimeline::TokenManager* getTokenManager() override { return &mTokenManager; }
@@ -464,6 +467,11 @@
std::shared_ptr<TimeStats> mTimeStats;
const pid_t mSurfaceFlingerPid;
const JankClassificationThresholds mJankClassificationThresholds;
+ // In SF Predictions, both end & present are the same. The predictions consider the time used by
+ // composer as well, but we have no way to estimate how much time the composer needs. We are
+ // assuming an arbitrary time for the composer work.
+ const nsecs_t mHwcDuration;
+ static constexpr nsecs_t kDefaultHwcDuration = std::chrono::nanoseconds(3ms).count();
static constexpr uint32_t kDefaultMaxDisplayFrames = 64;
// The initial container size for the vector<SurfaceFrames> inside display frame. Although
// this number doesn't represent any bounds on the number of surface frames that can go in a
diff --git a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp
index 9a4e020..7e6141e 100644
--- a/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp
+++ b/services/surfaceflinger/tests/unittests/FrameTimelineTest.cpp
@@ -67,7 +67,7 @@
void SetUp() override {
mTimeStats = std::make_shared<mock::TimeStats>();
mFrameTimeline = std::make_unique<impl::FrameTimeline>(mTimeStats, kSurfaceFlingerPid,
- kTestThresholds);
+ kTestThresholds, kHwcDuration);
mFrameTimeline->registerDataSource();
mTokenManager = &mFrameTimeline->mTokenManager;
mTraceCookieCounter = &mFrameTimeline->mTraceCookieCounter;
@@ -162,6 +162,7 @@
static constexpr JankClassificationThresholds kTestThresholds{kPresentThreshold,
kDeadlineThreshold,
kStartThreshold};
+ static constexpr nsecs_t kHwcDuration = std::chrono::nanoseconds(3ns).count();
};
static const std::string sLayerNameOne = "layer1";
@@ -420,37 +421,29 @@
// Tests related to TimeStats
TEST_F(FrameTimelineTest, presentFenceSignaled_reportsLongSfCpu) {
- Fps refreshRate = Fps(11);
+ Fps refreshRate = Fps::fromPeriodNsecs(11);
+ // Deadline delta is 2ms because, sf's adjusted deadline is 60 - composerTime(3) = 57ms.
EXPECT_CALL(*mTimeStats,
incrementJankyFrames(
TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
sLayerNameOne,
- JankType::SurfaceFlingerCpuDeadlineMissed,
- std::chrono::duration_cast<
- std::chrono::nanoseconds>(3ms)
- .count(),
- std::chrono::duration_cast<
- std::chrono::nanoseconds>(10ms)
- .count(),
+ JankType::SurfaceFlingerCpuDeadlineMissed, 2, 10,
0}));
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
- int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
- {std::chrono::nanoseconds(10ms).count(), std::chrono::nanoseconds(20ms).count(),
- std::chrono::nanoseconds(60ms).count()});
- int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
- {std::chrono::nanoseconds(52ms).count(), std::chrono::nanoseconds(56ms).count(),
- std::chrono::nanoseconds(60ms).count()});
+ int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
+ int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
+
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
sLayerNameOne);
- mFrameTimeline->setSfWakeUp(sfToken1, std::chrono::nanoseconds(52ms).count(), refreshRate);
- surfaceFrame1->setAcquireFenceTime(std::chrono::nanoseconds(20ms).count());
+ mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
+ surfaceFrame1->setAcquireFenceTime(20);
surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
mFrameTimeline->addSurfaceFrame(surfaceFrame1);
- presentFence1->signalForTest(std::chrono::nanoseconds(70ms).count());
+ presentFence1->signalForTest(70);
- mFrameTimeline->setSfPresent(std::chrono::nanoseconds(59ms).count(), presentFence1);
+ mFrameTimeline->setSfPresent(59, presentFence1);
}
TEST_F(FrameTimelineTest, presentFenceSignaled_reportsDisplayMiss) {
@@ -458,186 +451,153 @@
EXPECT_CALL(*mTimeStats,
incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
sLayerNameOne, JankType::DisplayHAL,
- 0, 0, 0}));
+ -1, 0, 0}));
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
- int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
- {std::chrono::nanoseconds(10ms).count(), std::chrono::nanoseconds(20ms).count(),
- std::chrono::nanoseconds(60ms).count()});
- int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
- {std::chrono::nanoseconds(52ms).count(), std::chrono::nanoseconds(56ms).count(),
- std::chrono::nanoseconds(60ms).count()});
+ int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
+ int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
+
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
sLayerNameOne);
- mFrameTimeline->setSfWakeUp(sfToken1, std::chrono::nanoseconds(52ms).count(), refreshRate);
+ mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
- surfaceFrame1->setAcquireFenceTime(std::chrono::nanoseconds(20ms).count());
+ surfaceFrame1->setAcquireFenceTime(20);
mFrameTimeline->addSurfaceFrame(surfaceFrame1);
- presentFence1->signalForTest(std::chrono::nanoseconds(90ms).count());
- mFrameTimeline->setSfPresent(std::chrono::nanoseconds(56ms).count(), presentFence1);
+ presentFence1->signalForTest(90);
+ mFrameTimeline->setSfPresent(56, presentFence1);
EXPECT_EQ(surfaceFrame1->getJankType(), JankType::DisplayHAL);
}
TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMiss) {
Fps refreshRate = Fps(11.0);
EXPECT_CALL(*mTimeStats,
- incrementJankyFrames(
- TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
- sLayerNameOne, JankType::AppDeadlineMissed, 0, 0,
- std::chrono::duration_cast<
- std::chrono::nanoseconds>(25ms)
- .count()}));
+ incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
+ sLayerNameOne,
+ JankType::AppDeadlineMissed, -1, 0,
+ 25}));
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
- int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
- {std::chrono::nanoseconds(10ms).count(), std::chrono::nanoseconds(20ms).count(),
- std::chrono::nanoseconds(60ms).count()});
- int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
- {std::chrono::nanoseconds(82ms).count(), std::chrono::nanoseconds(86ms).count(),
- std::chrono::nanoseconds(90ms).count()});
+ int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
+ int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
+
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
sLayerNameOne);
- surfaceFrame1->setAcquireFenceTime(std::chrono::nanoseconds(45ms).count());
- mFrameTimeline->setSfWakeUp(sfToken1, std::chrono::nanoseconds(52ms).count(), refreshRate);
+ surfaceFrame1->setAcquireFenceTime(45);
+ mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
mFrameTimeline->addSurfaceFrame(surfaceFrame1);
- presentFence1->signalForTest(std::chrono::nanoseconds(90ms).count());
- mFrameTimeline->setSfPresent(std::chrono::nanoseconds(86ms).count(), presentFence1);
+ presentFence1->signalForTest(90);
+ mFrameTimeline->setSfPresent(86, presentFence1);
EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
}
TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfScheduling) {
- Fps refreshRate = Fps::fromPeriodNsecs(std::chrono::nanoseconds(32ms).count());
+ Fps refreshRate = Fps::fromPeriodNsecs(32);
EXPECT_CALL(*mTimeStats,
- incrementJankyFrames(
- TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
- sLayerNameOne,
- JankType::SurfaceFlingerScheduling, 0, 0,
- std::chrono::duration_cast<
- std::chrono::nanoseconds>(-10ms)
- .count()}));
+ incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
+ sLayerNameOne,
+ JankType::SurfaceFlingerScheduling,
+ -1, 0, -10}));
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
- int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
- {std::chrono::nanoseconds(40ms).count(), std::chrono::nanoseconds(60ms).count(),
- std::chrono::nanoseconds(92ms).count()});
- int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
- {std::chrono::nanoseconds(52ms).count(), std::chrono::nanoseconds(56ms).count(),
- std::chrono::nanoseconds(60ms).count()});
+ int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({40, 60, 92});
+ int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
+
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
sLayerNameOne);
- surfaceFrame1->setAcquireFenceTime(std::chrono::nanoseconds(50ms).count());
- mFrameTimeline->setSfWakeUp(sfToken1, std::chrono::nanoseconds(52ms).count(), refreshRate);
+ surfaceFrame1->setAcquireFenceTime(50);
+ mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
mFrameTimeline->addSurfaceFrame(surfaceFrame1);
- presentFence1->signalForTest(std::chrono::nanoseconds(60ms).count());
- mFrameTimeline->setSfPresent(std::chrono::nanoseconds(56ms).count(), presentFence1);
+ presentFence1->signalForTest(60);
+ mFrameTimeline->setSfPresent(56, presentFence1);
EXPECT_EQ(surfaceFrame1->getJankType(), JankType::SurfaceFlingerScheduling);
}
TEST_F(FrameTimelineTest, presentFenceSignaled_reportsSfPredictionError) {
- Fps refreshRate = Fps(16.66f);
+ Fps refreshRate = Fps::fromPeriodNsecs(16);
EXPECT_CALL(*mTimeStats,
- incrementJankyFrames(
- TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
- sLayerNameOne, JankType::PredictionError, 0,
- std::chrono::duration_cast<
- std::chrono::nanoseconds>(5ms)
- .count(),
- 0}));
+ incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
+ sLayerNameOne,
+ JankType::PredictionError, -1, 5,
+ 0}));
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
- int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
- {std::chrono::nanoseconds(30ms).count(), std::chrono::nanoseconds(40ms).count(),
- std::chrono::nanoseconds(60ms).count()});
- int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
- {std::chrono::nanoseconds(52ms).count(), std::chrono::nanoseconds(56ms).count(),
- std::chrono::nanoseconds(60ms).count()});
+ int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 60});
+ int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
+
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
sLayerNameOne);
- surfaceFrame1->setAcquireFenceTime(std::chrono::nanoseconds(40ms).count());
- mFrameTimeline->setSfWakeUp(sfToken1, std::chrono::nanoseconds(52ms).count(), refreshRate);
+ surfaceFrame1->setAcquireFenceTime(40);
+ mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
mFrameTimeline->addSurfaceFrame(surfaceFrame1);
- presentFence1->signalForTest(std::chrono::nanoseconds(65ms).count());
- mFrameTimeline->setSfPresent(std::chrono::nanoseconds(56ms).count(), presentFence1);
+ presentFence1->signalForTest(65);
+ mFrameTimeline->setSfPresent(56, presentFence1);
EXPECT_EQ(surfaceFrame1->getJankType(), JankType::PredictionError);
}
TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppBufferStuffing) {
- Fps refreshRate = Fps::fromPeriodNsecs(std::chrono::nanoseconds(32ms).count());
+ Fps refreshRate = Fps::fromPeriodNsecs(32);
EXPECT_CALL(*mTimeStats,
- incrementJankyFrames(
- TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
- sLayerNameOne,
- JankType::BufferStuffing |
- JankType::SurfaceFlingerScheduling,
- 0, 0, 0}));
+ incrementJankyFrames(TimeStats::JankyFramesInfo{refreshRate, std::nullopt, sUidOne,
+ sLayerNameOne,
+ JankType::BufferStuffing, -1, 0,
+ 0}));
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
- int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
- {std::chrono::nanoseconds(30ms).count(), std::chrono::nanoseconds(40ms).count(),
- std::chrono::nanoseconds(58ms).count()});
- int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
- {std::chrono::nanoseconds(82ms).count(), std::chrono::nanoseconds(86ms).count(),
- std::chrono::nanoseconds(90ms).count()});
+ int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({30, 40, 58});
+ int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
+
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
sLayerNameOne);
- surfaceFrame1->setAcquireFenceTime(std::chrono::nanoseconds(40ms).count());
- mFrameTimeline->setSfWakeUp(sfToken1, std::chrono::nanoseconds(82ms).count(), refreshRate);
+ surfaceFrame1->setAcquireFenceTime(40);
+ mFrameTimeline->setSfWakeUp(sfToken1, 82, refreshRate);
surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented,
- /*previousLatchTime*/
- std::chrono::nanoseconds(56ms).count());
+ /*previousLatchTime*/ 56);
mFrameTimeline->addSurfaceFrame(surfaceFrame1);
- presentFence1->signalForTest(std::chrono::nanoseconds(90ms).count());
- mFrameTimeline->setSfPresent(std::chrono::nanoseconds(86ms).count(), presentFence1);
+ presentFence1->signalForTest(90);
+ mFrameTimeline->setSfPresent(86, presentFence1);
- EXPECT_EQ(surfaceFrame1->getJankType(),
- JankType::BufferStuffing | JankType::SurfaceFlingerScheduling);
+ EXPECT_EQ(surfaceFrame1->getJankType(), JankType::BufferStuffing);
}
TEST_F(FrameTimelineTest, presentFenceSignaled_reportsAppMissWithRenderRate) {
- Fps refreshRate = Fps(11.0);
- Fps renderRate = Fps(30.0);
+ Fps refreshRate = Fps::fromPeriodNsecs(11);
+ Fps renderRate = Fps::fromPeriodNsecs(30);
EXPECT_CALL(*mTimeStats,
incrementJankyFrames(
TimeStats::JankyFramesInfo{refreshRate, renderRate, sUidOne, sLayerNameOne,
- JankType::AppDeadlineMissed, 0, 0,
- std::chrono::duration_cast<
- std::chrono::nanoseconds>(25ms)
- .count()}));
+ JankType::AppDeadlineMissed, -1, 0, 25}));
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
- int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions(
- {std::chrono::nanoseconds(10ms).count(), std::chrono::nanoseconds(20ms).count(),
- std::chrono::nanoseconds(60ms).count()});
- int64_t sfToken1 = mTokenManager->generateTokenForPredictions(
- {std::chrono::nanoseconds(82ms).count(), std::chrono::nanoseconds(86ms).count(),
- std::chrono::nanoseconds(90ms).count()});
+ int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 60});
+ int64_t sfToken1 = mTokenManager->generateTokenForPredictions({82, 90, 90});
+
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
sLayerNameOne);
- surfaceFrame1->setAcquireFenceTime(std::chrono::nanoseconds(45ms).count());
- mFrameTimeline->setSfWakeUp(sfToken1, std::chrono::nanoseconds(52ms).count(), refreshRate);
+ surfaceFrame1->setAcquireFenceTime(45);
+ mFrameTimeline->setSfWakeUp(sfToken1, 52, refreshRate);
surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
surfaceFrame1->setRenderRate(renderRate);
mFrameTimeline->addSurfaceFrame(surfaceFrame1);
- presentFence1->signalForTest(std::chrono::nanoseconds(90ms).count());
- mFrameTimeline->setSfPresent(std::chrono::nanoseconds(86ms).count(), presentFence1);
+ presentFence1->signalForTest(90);
+ mFrameTimeline->setSfPresent(86, presentFence1);
EXPECT_EQ(surfaceFrame1->getJankType(), JankType::AppDeadlineMissed);
}
@@ -893,7 +853,7 @@
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
tracingSession->StartBlocking();
- int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 25, 30});
+ int64_t displayFrameToken1 = mTokenManager->generateTokenForPredictions({10, 30, 30});
// Set up the display frame
mFrameTimeline->setSfWakeUp(displayFrameToken1, 20, Fps::fromPeriodNsecs(11));
@@ -933,7 +893,7 @@
// Packet - 1 : FrameEnd (ExpectedDisplayFrame)
const auto& packet1 = packets[1];
ASSERT_TRUE(packet1.has_timestamp());
- EXPECT_EQ(packet1.timestamp(), 25u);
+ EXPECT_EQ(packet1.timestamp(), 30u);
ASSERT_TRUE(packet1.has_frame_timeline_event());
const auto& event1 = packet1.frame_timeline_event();
@@ -1179,12 +1139,9 @@
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
tracingSession->StartBlocking();
- constexpr nsecs_t appStartTime =
- std::chrono::duration_cast<std::chrono::nanoseconds>(10ms).count();
- constexpr nsecs_t appEndTime =
- std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count();
- constexpr nsecs_t appPresentTime =
- std::chrono::duration_cast<std::chrono::nanoseconds>(30ms).count();
+ constexpr nsecs_t appStartTime = std::chrono::nanoseconds(10ms).count();
+ constexpr nsecs_t appEndTime = std::chrono::nanoseconds(20ms).count();
+ constexpr nsecs_t appPresentTime = std::chrono::nanoseconds(30ms).count();
int64_t surfaceFrameToken =
mTokenManager->generateTokenForPredictions({appStartTime, appEndTime, appPresentTime});
@@ -1197,12 +1154,9 @@
surfaceFrame1->setActualQueueTime(appEndTime);
surfaceFrame1->setAcquireFenceTime(appEndTime);
- constexpr nsecs_t sfStartTime =
- std::chrono::duration_cast<std::chrono::nanoseconds>(20ms).count();
- constexpr nsecs_t sfEndTime =
- std::chrono::duration_cast<std::chrono::nanoseconds>(30ms).count();
- constexpr nsecs_t sfPresentTime =
- std::chrono::duration_cast<std::chrono::nanoseconds>(30ms).count();
+ constexpr nsecs_t sfStartTime = std::chrono::nanoseconds(20ms).count();
+ constexpr nsecs_t sfEndTime = std::chrono::nanoseconds(30ms).count();
+ constexpr nsecs_t sfPresentTime = std::chrono::nanoseconds(30ms).count();
int64_t displayFrameToken =
mTokenManager->generateTokenForPredictions({sfStartTime, sfEndTime, sfPresentTime});
@@ -1261,7 +1215,7 @@
EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
int64_t surfaceFrameToken = mTokenManager->generateTokenForPredictions({10, 20, 30});
- int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 30});
+ int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 30});
auto surfaceFrame =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
@@ -1292,8 +1246,8 @@
TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishEarlyPresent) {
Fps vsyncRate = Fps::fromPeriodNsecs(11);
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
- int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
- int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 70});
+ int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
+ int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
mFrameTimeline->setSfPresent(26, presentFence1);
auto displayFrame = getDisplayFrame(0);
@@ -1331,8 +1285,8 @@
TEST_F(FrameTimelineTest, jankClassification_displayFrameOnTimeFinishLatePresent) {
Fps vsyncRate = Fps::fromPeriodNsecs(11);
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
- int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
- int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 70});
+ int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
+ int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
mFrameTimeline->setSfWakeUp(sfToken1, 22, vsyncRate);
mFrameTimeline->setSfPresent(26, presentFence1);
auto displayFrame = getDisplayFrame(0);
@@ -1411,11 +1365,33 @@
EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerCpuDeadlineMissed);
}
+TEST_F(FrameTimelineTest, jankClassification_displayFrameLateStartLateFinishLatePresent) {
+ auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
+ int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
+ mFrameTimeline->setSfWakeUp(sfToken1, 26, Fps::fromPeriodNsecs(11));
+ mFrameTimeline->setSfPresent(36, presentFence1);
+ auto displayFrame = getDisplayFrame(0);
+ presentFence1->signalForTest(52);
+
+ // Fences haven't been flushed yet, so it should be 0
+ EXPECT_EQ(displayFrame->getActuals().presentTime, 0);
+
+ addEmptyDisplayFrame();
+ displayFrame = getDisplayFrame(0);
+
+ // Fences have flushed, so the present timestamps should be updated
+ EXPECT_EQ(displayFrame->getActuals().presentTime, 52);
+ EXPECT_EQ(displayFrame->getFrameStartMetadata(), FrameStartMetadata::LateStart);
+ EXPECT_EQ(displayFrame->getFramePresentMetadata(), FramePresentMetadata::LatePresent);
+ EXPECT_EQ(displayFrame->getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
+ EXPECT_EQ(displayFrame->getJankType(), JankType::SurfaceFlingerScheduling);
+}
+
TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishEarlyPresent) {
EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
- int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
- int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 70});
+ int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
+ int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
auto surfaceFrame1 =
@@ -1426,7 +1402,7 @@
mFrameTimeline->setSfWakeUp(sfToken1, 22, Fps::fromPeriodNsecs(11));
surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
mFrameTimeline->addSurfaceFrame(surfaceFrame1);
- mFrameTimeline->setSfPresent(26, presentFence1);
+ mFrameTimeline->setSfPresent(27, presentFence1);
auto displayFrame1 = getDisplayFrame(0);
auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
presentFence1->signalForTest(30);
@@ -1446,7 +1422,7 @@
mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
mFrameTimeline->addSurfaceFrame(surfaceFrame2);
- mFrameTimeline->setSfPresent(56, presentFence2);
+ mFrameTimeline->setSfPresent(57, presentFence2);
auto displayFrame2 = getDisplayFrame(1);
auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
@@ -1494,8 +1470,8 @@
TEST_F(FrameTimelineTest, jankClassification_surfaceFrameOnTimeFinishLatePresent) {
EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
- int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 26, 40});
- int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 56, 70});
+ int64_t sfToken1 = mTokenManager->generateTokenForPredictions({22, 30, 40});
+ int64_t sfToken2 = mTokenManager->generateTokenForPredictions({52, 60, 70});
int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 40});
int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 70});
auto surfaceFrame1 =
@@ -1526,7 +1502,7 @@
mFrameTimeline->setSfWakeUp(sfToken2, 52, Fps::fromPeriodNsecs(11));
surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented);
mFrameTimeline->addSurfaceFrame(surfaceFrame2);
- mFrameTimeline->setSfPresent(56, presentFence2);
+ mFrameTimeline->setSfPresent(57, presentFence2);
auto displayFrame2 = getDisplayFrame(1);
auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
@@ -1575,7 +1551,7 @@
EXPECT_CALL(*mTimeStats, incrementJankyFrames(_));
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
- int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 46, 50});
+ int64_t sfToken1 = mTokenManager->generateTokenForPredictions({42, 50, 50});
int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 26, 60});
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
@@ -1617,8 +1593,8 @@
EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
- int64_t sfToken1 = mTokenManager->generateTokenForPredictions({32, 36, 40});
- int64_t sfToken2 = mTokenManager->generateTokenForPredictions({42, 46, 50});
+ int64_t sfToken1 = mTokenManager->generateTokenForPredictions({32, 40, 40});
+ int64_t sfToken2 = mTokenManager->generateTokenForPredictions({42, 50, 50});
int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({5, 16, 30});
int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({25, 36, 50});
auto surfaceFrame1 =
@@ -1693,8 +1669,8 @@
int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
- int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 56, 60});
- int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 116, 120});
+ int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
+ int64_t sfToken2 = mTokenManager->generateTokenForPredictions({112, 120, 120});
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
sUidOne, sLayerIdOne, sLayerNameOne,
@@ -1764,12 +1740,90 @@
JankType::AppDeadlineMissed | JankType::BufferStuffing);
}
+TEST_F(FrameTimelineTest, jankClassification_appDeadlineAdjustedForBufferStuffing) {
+ // Layer specific increment
+ EXPECT_CALL(*mTimeStats, incrementJankyFrames(_)).Times(2);
+ auto presentFence1 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
+ int64_t surfaceFrameToken1 = mTokenManager->generateTokenForPredictions({10, 20, 30});
+ int64_t surfaceFrameToken2 = mTokenManager->generateTokenForPredictions({40, 50, 60});
+
+ int64_t sfToken1 = mTokenManager->generateTokenForPredictions({52, 60, 60});
+ int64_t sfToken2 = mTokenManager->generateTokenForPredictions({82, 90, 90});
+ auto surfaceFrame1 =
+ mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken1, sInputEventId}, sPidOne,
+ sUidOne, sLayerIdOne, sLayerNameOne,
+ sLayerNameOne);
+ surfaceFrame1->setAcquireFenceTime(50);
+ mFrameTimeline->setSfWakeUp(sfToken1, 52, Fps::fromPeriodNsecs(30));
+ surfaceFrame1->setPresentState(SurfaceFrame::PresentState::Presented);
+ mFrameTimeline->addSurfaceFrame(surfaceFrame1);
+ mFrameTimeline->setSfPresent(56, presentFence1);
+ auto displayFrame1 = getDisplayFrame(0);
+ auto& presentedSurfaceFrame1 = getSurfaceFrame(0, 0);
+ presentFence1->signalForTest(60);
+
+ // Fences for the first frame haven't been flushed yet, so it should be 0
+ EXPECT_EQ(displayFrame1->getActuals().presentTime, 0);
+ auto actuals1 = presentedSurfaceFrame1.getActuals();
+ EXPECT_EQ(actuals1.presentTime, 0);
+
+ // Trigger a flush by finalizing the next DisplayFrame
+ auto presentFence2 = fenceFactory.createFenceTimeForTest(Fence::NO_FENCE);
+ auto surfaceFrame2 =
+ mFrameTimeline->createSurfaceFrameForToken({surfaceFrameToken2, sInputEventId}, sPidOne,
+ sUidOne, sLayerIdOne, sLayerNameOne,
+ sLayerNameOne);
+ surfaceFrame2->setAcquireFenceTime(80);
+ mFrameTimeline->setSfWakeUp(sfToken2, 82, Fps::fromPeriodNsecs(30));
+ // Setting previous latch time to 54, adjusted deadline will be 54 + vsyncTime(30) = 84
+ surfaceFrame2->setPresentState(SurfaceFrame::PresentState::Presented, 54);
+ mFrameTimeline->addSurfaceFrame(surfaceFrame2);
+ mFrameTimeline->setSfPresent(86, presentFence2);
+ auto displayFrame2 = getDisplayFrame(1);
+ auto& presentedSurfaceFrame2 = getSurfaceFrame(1, 0);
+ presentFence2->signalForTest(90);
+
+ // Fences for the first frame have flushed, so the present timestamps should be updated
+ EXPECT_EQ(displayFrame1->getActuals().presentTime, 60);
+ actuals1 = presentedSurfaceFrame1.getActuals();
+ EXPECT_EQ(actuals1.endTime, 50);
+ EXPECT_EQ(actuals1.presentTime, 60);
+
+ EXPECT_EQ(displayFrame1->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
+ EXPECT_EQ(displayFrame1->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
+ EXPECT_EQ(displayFrame1->getJankType(), JankType::None);
+
+ EXPECT_EQ(presentedSurfaceFrame1.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
+ EXPECT_EQ(presentedSurfaceFrame1.getFrameReadyMetadata(), FrameReadyMetadata::LateFinish);
+ EXPECT_EQ(presentedSurfaceFrame1.getJankType(), JankType::AppDeadlineMissed);
+
+ // Fences for the second frame haven't been flushed yet, so it should be 0
+ EXPECT_EQ(displayFrame2->getActuals().presentTime, 0);
+ auto actuals2 = presentedSurfaceFrame2.getActuals();
+ EXPECT_EQ(actuals2.presentTime, 0);
+
+ addEmptyDisplayFrame();
+
+ // Fences for the second frame have flushed, so the present timestamps should be updated
+ EXPECT_EQ(displayFrame2->getActuals().presentTime, 90);
+ actuals2 = presentedSurfaceFrame2.getActuals();
+ EXPECT_EQ(actuals2.presentTime, 90);
+
+ EXPECT_EQ(displayFrame2->getFramePresentMetadata(), FramePresentMetadata::OnTimePresent);
+ EXPECT_EQ(displayFrame2->getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
+ EXPECT_EQ(displayFrame2->getJankType(), JankType::None);
+
+ EXPECT_EQ(presentedSurfaceFrame2.getFramePresentMetadata(), FramePresentMetadata::LatePresent);
+ EXPECT_EQ(presentedSurfaceFrame2.getFrameReadyMetadata(), FrameReadyMetadata::OnTimeFinish);
+ EXPECT_EQ(presentedSurfaceFrame2.getJankType(), JankType::BufferStuffing);
+}
+
TEST_F(FrameTimelineTest, computeFps_noLayerIds_returnsZero) {
EXPECT_EQ(mFrameTimeline->computeFps({}), 0.0f);
}
TEST_F(FrameTimelineTest, computeFps_singleDisplayFrame_returnsZero) {
- const auto oneHundredMs = std::chrono::duration_cast<std::chrono::nanoseconds>(100ms).count();
+ const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
@@ -1784,8 +1838,8 @@
}
TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_oneLayer) {
- const auto oneHundredMs = std::chrono::duration_cast<std::chrono::nanoseconds>(100ms).count();
- const auto twoHundredMs = std::chrono::duration_cast<std::chrono::nanoseconds>(200ms).count();
+ const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
+ const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
sLayerIdOne, sLayerNameOne, sLayerNameOne);
@@ -1808,8 +1862,8 @@
}
TEST_F(FrameTimelineTest, computeFps_twoDisplayFrames_twoLayers) {
- const auto oneHundredMs = std::chrono::duration_cast<std::chrono::nanoseconds>(100ms).count();
- const auto twoHundredMs = std::chrono::duration_cast<std::chrono::nanoseconds>(200ms).count();
+ const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
+ const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
sLayerIdOne, sLayerNameOne, sLayerNameOne);
@@ -1832,8 +1886,8 @@
}
TEST_F(FrameTimelineTest, computeFps_filtersOutLayers) {
- const auto oneHundredMs = std::chrono::duration_cast<std::chrono::nanoseconds>(100ms).count();
- const auto twoHundredMs = std::chrono::duration_cast<std::chrono::nanoseconds>(200ms).count();
+ const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
+ const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
sLayerIdOne, sLayerNameOne, sLayerNameOne);
@@ -1856,11 +1910,11 @@
}
TEST_F(FrameTimelineTest, computeFps_averagesOverMultipleFrames) {
- const auto oneHundredMs = std::chrono::duration_cast<std::chrono::nanoseconds>(100ms).count();
- const auto twoHundredMs = std::chrono::duration_cast<std::chrono::nanoseconds>(200ms).count();
- const auto threeHundredMs = std::chrono::duration_cast<std::chrono::nanoseconds>(300ms).count();
- const auto fiveHundredMs = std::chrono::duration_cast<std::chrono::nanoseconds>(500ms).count();
- const auto sixHundredMs = std::chrono::duration_cast<std::chrono::nanoseconds>(600ms).count();
+ const auto oneHundredMs = std::chrono::nanoseconds(100ms).count();
+ const auto twoHundredMs = std::chrono::nanoseconds(200ms).count();
+ const auto threeHundredMs = std::chrono::nanoseconds(300ms).count();
+ const auto fiveHundredMs = std::chrono::nanoseconds(500ms).count();
+ const auto sixHundredMs = std::chrono::nanoseconds(600ms).count();
auto surfaceFrame1 =
mFrameTimeline->createSurfaceFrameForToken(FrameTimelineInfo(), sPidOne, sUidOne,
sLayerIdOne, sLayerNameOne, sLayerNameOne);