Index: cc/scheduler/scheduler.cc |
diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc |
index d308b0d0005f661be15dc36c90cc92da73463683..7110bff7c3ae3c2ea435580d3a1f9bd3fc2b402e 100644 |
--- a/cc/scheduler/scheduler.cc |
+++ b/cc/scheduler/scheduler.cc |
@@ -7,23 +7,29 @@ |
#include "base/auto_reset.h" |
#include "base/debug/trace_event.h" |
#include "base/logging.h" |
+#include "cc/base/thread.h" |
namespace cc { |
Scheduler::Scheduler(SchedulerClient* client, |
- scoped_ptr<FrameRateController> frame_rate_controller, |
const SchedulerSettings& scheduler_settings) |
: settings_(scheduler_settings), |
client_(client), |
- frame_rate_controller_(frame_rate_controller.Pass()), |
+ weak_factory_(this), |
+ last_set_needs_begin_frame_(false), |
+ has_pending_begin_frame_(false), |
+ last_begin_frame_time_(base::TimeTicks()), |
+ // TODO(brianderson): Pass with BeginFrame in the near future. |
+ interval_(base::TimeDelta::FromMicroseconds(16666)), |
state_machine_(scheduler_settings), |
inside_process_scheduled_actions_(false) { |
DCHECK(client_); |
- frame_rate_controller_->SetClient(this); |
DCHECK(!state_machine_.BeginFrameNeededByImplThread()); |
} |
-Scheduler::~Scheduler() { frame_rate_controller_->SetActive(false); } |
+Scheduler::~Scheduler() { |
+ client_->SetNeedsBeginFrameOnImplThread(false); |
+} |
void Scheduler::SetCanStart() { |
state_machine_.SetCanStart(); |
@@ -88,23 +94,6 @@ void Scheduler::BeginFrameAbortedByMainThread() { |
ProcessScheduledActions(); |
} |
-void Scheduler::SetMaxFramesPending(int max_frames_pending) { |
- frame_rate_controller_->SetMaxFramesPending(max_frames_pending); |
-} |
- |
-int Scheduler::MaxFramesPending() const { |
- return frame_rate_controller_->MaxFramesPending(); |
-} |
- |
-int Scheduler::NumFramesPendingForTesting() const { |
- return frame_rate_controller_->NumFramesPendingForTesting(); |
-} |
- |
-void Scheduler::DidSwapBuffersComplete() { |
- TRACE_EVENT0("cc", "Scheduler::DidSwapBuffersComplete"); |
- frame_rate_controller_->DidSwapBuffersComplete(); |
-} |
- |
void Scheduler::DidLoseOutputSurface() { |
TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface"); |
state_machine_.DidLoseOutputSurface(); |
@@ -113,31 +102,69 @@ void Scheduler::DidLoseOutputSurface() { |
void Scheduler::DidCreateAndInitializeOutputSurface() { |
TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface"); |
- frame_rate_controller_->DidAbortAllPendingFrames(); |
state_machine_.DidCreateAndInitializeOutputSurface(); |
+ has_pending_begin_frame_ = false; |
+ last_set_needs_begin_frame_ = false; |
ProcessScheduledActions(); |
} |
-void Scheduler::SetTimebaseAndInterval(base::TimeTicks timebase, |
- base::TimeDelta interval) { |
- frame_rate_controller_->SetTimebaseAndInterval(timebase, interval); |
-} |
- |
base::TimeTicks Scheduler::AnticipatedDrawTime() { |
- return frame_rate_controller_->NextTickTime(); |
+ TRACE_EVENT0("cc", "Scheduler::AnticipatedDrawTime"); |
+ base::TimeTicks now = base::TimeTicks::Now(); |
+ int64 intervals = ((now - last_begin_frame_time_) / interval_) + 1; |
+ return last_begin_frame_time_ + (interval_ * intervals); |
} |
base::TimeTicks Scheduler::LastBeginFrameOnImplThreadTime() { |
- return frame_rate_controller_->LastTickTime(); |
+ return last_begin_frame_time_; |
+} |
+ |
+void Scheduler::SetupNextBeginFrameIfNeeded() { |
+ // Determine if we need BeginFrame notifications. |
+ // If we do, always request the BeginFrame immediately. |
+ // If not, only disable on the next BeginFrame to avoid unnecessary toggles. |
+ // The synchronous renderer compositor requires immediate disables though. |
+ bool needs_begin_frame = state_machine_.BeginFrameNeededByImplThread(); |
+ if ((needs_begin_frame || |
+ state_machine_.inside_begin_frame() || |
+ settings_.using_synchronous_renderer_compositor) && |
+ (needs_begin_frame != last_set_needs_begin_frame_)) { |
+ client_->SetNeedsBeginFrameOnImplThread(needs_begin_frame); |
+ last_set_needs_begin_frame_ = needs_begin_frame; |
+ } |
+ |
+ // Request another BeginFrame if we haven't drawn for now until we have |
+ // deadlines implemented. |
+ if (state_machine_.inside_begin_frame() && has_pending_begin_frame_) { |
+ has_pending_begin_frame_ = false; |
+ client_->SetNeedsBeginFrameOnImplThread(true); |
+ } |
} |
-void Scheduler::BeginFrame(bool throttled) { |
- TRACE_EVENT1("cc", "Scheduler::BeginFrame", "throttled", throttled); |
- if (!throttled) |
- state_machine_.DidEnterBeginFrame(); |
+void Scheduler::BeginFrame(base::TimeTicks frame_time) { |
+ TRACE_EVENT0("cc", "Scheduler::BeginFrame"); |
+ DCHECK(!has_pending_begin_frame_); |
+ has_pending_begin_frame_ = true; |
+ last_begin_frame_time_ = frame_time; |
+ state_machine_.DidEnterBeginFrame(); |
+ state_machine_.SetFrameTime(frame_time); |
ProcessScheduledActions(); |
- if (!throttled) |
- state_machine_.DidLeaveBeginFrame(); |
+ state_machine_.DidLeaveBeginFrame(); |
+} |
+ |
+void Scheduler::DrawAndSwapIfPossible() { |
+ ScheduledActionDrawAndSwapResult result = |
+ client_->ScheduledActionDrawAndSwapIfPossible(); |
+ state_machine_.DidDrawIfPossibleCompleted(result.did_draw); |
+ if (result.did_swap) |
+ has_pending_begin_frame_ = false; |
+} |
+ |
+void Scheduler::DrawAndSwapForced() { |
+ ScheduledActionDrawAndSwapResult result = |
+ client_->ScheduledActionDrawAndSwapForced(); |
+ if (result.did_swap) |
+ has_pending_begin_frame_ = false; |
} |
void Scheduler::ProcessScheduledActions() { |
@@ -151,9 +178,6 @@ void Scheduler::ProcessScheduledActions() { |
SchedulerStateMachine::Action action = state_machine_.NextAction(); |
while (action != SchedulerStateMachine::ACTION_NONE) { |
state_machine_.UpdateState(action); |
- TRACE_EVENT1( |
- "cc", "Scheduler::ProcessScheduledActions()", "action", action); |
- |
switch (action) { |
case SchedulerStateMachine::ACTION_NONE: |
break; |
@@ -169,23 +193,12 @@ void Scheduler::ProcessScheduledActions() { |
case SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED: |
client_->ScheduledActionActivatePendingTreeIfNeeded(); |
break; |
- case SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE: { |
- frame_rate_controller_->DidSwapBuffers(); |
- ScheduledActionDrawAndSwapResult result = |
- client_->ScheduledActionDrawAndSwapIfPossible(); |
- state_machine_.DidDrawIfPossibleCompleted(result.did_draw); |
- if (!result.did_swap) |
- frame_rate_controller_->DidSwapBuffersComplete(); |
+ case SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE: |
+ DrawAndSwapIfPossible(); |
break; |
- } |
- case SchedulerStateMachine::ACTION_DRAW_FORCED: { |
- frame_rate_controller_->DidSwapBuffers(); |
- ScheduledActionDrawAndSwapResult result = |
- client_->ScheduledActionDrawAndSwapForced(); |
- if (!result.did_swap) |
- frame_rate_controller_->DidSwapBuffersComplete(); |
+ case SchedulerStateMachine::ACTION_DRAW_FORCED: |
+ DrawAndSwapForced(); |
break; |
- } |
case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION: |
client_->ScheduledActionBeginOutputSurfaceCreation(); |
break; |
@@ -196,10 +209,8 @@ void Scheduler::ProcessScheduledActions() { |
action = state_machine_.NextAction(); |
} |
- // Activate or deactivate the frame rate controller. |
- frame_rate_controller_->SetActive( |
- state_machine_.BeginFrameNeededByImplThread()); |
- client_->DidAnticipatedDrawTimeChange(frame_rate_controller_->NextTickTime()); |
+ SetupNextBeginFrameIfNeeded(); |
+ client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime()); |
} |
bool Scheduler::WillDrawIfNeeded() const { |