Commit fc04607a authored by Sunny Sachanandani's avatar Sunny Sachanandani Committed by Commit Bot

cc: Subtract estimated display draw time from begin frame deadline

Display draw time was being subtraced from display scheduler's deadline,
but a similar adjustment was missing from cc scheduler's deadline. To
fix this inconsistency, this CL applies the deadline adjustment at a
single place, the begin frame source so that there's no mismatch.

This makes cc scheduler have a later deadline and can cause it to wait
longer for the main thread. Recent experimentation has shown improved
latency in the absence of a scheduler deadline. It's hoped that some of
the improvement can be achieved by just fixing the deadline.

Bug: 1042584
Change-Id: Ia948b64c1dbba5239d1b97062224e73487e35fba
Reviewed-on: https://chromium-review.googlesource.com/c/chromium/src/+/2045210
Commit-Queue: Sunny Sachanandani <sunnyps@chromium.org>
Auto-Submit: Sunny Sachanandani <sunnyps@chromium.org>
Reviewed-by: default avatarKhushal <khushalsagar@chromium.org>
Cr-Commit-Position: refs/heads/master@{#781159}
parent fa52a0bd
...@@ -460,28 +460,26 @@ void Scheduler::BeginImplFrameWithDeadline(const viz::BeginFrameArgs& args) { ...@@ -460,28 +460,26 @@ void Scheduler::BeginImplFrameWithDeadline(const viz::BeginFrameArgs& args) {
adjusted_args.deadline -= compositor_timing_history_->DrawDurationEstimate(); adjusted_args.deadline -= compositor_timing_history_->DrawDurationEstimate();
adjusted_args.deadline -= kDeadlineFudgeFactor; adjusted_args.deadline -= kDeadlineFudgeFactor;
// TODO(khushalsagar): We need to consider the deadline fudge factor here to // TODO(khushalsagar): We need to match the deadline used in
// match the deadline used in BeginImplFrameDeadlineMode::REGULAR mode // BeginImplFrameDeadlineMode::REGULAR mode (used in the case where the impl
// (used in the case where the impl thread needs to redraw). In the case where // thread needs to redraw). In the case where main_frame_to_active is fast, we
// main_frame_to_active is fast, we should consider using // should consider using BeginImplFrameDeadlineMode::LATE instead to avoid
// BeginImplFrameDeadlineMode::LATE instead to avoid putting the main // putting the main thread in high latency mode. See crbug.com/753146.
// thread in high latency mode. See crbug.com/753146. const base::TimeDelta bmf_to_activate_threshold =
base::TimeDelta bmf_to_activate_threshold = adjusted_args.deadline - adjusted_args.frame_time;
adjusted_args.interval -
compositor_timing_history_->DrawDurationEstimate() - kDeadlineFudgeFactor;
// An estimate of time from starting the main frame on the main thread to when // An estimate of time from starting the main frame on the main thread to when
// the resulting pending tree is activated. Note that this excludes the // the resulting pending tree is activated. Note that this excludes the
// durations where progress is blocked due to back pressure in the pipeline // durations where progress is blocked due to back pressure in the pipeline
// (ready to commit to commit, ready to activate to activate, etc.) // (ready to commit to commit, ready to activate to activate, etc.)
base::TimeDelta bmf_start_to_activate = const base::TimeDelta bmf_start_to_activate =
compositor_timing_history_ compositor_timing_history_
->BeginMainFrameStartToReadyToCommitDurationEstimate() + ->BeginMainFrameStartToReadyToCommitDurationEstimate() +
compositor_timing_history_->CommitDurationEstimate() + compositor_timing_history_->CommitDurationEstimate() +
compositor_timing_history_->CommitToReadyToActivateDurationEstimate() + compositor_timing_history_->CommitToReadyToActivateDurationEstimate() +
compositor_timing_history_->ActivateDurationEstimate(); compositor_timing_history_->ActivateDurationEstimate();
base::TimeDelta bmf_to_activate_estimate_critical = const base::TimeDelta bmf_to_activate_estimate_critical =
bmf_start_to_activate + bmf_start_to_activate +
compositor_timing_history_->BeginMainFrameQueueDurationCriticalEstimate(); compositor_timing_history_->BeginMainFrameQueueDurationCriticalEstimate();
state_machine_.SetCriticalBeginMainFrameToActivateIsFast( state_machine_.SetCriticalBeginMainFrameToActivateIsFast(
......
...@@ -131,7 +131,7 @@ struct VIZ_COMMON_EXPORT BeginFrameArgs { ...@@ -131,7 +131,7 @@ struct VIZ_COMMON_EXPORT BeginFrameArgs {
// Returns how much time the display should reserve for draw and swap if the // Returns how much time the display should reserve for draw and swap if the
// BeginFrame interval is |interval|. // BeginFrame interval is |interval|.
static base::TimeDelta DefaultEstimatedDisplayDrawTime( static constexpr base::TimeDelta DefaultEstimatedDisplayDrawTime(
base::TimeDelta interval) { base::TimeDelta interval) {
return interval * kDefaultEstimatedDisplayDrawTimeRatio; return interval * kDefaultEstimatedDisplayDrawTimeRatio;
} }
......
...@@ -102,6 +102,7 @@ BeginFrameArgs ...@@ -102,6 +102,7 @@ BeginFrameArgs
BeginFrameSource::BeginFrameArgsGenerator::GenerateBeginFrameArgs( BeginFrameSource::BeginFrameArgsGenerator::GenerateBeginFrameArgs(
uint64_t source_id, uint64_t source_id,
base::TimeTicks frame_time, base::TimeTicks frame_time,
base::TimeTicks deadline,
base::TimeTicks next_frame_time, base::TimeTicks next_frame_time,
base::TimeDelta vsync_interval) { base::TimeDelta vsync_interval) {
uint64_t sequence_number = uint64_t sequence_number =
...@@ -111,7 +112,7 @@ BeginFrameSource::BeginFrameArgsGenerator::GenerateBeginFrameArgs( ...@@ -111,7 +112,7 @@ BeginFrameSource::BeginFrameArgsGenerator::GenerateBeginFrameArgs(
next_expected_frame_time_ = next_frame_time; next_expected_frame_time_ = next_frame_time;
next_sequence_number_ = sequence_number + 1; next_sequence_number_ = sequence_number + 1;
return BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, source_id, return BeginFrameArgs::Create(BEGINFRAME_FROM_HERE, source_id,
sequence_number, frame_time, next_frame_time, sequence_number, frame_time, deadline,
vsync_interval, BeginFrameArgs::NORMAL); vsync_interval, BeginFrameArgs::NORMAL);
} }
...@@ -204,8 +205,7 @@ SyntheticBeginFrameSource::~SyntheticBeginFrameSource() = default; ...@@ -204,8 +205,7 @@ SyntheticBeginFrameSource::~SyntheticBeginFrameSource() = default;
BackToBackBeginFrameSource::BackToBackBeginFrameSource( BackToBackBeginFrameSource::BackToBackBeginFrameSource(
std::unique_ptr<DelayBasedTimeSource> time_source) std::unique_ptr<DelayBasedTimeSource> time_source)
: SyntheticBeginFrameSource(kNotRestartableId), : SyntheticBeginFrameSource(kNotRestartableId),
time_source_(std::move(time_source)), time_source_(std::move(time_source)) {
next_sequence_number_(BeginFrameArgs::kStartingFrameNumber) {
time_source_->SetClient(this); time_source_->SetClient(this);
// The time_source_ ticks immediately, so we SetActive(true) for a single // The time_source_ ticks immediately, so we SetActive(true) for a single
// tick when we need it, and keep it as SetActive(false) otherwise. // tick when we need it, and keep it as SetActive(false) otherwise.
...@@ -250,12 +250,15 @@ void BackToBackBeginFrameSource::OnGpuNoLongerBusy() { ...@@ -250,12 +250,15 @@ void BackToBackBeginFrameSource::OnGpuNoLongerBusy() {
void BackToBackBeginFrameSource::OnTimerTick() { void BackToBackBeginFrameSource::OnTimerTick() {
if (RequestCallbackOnGpuAvailable()) if (RequestCallbackOnGpuAvailable())
return; return;
base::TimeTicks frame_time = time_source_->LastTickTime(); const base::TimeTicks frame_time = time_source_->LastTickTime();
base::TimeDelta default_interval = BeginFrameArgs::DefaultInterval(); const base::TimeDelta interval = BeginFrameArgs::DefaultInterval();
BeginFrameArgs args = BeginFrameArgs::Create( const base::TimeTicks next_frame_time = frame_time + interval;
BEGINFRAME_FROM_HERE, source_id(), next_sequence_number_, frame_time, const base::TimeTicks deadline =
frame_time + default_interval, default_interval, BeginFrameArgs::NORMAL); next_frame_time -
next_sequence_number_++; BeginFrameArgs::DefaultEstimatedDisplayDrawTime(interval);
BeginFrameArgs args = begin_frame_args_generator_.GenerateBeginFrameArgs(
source_id(), frame_time, deadline, next_frame_time, interval);
// This must happen after getting the LastTickTime() from the time source. // This must happen after getting the LastTickTime() from the time source.
time_source_->SetActive(false); time_source_->SetActive(false);
...@@ -293,8 +296,12 @@ void DelayBasedBeginFrameSource::OnUpdateVSyncParameters( ...@@ -293,8 +296,12 @@ void DelayBasedBeginFrameSource::OnUpdateVSyncParameters(
BeginFrameArgs DelayBasedBeginFrameSource::CreateBeginFrameArgs( BeginFrameArgs DelayBasedBeginFrameSource::CreateBeginFrameArgs(
base::TimeTicks frame_time) { base::TimeTicks frame_time) {
base::TimeDelta interval = time_source_->Interval(); base::TimeDelta interval = time_source_->Interval();
base::TimeTicks next_frame_time = time_source_->NextTickTime();
base::TimeTicks deadline = next_frame_time;
if (apply_display_deadline_adjustment_)
deadline -= BeginFrameArgs::DefaultEstimatedDisplayDrawTime(interval);
return begin_frame_args_generator_.GenerateBeginFrameArgs( return begin_frame_args_generator_.GenerateBeginFrameArgs(
source_id(), frame_time, time_source_->NextTickTime(), interval); source_id(), frame_time, deadline, next_frame_time, interval);
} }
void DelayBasedBeginFrameSource::AddObserver(BeginFrameObserver* obs) { void DelayBasedBeginFrameSource::AddObserver(BeginFrameObserver* obs) {
......
...@@ -137,6 +137,7 @@ class VIZ_COMMON_EXPORT BeginFrameSource { ...@@ -137,6 +137,7 @@ class VIZ_COMMON_EXPORT BeginFrameSource {
BeginFrameArgs GenerateBeginFrameArgs(uint64_t source_id, BeginFrameArgs GenerateBeginFrameArgs(uint64_t source_id,
base::TimeTicks frame_time, base::TimeTicks frame_time,
base::TimeTicks deadline,
base::TimeTicks next_frame_time, base::TimeTicks next_frame_time,
base::TimeDelta vsync_interval); base::TimeDelta vsync_interval);
...@@ -282,10 +283,10 @@ class VIZ_COMMON_EXPORT BackToBackBeginFrameSource ...@@ -282,10 +283,10 @@ class VIZ_COMMON_EXPORT BackToBackBeginFrameSource
void OnTimerTick() override; void OnTimerTick() override;
private: private:
BeginFrameArgsGenerator begin_frame_args_generator_;
std::unique_ptr<DelayBasedTimeSource> time_source_; std::unique_ptr<DelayBasedTimeSource> time_source_;
base::flat_set<BeginFrameObserver*> observers_; base::flat_set<BeginFrameObserver*> observers_;
base::flat_set<BeginFrameObserver*> pending_begin_frame_observers_; base::flat_set<BeginFrameObserver*> pending_begin_frame_observers_;
uint64_t next_sequence_number_;
base::WeakPtrFactory<BackToBackBeginFrameSource> weak_factory_{this}; base::WeakPtrFactory<BackToBackBeginFrameSource> weak_factory_{this};
DISALLOW_COPY_AND_ASSIGN(BackToBackBeginFrameSource); DISALLOW_COPY_AND_ASSIGN(BackToBackBeginFrameSource);
...@@ -315,6 +316,11 @@ class VIZ_COMMON_EXPORT DelayBasedBeginFrameSource ...@@ -315,6 +316,11 @@ class VIZ_COMMON_EXPORT DelayBasedBeginFrameSource
// DelayBasedTimeSourceClient implementation. // DelayBasedTimeSourceClient implementation.
void OnTimerTick() override; void OnTimerTick() override;
// TODO(sunnyps): Apply deadline adjustment by default after fixing tests.
void set_apply_display_deadline_adjustment_for_testing(bool apply) {
apply_display_deadline_adjustment_ = apply;
}
private: private:
// The created BeginFrameArgs' sequence_number is calculated based on what // The created BeginFrameArgs' sequence_number is calculated based on what
// interval |frame_time| is in. For example, if |last_frame_time_| is 100, // interval |frame_time| is in. For example, if |last_frame_time_| is 100,
...@@ -331,6 +337,7 @@ class VIZ_COMMON_EXPORT DelayBasedBeginFrameSource ...@@ -331,6 +337,7 @@ class VIZ_COMMON_EXPORT DelayBasedBeginFrameSource
BeginFrameArgs last_begin_frame_args_; BeginFrameArgs last_begin_frame_args_;
BeginFrameArgsGenerator begin_frame_args_generator_; BeginFrameArgsGenerator begin_frame_args_generator_;
bool apply_display_deadline_adjustment_ = true;
DISALLOW_COPY_AND_ASSIGN(DelayBasedBeginFrameSource); DISALLOW_COPY_AND_ASSIGN(DelayBasedBeginFrameSource);
}; };
......
...@@ -59,8 +59,12 @@ class TestTaskRunner : public base::TestMockTimeTaskRunner { ...@@ -59,8 +59,12 @@ class TestTaskRunner : public base::TestMockTimeTaskRunner {
// ------------------------------------------ // ------------------------------------------
class BackToBackBeginFrameSourceTest : public ::testing::Test { class BackToBackBeginFrameSourceTest : public ::testing::Test {
protected: protected:
static const int64_t kDeadline; static constexpr int64_t kInterval =
static const int64_t kInterval; BeginFrameArgs::DefaultInterval().InMicroseconds();
static constexpr int64_t kDeadline =
kInterval - BeginFrameArgs::DefaultEstimatedDisplayDrawTime(
base::TimeDelta::FromMicroseconds(kInterval))
.InMicroseconds();
void SetUp() override { void SetUp() override {
task_runner_ = base::MakeRefCounted<TestTaskRunner>(); task_runner_ = base::MakeRefCounted<TestTaskRunner>();
...@@ -81,12 +85,6 @@ class BackToBackBeginFrameSourceTest : public ::testing::Test { ...@@ -81,12 +85,6 @@ class BackToBackBeginFrameSourceTest : public ::testing::Test {
FakeDelayBasedTimeSource* delay_based_time_source_; // Owned by |source_|. FakeDelayBasedTimeSource* delay_based_time_source_; // Owned by |source_|.
}; };
const int64_t BackToBackBeginFrameSourceTest::kDeadline =
BeginFrameArgs::DefaultInterval().InMicroseconds();
const int64_t BackToBackBeginFrameSourceTest::kInterval =
BeginFrameArgs::DefaultInterval().InMicroseconds();
TEST_F(BackToBackBeginFrameSourceTest, AddObserverSendsBeginFrame) { TEST_F(BackToBackBeginFrameSourceTest, AddObserverSendsBeginFrame) {
EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false); EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
source_->AddObserver(obs_.get()); source_->AddObserver(obs_.get());
...@@ -353,6 +351,8 @@ TEST_F(BackToBackBeginFrameSourceTest, MultipleObserversAtOnce) { ...@@ -353,6 +351,8 @@ TEST_F(BackToBackBeginFrameSourceTest, MultipleObserversAtOnce) {
// ------------------------------------------ // ------------------------------------------
class DelayBasedBeginFrameSourceTest : public ::testing::Test { class DelayBasedBeginFrameSourceTest : public ::testing::Test {
public: public:
static constexpr int64_t kInterval = 10000;
void SetUp() override { void SetUp() override {
task_runner_ = base::MakeRefCounted<TestTaskRunner>(); task_runner_ = base::MakeRefCounted<TestTaskRunner>();
std::unique_ptr<FakeDelayBasedTimeSource> time_source = std::unique_ptr<FakeDelayBasedTimeSource> time_source =
...@@ -360,10 +360,12 @@ class DelayBasedBeginFrameSourceTest : public ::testing::Test { ...@@ -360,10 +360,12 @@ class DelayBasedBeginFrameSourceTest : public ::testing::Test {
task_runner_->GetMockTickClock(), task_runner_.get()); task_runner_->GetMockTickClock(), task_runner_.get());
time_source->SetTimebaseAndInterval( time_source->SetTimebaseAndInterval(
base::TimeTicks(), base::TimeDelta::FromMicroseconds(10000)); base::TimeTicks(), base::TimeDelta::FromMicroseconds(kInterval));
source_ = std::make_unique<DelayBasedBeginFrameSource>( source_ = std::make_unique<DelayBasedBeginFrameSource>(
std::move(time_source), BeginFrameSource::kNotRestartableId); std::move(time_source), BeginFrameSource::kNotRestartableId);
obs_.reset(new MockBeginFrameObserver); // TODO(sunnyps): Apply deadline adjustment by default after fixing tests.
source_->set_apply_display_deadline_adjustment_for_testing(false);
obs_ = std::make_unique<MockBeginFrameObserver>();
} }
void TearDown() override { obs_.reset(); } void TearDown() override { obs_.reset(); }
...@@ -665,6 +667,32 @@ TEST_F(DelayBasedBeginFrameSourceTest, ConsecutiveArgsDelayedByMultipleVsyncs) { ...@@ -665,6 +667,32 @@ TEST_F(DelayBasedBeginFrameSourceTest, ConsecutiveArgsDelayedByMultipleVsyncs) {
source_->AddObserver(&obs); source_->AddObserver(&obs);
} }
TEST_F(DelayBasedBeginFrameSourceTest, DisplayDeadlineAdjustment) {
source_->set_apply_display_deadline_adjustment_for_testing(true);
constexpr int64_t kDeadline =
kInterval - BeginFrameArgs::DefaultEstimatedDisplayDrawTime(
base::TimeDelta::FromMicroseconds(kInterval))
.InMicroseconds();
EXPECT_BEGIN_FRAME_SOURCE_PAUSED(*obs_, false);
EXPECT_BEGIN_FRAME_USED_MISSED(*obs_, source_->source_id(), 1, 0,
0 + kDeadline, kInterval);
source_->AddObserver(obs_.get());
EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 2, 10000,
10000 + kDeadline, kInterval);
EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 3, 20000,
20000 + kDeadline, kInterval);
EXPECT_BEGIN_FRAME_USED(*obs_, source_->source_id(), 4, 30000,
30000 + kDeadline, kInterval);
task_runner_->FastForwardTo(TicksFromMicroseconds(30001));
source_->RemoveObserver(obs_.get());
// No new frames....
task_runner_->FastForwardTo(TicksFromMicroseconds(60000));
}
// ExternalBeginFrameSource testing // ExternalBeginFrameSource testing
// -------------------------------------------- // --------------------------------------------
class MockExternalBeginFrameSourceClient class MockExternalBeginFrameSourceClient
......
...@@ -176,8 +176,6 @@ bool DisplayScheduler::OnBeginFrame(const BeginFrameArgs& args) { ...@@ -176,8 +176,6 @@ bool DisplayScheduler::OnBeginFrame(const BeginFrameArgs& args) {
// Schedule the deadline. // Schedule the deadline.
current_begin_frame_args_ = save_args; current_begin_frame_args_ = save_args;
current_begin_frame_args_.deadline -=
BeginFrameArgs::DefaultEstimatedDisplayDrawTime(save_args.interval);
inside_begin_frame_deadline_interval_ = true; inside_begin_frame_deadline_interval_ = true;
UpdateHasPendingSurfaces(); UpdateHasPendingSurfaces();
ScheduleBeginFrameDeadline(); ScheduleBeginFrameDeadline();
......
...@@ -256,8 +256,8 @@ TEST_F(DisplaySchedulerTest, ResizeHasLateDeadlineUntilNewRootSurface) { ...@@ -256,8 +256,8 @@ TEST_F(DisplaySchedulerTest, ResizeHasLateDeadlineUntilNewRootSurface) {
scheduler_.BeginFrameDeadlineForTest(); scheduler_.BeginFrameDeadlineForTest();
// Verify deadline goes back to normal after resize. // Verify deadline goes back to normal after resize.
late_deadline = now_src().NowTicks() + BeginFrameArgs::DefaultInterval();
AdvanceTimeAndBeginFrameForTest({root_surface_id2, sid1}); AdvanceTimeAndBeginFrameForTest({root_surface_id2, sid1});
late_deadline = now_src().NowTicks() + BeginFrameArgs::DefaultInterval();
SurfaceDamaged(sid1); SurfaceDamaged(sid1);
EXPECT_GT(late_deadline, scheduler_.DesiredBeginFrameDeadlineTimeForTest()); EXPECT_GT(late_deadline, scheduler_.DesiredBeginFrameDeadlineTimeForTest());
SurfaceDamaged(root_surface_id2); SurfaceDamaged(root_surface_id2);
...@@ -734,11 +734,7 @@ TEST_F(DisplaySchedulerTest, DidSwapBuffers) { ...@@ -734,11 +734,7 @@ TEST_F(DisplaySchedulerTest, DidSwapBuffers) {
// Damage from previous BeginFrame should cary over, so don't damage again. // Damage from previous BeginFrame should cary over, so don't damage again.
scheduler_.DidReceiveSwapBuffersAck(); scheduler_.DidReceiveSwapBuffersAck();
AdvanceTimeAndBeginFrameForTest({sid2}); AdvanceTimeAndBeginFrameForTest({sid2});
base::TimeTicks expected_deadline = EXPECT_EQ(last_begin_frame_args_.deadline,
last_begin_frame_args_.deadline -
BeginFrameArgs::DefaultEstimatedDisplayDrawTime(
last_begin_frame_args_.interval);
EXPECT_EQ(expected_deadline,
scheduler_.DesiredBeginFrameDeadlineTimeForTest()); scheduler_.DesiredBeginFrameDeadlineTimeForTest());
// Still waiting for surface 2. Once it updates, deadline should trigger // Still waiting for surface 2. Once it updates, deadline should trigger
// immediately again. // immediately again.
......
...@@ -38,10 +38,13 @@ void ExternalBeginFrameSourceAndroid::OnVSync( ...@@ -38,10 +38,13 @@ void ExternalBeginFrameSourceAndroid::OnVSync(
base::TimeDelta vsync_period( base::TimeDelta vsync_period(
base::TimeDelta::FromMicroseconds(period_micros)); base::TimeDelta::FromMicroseconds(period_micros));
// Calculate the next frame deadline: // Calculate the next frame deadline:
base::TimeTicks deadline = frame_time + vsync_period; base::TimeTicks next_frame_time = frame_time + vsync_period;
base::TimeTicks deadline =
next_frame_time -
BeginFrameArgs::DefaultEstimatedDisplayDrawTime(vsync_period);
auto begin_frame_args = begin_frame_args_generator_.GenerateBeginFrameArgs( auto begin_frame_args = begin_frame_args_generator_.GenerateBeginFrameArgs(
source_id(), frame_time, deadline, vsync_period); source_id(), frame_time, deadline, next_frame_time, vsync_period);
OnBeginFrame(begin_frame_args); OnBeginFrame(begin_frame_args);
} }
......
...@@ -36,8 +36,12 @@ void GpuVSyncBeginFrameSource::OnGpuVSync(base::TimeTicks vsync_time, ...@@ -36,8 +36,12 @@ void GpuVSyncBeginFrameSource::OnGpuVSync(base::TimeTicks vsync_time,
skip_next_vsync_ = true; skip_next_vsync_ = true;
vsync_interval *= 2; vsync_interval *= 2;
} }
auto next_frame_time = vsync_time + vsync_interval;
auto deadline =
next_frame_time -
BeginFrameArgs::DefaultEstimatedDisplayDrawTime(vsync_interval);
auto begin_frame_args = begin_frame_args_generator_.GenerateBeginFrameArgs( auto begin_frame_args = begin_frame_args_generator_.GenerateBeginFrameArgs(
source_id(), vsync_time, vsync_time + vsync_interval, vsync_interval); source_id(), vsync_time, deadline, next_frame_time, vsync_interval);
ExternalBeginFrameSource::OnBeginFrame(begin_frame_args); ExternalBeginFrameSource::OnBeginFrame(begin_frame_args);
} }
...@@ -58,8 +62,11 @@ BeginFrameArgs GpuVSyncBeginFrameSource::GetMissedBeginFrameArgs( ...@@ -58,8 +62,11 @@ BeginFrameArgs GpuVSyncBeginFrameSource::GetMissedBeginFrameArgs(
// Don't create new args unless we've actually moved past the previous frame. // Don't create new args unless we've actually moved past the previous frame.
if (!last_begin_frame_args_.IsValid() || if (!last_begin_frame_args_.IsValid() ||
frame_time > last_begin_frame_args_.frame_time) { frame_time > last_begin_frame_args_.frame_time) {
auto next_frame_time = frame_time + interval;
auto deadline = next_frame_time -
BeginFrameArgs::DefaultEstimatedDisplayDrawTime(interval);
last_begin_frame_args_ = begin_frame_args_generator_.GenerateBeginFrameArgs( last_begin_frame_args_ = begin_frame_args_generator_.GenerateBeginFrameArgs(
source_id(), frame_time, frame_time + interval, interval); source_id(), frame_time, deadline, next_frame_time, interval);
} }
return ExternalBeginFrameSource::GetMissedBeginFrameArgs(obs); return ExternalBeginFrameSource::GetMissedBeginFrameArgs(obs);
......
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