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

Unified Diff: cc/scheduler/scheduler.cc

Issue 16871016: cc: Use BeginFrameArgs (Closed) Base URL: http://git.chromium.org/chromium/src.git@bfargs2
Patch Set: StateMachine test working; Reworked readback. Created 7 years, 5 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 edf5e2549d54d0554995c6352db047a1018c27e9..897ad07f0e86ff645bfb5ddfc0936724e03224f5 100644
--- a/cc/scheduler/scheduler.cc
+++ b/cc/scheduler/scheduler.cc
@@ -4,10 +4,18 @@
#include "cc/scheduler/scheduler.h"
+#include <algorithm>
#include "base/auto_reset.h"
#include "base/debug/trace_event.h"
#include "base/logging.h"
+class DEVNULL {};
+template <typename A>
+DEVNULL& operator <<(DEVNULL &d, A a) { return d; }
+//static DEVNULL gDevNull;
+//#undef VLOG
+//#define VLOG(x) gDevNull
+
namespace cc {
Scheduler::Scheduler(SchedulerClient* client,
@@ -21,7 +29,7 @@ Scheduler::Scheduler(SchedulerClient* client,
state_machine_(scheduler_settings),
inside_process_scheduled_actions_(false) {
DCHECK(client_);
- DCHECK(!state_machine_.BeginFrameNeededToDrawByImplThread());
+ DCHECK(!state_machine_.BeginFrameNeededByImplThread());
}
Scheduler::~Scheduler() {
@@ -43,9 +51,12 @@ void Scheduler::SetCanDraw(bool can_draw) {
ProcessScheduledActions();
}
-void Scheduler::SetHasPendingTree(bool has_pending_tree) {
- state_machine_.SetHasPendingTree(has_pending_tree);
+void Scheduler::SetHasTrees(bool has_pending_tree, bool active_tree_is_null) {
+ state_machine_.SetHasTrees(has_pending_tree, active_tree_is_null);
ProcessScheduledActions();
+
+ if (state_machine_.ShouldTriggerBeginFrameDeadlineEarly())
+ PostBeginFrameDeadline(base::TimeTicks());
}
void Scheduler::SetNeedsCommit() {
@@ -53,9 +64,9 @@ void Scheduler::SetNeedsCommit() {
ProcessScheduledActions();
}
-void Scheduler::SetNeedsForcedCommit() {
+void Scheduler::SetNeedsForcedCommitForReadback() {
state_machine_.SetNeedsCommit();
- state_machine_.SetNeedsForcedCommit();
+ state_machine_.SetNeedsForcedCommitForReadback();
ProcessScheduledActions();
}
@@ -69,11 +80,6 @@ void Scheduler::DidSwapUseIncompleteTile() {
ProcessScheduledActions();
}
-void Scheduler::SetNeedsForcedRedraw() {
- state_machine_.SetNeedsForcedRedraw();
- ProcessScheduledActions();
-}
-
void Scheduler::SetMainThreadNeedsLayerTextures() {
state_machine_.SetMainThreadNeedsLayerTextures();
ProcessScheduledActions();
@@ -83,6 +89,9 @@ void Scheduler::FinishCommit() {
TRACE_EVENT0("cc", "Scheduler::FinishCommit");
state_machine_.FinishCommit();
ProcessScheduledActions();
+
+ if (state_machine_.ShouldTriggerBeginFrameDeadlineEarly())
+ PostBeginFrameDeadline(base::TimeTicks());
}
void Scheduler::BeginFrameAbortedByMainThread() {
@@ -113,12 +122,11 @@ base::TimeTicks Scheduler::AnticipatedDrawTime() {
last_begin_frame_args_.interval <= base::TimeDelta())
return base::TimeTicks();
- // TODO(brianderson): Express this in terms of the deadline.
base::TimeTicks now = base::TimeTicks::Now();
- int64 intervals = 1 + ((now - last_begin_frame_args_.frame_time) /
- last_begin_frame_args_.interval);
- return last_begin_frame_args_.frame_time +
- (last_begin_frame_args_.interval * intervals);
+ base::TimeTicks timebase = std::max(last_begin_frame_args_.frame_time,
+ last_begin_frame_args_.deadline);
+ int64 intervals = 1 + ((now - timebase) / last_begin_frame_args_.interval);
+ return timebase + (last_begin_frame_args_.interval * intervals);
}
base::TimeTicks Scheduler::LastBeginFrameOnImplThreadTime() {
@@ -128,41 +136,37 @@ base::TimeTicks Scheduler::LastBeginFrameOnImplThreadTime() {
void Scheduler::SetupNextBeginFrameIfNeeded() {
bool needs_begin_frame_to_draw =
state_machine_.BeginFrameNeededToDrawByImplThread();
- // We want to avoid proactive begin frames with the synchronous compositor
- // because every SetNeedsBeginFrame will force a redraw.
bool proactive_begin_frame_wanted =
- state_machine_.ProactiveBeginFrameWantedByImplThread() &&
- !settings_.using_synchronous_renderer_compositor &&
- settings_.throttle_frame_production;
+ state_machine_.BeginFrameProactivelyNeededByImplThread();
+
+ // We want to avoid proactive begin frames with the synchronous
+ // compositor because every SetNeedsBeginFrame will force a redraw.
bool needs_begin_frame = needs_begin_frame_to_draw ||
proactive_begin_frame_wanted;
- bool immediate_disables_needed =
- settings_.using_synchronous_renderer_compositor;
+
+ bool should_call_set_needs_begin_frame =
+ // The synchronous renderer compositor needs immediate enables/disables.
+ (settings_.using_synchronous_renderer_compositor &&
+ needs_begin_frame != last_set_needs_begin_frame_) ||
+ // Always request the BeginFrame immediately if it wasn't needed before.
+ (needs_begin_frame && !last_set_needs_begin_frame_) ||
+ // Only disable the BeginFrame after a BeginFrame where we didn't swap.
+ (!needs_begin_frame && last_set_needs_begin_frame_ &&
+ has_pending_begin_frame_ && !state_machine_.InsideBeginFrame()) ||
+ // We did not draw and swap this BeginFrame,
+ // so we need to explicitly request another BeginFrame.
+ (needs_begin_frame && has_pending_begin_frame_ &&
+ state_machine_.InsideBeginFrame());
if (needs_begin_frame_to_draw)
safe_to_expect_begin_frame_ = true;
- // 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.
- if ((needs_begin_frame ||
- state_machine_.inside_begin_frame() ||
- immediate_disables_needed) &&
- (needs_begin_frame != last_set_needs_begin_frame_)) {
+ if (should_call_set_needs_begin_frame) {
has_pending_begin_frame_ = false;
client_->SetNeedsBeginFrameOnImplThread(needs_begin_frame);
if (safe_to_expect_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);
- return;
- }
}
void Scheduler::BeginFrame(const BeginFrameArgs& args) {
@@ -171,13 +175,36 @@ void Scheduler::BeginFrame(const BeginFrameArgs& args) {
has_pending_begin_frame_ = true;
safe_to_expect_begin_frame_ = true;
last_begin_frame_args_ = args;
- state_machine_.DidEnterBeginFrame(args);
+ last_begin_frame_args_.AdjustDeadline(-client_->DrawDurationEstimate());
+ state_machine_.OnBeginFrame(last_begin_frame_args_);
ProcessScheduledActions();
- state_machine_.DidLeaveBeginFrame();
+
+ if (settings_.using_synchronous_renderer_compositor)
+ OnBeginFrameDeadline();
+ else if (state_machine_.ShouldTriggerBeginFrameDeadlineEarly())
+ PostBeginFrameDeadline(base::TimeTicks());
+ else
+ PostBeginFrameDeadline(last_begin_frame_args_.deadline);
+}
+
+void Scheduler::PostBeginFrameDeadline(base::TimeTicks deadline) {
+ begin_frame_deadline_closure_.Cancel();
+ begin_frame_deadline_closure_.Reset(
+ base::Bind(&Scheduler::OnBeginFrameDeadline, weak_factory_.GetWeakPtr()));
+ client_->PostBeginFrameDeadline(
+ begin_frame_deadline_closure_.callback(), deadline);
+}
+
+void Scheduler::OnBeginFrameDeadline() {
+ TRACE_EVENT0("cc", "Scheduler::OnBeginFrameDeadline");
+ begin_frame_deadline_closure_.Cancel();
+ state_machine_.OnBeginFrameDeadline();
+ ProcessScheduledActions();
+ client_->DidBeginFrameDeadlineOnImplThread();
}
void Scheduler::DrawAndSwapIfPossible() {
- ScheduledActionDrawAndSwapResult result =
+ ScheduledActionDrawSwapReadbackResult result =
client_->ScheduledActionDrawAndSwapIfPossible();
state_machine_.DidDrawIfPossibleCompleted(result.did_draw);
if (result.did_swap)
@@ -185,12 +212,16 @@ void Scheduler::DrawAndSwapIfPossible() {
}
void Scheduler::DrawAndSwapForced() {
- ScheduledActionDrawAndSwapResult result =
+ ScheduledActionDrawSwapReadbackResult result =
client_->ScheduledActionDrawAndSwapForced();
if (result.did_swap)
has_pending_begin_frame_ = false;
}
+void Scheduler::DrawAndReadback() {
+ client_->ScheduledActionDrawAndReadback();
+}
+
void Scheduler::ProcessScheduledActions() {
// We do not allow ProcessScheduledActions to be recursive.
// The top-level call will iteratively execute the next action for us anyway.
@@ -199,40 +230,46 @@ void Scheduler::ProcessScheduledActions() {
base::AutoReset<bool> mark_inside(&inside_process_scheduled_actions_, true);
- SchedulerStateMachine::Action action = state_machine_.NextAction();
- while (action != SchedulerStateMachine::ACTION_NONE) {
+ SchedulerStateMachine::Action action;
+ do {
+ //TRACE_EVENT1("cc", "SchedulerStateMachine",
+ // "state", state_machine_.ToString());
+ action = state_machine_.NextAction();
state_machine_.UpdateState(action);
switch (action) {
- case SchedulerStateMachine::ACTION_NONE:
+ case SchedulerStateMachine::ACTION_NONE:VLOG(0) << __LINE__ << "ACTION_NONE\n";
break;
- case SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD:
+ case SchedulerStateMachine::ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD:VLOG(0) << __LINE__ << "ACTION_SEND_BEGIN_FRAME_TO_MAIN_THREAD\n";
client_->ScheduledActionSendBeginFrameToMainThread();
break;
- case SchedulerStateMachine::ACTION_COMMIT:
+ case SchedulerStateMachine::ACTION_COMMIT:VLOG(0) << __LINE__ << "ACTION_COMMIT\n";
client_->ScheduledActionCommit();
break;
- case SchedulerStateMachine::ACTION_CHECK_FOR_COMPLETED_TILE_UPLOADS:
+ case SchedulerStateMachine::ACTION_CHECK_FOR_COMPLETED_TILE_UPLOADS:VLOG(0) << __LINE__ << "ACTION_CHECK_FOR_COMPLETED_TILE_UPLOADS\n";
client_->ScheduledActionCheckForCompletedTileUploads();
break;
- case SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED:
+ case SchedulerStateMachine::ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED:VLOG(0) << __LINE__ << "ACTION_ACTIVATE_PENDING_TREE_IF_NEEDED\n";
client_->ScheduledActionActivatePendingTreeIfNeeded();
break;
- case SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE:
+ case SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE:VLOG(0) << __LINE__ << "ACTION_DRAW_IF_POSSIBLE\n";
DrawAndSwapIfPossible();
break;
- case SchedulerStateMachine::ACTION_DRAW_FORCED:
+ case SchedulerStateMachine::ACTION_DRAW_FORCED:VLOG(0) << __LINE__ << "ACTION_DRAW_FORCED\n";
DrawAndSwapForced();
break;
- case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION:
+ case SchedulerStateMachine::ACTION_DRAW_AND_READBACK:VLOG(0) << __LINE__ << "ACTION_DRAW_AND_READBACK";
+ DrawAndReadback();
+ break;
+ case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION:VLOG(0) << __LINE__ << "ACTION_BEGIN_OUTPUT_SURFACE_CREATION\n";
client_->ScheduledActionBeginOutputSurfaceCreation();
break;
- case SchedulerStateMachine::ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD:
+ case SchedulerStateMachine::ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD:VLOG(0) << __LINE__ << "ACTION_ACQUIRE_LAYER_TEXTURES_FOR_MAIN_THREAD\n";
client_->ScheduledActionAcquireLayerTexturesForMainThread();
break;
}
- action = state_machine_.NextAction();
- }
+ } while (action != SchedulerStateMachine::ACTION_NONE);
+ state_machine_.AdvanceBeginFrameStateWhenNoActionsRemain();
SetupNextBeginFrameIfNeeded();
client_->DidAnticipatedDrawTimeChange(AnticipatedDrawTime());
}

Powered by Google App Engine
This is Rietveld 408576698