Commit bb5a3900 authored by sunnyps's avatar sunnyps Committed by Commit bot

cc: Aggressively expire retro frames.

If we're not aggressive about expiring a retro frame (e.g. MISSED frames)
then it's possible to enter a high latency mode often.

BUG=469953

Review URL: https://codereview.chromium.org/1055113004

Cr-Commit-Position: refs/heads/master@{#330465}
parent 0160d130
...@@ -434,7 +434,7 @@ void Scheduler::BeginRetroFrame() { ...@@ -434,7 +434,7 @@ void Scheduler::BeginRetroFrame() {
while (!begin_retro_frame_args_.empty()) { while (!begin_retro_frame_args_.empty()) {
const BeginFrameArgs& args = begin_retro_frame_args_.front(); const BeginFrameArgs& args = begin_retro_frame_args_.front();
base::TimeTicks expiration_time = args.frame_time + args.interval; base::TimeTicks expiration_time = args.deadline;
if (now <= expiration_time) if (now <= expiration_time)
break; break;
TRACE_EVENT_INSTANT2( TRACE_EVENT_INSTANT2(
......
...@@ -400,13 +400,15 @@ class SchedulerTest : public testing::Test { ...@@ -400,13 +400,15 @@ class SchedulerTest : public testing::Test {
} }
} }
void SendNextBeginFrame() { BeginFrameArgs SendNextBeginFrame() {
DCHECK(scheduler_->settings().use_external_begin_frame_source); DCHECK(scheduler_->settings().use_external_begin_frame_source);
// Creep the time forward so that any BeginFrameArgs is not equal to the // Creep the time forward so that any BeginFrameArgs is not equal to the
// last one otherwise we violate the BeginFrameSource contract. // last one otherwise we violate the BeginFrameSource contract.
now_src_->AdvanceNow(BeginFrameArgs::DefaultInterval()); now_src_->AdvanceNow(BeginFrameArgs::DefaultInterval());
fake_external_begin_frame_source_->TestOnBeginFrame( BeginFrameArgs args =
CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src())); CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src());
fake_external_begin_frame_source_->TestOnBeginFrame(args);
return args;
} }
FakeExternalBeginFrameSource* fake_external_begin_frame_source() const { FakeExternalBeginFrameSource* fake_external_begin_frame_source() const {
...@@ -1606,7 +1608,7 @@ TEST_F(SchedulerTest, RetroFrameDoesNotExpireTooEarly) { ...@@ -1606,7 +1608,7 @@ TEST_F(SchedulerTest, RetroFrameDoesNotExpireTooEarly) {
scheduler_->NotifyBeginMainFrameStarted(); scheduler_->NotifyBeginMainFrameStarted();
client_->Reset(); client_->Reset();
SendNextBeginFrame(); BeginFrameArgs retro_frame_args = SendNextBeginFrame();
// This BeginFrame is queued up as a retro frame. // This BeginFrame is queued up as a retro frame.
EXPECT_NO_ACTION(client_); EXPECT_NO_ACTION(client_);
// The previous deadline is still pending. // The previous deadline is still pending.
...@@ -1630,10 +1632,8 @@ TEST_F(SchedulerTest, RetroFrameDoesNotExpireTooEarly) { ...@@ -1630,10 +1632,8 @@ TEST_F(SchedulerTest, RetroFrameDoesNotExpireTooEarly) {
scheduler_->SetNeedsRedraw(); scheduler_->SetNeedsRedraw();
EXPECT_NO_ACTION(client_); EXPECT_NO_ACTION(client_);
// Let's advance sufficiently past the next frame's deadline. // Let's advance to the retro frame's deadline.
now_src()->AdvanceNow(BeginFrameArgs::DefaultInterval() - now_src()->AdvanceNow(retro_frame_args.deadline - now_src()->Now());
BeginFrameArgs::DefaultEstimatedParentDrawTime() +
base::TimeDelta::FromMicroseconds(1));
// The retro frame hasn't expired yet. // The retro frame hasn't expired yet.
task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(false)); task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(false));
...@@ -1648,7 +1648,7 @@ TEST_F(SchedulerTest, RetroFrameDoesNotExpireTooEarly) { ...@@ -1648,7 +1648,7 @@ TEST_F(SchedulerTest, RetroFrameDoesNotExpireTooEarly) {
EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_); EXPECT_SINGLE_ACTION("ScheduledActionDrawAndSwapIfPossible", client_);
} }
TEST_F(SchedulerTest, RetroFrameDoesNotExpireTooLate) { TEST_F(SchedulerTest, RetroFrameExpiresOnTime) {
scheduler_settings_.use_external_begin_frame_source = true; scheduler_settings_.use_external_begin_frame_source = true;
SetUpScheduler(true); SetUpScheduler(true);
...@@ -1666,7 +1666,7 @@ TEST_F(SchedulerTest, RetroFrameDoesNotExpireTooLate) { ...@@ -1666,7 +1666,7 @@ TEST_F(SchedulerTest, RetroFrameDoesNotExpireTooLate) {
scheduler_->NotifyBeginMainFrameStarted(); scheduler_->NotifyBeginMainFrameStarted();
client_->Reset(); client_->Reset();
SendNextBeginFrame(); BeginFrameArgs retro_frame_args = SendNextBeginFrame();
// This BeginFrame is queued up as a retro frame. // This BeginFrame is queued up as a retro frame.
EXPECT_NO_ACTION(client_); EXPECT_NO_ACTION(client_);
// The previous deadline is still pending. // The previous deadline is still pending.
...@@ -1690,14 +1690,64 @@ TEST_F(SchedulerTest, RetroFrameDoesNotExpireTooLate) { ...@@ -1690,14 +1690,64 @@ TEST_F(SchedulerTest, RetroFrameDoesNotExpireTooLate) {
scheduler_->SetNeedsRedraw(); scheduler_->SetNeedsRedraw();
EXPECT_NO_ACTION(client_); EXPECT_NO_ACTION(client_);
// Let's advance sufficiently past the next frame's deadline. // Let's advance sufficiently past the retro frame's deadline.
now_src()->AdvanceNow(BeginFrameArgs::DefaultInterval() + now_src()->AdvanceNow(retro_frame_args.deadline - now_src()->Now() +
base::TimeDelta::FromMicroseconds(1)); base::TimeDelta::FromMicroseconds(1));
// The retro frame should've expired. // The retro frame should've expired.
EXPECT_NO_ACTION(client_); EXPECT_NO_ACTION(client_);
} }
TEST_F(SchedulerTest, MissedFrameDoesNotExpireTooEarly) {
scheduler_settings_.use_external_begin_frame_source = true;
SetUpScheduler(true);
scheduler_->SetNeedsCommit();
EXPECT_TRUE(client_->needs_begin_frames());
EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
BeginFrameArgs missed_frame_args =
CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src());
missed_frame_args.type = BeginFrameArgs::MISSED;
// Advance to the deadline.
now_src()->AdvanceNow(missed_frame_args.deadline - now_src()->Now());
// Missed frame is handled because it's on time.
client_->Reset();
fake_external_begin_frame_source_->TestOnBeginFrame(missed_frame_args);
EXPECT_TRUE(
task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(false)));
EXPECT_ACTION("WillBeginImplFrame", client_, 0, 2);
EXPECT_ACTION("ScheduledActionSendBeginMainFrame", client_, 1, 2);
EXPECT_TRUE(scheduler_->BeginImplFrameDeadlinePending());
}
TEST_F(SchedulerTest, MissedFrameExpiresOnTime) {
scheduler_settings_.use_external_begin_frame_source = true;
SetUpScheduler(true);
scheduler_->SetNeedsCommit();
EXPECT_TRUE(client_->needs_begin_frames());
EXPECT_SINGLE_ACTION("SetNeedsBeginFrames(true)", client_);
BeginFrameArgs missed_frame_args =
CreateBeginFrameArgsForTesting(BEGINFRAME_FROM_HERE, now_src());
missed_frame_args.type = BeginFrameArgs::MISSED;
// Advance sufficiently past the deadline.
now_src()->AdvanceNow(missed_frame_args.deadline - now_src()->Now() +
base::TimeDelta::FromMicroseconds(1));
// Missed frame is dropped because it's too late.
client_->Reset();
fake_external_begin_frame_source_->TestOnBeginFrame(missed_frame_args);
EXPECT_FALSE(
task_runner().RunTasksWhile(client_->ImplFrameDeadlinePending(false)));
EXPECT_NO_ACTION(client_);
EXPECT_FALSE(scheduler_->BeginImplFrameDeadlinePending());
}
void SchedulerTest::BeginFramesNotFromClient( void SchedulerTest::BeginFramesNotFromClient(
bool use_external_begin_frame_source, bool use_external_begin_frame_source,
bool throttle_frame_production) { bool throttle_frame_production) {
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment