Chromium Code Reviews| Index: cc/output/output_surface.cc |
| diff --git a/cc/output/output_surface.cc b/cc/output/output_surface.cc |
| index 2ab30f6437bdb315c0869fe352afa5a9ca7df149..fa297c2823ecd4e81a22ca9c5a11cef68ddf203e 100644 |
| --- a/cc/output/output_surface.cc |
| +++ b/cc/output/output_surface.cc |
| @@ -101,6 +101,7 @@ OutputSurface::OutputSurface( |
| needs_begin_frame_(false), |
| begin_frame_pending_(false), |
| client_(NULL), |
| + consecutive_missed_deadlines_(0), |
| check_for_retroactive_begin_frame_pending_(false) { |
| } |
| @@ -116,6 +117,7 @@ OutputSurface::OutputSurface( |
| needs_begin_frame_(false), |
| begin_frame_pending_(false), |
| client_(NULL), |
| + consecutive_missed_deadlines_(0), |
| check_for_retroactive_begin_frame_pending_(false) { |
| } |
| @@ -133,6 +135,7 @@ OutputSurface::OutputSurface( |
| needs_begin_frame_(false), |
| begin_frame_pending_(false), |
| client_(NULL), |
| + consecutive_missed_deadlines_(0), |
| check_for_retroactive_begin_frame_pending_(false) { |
| } |
| @@ -175,11 +178,19 @@ void OutputSurface::OnVSyncParametersChanged(base::TimeTicks timebase, |
| frame_rate_controller_->SetTimebaseAndInterval(timebase, interval); |
| } |
| +void OutputSurface::AddSkippedBeginFrame(const BeginFrameArgs& skipped) { |
| + if (skipped.IsValid() && |
| + (skipped_begin_frame_args_.empty() || |
| + skipped.frame_time != skipped_begin_frame_args_.back().frame_time)) { |
| + skipped_begin_frame_args_.push_back(skipped); |
| + } |
| +} |
| + |
| void OutputSurface::FrameRateControllerTick(bool throttled, |
| const BeginFrameArgs& args) { |
| DCHECK(frame_rate_controller_); |
| if (throttled) |
| - skipped_begin_frame_args_ = args; |
| + AddSkippedBeginFrame(args); |
| else |
| BeginFrame(args); |
| } |
| @@ -196,8 +207,7 @@ void OutputSurface::SetNeedsBeginFrame(bool enable) { |
| begin_frame_pending_ = false; |
| if (frame_rate_controller_) { |
| BeginFrameArgs skipped = frame_rate_controller_->SetActive(enable); |
| - if (skipped.IsValid()) |
| - skipped_begin_frame_args_ = skipped; |
| + AddSkippedBeginFrame(skipped); |
| } |
| if (needs_begin_frame_) |
| PostCheckForRetroactiveBeginFrame(); |
| @@ -210,27 +220,31 @@ void OutputSurface::BeginFrame(const BeginFrameArgs& args) { |
| if (!needs_begin_frame_ || begin_frame_pending_ || |
| (pending_swap_buffers_ >= max_frames_pending_ && |
| max_frames_pending_ > 0)) { |
| - skipped_begin_frame_args_ = args; |
| + AddSkippedBeginFrame(args); |
| } else { |
| begin_frame_pending_ = true; |
| + consecutive_missed_deadlines_ = 0; |
| client_->BeginFrame(args); |
| - // args might be an alias for skipped_begin_frame_args_. |
| - // Do not reset it before calling BeginFrame! |
| - skipped_begin_frame_args_ = BeginFrameArgs(); |
| } |
| } |
| base::TimeTicks OutputSurface::RetroactiveBeginFrameDeadline() { |
| + if (consecutive_missed_deadlines_) { |
|
Sami
2013/08/13 16:44:08
I think the interaction between CheckForRetroactiv
|
| + return skipped_begin_frame_args_.front().frame_time + |
| + skipped_begin_frame_args_.front().interval; |
| + } |
| + |
| // TODO(brianderson): Remove the alternative deadline once we have better |
| // deadline estimations. |
| base::TimeTicks alternative_deadline = |
| - skipped_begin_frame_args_.frame_time + |
| + skipped_begin_frame_args_.front().frame_time + |
| BeginFrameArgs::DefaultRetroactiveBeginFramePeriod(); |
| - return std::max(skipped_begin_frame_args_.deadline, alternative_deadline); |
| + return std::max(skipped_begin_frame_args_.front().deadline, |
| + alternative_deadline); |
| } |
| void OutputSurface::PostCheckForRetroactiveBeginFrame() { |
| - if (!skipped_begin_frame_args_.IsValid() || |
| + if (skipped_begin_frame_args_.empty() || |
| check_for_retroactive_begin_frame_pending_) |
| return; |
| @@ -242,10 +256,24 @@ void OutputSurface::PostCheckForRetroactiveBeginFrame() { |
| } |
| void OutputSurface::CheckForRetroactiveBeginFrame() { |
| - TRACE_EVENT0("cc", "OutputSurface::CheckForRetroactiveBeginFrame"); |
| check_for_retroactive_begin_frame_pending_ = false; |
| - if (base::TimeTicks::Now() < RetroactiveBeginFrameDeadline()) |
| - BeginFrame(skipped_begin_frame_args_); |
| + if (skipped_begin_frame_args_.empty()) |
| + return; |
| + |
| + TRACE_EVENT0("cc", "OutputSurface::CheckForRetroactiveBeginFrame"); |
| + base::TimeTicks now = base::TimeTicks::Now(); |
| + while (skipped_begin_frame_args_.size() > 1 && |
| + now > skipped_begin_frame_args_.front().deadline) { |
| + skipped_begin_frame_args_.pop_front(); |
| + consecutive_missed_deadlines_++; |
| + } |
| + |
| + if (now < RetroactiveBeginFrameDeadline()) |
| + BeginFrame(skipped_begin_frame_args_.front()); |
| + else |
| + consecutive_missed_deadlines_++; |
| + |
| + skipped_begin_frame_args_.pop_front(); |
| } |
| void OutputSurface::DidSwapBuffers() { |