SurfaceFlinger: refresh rate calculation when no timestamps
Frames without presentation timestamp should be excluded from refresh rate calculation. This changes skips these frames instead of just declaring refresh rate unknown. This impacts scenarios that we get few frames without presentation timestamps where the majority does include them. Bug: 155710271 Test: Facebook feed videos Change-Id: Id79f4d6cb87b2fd6fb787fab2d863f50be99cac5
This commit is contained in:
parent
4264917141
commit
38601a9beb
2 changed files with 51 additions and 3 deletions
|
@ -111,21 +111,28 @@ std::optional<float> LayerInfoV2::calculateRefreshRateIfPossible() {
|
|||
|
||||
// Calculate the refresh rate by finding the average delta between frames
|
||||
nsecs_t totalPresentTimeDeltas = 0;
|
||||
int numFrames = 0;
|
||||
for (auto it = mFrameTimes.begin(); it != mFrameTimes.end() - 1; ++it) {
|
||||
// If there are no presentation timestamp provided we can't calculate the refresh rate
|
||||
if (it->presetTime == 0 || (it + 1)->presetTime == 0) {
|
||||
return std::nullopt;
|
||||
continue;
|
||||
}
|
||||
|
||||
totalPresentTimeDeltas +=
|
||||
std::max(((it + 1)->presetTime - it->presetTime), mHighRefreshRatePeriod);
|
||||
numFrames++;
|
||||
}
|
||||
const float averageFrameTime =
|
||||
static_cast<float>(totalPresentTimeDeltas) / (mFrameTimes.size() - 1);
|
||||
if (numFrames == 0) {
|
||||
return std::nullopt;
|
||||
}
|
||||
const float averageFrameTime = static_cast<float>(totalPresentTimeDeltas) / numFrames;
|
||||
|
||||
// Now once we calculated the refresh rate we need to make sure that all the frames we captured
|
||||
// are evenly distributed and we don't calculate the average across some burst of frames.
|
||||
for (auto it = mFrameTimes.begin(); it != mFrameTimes.end() - 1; ++it) {
|
||||
if (it->presetTime == 0 || (it + 1)->presetTime == 0) {
|
||||
continue;
|
||||
}
|
||||
const nsecs_t presentTimeDeltas =
|
||||
std::max(((it + 1)->presetTime - it->presetTime), mHighRefreshRatePeriod);
|
||||
if (std::abs(presentTimeDeltas - averageFrameTime) > 2 * averageFrameTime) {
|
||||
|
|
|
@ -512,5 +512,46 @@ TEST_F(LayerHistoryTestV2, inactiveLayers) {
|
|||
EXPECT_EQ(1, frequentLayerCount(time));
|
||||
}
|
||||
|
||||
TEST_F(LayerHistoryTestV2, calculateRefreshRate30Hz) {
|
||||
const auto layer = createLayer();
|
||||
EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(true));
|
||||
EXPECT_CALL(*layer, getFrameRateForLayerTree()).WillRepeatedly(Return(Layer::FrameRate()));
|
||||
|
||||
EXPECT_EQ(1, layerCount());
|
||||
EXPECT_EQ(0, activeLayerCount());
|
||||
|
||||
nsecs_t time = systemTime();
|
||||
const nsecs_t frameTime = 33'333'333;
|
||||
|
||||
for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE; i++) {
|
||||
time += frameTime;
|
||||
history().record(layer.get(), time, time);
|
||||
}
|
||||
ASSERT_EQ(1, history().summarize(time).size());
|
||||
EXPECT_EQ(LayerHistory::LayerVoteType::Heuristic, history().summarize(time)[0].vote);
|
||||
EXPECT_FLOAT_EQ(30.f, history().summarize(time)[0].desiredRefreshRate);
|
||||
}
|
||||
|
||||
TEST_F(LayerHistoryTestV2, calculateRefreshRate30HzSkipTimestamp) {
|
||||
const auto layer = createLayer();
|
||||
EXPECT_CALL(*layer, isVisible()).WillRepeatedly(Return(true));
|
||||
EXPECT_CALL(*layer, getFrameRateForLayerTree()).WillRepeatedly(Return(Layer::FrameRate()));
|
||||
|
||||
EXPECT_EQ(1, layerCount());
|
||||
EXPECT_EQ(0, activeLayerCount());
|
||||
|
||||
nsecs_t time = systemTime();
|
||||
const nsecs_t frameTime = 33'333'333;
|
||||
|
||||
for (int i = 0; i < PRESENT_TIME_HISTORY_SIZE; i++) {
|
||||
time += frameTime;
|
||||
const auto timestamp = (i == PRESENT_TIME_HISTORY_SIZE / 2) ? 0 : time;
|
||||
history().record(layer.get(), timestamp, time);
|
||||
}
|
||||
ASSERT_EQ(1, history().summarize(time).size());
|
||||
EXPECT_EQ(LayerHistory::LayerVoteType::Heuristic, history().summarize(time)[0].vote);
|
||||
EXPECT_FLOAT_EQ(30.f, history().summarize(time)[0].desiredRefreshRate);
|
||||
}
|
||||
|
||||
} // namespace
|
||||
} // namespace android::scheduler
|
||||
|
|
Loading…
Reference in a new issue