summaryrefslogtreecommitdiff
path: root/chromium/cc/scheduler
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2017-11-20 15:06:40 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2017-11-22 11:48:58 +0000
commitdaa093eea7c773db06799a13bd7e4e2e2a9f8f14 (patch)
tree96cc5e7b9194c1b29eab927730bfa419e7111c25 /chromium/cc/scheduler
parentbe59a35641616a4cf23c4a13fa0632624b021c1b (diff)
downloadqtwebengine-chromium-daa093eea7c773db06799a13bd7e4e2e2a9f8f14.tar.gz
BASELINE: Update Chromium to 63.0.3239.58
Change-Id: Ia93b322a00ba4dd4004f3bcf1254063ba90e1605 Reviewed-by: Alexandru Croitor <alexandru.croitor@qt.io>
Diffstat (limited to 'chromium/cc/scheduler')
-rw-r--r--chromium/cc/scheduler/begin_frame_tracker.cc2
-rw-r--r--chromium/cc/scheduler/begin_frame_tracker.h4
-rw-r--r--chromium/cc/scheduler/compositor_timing_history.cc1
-rw-r--r--chromium/cc/scheduler/compositor_timing_history.h1
-rw-r--r--chromium/cc/scheduler/compositor_timing_history_unittest.cc4
-rw-r--r--chromium/cc/scheduler/scheduler.cc9
-rw-r--r--chromium/cc/scheduler/scheduler.h1
-rw-r--r--chromium/cc/scheduler/scheduler_state_machine.cc75
-rw-r--r--chromium/cc/scheduler/scheduler_state_machine.h4
-rw-r--r--chromium/cc/scheduler/scheduler_state_machine_unittest.cc52
10 files changed, 100 insertions, 53 deletions
diff --git a/chromium/cc/scheduler/begin_frame_tracker.cc b/chromium/cc/scheduler/begin_frame_tracker.cc
index 4c1ef9a0f45..c220552d2f3 100644
--- a/chromium/cc/scheduler/begin_frame_tracker.cc
+++ b/chromium/cc/scheduler/begin_frame_tracker.cc
@@ -6,7 +6,7 @@
namespace cc {
-BeginFrameTracker::BeginFrameTracker(const tracked_objects::Location& location)
+BeginFrameTracker::BeginFrameTracker(const base::Location& location)
: location_(location),
location_string_(location.ToString()),
current_finished_at_(base::TimeTicks() +
diff --git a/chromium/cc/scheduler/begin_frame_tracker.h b/chromium/cc/scheduler/begin_frame_tracker.h
index 4e237c70d8d..33d124ad7e5 100644
--- a/chromium/cc/scheduler/begin_frame_tracker.h
+++ b/chromium/cc/scheduler/begin_frame_tracker.h
@@ -35,7 +35,7 @@ namespace cc {
// TODO(mithro): Record stats about the viz::BeginFrameArgs
class CC_EXPORT BeginFrameTracker {
public:
- explicit BeginFrameTracker(const tracked_objects::Location& location);
+ explicit BeginFrameTracker(const base::Location& location);
~BeginFrameTracker();
// The Start and Finish methods manage the period that a BFA should be
@@ -85,7 +85,7 @@ class CC_EXPORT BeginFrameTracker {
// the BFA object. Can be called at any time.
bool HasFinished() const { return !current_finished_at_.is_null(); }
- const tracked_objects::Location location_;
+ const base::Location location_;
const std::string location_string_;
base::TimeTicks current_updated_at_;
diff --git a/chromium/cc/scheduler/compositor_timing_history.cc b/chromium/cc/scheduler/compositor_timing_history.cc
index d7e128c2791..2dd48bfdb43 100644
--- a/chromium/cc/scheduler/compositor_timing_history.cc
+++ b/chromium/cc/scheduler/compositor_timing_history.cc
@@ -801,7 +801,6 @@ void CompositorTimingHistory::DrawAborted() {
}
void CompositorTimingHistory::DidDraw(bool used_new_active_tree,
- bool main_thread_missed_last_deadline,
base::TimeTicks impl_frame_time) {
DCHECK_NE(base::TimeTicks(), draw_start_time_);
base::TimeTicks draw_end_time = Now();
diff --git a/chromium/cc/scheduler/compositor_timing_history.h b/chromium/cc/scheduler/compositor_timing_history.h
index 5e97dcb2486..40c3133df20 100644
--- a/chromium/cc/scheduler/compositor_timing_history.h
+++ b/chromium/cc/scheduler/compositor_timing_history.h
@@ -75,7 +75,6 @@ class CC_EXPORT CompositorTimingHistory {
void DrawAborted();
void WillDraw();
void DidDraw(bool used_new_active_tree,
- bool main_thread_missed_last_deadline,
base::TimeTicks impl_frame_time);
void DidSubmitCompositorFrame();
void DidReceiveCompositorFrameAck();
diff --git a/chromium/cc/scheduler/compositor_timing_history_unittest.cc b/chromium/cc/scheduler/compositor_timing_history_unittest.cc
index 08e9c006047..a6fac32f8f0 100644
--- a/chromium/cc/scheduler/compositor_timing_history_unittest.cc
+++ b/chromium/cc/scheduler/compositor_timing_history_unittest.cc
@@ -88,7 +88,7 @@ TEST_F(CompositorTimingHistoryTest, AllSequential_Commit) {
AdvanceNowBy(one_second);
timing_history_.WillDraw();
AdvanceNowBy(draw_duration);
- timing_history_.DidDraw(true, true, Now());
+ timing_history_.DidDraw(true, Now());
EXPECT_EQ(begin_main_frame_queue_duration,
timing_history_.BeginMainFrameQueueDurationCriticalEstimate());
@@ -138,7 +138,7 @@ TEST_F(CompositorTimingHistoryTest, AllSequential_BeginMainFrameAborted) {
AdvanceNowBy(one_second);
timing_history_.WillDraw();
AdvanceNowBy(draw_duration);
- timing_history_.DidDraw(false, false, Now());
+ timing_history_.DidDraw(false, Now());
EXPECT_EQ(base::TimeDelta(),
timing_history_.BeginMainFrameQueueDurationCriticalEstimate());
diff --git a/chromium/cc/scheduler/scheduler.cc b/chromium/cc/scheduler/scheduler.cc
index a3331aa3b70..d53df70e95c 100644
--- a/chromium/cc/scheduler/scheduler.cc
+++ b/chromium/cc/scheduler/scheduler.cc
@@ -9,7 +9,6 @@
#include "base/auto_reset.h"
#include "base/logging.h"
#include "base/memory/ptr_util.h"
-#include "base/profiler/scoped_tracker.h"
#include "base/single_thread_task_runner.h"
#include "base/trace_event/trace_event.h"
#include "base/trace_event/trace_event_argument.h"
@@ -573,14 +572,12 @@ void Scheduler::DrawIfPossible() {
bool drawing_with_new_active_tree =
state_machine_.active_tree_needs_first_draw() &&
!state_machine_.previous_pending_tree_was_impl_side();
- bool main_thread_missed_last_deadline =
- state_machine_.main_thread_missed_last_deadline();
compositor_timing_history_->WillDraw();
state_machine_.WillDraw();
DrawResult result = client_->ScheduledActionDrawIfPossible();
state_machine_.DidDraw(result);
compositor_timing_history_->DidDraw(
- drawing_with_new_active_tree, main_thread_missed_last_deadline,
+ drawing_with_new_active_tree,
begin_impl_frame_tracker_.DangerousMethodCurrentOrLast().frame_time);
}
@@ -588,14 +585,12 @@ void Scheduler::DrawForced() {
bool drawing_with_new_active_tree =
state_machine_.active_tree_needs_first_draw() &&
!state_machine_.previous_pending_tree_was_impl_side();
- bool main_thread_missed_last_deadline =
- state_machine_.main_thread_missed_last_deadline();
compositor_timing_history_->WillDraw();
state_machine_.WillDraw();
DrawResult result = client_->ScheduledActionDrawForced();
state_machine_.DidDraw(result);
compositor_timing_history_->DidDraw(
- drawing_with_new_active_tree, main_thread_missed_last_deadline,
+ drawing_with_new_active_tree,
begin_impl_frame_tracker_.DangerousMethodCurrentOrLast().frame_time);
}
diff --git a/chromium/cc/scheduler/scheduler.h b/chromium/cc/scheduler/scheduler.h
index fb354cdee63..2fa0e7114b7 100644
--- a/chromium/cc/scheduler/scheduler.h
+++ b/chromium/cc/scheduler/scheduler.h
@@ -5,7 +5,6 @@
#ifndef CC_SCHEDULER_SCHEDULER_H_
#define CC_SCHEDULER_SCHEDULER_H_
-#include <deque>
#include <memory>
#include <string>
diff --git a/chromium/cc/scheduler/scheduler_state_machine.cc b/chromium/cc/scheduler/scheduler_state_machine.cc
index f75966b4ebc..d2f6b201ea2 100644
--- a/chromium/cc/scheduler/scheduler_state_machine.cc
+++ b/chromium/cc/scheduler/scheduler_state_machine.cc
@@ -246,34 +246,35 @@ bool SchedulerStateMachine::PendingDrawsShouldBeAborted() const {
if (resourceless_draw_)
return is_layer_tree_frame_sink_lost || !can_draw_;
- // These are all the cases where we normally cannot or do not want to draw
- // but, if needs_redraw_ is true and we do not draw to make forward progress,
- // we might deadlock with the main thread.
- // This should be a superset of PendingActivationsShouldBeForced() since
- // activation of the pending tree is blocked by drawing of the active tree and
- // the main thread might be blocked on activation of the most recent commit.
+ // These are all the cases where we normally cannot or do not want
+ // to draw but, if |needs_redraw_| is true and we do not draw to
+ // make forward progress, we might deadlock with the main
+ // thread. This should be a superset of ShouldAbortCurrentFrame()
+ // since activation of the pending tree is blocked by drawing of the
+ // active tree and the main thread might be blocked on activation of
+ // the most recent commit.
return is_layer_tree_frame_sink_lost || !can_draw_ || !visible_ ||
begin_frame_source_paused_;
}
-bool SchedulerStateMachine::PendingActivationsShouldBeForced() const {
- // There is no output surface to trigger our activations.
- // If we do not force activations to make forward progress, we might deadlock
- // with the main thread.
+bool SchedulerStateMachine::ShouldAbortCurrentFrame() const {
+ // Abort the frame if there is no output surface to trigger our
+ // activations, avoiding deadlock with the main thread.
if (layer_tree_frame_sink_state_ == LAYER_TREE_FRAME_SINK_NONE)
return true;
- // If we're not visible, we should force activation.
- // Since we set RequiresHighResToDraw when becoming visible, we ensure that we
- // don't checkerboard until all visible resources are done. Furthermore, if we
- // do keep the pending tree around, when becoming visible we might activate
- // prematurely causing RequiresHighResToDraw flag to be reset. In all cases,
- // we can simply activate on becoming invisible since we don't need to draw
+ // If we're not visible, we should just abort the frame. Since we
+ // set RequiresHighResToDraw when becoming visible, we ensure that
+ // we don't checkerboard until all visible resources are
+ // done. Furthermore, if we do keep the pending tree around, when
+ // becoming visible we might activate prematurely causing
+ // RequiresHighResToDraw flag to be reset. In all cases, we can
+ // simply activate on becoming invisible since we don't need to draw
// the active tree when we're in this state.
if (!visible_)
return true;
- // Force pending activations when viz::BeginFrameSource is paused to avoid
+ // Abort the frame when viz::BeginFrameSource is paused to avoid
// deadlocking the main thread.
if (begin_frame_source_paused_)
return true;
@@ -366,8 +367,7 @@ bool SchedulerStateMachine::ShouldActivateSyncTree() const {
if (active_tree_needs_first_draw_)
return false;
- // If we want to force activation, do so ASAP.
- if (PendingActivationsShouldBeForced())
+ if (ShouldAbortCurrentFrame())
return true;
// At this point, only activate if we are ready to activate.
@@ -526,6 +526,11 @@ bool SchedulerStateMachine::ShouldCommit() const {
}
bool SchedulerStateMachine::ShouldPrepareTiles() const {
+ // In full-pipeline mode, we need to prepare tiles ASAP to ensure that we
+ // don't get stuck.
+ if (settings_.wait_for_all_pipeline_stages_before_draw)
+ return needs_prepare_tiles_;
+
// Do not prepare tiles if we've already done so in commit or impl side
// invalidation.
if (did_prepare_tiles_)
@@ -592,6 +597,8 @@ bool SchedulerStateMachine::ShouldPerformImplSideInvalidation() const {
// Only perform impl side invalidation after the frame ends so that we wait
// for any commit to happen before invalidating.
+ // TODO(khushalsagar): Invalidate at the beginning of the frame if there is no
+ // commit request from the main thread.
if (begin_impl_frame_state_ != BEGIN_IMPL_FRAME_STATE_INSIDE_DEADLINE)
return false;
@@ -1014,8 +1021,8 @@ SchedulerStateMachine::CurrentBeginImplFrameDeadlineMode() const {
bool SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately()
const {
- // If we just forced activation, we should end the deadline right now.
- if (PendingActivationsShouldBeForced() && !has_pending_tree_)
+ // If we aborted the current frame we should end the deadline right now.
+ if (ShouldAbortCurrentFrame() && !has_pending_tree_)
return true;
// Throttle the deadline on CompositorFrameAck since we wont draw and submit
@@ -1055,21 +1062,39 @@ bool SchedulerStateMachine::ShouldBlockDeadlineIndefinitely() const {
return false;
}
- // Avoid blocking when invisible / frame sink lost / can't draw, i.e. when
- // PendingDrawsShouldBeAborted is true.
- if (PendingDrawsShouldBeAborted())
+ // Avoid blocking for any reason if we don't have a layer tree frame sink or
+ // are invisible.
+ if (layer_tree_frame_sink_state_ == LAYER_TREE_FRAME_SINK_NONE)
return false;
- // Wait for all pipeline stages.
+ if (!visible_)
+ return false;
+
+ // Wait for main frame to be ready for commits if in full-pipe mode, so that
+ // we ensure we block during renderer initialization. In commit_to_active_tree
+ // mode, we cannot block for defer_commits_, as this may negatively affect
+ // animation smoothness during resize or orientation changes.
+ if (defer_commits_ && settings_.wait_for_all_pipeline_stages_before_draw)
+ return true;
+
+ // Wait for main frame if one is in progress or about to be started.
if (ShouldSendBeginMainFrame())
return true;
if (begin_main_frame_state_ != BEGIN_MAIN_FRAME_STATE_IDLE)
return true;
+ // Wait for tiles and activation.
if (has_pending_tree_)
return true;
+ // Avoid blocking for draw when we can't draw. We block in the above cases
+ // even if we cannot draw, because we may still be waiting for the first
+ // active tree.
+ if (!can_draw_)
+ return false;
+
+ // Wait for remaining tiles and draw.
if (!active_tree_is_ready_to_draw_)
return true;
diff --git a/chromium/cc/scheduler/scheduler_state_machine.h b/chromium/cc/scheduler/scheduler_state_machine.h
index 3370c63e616..9985bfe6a40 100644
--- a/chromium/cc/scheduler/scheduler_state_machine.h
+++ b/chromium/cc/scheduler/scheduler_state_machine.h
@@ -305,9 +305,7 @@ class CC_EXPORT SchedulerStateMachine {
bool ShouldTriggerBeginImplFrameDeadlineImmediately() const;
bool ShouldBlockDeadlineIndefinitely() const;
- // True if we need to force activations to make forward progress.
- // TODO(sunnyps): Rename this to ShouldAbortCurrentFrame or similar.
- bool PendingActivationsShouldBeForced() const;
+ bool ShouldAbortCurrentFrame() const;
bool ShouldBeginLayerTreeFrameSinkCreation() const;
bool ShouldDraw() const;
diff --git a/chromium/cc/scheduler/scheduler_state_machine_unittest.cc b/chromium/cc/scheduler/scheduler_state_machine_unittest.cc
index 86516f56b9c..9e77c27c73f 100644
--- a/chromium/cc/scheduler/scheduler_state_machine_unittest.cc
+++ b/chromium/cc/scheduler/scheduler_state_machine_unittest.cc
@@ -146,8 +146,8 @@ class StateMachine : public SchedulerStateMachine {
bool CanDraw() const { return can_draw_; }
bool Visible() const { return visible_; }
- bool PendingActivationsShouldBeForced() const {
- return SchedulerStateMachine::PendingActivationsShouldBeForced();
+ bool ShouldAbortCurrentFrame() const {
+ return SchedulerStateMachine::ShouldAbortCurrentFrame();
}
bool has_pending_tree() const { return has_pending_tree_; }
@@ -159,6 +159,7 @@ class StateMachine : public SchedulerStateMachine {
return needs_impl_side_invalidation_;
}
+ using SchedulerStateMachine::ShouldPrepareTiles;
using SchedulerStateMachine::ShouldTriggerBeginImplFrameDeadlineImmediately;
using SchedulerStateMachine::ProactiveBeginFrameWanted;
using SchedulerStateMachine::WillCommit;
@@ -1181,6 +1182,12 @@ TEST(SchedulerStateMachineTest, TestFullCycleWithCommitToActive) {
state.OnBeginImplFrameDeadline();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_DRAW_IF_POSSIBLE);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
+
+ // When commits are deferred, we don't block the deadline.
+ state.SetDeferCommits(true);
+ state.OnBeginImplFrame(0, 13);
+ EXPECT_NE(SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED,
+ state.CurrentBeginImplFrameDeadlineMode());
}
TEST(SchedulerStateMachineTest, TestFullCycleWithCommitRequestInbetween) {
@@ -1711,7 +1718,7 @@ TEST(SchedulerStateMachineTest,
}
TEST(SchedulerStateMachineTest,
- TestPendingActivationsShouldBeForcedAfterLostLayerTreeFrameSink) {
+ TestShouldAbortCurrentFrameAfterLostLayerTreeFrameSink) {
SchedulerSettings default_scheduler_settings;
StateMachine state(default_scheduler_settings);
SET_UP_STATE(state)
@@ -1726,7 +1733,7 @@ TEST(SchedulerStateMachineTest,
state.NotifyReadyToCommit();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
- EXPECT_TRUE(state.PendingActivationsShouldBeForced());
+ EXPECT_TRUE(state.ShouldAbortCurrentFrame());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
EXPECT_TRUE(state.PendingDrawsShouldBeAborted());
@@ -1816,7 +1823,7 @@ TEST(SchedulerStateMachineTest,
// because we are not visible.
state.NotifyBeginMainFrameStarted();
state.NotifyReadyToCommit();
- EXPECT_TRUE(state.PendingActivationsShouldBeForced());
+ EXPECT_TRUE(state.ShouldAbortCurrentFrame());
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_COMMIT);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
EXPECT_TRUE(state.active_tree_needs_first_draw());
@@ -2066,7 +2073,7 @@ TEST(SchedulerStateMachineTest, TestTriggerDeadlineImmediatelyWhenInvisible) {
state.SetVisible(false);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
- EXPECT_TRUE(state.PendingActivationsShouldBeForced());
+ EXPECT_TRUE(state.ShouldAbortCurrentFrame());
EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
}
@@ -2086,7 +2093,7 @@ TEST(SchedulerStateMachineTest,
state.SetBeginFrameSourcePaused(true);
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
- EXPECT_TRUE(state.PendingActivationsShouldBeForced());
+ EXPECT_TRUE(state.ShouldAbortCurrentFrame());
EXPECT_TRUE(state.ShouldTriggerBeginImplFrameDeadlineImmediately());
}
@@ -2432,11 +2439,22 @@ TEST(SchedulerStateMachineTest, TestFullPipelineMode) {
// Start clean and set commit.
state.SetNeedsBeginMainFrame();
+ // While we are waiting for an main frame or pending tree activation, we
+ // should even block while we can't draw.
+ state.SetCanDraw(false);
+
// Begin the frame.
state.OnBeginImplFrame(0, 10);
- // Deadline immediately enters blocking mode, because we need a main frame.
+ // We are blocking because we need a main frame.
EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED,
state.CurrentBeginImplFrameDeadlineMode());
+
+ // Even if main thread defers commits, we still need to wait for it.
+ state.SetDeferCommits(true);
+ EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED,
+ state.CurrentBeginImplFrameDeadlineMode());
+ state.SetDeferCommits(false);
+
EXPECT_ACTION_UPDATE_STATE(
SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME);
EXPECT_MAIN_FRAME_STATE(SchedulerStateMachine::BEGIN_MAIN_FRAME_STATE_SENT);
@@ -2459,14 +2477,28 @@ TEST(SchedulerStateMachineTest, TestFullPipelineMode) {
// We are blocking on activation.
EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED,
state.CurrentBeginImplFrameDeadlineMode());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
+
+ // We should prepare tiles even though we are not in the deadline, otherwise
+ // we would get stuck here.
+ EXPECT_FALSE(state.ShouldPrepareTiles());
+ state.SetNeedsPrepareTiles();
+ EXPECT_TRUE(state.ShouldPrepareTiles());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_PREPARE_TILES);
// Ready to activate, but not draw.
state.NotifyReadyToActivate();
EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_ACTIVATE_SYNC_TREE);
- EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
- // We are blocking on ready to draw.
+ // We should no longer block, because can_draw is still false, and we are no
+ // longer waiting for activation.
+ EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_IMMEDIATE,
+ state.CurrentBeginImplFrameDeadlineMode());
+
+ // However, we should continue to block on ready to draw if we can draw.
+ state.SetCanDraw(true);
EXPECT_EQ(SchedulerStateMachine::BEGIN_IMPL_FRAME_DEADLINE_MODE_BLOCKED,
state.CurrentBeginImplFrameDeadlineMode());
+ EXPECT_ACTION_UPDATE_STATE(SchedulerStateMachine::ACTION_NONE);
// Ready to draw triggers immediate deadline.
state.NotifyReadyToDraw();