summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorbrianderson <brianderson@chromium.org>2016-02-19 21:21:14 -0800
committerCommit bot <commit-bot@chromium.org>2016-02-20 05:22:17 +0000
commitbb917ddb01a8c3e373d6df02046c69ff00b07254 (patch)
tree5baac1ba4ed5552d7336b7c6242b68cbe8d792ea
parentfe2fee44edf473f083d7b51873d6c9334da8cae2 (diff)
downloadchromium_src-bb917ddb01a8c3e373d6df02046c69ff00b07254.zip
chromium_src-bb917ddb01a8c3e373d6df02046c69ff00b07254.tar.gz
chromium_src-bb917ddb01a8c3e373d6df02046c69ff00b07254.tar.bz2
cc: Add MainAndImplFrameTimeDelta UMA.
Records how often the main and impl threads are synchronized when the compositor draws with a new active tree. Some DCHECKS are disabled for the synchronous compositor because draws can come in at any time or not at all. BUG=582749 CQ_INCLUDE_TRYBOTS=tryserver.blink:linux_blink_rel Review URL: https://codereview.chromium.org/1681393003 Cr-Commit-Position: refs/heads/master@{#376628}
-rw-r--r--cc/scheduler/compositor_timing_history.cc79
-rw-r--r--cc/scheduler/compositor_timing_history.h17
-rw-r--r--cc/scheduler/compositor_timing_history_unittest.cc25
-rw-r--r--cc/scheduler/scheduler.cc18
-rw-r--r--cc/scheduler/scheduler_state_machine.cc1
-rw-r--r--cc/scheduler/scheduler_unittest.cc3
-rw-r--r--cc/test/scheduler_test_common.cc8
-rw-r--r--cc/test/scheduler_test_common.h6
-rw-r--r--cc/trees/proxy_impl.cc6
-rw-r--r--cc/trees/single_thread_proxy.cc1
-rw-r--r--tools/metrics/histograms/histograms.xml13
11 files changed, 137 insertions, 40 deletions
diff --git a/cc/scheduler/compositor_timing_history.cc b/cc/scheduler/compositor_timing_history.cc
index f546062..ab1cd04 100644
--- a/cc/scheduler/compositor_timing_history.cc
+++ b/cc/scheduler/compositor_timing_history.cc
@@ -50,6 +50,9 @@ class CompositorTimingHistory::UMAReporter {
base::TimeDelta estimate,
bool affects_estimate) = 0;
virtual void AddSwapToAckLatency(base::TimeDelta duration) = 0;
+
+ // Synchronization measurements
+ virtual void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) = 0;
};
namespace {
@@ -217,6 +220,11 @@ class RendererUMAReporter : public CompositorTimingHistory::UMAReporter {
UMA_HISTOGRAM_CUSTOM_TIMES_MICROS("Scheduling.Renderer.SwapToAckLatency",
duration);
}
+
+ void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) override {
+ UMA_HISTOGRAM_CUSTOM_TIMES_MICROS(
+ "Scheduling.Renderer.MainAndImplFrameTimeDelta", delta);
+ }
};
class BrowserUMAReporter : public CompositorTimingHistory::UMAReporter {
@@ -298,6 +306,11 @@ class BrowserUMAReporter : public CompositorTimingHistory::UMAReporter {
UMA_HISTOGRAM_CUSTOM_TIMES_MICROS("Scheduling.Browser.SwapToAckLatency",
duration);
}
+
+ void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) override {
+ UMA_HISTOGRAM_CUSTOM_TIMES_MICROS(
+ "Scheduling.Browser.MainAndImplFrameTimeDelta", delta);
+ }
};
class NullUMAReporter : public CompositorTimingHistory::UMAReporter {
@@ -332,14 +345,18 @@ class NullUMAReporter : public CompositorTimingHistory::UMAReporter {
base::TimeDelta estimate,
bool affects_estimate) override {}
void AddSwapToAckLatency(base::TimeDelta duration) override {}
+ void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) override {}
};
} // namespace
CompositorTimingHistory::CompositorTimingHistory(
+ bool using_synchronous_renderer_compositor,
UMACategory uma_category,
RenderingStatsInstrumentation* rendering_stats_instrumentation)
- : enabled_(false),
+ : using_synchronous_renderer_compositor_(
+ using_synchronous_renderer_compositor),
+ enabled_(false),
did_send_begin_main_frame_(false),
begin_main_frame_needed_continuously_(false),
begin_main_frame_committing_continuously_(false),
@@ -478,6 +495,12 @@ base::TimeDelta CompositorTimingHistory::DrawDurationEstimate() const {
return draw_duration_history_.Percentile(kDrawEstimationPercentile);
}
+void CompositorTimingHistory::DidCreateAndInitializeOutputSurface() {
+ // After we get a new output surface, we won't get a spurious
+ // swap ack from the old output surface.
+ swap_start_time_ = base::TimeTicks();
+}
+
void CompositorTimingHistory::WillBeginImplFrame(
bool new_active_tree_is_likely) {
// The check for whether a BeginMainFrame was sent anytime between two
@@ -505,10 +528,15 @@ void CompositorTimingHistory::BeginImplFrameNotExpectedSoon() {
SetCompositorDrawingContinuously(false);
}
-void CompositorTimingHistory::WillBeginMainFrame(bool on_critical_path) {
+void CompositorTimingHistory::WillBeginMainFrame(
+ bool on_critical_path,
+ base::TimeTicks main_frame_time) {
DCHECK_EQ(base::TimeTicks(), begin_main_frame_sent_time_);
+ DCHECK_EQ(base::TimeTicks(), begin_main_frame_frame_time_);
+
begin_main_frame_on_critical_path_ = on_critical_path;
begin_main_frame_sent_time_ = Now();
+ begin_main_frame_frame_time_ = main_frame_time;
did_send_begin_main_frame_ = true;
SetBeginMainFrameNeededContinuously(true);
@@ -524,11 +552,15 @@ void CompositorTimingHistory::BeginMainFrameStarted(
void CompositorTimingHistory::BeginMainFrameAborted() {
SetBeginMainFrameCommittingContinuously(false);
DidBeginMainFrame();
+ begin_main_frame_frame_time_ = base::TimeTicks();
}
void CompositorTimingHistory::DidCommit() {
+ DCHECK_EQ(base::TimeTicks(), pending_tree_main_frame_time_);
SetBeginMainFrameCommittingContinuously(true);
DidBeginMainFrame();
+ pending_tree_main_frame_time_ = begin_main_frame_frame_time_;
+ begin_main_frame_frame_time_ = base::TimeTicks();
}
void CompositorTimingHistory::DidBeginMainFrame() {
@@ -666,7 +698,13 @@ void CompositorTimingHistory::DidActivate() {
if (enabled_)
activate_duration_history_.InsertSample(activate_duration);
+ // The synchronous compositor doesn't necessarily draw every new active tree.
+ if (!using_synchronous_renderer_compositor_)
+ DCHECK_EQ(base::TimeTicks(), active_tree_main_frame_time_);
+ active_tree_main_frame_time_ = pending_tree_main_frame_time_;
+
activate_start_time_ = base::TimeTicks();
+ pending_tree_main_frame_time_ = base::TimeTicks();
}
void CompositorTimingHistory::WillDraw() {
@@ -674,7 +712,13 @@ void CompositorTimingHistory::WillDraw() {
draw_start_time_ = Now();
}
-void CompositorTimingHistory::DidDraw(bool used_new_active_tree) {
+void CompositorTimingHistory::DrawAborted() {
+ active_tree_main_frame_time_ = base::TimeTicks();
+}
+
+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();
base::TimeDelta draw_duration = draw_end_time - draw_start_time_;
@@ -699,13 +743,26 @@ void CompositorTimingHistory::DidDraw(bool used_new_active_tree) {
}
draw_end_time_prev_ = draw_end_time;
- if (begin_main_frame_committing_continuously_ && used_new_active_tree) {
- if (!new_active_tree_draw_end_time_prev_.is_null()) {
- base::TimeDelta draw_interval =
- draw_end_time - new_active_tree_draw_end_time_prev_;
- uma_reporter_->AddCommitInterval(draw_interval);
+ if (used_new_active_tree) {
+ DCHECK_NE(base::TimeTicks(), active_tree_main_frame_time_);
+ base::TimeDelta main_and_impl_delta =
+ impl_frame_time - active_tree_main_frame_time_;
+ DCHECK_GE(main_and_impl_delta, base::TimeDelta());
+ if (!using_synchronous_renderer_compositor_) {
+ DCHECK_EQ(main_thread_missed_last_deadline,
+ !main_and_impl_delta.is_zero());
+ }
+ uma_reporter_->AddMainAndImplFrameTimeDelta(main_and_impl_delta);
+ active_tree_main_frame_time_ = base::TimeTicks();
+
+ if (begin_main_frame_committing_continuously_) {
+ if (!new_active_tree_draw_end_time_prev_.is_null()) {
+ base::TimeDelta draw_interval =
+ draw_end_time - new_active_tree_draw_end_time_prev_;
+ uma_reporter_->AddCommitInterval(draw_interval);
+ }
+ new_active_tree_draw_end_time_prev_ = draw_end_time;
}
- new_active_tree_draw_end_time_prev_ = draw_end_time;
}
draw_start_time_ = base::TimeTicks();
@@ -723,8 +780,4 @@ void CompositorTimingHistory::DidSwapBuffersComplete() {
swap_start_time_ = base::TimeTicks();
}
-void CompositorTimingHistory::DidSwapBuffersReset() {
- swap_start_time_ = base::TimeTicks();
-}
-
} // namespace cc
diff --git a/cc/scheduler/compositor_timing_history.h b/cc/scheduler/compositor_timing_history.h
index 11dfc00..a7c58dd 100644
--- a/cc/scheduler/compositor_timing_history.h
+++ b/cc/scheduler/compositor_timing_history.h
@@ -29,6 +29,7 @@ class CC_EXPORT CompositorTimingHistory {
class UMAReporter;
CompositorTimingHistory(
+ bool using_synchronous_renderer_compositor,
UMACategory uma_category,
RenderingStatsInstrumentation* rendering_stats_instrumentation);
virtual ~CompositorTimingHistory();
@@ -49,12 +50,16 @@ class CC_EXPORT CompositorTimingHistory {
virtual base::TimeDelta ActivateDurationEstimate() const;
virtual base::TimeDelta DrawDurationEstimate() const;
+ // State that affects when events should be expected/recorded/reported.
void SetRecordingEnabled(bool enabled);
+ void DidCreateAndInitializeOutputSurface();
+ // Events to be timed.
void WillBeginImplFrame(bool new_active_tree_is_likely);
void WillFinishImplFrame(bool needs_redraw);
void BeginImplFrameNotExpectedSoon();
- void WillBeginMainFrame(bool on_critical_path);
+ void WillBeginMainFrame(bool on_critical_path,
+ base::TimeTicks main_frame_time);
void BeginMainFrameStarted(base::TimeTicks main_thread_start_time);
void BeginMainFrameAborted();
void DidCommit();
@@ -63,11 +68,13 @@ class CC_EXPORT CompositorTimingHistory {
void ReadyToActivate();
void WillActivate();
void DidActivate();
+ void DrawAborted();
void WillDraw();
- void DidDraw(bool used_new_active_tree);
+ void DidDraw(bool used_new_active_tree,
+ bool main_thread_missed_last_deadline,
+ base::TimeTicks impl_frame_time);
void DidSwapBuffers();
void DidSwapBuffersComplete();
- void DidSwapBuffersReset();
protected:
void DidBeginMainFrame();
@@ -79,6 +86,7 @@ class CC_EXPORT CompositorTimingHistory {
static scoped_ptr<UMAReporter> CreateUMAReporter(UMACategory category);
virtual base::TimeTicks Now() const;
+ bool using_synchronous_renderer_compositor_;
bool enabled_;
// Used to calculate frame rates of Main and Impl threads.
@@ -101,11 +109,14 @@ class CC_EXPORT CompositorTimingHistory {
RollingTimeDeltaHistory draw_duration_history_;
bool begin_main_frame_on_critical_path_;
+ base::TimeTicks begin_main_frame_frame_time_;
base::TimeTicks begin_main_frame_sent_time_;
base::TimeTicks begin_main_frame_start_time_;
base::TimeTicks begin_main_frame_end_time_;
+ base::TimeTicks pending_tree_main_frame_time_;
base::TimeTicks prepare_tiles_start_time_;
base::TimeTicks activate_start_time_;
+ base::TimeTicks active_tree_main_frame_time_;
base::TimeTicks draw_start_time_;
base::TimeTicks swap_start_time_;
diff --git a/cc/scheduler/compositor_timing_history_unittest.cc b/cc/scheduler/compositor_timing_history_unittest.cc
index 900367f..f57d443 100644
--- a/cc/scheduler/compositor_timing_history_unittest.cc
+++ b/cc/scheduler/compositor_timing_history_unittest.cc
@@ -17,7 +17,8 @@ class TestCompositorTimingHistory : public CompositorTimingHistory {
public:
TestCompositorTimingHistory(CompositorTimingHistoryTest* test,
RenderingStatsInstrumentation* rendering_stats)
- : CompositorTimingHistory(NULL_UMA, rendering_stats), test_(test) {}
+ : CompositorTimingHistory(false, NULL_UMA, rendering_stats),
+ test_(test) {}
protected:
base::TimeTicks Now() const override;
@@ -68,7 +69,7 @@ TEST_F(CompositorTimingHistoryTest, AllSequential_Commit) {
base::TimeDelta activate_duration = base::TimeDelta::FromMilliseconds(4);
base::TimeDelta draw_duration = base::TimeDelta::FromMilliseconds(5);
- timing_history_.WillBeginMainFrame(true);
+ timing_history_.WillBeginMainFrame(true, Now());
AdvanceNowBy(begin_main_frame_queue_duration);
timing_history_.BeginMainFrameStarted(Now());
AdvanceNowBy(begin_main_frame_start_to_commit_duration);
@@ -87,7 +88,7 @@ TEST_F(CompositorTimingHistoryTest, AllSequential_Commit) {
AdvanceNowBy(one_second);
timing_history_.WillDraw();
AdvanceNowBy(draw_duration);
- timing_history_.DidDraw(true);
+ timing_history_.DidDraw(true, true, Now());
EXPECT_EQ(begin_main_frame_queue_duration,
timing_history_.BeginMainFrameQueueDurationCriticalEstimate());
@@ -126,7 +127,7 @@ TEST_F(CompositorTimingHistoryTest, AllSequential_BeginMainFrameAborted) {
base::TimeDelta activate_duration = base::TimeDelta::FromMilliseconds(4);
base::TimeDelta draw_duration = base::TimeDelta::FromMilliseconds(5);
- timing_history_.WillBeginMainFrame(true);
+ timing_history_.WillBeginMainFrame(false, Now());
AdvanceNowBy(begin_main_frame_queue_duration);
timing_history_.BeginMainFrameStarted(Now());
AdvanceNowBy(begin_main_frame_start_to_commit_duration);
@@ -146,9 +147,9 @@ TEST_F(CompositorTimingHistoryTest, AllSequential_BeginMainFrameAborted) {
AdvanceNowBy(one_second);
timing_history_.WillDraw();
AdvanceNowBy(draw_duration);
- timing_history_.DidDraw(true);
+ timing_history_.DidDraw(false, false, Now());
- EXPECT_EQ(begin_main_frame_queue_duration,
+ EXPECT_EQ(base::TimeDelta(),
timing_history_.BeginMainFrameQueueDurationCriticalEstimate());
EXPECT_EQ(begin_main_frame_queue_duration,
timing_history_.BeginMainFrameQueueDurationNotCriticalEstimate());
@@ -179,13 +180,13 @@ TEST_F(CompositorTimingHistoryTest, BeginMainFrame_CriticalFaster) {
base::TimeDelta begin_main_frame_start_to_commit_duration =
base::TimeDelta::FromMilliseconds(1);
- timing_history_.WillBeginMainFrame(true);
+ timing_history_.WillBeginMainFrame(true, Now());
AdvanceNowBy(begin_main_frame_queue_duration_critical);
timing_history_.BeginMainFrameStarted(Now());
AdvanceNowBy(begin_main_frame_start_to_commit_duration);
timing_history_.BeginMainFrameAborted();
- timing_history_.WillBeginMainFrame(false);
+ timing_history_.WillBeginMainFrame(false, Now());
AdvanceNowBy(begin_main_frame_queue_duration_not_critical);
timing_history_.BeginMainFrameStarted(Now());
AdvanceNowBy(begin_main_frame_start_to_commit_duration);
@@ -219,7 +220,7 @@ TEST_F(CompositorTimingHistoryTest, BeginMainFrames_OldCriticalSlower) {
base::TimeDelta::FromMilliseconds(1);
// A single critical frame that is slow.
- timing_history_.WillBeginMainFrame(true);
+ timing_history_.WillBeginMainFrame(true, Now());
AdvanceNowBy(begin_main_frame_queue_duration_critical);
timing_history_.BeginMainFrameStarted(Now());
AdvanceNowBy(begin_main_frame_start_to_commit_duration);
@@ -228,7 +229,7 @@ TEST_F(CompositorTimingHistoryTest, BeginMainFrames_OldCriticalSlower) {
// A bunch of faster non critical frames that are newer.
for (int i = 0; i < 100; i++) {
- timing_history_.WillBeginMainFrame(false);
+ timing_history_.WillBeginMainFrame(false, Now());
AdvanceNowBy(begin_main_frame_queue_duration_not_critical);
timing_history_.BeginMainFrameStarted(Now());
AdvanceNowBy(begin_main_frame_start_to_commit_duration);
@@ -265,7 +266,7 @@ TEST_F(CompositorTimingHistoryTest, BeginMainFrames_NewCriticalSlower) {
base::TimeDelta::FromMilliseconds(1);
// A single non critical frame that is fast.
- timing_history_.WillBeginMainFrame(false);
+ timing_history_.WillBeginMainFrame(false, Now());
AdvanceNowBy(begin_main_frame_queue_duration_not_critical);
timing_history_.BeginMainFrameStarted(Now());
AdvanceNowBy(begin_main_frame_start_to_commit_duration);
@@ -273,7 +274,7 @@ TEST_F(CompositorTimingHistoryTest, BeginMainFrames_NewCriticalSlower) {
// A bunch of slower critical frames that are newer.
for (int i = 0; i < 100; i++) {
- timing_history_.WillBeginMainFrame(true);
+ timing_history_.WillBeginMainFrame(true, Now());
AdvanceNowBy(begin_main_frame_queue_duration_critical);
timing_history_.BeginMainFrameStarted(Now());
AdvanceNowBy(begin_main_frame_start_to_commit_duration);
diff --git a/cc/scheduler/scheduler.cc b/cc/scheduler/scheduler.cc
index 499fae7..61607de 100644
--- a/cc/scheduler/scheduler.cc
+++ b/cc/scheduler/scheduler.cc
@@ -249,8 +249,8 @@ void Scheduler::DidCreateAndInitializeOutputSurface() {
TRACE_EVENT0("cc", "Scheduler::DidCreateAndInitializeOutputSurface");
DCHECK(!observing_frame_source_);
DCHECK(begin_impl_frame_deadline_task_.IsCancelled());
- compositor_timing_history_->DidSwapBuffersReset();
state_machine_.DidCreateAndInitializeOutputSurface();
+ compositor_timing_history_->DidCreateAndInitializeOutputSurface();
UpdateCompositorTimingHistoryRecordingEnabled();
ProcessScheduledActions();
}
@@ -663,21 +663,29 @@ void Scheduler::OnBeginImplFrameDeadline() {
void Scheduler::DrawAndSwapIfPossible() {
bool drawing_with_new_active_tree =
state_machine_.active_tree_needs_first_draw();
+ bool main_thread_missed_last_deadline =
+ state_machine_.main_thread_missed_last_deadline();
compositor_timing_history_->WillDraw();
state_machine_.WillDraw();
DrawResult result = client_->ScheduledActionDrawAndSwapIfPossible();
state_machine_.DidDraw(result);
- compositor_timing_history_->DidDraw(drawing_with_new_active_tree);
+ compositor_timing_history_->DidDraw(
+ drawing_with_new_active_tree, main_thread_missed_last_deadline,
+ begin_impl_frame_tracker_.DangerousMethodCurrentOrLast().frame_time);
}
void Scheduler::DrawAndSwapForced() {
bool drawing_with_new_active_tree =
state_machine_.active_tree_needs_first_draw();
+ bool main_thread_missed_last_deadline =
+ state_machine_.main_thread_missed_last_deadline();
compositor_timing_history_->WillDraw();
state_machine_.WillDraw();
DrawResult result = client_->ScheduledActionDrawAndSwapForced();
state_machine_.DidDraw(result);
- compositor_timing_history_->DidDraw(drawing_with_new_active_tree);
+ compositor_timing_history_->DidDraw(
+ drawing_with_new_active_tree, main_thread_missed_last_deadline,
+ begin_impl_frame_tracker_.DangerousMethodCurrentOrLast().frame_time);
}
void Scheduler::SetDeferCommits(bool defer_commits) {
@@ -710,7 +718,8 @@ void Scheduler::ProcessScheduledActions() {
break;
case SchedulerStateMachine::ACTION_SEND_BEGIN_MAIN_FRAME:
compositor_timing_history_->WillBeginMainFrame(
- begin_main_frame_args_.on_critical_path);
+ begin_main_frame_args_.on_critical_path,
+ begin_main_frame_args_.frame_time);
state_machine_.WillSendBeginMainFrame();
// TODO(brianderson): Pass begin_main_frame_args_ directly to client.
client_->ScheduledActionSendBeginMainFrame(begin_main_frame_args_);
@@ -748,6 +757,7 @@ void Scheduler::ProcessScheduledActions() {
// No action is actually performed, but this allows the state machine to
// drain the pipeline without actually drawing.
state_machine_.AbortDrawAndSwap();
+ compositor_timing_history_->DrawAborted();
break;
}
case SchedulerStateMachine::ACTION_BEGIN_OUTPUT_SURFACE_CREATION:
diff --git a/cc/scheduler/scheduler_state_machine.cc b/cc/scheduler/scheduler_state_machine.cc
index a1314fa..23715ae 100644
--- a/cc/scheduler/scheduler_state_machine.cc
+++ b/cc/scheduler/scheduler_state_machine.cc
@@ -613,7 +613,6 @@ void SchedulerStateMachine::WillCommit(bool commit_has_no_updates) {
forced_redraw_state_ == FORCED_REDRAW_STATE_WAITING_FOR_DRAW) {
DCHECK(!has_pending_tree_);
needs_redraw_ = true;
- active_tree_needs_first_draw_ = true;
}
// This post-commit work is common to both completed and aborted commits.
diff --git a/cc/scheduler/scheduler_unittest.cc b/cc/scheduler/scheduler_unittest.cc
index 8b8193b..8989e04 100644
--- a/cc/scheduler/scheduler_unittest.cc
+++ b/cc/scheduler/scheduler_unittest.cc
@@ -263,7 +263,8 @@ class SchedulerTest : public testing::Test {
}
scoped_ptr<FakeCompositorTimingHistory> fake_compositor_timing_history =
- FakeCompositorTimingHistory::Create();
+ FakeCompositorTimingHistory::Create(
+ scheduler_settings_.using_synchronous_renderer_compositor);
fake_compositor_timing_history_ = fake_compositor_timing_history.get();
scheduler_ = TestScheduler::Create(
diff --git a/cc/test/scheduler_test_common.cc b/cc/test/scheduler_test_common.cc
index b6b1b2b..ef760d2 100644
--- a/cc/test/scheduler_test_common.cc
+++ b/cc/test/scheduler_test_common.cc
@@ -67,16 +67,20 @@ TestSyntheticBeginFrameSource::TestSyntheticBeginFrameSource(
TestSyntheticBeginFrameSource::~TestSyntheticBeginFrameSource() {
}
-scoped_ptr<FakeCompositorTimingHistory> FakeCompositorTimingHistory::Create() {
+scoped_ptr<FakeCompositorTimingHistory> FakeCompositorTimingHistory::Create(
+ bool using_synchronous_renderer_compositor) {
scoped_ptr<RenderingStatsInstrumentation> rendering_stats_instrumentation =
RenderingStatsInstrumentation::Create();
return make_scoped_ptr(new FakeCompositorTimingHistory(
+ using_synchronous_renderer_compositor,
std::move(rendering_stats_instrumentation)));
}
FakeCompositorTimingHistory::FakeCompositorTimingHistory(
+ bool using_synchronous_renderer_compositor,
scoped_ptr<RenderingStatsInstrumentation> rendering_stats_instrumentation)
- : CompositorTimingHistory(CompositorTimingHistory::NULL_UMA,
+ : CompositorTimingHistory(using_synchronous_renderer_compositor,
+ CompositorTimingHistory::NULL_UMA,
rendering_stats_instrumentation.get()),
rendering_stats_instrumentation_owned_(
std::move(rendering_stats_instrumentation)) {}
diff --git a/cc/test/scheduler_test_common.h b/cc/test/scheduler_test_common.h
index 3993c9f..d442aca 100644
--- a/cc/test/scheduler_test_common.h
+++ b/cc/test/scheduler_test_common.h
@@ -164,7 +164,8 @@ class TestSyntheticBeginFrameSource : public SyntheticBeginFrameSource {
class FakeCompositorTimingHistory : public CompositorTimingHistory {
public:
- static scoped_ptr<FakeCompositorTimingHistory> Create();
+ static scoped_ptr<FakeCompositorTimingHistory> Create(
+ bool using_synchronous_renderer_compositor);
~FakeCompositorTimingHistory() override;
void SetAllEstimatesTo(base::TimeDelta duration);
@@ -190,7 +191,8 @@ class FakeCompositorTimingHistory : public CompositorTimingHistory {
base::TimeDelta DrawDurationEstimate() const override;
protected:
- FakeCompositorTimingHistory(scoped_ptr<RenderingStatsInstrumentation>
+ FakeCompositorTimingHistory(bool using_synchronous_renderer_compositor,
+ scoped_ptr<RenderingStatsInstrumentation>
rendering_stats_instrumentation_owned);
scoped_ptr<RenderingStatsInstrumentation>
diff --git a/cc/trees/proxy_impl.cc b/cc/trees/proxy_impl.cc
index f9a1eab..aefd847 100644
--- a/cc/trees/proxy_impl.cc
+++ b/cc/trees/proxy_impl.cc
@@ -74,8 +74,10 @@ ProxyImpl::ProxyImpl(ChannelImpl* channel_impl,
layer_tree_host->settings().ToSchedulerSettings());
scoped_ptr<CompositorTimingHistory> compositor_timing_history(
- new CompositorTimingHistory(CompositorTimingHistory::RENDERER_UMA,
- rendering_stats_instrumentation_));
+ new CompositorTimingHistory(
+ scheduler_settings.using_synchronous_renderer_compositor,
+ CompositorTimingHistory::RENDERER_UMA,
+ rendering_stats_instrumentation_));
scheduler_ = Scheduler::Create(this, scheduler_settings, layer_tree_host_id_,
task_runner_provider_->ImplThreadTaskRunner(),
diff --git a/cc/trees/single_thread_proxy.cc b/cc/trees/single_thread_proxy.cc
index 5898c7a..571c78d 100644
--- a/cc/trees/single_thread_proxy.cc
+++ b/cc/trees/single_thread_proxy.cc
@@ -67,6 +67,7 @@ void SingleThreadProxy::Start(
scoped_ptr<CompositorTimingHistory> compositor_timing_history(
new CompositorTimingHistory(
+ scheduler_settings.using_synchronous_renderer_compositor,
CompositorTimingHistory::BROWSER_UMA,
layer_tree_host_->rendering_stats_instrumentation()));
diff --git a/tools/metrics/histograms/histograms.xml b/tools/metrics/histograms/histograms.xml
index 89ec16f..cf050a1 100644
--- a/tools/metrics/histograms/histograms.xml
+++ b/tools/metrics/histograms/histograms.xml
@@ -43581,6 +43581,18 @@ http://cs/file:chrome/histograms.xml - but prefer this file for new entries.
</summary>
</histogram>
+<histogram name="Scheduling.MainAndImplFrameTimeDelta" units="microseconds">
+ <owner>brianderson@chromium.org</owner>
+ <summary>
+ Recorded every time the compositor draws with a new active tree. A value of
+ 0 indicates the main-side started and finished within the same frame
+ interval as the impl-side. Positive values correspond to how old any
+ main-side updates are compared to the impl-side updates. If there are no
+ mid-frame updates, this metric is a good proxy for how well the main and
+ impl threads are synchronized.
+ </summary>
+</histogram>
+
<histogram name="Scheduling.PrepareTilesDuration" units="microseconds">
<owner>brianderson@chromium.org</owner>
<summary>
@@ -83318,6 +83330,7 @@ To add a new entry, add it with any value and run test to compute valid value.
<affected-histogram name="Scheduling.BeginMainFrameToCommitDuration"/>
<affected-histogram name="Scheduling.CommitToReadyToActivateDuration"/>
<affected-histogram name="Scheduling.DrawDuration"/>
+ <affected-histogram name="Scheduling.MainAndImplFrameTimeDelta"/>
<affected-histogram name="Scheduling.PrepareTilesDuration"/>
<affected-histogram name="Scheduling.SwapToAckLatency"/>
</histogram_suffixes>