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

Unified Diff: cc/scheduler/scheduler_state_machine.cc

Issue 2659123004: cc: Add scheduler support for invalidating content on impl thread. (Closed)
Patch Set: commit_to_active Created 3 years, 11 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_state_machine.cc
diff --git a/cc/scheduler/scheduler_state_machine.cc b/cc/scheduler/scheduler_state_machine.cc
index 91ae485850381b5ce41b3eb509a11d06deb5ba09..3e85448ee2a7f2140c731e560328576b71c67713 100644
--- a/cc/scheduler/scheduler_state_machine.cc
+++ b/cc/scheduler/scheduler_state_machine.cc
@@ -33,6 +33,7 @@ SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings)
draw_funnel_(false),
send_begin_main_frame_funnel_(true),
invalidate_compositor_frame_sink_funnel_(false),
+ impl_side_invalidation_funnel_(false),
prepare_tiles_funnel_(0),
consecutive_checkerboard_animations_(0),
pending_submit_frames_(0),
@@ -60,7 +61,9 @@ SchedulerStateMachine::SchedulerStateMachine(const SchedulerSettings& settings)
last_commit_had_no_updates_(false),
wait_for_ready_to_draw_(false),
did_draw_in_last_frame_(false),
- did_submit_in_last_frame_(false) {}
+ did_submit_in_last_frame_(false),
+ needs_impl_side_invalidation_(false),
+ run_impl_side_invalidation_after_main_frame_aborted_(false) {}
const char* SchedulerStateMachine::CompositorFrameSinkStateToString(
CompositorFrameSinkState state) {
@@ -177,6 +180,8 @@ const char* SchedulerStateMachine::ActionToString(Action action) {
return "ACTION_PREPARE_TILES";
case ACTION_INVALIDATE_COMPOSITOR_FRAME_SINK:
return "ACTION_INVALIDATE_COMPOSITOR_FRAME_SINK";
+ case ACTION_RUN_IMPL_SIDE_INVALIDATION:
+ return "ACTION_RUN_IMPL_SIDE_INVALIDATION";
}
NOTREACHED();
return "???";
@@ -558,6 +563,8 @@ SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const {
return ACTION_PREPARE_TILES;
if (ShouldSendBeginMainFrame())
return ACTION_SEND_BEGIN_MAIN_FRAME;
+ if (ShouldRunImplSideInvalidation())
+ return ACTION_RUN_IMPL_SIDE_INVALIDATION;
if (ShouldInvalidateCompositorFrameSink())
return ACTION_INVALIDATE_COMPOSITOR_FRAME_SINK;
if (ShouldBeginCompositorFrameSinkCreation())
@@ -565,6 +572,79 @@ SchedulerStateMachine::Action SchedulerStateMachine::NextAction() const {
return ACTION_NONE;
}
+bool SchedulerStateMachine::ShouldRunImplSideInvalidation() const {
+ if (!needs_impl_side_invalidation_)
+ return false;
+
+ if (!CouldCreatePendingTree())
+ return false;
+
+ // If the main thread is ready to commit, the impl-side invalidations will be
+ // merged with the incoming main frame.
+ if (begin_main_frame_state_ == BEGIN_MAIN_FRAME_STATE_READY_TO_COMMIT)
+ return false;
+
+ // Don't invalidate too many times in the same frame.
+ if (impl_side_invalidation_funnel_)
+ return false;
+
+ // If invalidations go to the active tree and we are waiting for the previous
+ // frame to be drawn, submitted and acked.
+ if (settings_.commit_to_active_tree &&
+ (active_tree_needs_first_draw_ || IsDrawThrottled())) {
+ return false;
+ }
+
+ // Don't keep waiting on the main thread if the commits are being aborted.
+ if (run_impl_side_invalidation_after_main_frame_aborted_)
+ return true;
+
+ // If BeginMainFrame has been sent, let's wait for the main thread before
+ // pipelining impl-side invalidations.
+ // TODO(khushalsagar): If the main thread is high latency, may be run
+ // impl-side invalidations instead of waiting on the main thread?
+ if (begin_main_frame_state_ == BEGIN_MAIN_FRAME_STATE_SENT ||
+ begin_main_frame_state_ == BEGIN_MAIN_FRAME_STATE_STARTED)
+ return false;
+
+ // If a main frame request is pending, always prioritize sending a
+ // BeginMainFrame and receiving an update from the main thread before creating
+ // a pending tree for impl-side invalidations.
+ if (CouldSendBeginMainFrame() &&
+ begin_main_frame_state_ ==
+ BeginMainFrameState::BEGIN_MAIN_FRAME_STATE_IDLE)
+ return false;
+
+ // At this point, create a pending tree to run impl-side invalidations.
+ return true;
+}
+
+void SchedulerStateMachine::WillRunImplSideInvalidation() {
+ DCHECK(needs_impl_side_invalidation_);
+
+ needs_impl_side_invalidation_ = false;
+ has_pending_tree_ = true;
+ run_impl_side_invalidation_after_main_frame_aborted_ = false;
+ impl_side_invalidation_funnel_ = true;
+}
+
+bool SchedulerStateMachine::CouldCreatePendingTree() const {
+ // Can't create a new pending tree till the current one is activated.
+ if (has_pending_tree_)
+ return false;
+
+ // Can't make frames while we're invisible.
+ if (!visible_)
+ return false;
+
+ // If the BeginFrameSource is paused, we will not be able to make any impl
+ // frames.
+ if (begin_frame_source_paused_)
+ return false;
+
+ return true;
+}
+
void SchedulerStateMachine::WillSendBeginMainFrame() {
DCHECK(!has_pending_tree_ || settings_.main_frame_before_activation_enabled);
DCHECK(visible_);
@@ -589,6 +669,13 @@ void SchedulerStateMachine::WillCommit(bool commit_has_no_updates) {
has_pending_tree_ = true;
pending_tree_is_ready_for_activation_ = false;
wait_for_ready_to_draw_ = settings_.commit_to_active_tree;
+
+ // If there was a commit, the impl-side invalidations will be merged with
+ // it.
+ if (needs_impl_side_invalidation_)
+ WillRunImplSideInvalidation();
brianderson 2017/02/03 00:54:53 I know it'll seem like extra boiler plate, but thi
Khushal 2017/02/03 01:45:11 Done.
+ } else if (needs_impl_side_invalidation_) {
+ run_impl_side_invalidation_after_main_frame_aborted_ = true;
}
// Update state related to forced draws.
@@ -689,6 +776,10 @@ void SchedulerStateMachine::DidDraw(DrawResult draw_result) {
DidDrawInternal(draw_result);
}
+void SchedulerStateMachine::SetNeedsImplSideInvalidation() {
+ needs_impl_side_invalidation_ = true;
+}
+
void SchedulerStateMachine::AbortDraw() {
// Pretend like the draw was successful.
// Note: We may abort at any time and cannot DCHECK that
@@ -767,7 +858,8 @@ bool SchedulerStateMachine::BeginFrameRequiredForAction() const {
return true;
return needs_redraw_ || needs_one_begin_impl_frame_ ||
- (needs_begin_main_frame_ && !defer_commits_);
+ (needs_begin_main_frame_ && !defer_commits_) ||
+ needs_impl_side_invalidation_;
}
// These are cases where we are very likely want a BeginFrame message in the
@@ -827,6 +919,7 @@ void SchedulerStateMachine::OnBeginImplFrame() {
// Clear funnels for any actions we perform during the frame.
send_begin_main_frame_funnel_ = false;
invalidate_compositor_frame_sink_funnel_ = false;
+ impl_side_invalidation_funnel_ = false;
// "Drain" the PrepareTiles funnel.
if (prepare_tiles_funnel_ > 0)

Powered by Google App Engine
This is Rietveld 408576698