Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(1147)

Unified Diff: cc/scheduler/scheduler.cc

Issue 15836005: cc: Emulate BeginFrame in OutputSurfaces that don't support it natively (Closed) Base URL: http://git.chromium.org/chromium/src.git@nofrc
Patch Set: Fix checkerboard; Track pending swaps; Created 7 years, 6 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View side-by-side diff with in-line comments
Download patch
Index: cc/scheduler/scheduler.cc
diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc
index 737ffc1bb1222b2af5fec3d72e7a468abd4fa2ad..7f410a7ed5937fc228e2de1dc24b473c5ce57cc5 100644
--- a/cc/scheduler/scheduler.cc
+++ b/cc/scheduler/scheduler.cc
@@ -7,23 +7,33 @@
#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)
+ const SchedulerSettings& scheduler_settings,
+ Thread *thread)
: settings_(scheduler_settings),
client_(client),
- frame_rate_controller_(frame_rate_controller.Pass()),
+ weak_factory_(this),
+ thread_(thread),
+ last_set_needs_begin_frame_(false),
+ pending_begin_frames_(0),
+ incomplete_swaps_(0),
+ last_begin_frame_time_(base::TimeTicks()),
+ anticipated_draw_time_(base::TimeTicks::Now()),
+ //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,27 +98,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::SetSwapBuffersCompleteSupported(bool supported) {
- frame_rate_controller_->SetSwapBuffersCompleteSupported(supported);
-}
-
-void Scheduler::DidSwapBuffersComplete() {
- TRACE_EVENT0("cc", "Scheduler::DidSwapBuffersComplete");
- frame_rate_controller_->DidSwapBuffersComplete();
-}
-
void Scheduler::DidLoseOutputSurface() {
TRACE_EVENT0("cc", "Scheduler::DidLoseOutputSurface");
state_machine_.DidLoseOutputSurface();
@@ -117,31 +106,78 @@ void Scheduler::DidLoseOutputSurface() {
void Scheduler::DidCreateAndInitializeOutputSurface() {
TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface");
- frame_rate_controller_->DidAbortAllPendingFrames();
state_machine_.DidCreateAndInitializeOutputSurface();
+ 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();
+ while (anticipated_draw_time_ < now) {
nduca 2013/06/04 04:53:59 i think delay based timesource has some crap in it
brianderson 2013/06/04 18:33:27 Will change this.
+ anticipated_draw_time_ += interval_;
+ }
+
+ return anticipated_draw_time_;
}
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;
+ }
+
+ if (state_machine_.inside_begin_frame() && pending_begin_frames_) {
+ // Self tick to retry a BeginFrame where we did not draw.
+ // TODO(brianderson): Implement smarter polling when deadlines are added.
+ thread_->PostDelayedTask(
+ base::Bind(&Scheduler::BeginFrameRetry, weak_factory_.GetWeakPtr()),
+ interval_);
+ }
+}
+
+void Scheduler::BeginFrame(base::TimeTicks frame_time) {
+ TRACE_EVENT0("cc", "Scheduler::BeginFrame");
+ pending_begin_frames_++;
nduca 2013/06/04 04:53:59 okay this bit i dont get. why would we ever have t
brianderson 2013/06/04 18:33:27 In this patch, pending_begin_frames_ will only eve
+ last_begin_frame_time_ = frame_time;
+ anticipated_draw_time_ = frame_time + interval_;
+ state_machine_.DidEnterBeginFrame();
+ ProcessScheduledActions();
+ state_machine_.DidLeaveBeginFrame();
}
-void Scheduler::BeginFrame(bool throttled) {
- TRACE_EVENT1("cc", "Scheduler::BeginFrame", "throttled", throttled);
- if (!throttled)
- state_machine_.DidEnterBeginFrame();
+void Scheduler::BeginFrameRetry() {
+ TRACE_EVENT0("cc", "Scheduler::BeginFrameRetry");
+ state_machine_.DidEnterBeginFrame();
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)
+ pending_begin_frames_--;
+}
+
+void Scheduler::DrawAndSwapForced() {
+ ScheduledActionDrawAndSwapResult result =
+ client_->ScheduledActionDrawAndSwapForced();
+ if (result.did_swap)
+ pending_begin_frames_--;
}
void Scheduler::ProcessScheduledActions() {
@@ -155,8 +191,10 @@ 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);
+ TRACE_EVENT2(
+ "cc", "Scheduler::ProcessScheduledActions()",
+ "action", action,
+ "state", state_machine_.ToString());
switch (action) {
case SchedulerStateMachine::ACTION_NONE:
@@ -173,21 +211,12 @@ void Scheduler::ProcessScheduledActions() {
case SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED:
client_->ScheduledActionActivatePendingTreeIfNeeded();
break;
- case SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE: {
- ScheduledActionDrawAndSwapResult result =
- client_->ScheduledActionDrawAndSwapIfPossible();
- state_machine_.DidDrawIfPossibleCompleted(result.did_draw);
- if (result.did_swap)
- frame_rate_controller_->DidSwapBuffers();
+ case SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE:
+ DrawAndSwapIfPossible();
break;
- }
- case SchedulerStateMachine::ACTION_DRAW_FORCED: {
- ScheduledActionDrawAndSwapResult result =
- client_->ScheduledActionDrawAndSwapForced();
- if (result.did_swap)
- frame_rate_controller_->DidSwapBuffers();
+ case SchedulerStateMachine::ACTION_DRAW_FORCED:
+ DrawAndSwapForced();
break;
- }
case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION:
client_->ScheduledActionBeginOutputSurfaceCreation();
break;
@@ -198,10 +227,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();
nduca 2013/06/04 04:53:59 This feels like more data suggesting that the task
brianderson 2013/06/04 18:33:27 I will revisit this idea in future patches that ad
+ client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime());
nduca 2013/06/04 04:53:59 so, if you actually look at who needs this, its th
brianderson 2013/06/04 18:33:27 This patch is already pretty big, so I opened anot
}
bool Scheduler::WillDrawIfNeeded() const {

Powered by Google App Engine
This is Rietveld 408576698