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() { |