summaryrefslogtreecommitdiff
path: root/chromium/cc/scheduler
diff options
context:
space:
mode:
authorAllan Sandfeld Jensen <allan.jensen@qt.io>2020-01-20 13:40:20 +0100
committerAllan Sandfeld Jensen <allan.jensen@qt.io>2020-01-22 12:41:23 +0000
commit7961cea6d1041e3e454dae6a1da660b453efd238 (patch)
treec0eeb4a9ff9ba32986289c1653d9608e53ccb444 /chromium/cc/scheduler
parentb7034d0803538058e5c9d904ef03cf5eab34f6ef (diff)
downloadqtwebengine-chromium-7961cea6d1041e3e454dae6a1da660b453efd238.tar.gz
BASELINE: Update Chromium to 78.0.3904.130
Change-Id: If185e0c0061b3437531c97c9c8c78f239352a68b Reviewed-by: Allan Sandfeld Jensen <allan.jensen@qt.io>
Diffstat (limited to 'chromium/cc/scheduler')
-rw-r--r--chromium/cc/scheduler/compositor_frame_reporter.cc227
-rw-r--r--chromium/cc/scheduler/compositor_frame_reporter.h129
-rw-r--r--chromium/cc/scheduler/compositor_frame_reporter_unittest.cc298
-rw-r--r--chromium/cc/scheduler/compositor_frame_reporting_controller.cc217
-rw-r--r--chromium/cc/scheduler/compositor_frame_reporting_controller.h93
-rw-r--r--chromium/cc/scheduler/compositor_frame_reporting_controller_unittest.cc234
-rw-r--r--chromium/cc/scheduler/compositor_timing_history.cc954
-rw-r--r--chromium/cc/scheduler/compositor_timing_history.h183
-rw-r--r--chromium/cc/scheduler/compositor_timing_history_unittest.cc455
-rw-r--r--chromium/cc/scheduler/scheduler.cc2
-rw-r--r--chromium/cc/scheduler/scheduler_state_machine.cc12
-rw-r--r--chromium/cc/scheduler/scheduler_state_machine_unittest.cc5
-rw-r--r--chromium/cc/scheduler/scheduler_unittest.cc8
13 files changed, 13 insertions, 2804 deletions
diff --git a/chromium/cc/scheduler/compositor_frame_reporter.cc b/chromium/cc/scheduler/compositor_frame_reporter.cc
deleted file mode 100644
index 1a41c5c6fec..00000000000
--- a/chromium/cc/scheduler/compositor_frame_reporter.cc
+++ /dev/null
@@ -1,227 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/scheduler/compositor_frame_reporter.h"
-
-#include <string>
-
-#include "base/metrics/histogram_macros.h"
-#include "base/strings/strcat.h"
-#include "base/trace_event/trace_event.h"
-#include "cc/base/rolling_time_delta_history.h"
-
-namespace cc {
-namespace {
-
-// When considering if a time is abnormal, compare the stage execution
-// time to this percentile from the previous times of the same stage.
-static constexpr double kAbnormalityPercentile = 95;
-
-// Use for determining abnormal execution times. If the sample size is less
-// than this then don't check for abnormal execution time.
-static constexpr size_t kMinimumTimeDeltaSampleSize = 20;
-
-static constexpr int kMissedFrameReportTypeCount =
- static_cast<int>(CompositorFrameReporter::MissedFrameReportTypes::
- kMissedFrameReportTypeCount);
-static constexpr int kStageTypeCount =
- static_cast<int>(CompositorFrameReporter::StageType::kStageTypeCount);
-
-// Names for CompositorFrameReporter::StageType, which should be updated in case
-// of changes to the enum.
-constexpr const char* kStageNames[]{
- "BeginImplFrameToSendBeginMainFrame",
- "SendBeginMainFrameToCommit",
- "Commit",
- "EndCommitToActivation",
- "Activation",
- "EndActivateToSubmitCompositorFrame",
- "SubmitCompositorFrameToPresentationCompositorFrame",
- "TotalLatency"};
-static_assert(sizeof(kStageNames) / sizeof(kStageNames[0]) == kStageTypeCount,
- "Compositor latency stages has changed.");
-
-// Names for CompositorFrameReporter::MissedFrameReportTypes, which should be
-// updated in case of changes to the enum.
-constexpr const char* kReportTypeNames[]{"", "MissedFrame.",
- "MissedFrameLatencyIncrease."};
-static_assert(sizeof(kReportTypeNames) / sizeof(kReportTypeNames[0]) ==
- kMissedFrameReportTypeCount,
- "Compositor latency report types has changed.");
-
-// This value should be recalculate in case of changes to the number of values
-// in CompositorFrameReporter::MissedFrameReportTypes or in
-// CompositorFrameReporter::StageType
-static constexpr int kMaxHistogramIndex =
- 2 * kMissedFrameReportTypeCount * kStageTypeCount;
-static constexpr int kHistogramMin = 1;
-static constexpr int kHistogramMax = 350000;
-static constexpr int kHistogramBucketCount = 50;
-} // namespace
-
-CompositorFrameReporter::CompositorFrameReporter(bool is_single_threaded)
- : is_single_threaded_(is_single_threaded) {
- TRACE_EVENT_ASYNC_BEGIN1("cc,benchmark", "PipelineReporter", this,
- "is_single_threaded", is_single_threaded);
-}
-
-CompositorFrameReporter::~CompositorFrameReporter() {
- TerminateReporter();
-}
-
-void CompositorFrameReporter::StartStage(
- CompositorFrameReporter::StageType stage_type,
- base::TimeTicks start_time,
- RollingTimeDeltaHistory* stage_time_delta_history) {
- EndCurrentStage(start_time);
- current_stage_.stage_type = stage_type;
- current_stage_.start_time = start_time;
- current_stage_.time_delta_history = stage_time_delta_history;
- int stage_type_index = static_cast<int>(current_stage_.stage_type);
- CHECK_LT(stage_type_index, static_cast<int>(StageType::kStageTypeCount));
- CHECK_GE(stage_type_index, 0);
- TRACE_EVENT_ASYNC_STEP_INTO_WITH_TIMESTAMP0(
- "cc,benchmark", "PipelineReporter", this,
- TRACE_STR_COPY(kStageNames[stage_type_index]), start_time);
-}
-
-void CompositorFrameReporter::EndCurrentStage(base::TimeTicks end_time) {
- if (current_stage_.start_time == base::TimeTicks())
- return;
- current_stage_.end_time = end_time;
- stage_history_.emplace_back(current_stage_);
- current_stage_.start_time = base::TimeTicks();
- current_stage_.time_delta_history = nullptr;
-}
-
-void CompositorFrameReporter::MissedSubmittedFrame() {
- submitted_frame_missed_deadline_ = true;
-}
-
-void CompositorFrameReporter::TerminateFrame(
- FrameTerminationStatus termination_status,
- base::TimeTicks termination_time) {
- frame_termination_status_ = termination_status;
- frame_termination_time_ = termination_time;
- EndCurrentStage(frame_termination_time_);
-}
-
-void CompositorFrameReporter::TerminateReporter() {
- DCHECK_EQ(current_stage_.start_time, base::TimeTicks());
- bool report_latency = false;
- const char* termination_status_str = nullptr;
- switch (frame_termination_status_) {
- case FrameTerminationStatus::kPresentedFrame:
- report_latency = true;
- termination_status_str = "presented_frame";
- break;
- case FrameTerminationStatus::kDidNotPresentFrame:
- termination_status_str = "did_not_present_frame";
- break;
- case FrameTerminationStatus::kMainFrameAborted:
- termination_status_str = "main_frame_aborted";
- break;
- case FrameTerminationStatus::kReplacedByNewReporter:
- termination_status_str = "replaced_by_new_reporter_at_same_stage";
- break;
- case FrameTerminationStatus::kDidNotProduceFrame:
- termination_status_str = "did_not_produce_frame";
- break;
- case FrameTerminationStatus::kUnknown:
- NOTREACHED();
- break;
- }
-
- const char* submission_status_str =
- submitted_frame_missed_deadline_ ? "missed_frame" : "non_missed_frame";
-
- TRACE_EVENT_ASYNC_END_WITH_TIMESTAMP2(
- "cc,benchmark", "PipelineReporter", this, frame_termination_time_,
- "termination_status", TRACE_STR_COPY(termination_status_str),
- "compositor_frame_submission_status",
- TRACE_STR_COPY(submission_status_str));
-
- // Only report histograms if the frame was presented.
- if (report_latency) {
- DCHECK(stage_history_.size());
- stage_history_.emplace_back(
- StageData{StageType::kTotalLatency, stage_history_.front().start_time,
- stage_history_.back().end_time, nullptr});
- ReportStageHistograms(submitted_frame_missed_deadline_);
- }
-}
-
-void CompositorFrameReporter::ReportStageHistograms(bool missed_frame) const {
- CompositorFrameReporter::MissedFrameReportTypes report_type =
- missed_frame
- ? CompositorFrameReporter::MissedFrameReportTypes::kMissedFrame
- : CompositorFrameReporter::MissedFrameReportTypes::kNonMissedFrame;
-
- for (const StageData& stage : stage_history_) {
- base::TimeDelta stage_delta = stage.end_time - stage.start_time;
- ReportHistogram(report_type, stage.stage_type, stage_delta);
-
- if (!stage.time_delta_history)
- continue;
-
- if (!missed_frame) {
- stage.time_delta_history->InsertSample(stage_delta);
- } else {
- // If enough sample data is recorded compare the stage duration with the
- // known normal stage duration and if it's higher than normal, report the
- // difference.
- if (stage.time_delta_history->sample_count() >=
- kMinimumTimeDeltaSampleSize) {
- base::TimeDelta time_upper_limit = GetStateNormalUpperLimit(stage);
- if (stage_delta > time_upper_limit) {
- ReportHistogram(CompositorFrameReporter::MissedFrameReportTypes::
- kMissedFrameLatencyIncrease,
- stage.stage_type, stage_delta - time_upper_limit);
- }
- }
-
- // In case of a missing frame, remove a sample from the recorded normal
- // stages. This invalidates the recorded normal durations if at a point
- // all frames start missing for a while.
- stage.time_delta_history->RemoveOldestSample();
- }
- }
-}
-
-void CompositorFrameReporter::ReportHistogram(
- CompositorFrameReporter::MissedFrameReportTypes report_type,
- CompositorFrameReporter::StageType stage_type,
- base::TimeDelta time_delta) const {
- const int report_type_index = static_cast<int>(report_type);
- const int stage_type_index = static_cast<int>(stage_type);
- const int histogram_index =
- (stage_type_index * kMissedFrameReportTypeCount + report_type_index) * 2 +
- (is_single_threaded_ ? 1 : 0);
-
- CHECK_LT(stage_type_index, kStageTypeCount);
- CHECK_GE(stage_type_index, 0);
- CHECK_LT(report_type_index, kMissedFrameReportTypeCount);
- CHECK_GE(report_type_index, 0);
- CHECK_LT(histogram_index, kMaxHistogramIndex);
- CHECK_GE(histogram_index, 0);
-
- const char* compositor_type = is_single_threaded_ ? "SingleThreaded" : "";
- const std::string name =
- base::StrCat({compositor_type, "CompositorLatency.",
- kReportTypeNames[static_cast<int>(report_type)],
- kStageNames[static_cast<int>(stage_type)]});
-
- STATIC_HISTOGRAM_POINTER_GROUP(
- name, histogram_index, kMaxHistogramIndex,
- AddTimeMicrosecondsGranularity(time_delta),
- base::Histogram::FactoryGet(
- name, kHistogramMin, kHistogramMax, kHistogramBucketCount,
- base::HistogramBase::kUmaTargetedHistogramFlag));
-}
-
-base::TimeDelta CompositorFrameReporter::GetStateNormalUpperLimit(
- const StageData& stage) const {
- return stage.time_delta_history->Percentile(kAbnormalityPercentile);
-}
-} // namespace cc
diff --git a/chromium/cc/scheduler/compositor_frame_reporter.h b/chromium/cc/scheduler/compositor_frame_reporter.h
deleted file mode 100644
index ae7d8bba562..00000000000
--- a/chromium/cc/scheduler/compositor_frame_reporter.h
+++ /dev/null
@@ -1,129 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_SCHEDULER_COMPOSITOR_FRAME_REPORTER_H_
-#define CC_SCHEDULER_COMPOSITOR_FRAME_REPORTER_H_
-
-#include <vector>
-
-#include "base/time/time.h"
-#include "cc/base/base_export.h"
-#include "cc/cc_export.h"
-
-namespace cc {
-class RollingTimeDeltaHistory;
-
-// This is used for tracing and reporting the duration of pipeline stages within
-// a single frame.
-//
-// For each stage in the frame pipeline, calling StartStage will start tracing
-// that stage (and end any currently running stages).
-//
-// If the tracked frame is submitted (i.e. the frame termination status is
-// kSubmittedFrame or kSubmittedFrameMissedDeadline), then the duration of each
-// stage along with the total latency will be reported to UMA. These reported
-// durations will be differentiated by whether the compositor is single threaded
-// and whether the submitted frame missed the deadline. The format of each stage
-// reported to UMA is "[SingleThreaded]Compositor.[MissedFrame.].<StageName>".
-class CC_EXPORT CompositorFrameReporter {
- public:
- enum class FrameTerminationStatus {
- // The tracked compositor frame was presented.
- kPresentedFrame,
-
- // The tracked compositor frame was submitted to the display compositor but
- // was not presented.
- kDidNotPresentFrame,
-
- // Main frame was aborted; the reporter will not continue reporting.
- kMainFrameAborted,
-
- // Reporter that is currently at a stage is replaced by a new one (e.g. two
- // BeginImplFrames can happen without issuing BeginMainFrame, so the first
- // reporter would terminate with this status).
- // TODO(alsan): Track impl-only frames.
- kReplacedByNewReporter,
-
- // Frame that was being tracked did not end up being submitting (e.g. frame
- // had no damage or LTHI was ended).
- kDidNotProduceFrame,
-
- // Default termination status. Should not be reachable.
- kUnknown
- };
-
- enum class MissedFrameReportTypes {
- kNonMissedFrame,
- kMissedFrame,
- kMissedFrameLatencyIncrease,
- kMissedFrameReportTypeCount
- };
-
- enum class StageType {
- kBeginImplFrameToSendBeginMainFrame,
- kSendBeginMainFrameToCommit,
- kCommit,
- kEndCommitToActivation,
- kActivation,
- kEndActivateToSubmitCompositorFrame,
- kSubmitCompositorFrameToPresentationCompositorFrame,
- kTotalLatency,
- kStageTypeCount
- };
-
- explicit CompositorFrameReporter(bool is_single_threaded = false);
- ~CompositorFrameReporter();
-
- CompositorFrameReporter(const CompositorFrameReporter& reporter) = delete;
- CompositorFrameReporter& operator=(const CompositorFrameReporter& reporter) =
- delete;
-
- void MissedSubmittedFrame();
-
- // Note that the started stage may be reported to UMA. If the histogram is
- // intended to be reported then the histograms.xml file must be updated too.
- void StartStage(StageType stage_type,
- base::TimeTicks start_time,
- RollingTimeDeltaHistory* stage_time_delta_history);
- void TerminateFrame(FrameTerminationStatus termination_status,
- base::TimeTicks termination_time);
-
- int StageHistorySizeForTesting() { return stage_history_.size(); }
-
- protected:
- struct StageData {
- StageType stage_type;
- base::TimeTicks start_time;
- base::TimeTicks end_time;
- RollingTimeDeltaHistory* time_delta_history;
- };
-
- StageData current_stage_;
-
- // Stage data is recorded here. On destruction these stages will be reported
- // to UMA if the termination status is |kPresentedFrame|. Reported data will
- // be divided based on the frame submission status.
- std::vector<StageData> stage_history_;
-
- private:
- void TerminateReporter();
- void EndCurrentStage(base::TimeTicks end_time);
- void ReportStageHistograms(bool missed_frame) const;
- void ReportHistogram(
- CompositorFrameReporter::MissedFrameReportTypes report_type,
- StageType stage_type,
- base::TimeDelta time_delta) const;
- // Returns true if the stage duration is greater than |kAbnormalityPercentile|
- // of its RollingTimeDeltaHistory.
- base::TimeDelta GetStateNormalUpperLimit(const StageData& stage) const;
-
- const bool is_single_threaded_;
- bool submitted_frame_missed_deadline_ = false;
- base::TimeTicks frame_termination_time_;
- FrameTerminationStatus frame_termination_status_ =
- FrameTerminationStatus::kUnknown;
-};
-} // namespace cc
-
-#endif // CC_SCHEDULER_COMPOSITOR_FRAME_REPORTER_H_"
diff --git a/chromium/cc/scheduler/compositor_frame_reporter_unittest.cc b/chromium/cc/scheduler/compositor_frame_reporter_unittest.cc
deleted file mode 100644
index d23a51bebc0..00000000000
--- a/chromium/cc/scheduler/compositor_frame_reporter_unittest.cc
+++ /dev/null
@@ -1,298 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/scheduler/compositor_frame_reporter.h"
-
-#include "base/test/metrics/histogram_tester.h"
-#include "cc/scheduler/compositor_frame_reporting_controller.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-namespace {
-
-class CompositorFrameReporterTest;
-
-class CompositorFrameReporterTest : public testing::Test {
- public:
- CompositorFrameReporterTest()
- : pipeline_reporter_(std::make_unique<CompositorFrameReporter>()) {
- AdvanceNowByMs(1);
- }
-
- void AdvanceNowByMs(int advance_ms) {
- now_ += base::TimeDelta::FromMicroseconds(advance_ms);
- }
-
- base::TimeTicks Now() { return now_; }
-
- protected:
- std::unique_ptr<CompositorFrameReporter> pipeline_reporter_;
- base::TimeTicks now_;
-};
-
-TEST_F(CompositorFrameReporterTest, MainFrameAbortedReportingTest) {
- base::HistogramTester histogram_tester;
-
- pipeline_reporter_->StartStage(
- CompositorFrameReporter::StageType::kBeginImplFrameToSendBeginMainFrame,
- Now(), nullptr);
- EXPECT_EQ(0, pipeline_reporter_->StageHistorySizeForTesting());
-
- AdvanceNowByMs(3);
- pipeline_reporter_->StartStage(
- CompositorFrameReporter::StageType::kSendBeginMainFrameToCommit, Now(),
- nullptr);
- EXPECT_EQ(1, pipeline_reporter_->StageHistorySizeForTesting());
-
- AdvanceNowByMs(2);
- pipeline_reporter_->TerminateFrame(
- CompositorFrameReporter::FrameTerminationStatus::kMainFrameAborted,
- Now());
- EXPECT_EQ(2, pipeline_reporter_->StageHistorySizeForTesting());
-
- pipeline_reporter_ = nullptr;
- histogram_tester.ExpectTotalCount(
- "CompositorLatency.BeginImplFrameToSendBeginMainFrame", 0);
- histogram_tester.ExpectTotalCount(
- "CompositorLatency.SendBeginMainFrameToCommit", 0);
-}
-
-TEST_F(CompositorFrameReporterTest, ReplacedByNewReporterReportingTest) {
- base::HistogramTester histogram_tester;
-
- pipeline_reporter_->StartStage(CompositorFrameReporter::StageType::kCommit,
- Now(), nullptr);
- EXPECT_EQ(0, pipeline_reporter_->StageHistorySizeForTesting());
-
- AdvanceNowByMs(3);
- pipeline_reporter_->StartStage(
- CompositorFrameReporter::StageType::kEndCommitToActivation, Now(),
- nullptr);
- EXPECT_EQ(1, pipeline_reporter_->StageHistorySizeForTesting());
-
- AdvanceNowByMs(2);
- pipeline_reporter_->TerminateFrame(
- CompositorFrameReporter::FrameTerminationStatus::kReplacedByNewReporter,
- Now());
- EXPECT_EQ(2, pipeline_reporter_->StageHistorySizeForTesting());
-
- pipeline_reporter_ = nullptr;
- histogram_tester.ExpectTotalCount("CompositorLatency.Commit", 0);
- histogram_tester.ExpectTotalCount("CompositorLatency.EndCommitToActivation",
- 0);
-}
-
-TEST_F(CompositorFrameReporterTest, SubmittedFrameReportingTest) {
- base::HistogramTester histogram_tester;
-
- pipeline_reporter_->StartStage(
- CompositorFrameReporter::StageType::kActivation, Now(), nullptr);
- EXPECT_EQ(0, pipeline_reporter_->StageHistorySizeForTesting());
-
- AdvanceNowByMs(3);
- pipeline_reporter_->StartStage(
- CompositorFrameReporter::StageType::kEndActivateToSubmitCompositorFrame,
- Now(), nullptr);
- EXPECT_EQ(1, pipeline_reporter_->StageHistorySizeForTesting());
-
- AdvanceNowByMs(2);
- pipeline_reporter_->TerminateFrame(
- CompositorFrameReporter::FrameTerminationStatus::kPresentedFrame, Now());
- EXPECT_EQ(2, pipeline_reporter_->StageHistorySizeForTesting());
-
- pipeline_reporter_ = nullptr;
- histogram_tester.ExpectTotalCount("CompositorLatency.Activation", 1);
- histogram_tester.ExpectTotalCount(
- "CompositorLatency.EndActivateToSubmitCompositorFrame", 1);
- histogram_tester.ExpectTotalCount("CompositorLatency.TotalLatency", 1);
- histogram_tester.ExpectTotalCount("CompositorLatency.MissedFrame.Activation",
- 0);
- histogram_tester.ExpectTotalCount(
- "CompositorLatency.MissedFrame.EndActivateToSubmitCompositorFrame", 0);
- histogram_tester.ExpectTotalCount(
- "CompositorLatency.MissedFrame.TotalLatency", 0);
-
- histogram_tester.ExpectBucketCount("CompositorLatency.Activation", 3, 1);
- histogram_tester.ExpectBucketCount(
- "CompositorLatency.EndActivateToSubmitCompositorFrame", 2, 1);
- histogram_tester.ExpectBucketCount("CompositorLatency.TotalLatency", 5, 1);
-}
-
-TEST_F(CompositorFrameReporterTest, SubmittedMissedFrameReportingTest) {
- base::HistogramTester histogram_tester;
-
- pipeline_reporter_->StartStage(
- CompositorFrameReporter::StageType::kSendBeginMainFrameToCommit, Now(),
- nullptr);
- EXPECT_EQ(0, pipeline_reporter_->StageHistorySizeForTesting());
-
- AdvanceNowByMs(3);
- pipeline_reporter_->StartStage(CompositorFrameReporter::StageType::kCommit,
- Now(), nullptr);
- EXPECT_EQ(1, pipeline_reporter_->StageHistorySizeForTesting());
-
- AdvanceNowByMs(2);
- pipeline_reporter_->MissedSubmittedFrame();
- pipeline_reporter_->TerminateFrame(
- CompositorFrameReporter::FrameTerminationStatus::kPresentedFrame, Now());
- EXPECT_EQ(2, pipeline_reporter_->StageHistorySizeForTesting());
-
- pipeline_reporter_ = nullptr;
- histogram_tester.ExpectTotalCount(
- "CompositorLatency.MissedFrame.SendBeginMainFrameToCommit", 1);
- histogram_tester.ExpectTotalCount("CompositorLatency.MissedFrame.Commit", 1);
- histogram_tester.ExpectTotalCount(
- "CompositorLatency.MissedFrame.TotalLatency", 1);
- histogram_tester.ExpectTotalCount(
- "CompositorLatency.SendBeginMainFrameToCommit", 0);
- histogram_tester.ExpectTotalCount("CompositorLatency.Commit", 0);
- histogram_tester.ExpectTotalCount("CompositorLatency.TotalLatency", 0);
-
- histogram_tester.ExpectBucketCount(
- "CompositorLatency.MissedFrame.SendBeginMainFrameToCommit", 3, 1);
- histogram_tester.ExpectBucketCount("CompositorLatency.MissedFrame.Commit", 2,
- 1);
- histogram_tester.ExpectBucketCount(
- "CompositorLatency.MissedFrame.TotalLatency", 5, 1);
-}
-
-TEST_F(CompositorFrameReporterTest, MissedFrameLatencyIncreaseReportingTest) {
- base::HistogramTester histogram_tester;
- RollingTimeDeltaHistory time_delta_history(50);
- RollingTimeDeltaHistory time_delta_history2(50);
-
- // Terminate this frame since it will get destroyed in the for loop.
- pipeline_reporter_->TerminateFrame(
- CompositorFrameReporter::FrameTerminationStatus::kDidNotProduceFrame,
- Now());
-
- // Submit 19 non-missed frames.
- for (int i = 0; i < 19; ++i) {
- pipeline_reporter_ = std::make_unique<CompositorFrameReporter>();
- pipeline_reporter_->StartStage(CompositorFrameReporter::StageType::kCommit,
- Now(), &time_delta_history);
- AdvanceNowByMs(1);
- pipeline_reporter_->StartStage(
- CompositorFrameReporter::StageType::kEndCommitToActivation, Now(),
- &time_delta_history2);
- pipeline_reporter_->TerminateFrame(
- CompositorFrameReporter::FrameTerminationStatus::kPresentedFrame,
- Now());
- }
- pipeline_reporter_ = nullptr;
- EXPECT_EQ((size_t)19, time_delta_history.sample_count());
- EXPECT_EQ((size_t)19, time_delta_history2.sample_count());
- histogram_tester.ExpectTotalCount("CompositorLatency.Commit", 19);
- histogram_tester.ExpectTotalCount("CompositorLatency.EndCommitToActivation",
- 19);
-
- // Submit 3 frames missed frames. This will remove 3 sample from the front of
- // time delta history. And 16 sample will be in the time delta history.
- for (int i = 0; i < 3; ++i) {
- pipeline_reporter_ = std::make_unique<CompositorFrameReporter>();
- pipeline_reporter_->StartStage(CompositorFrameReporter::StageType::kCommit,
- Now(), &time_delta_history);
- AdvanceNowByMs(100);
- pipeline_reporter_->StartStage(
- CompositorFrameReporter::StageType::kEndCommitToActivation, Now(),
- &time_delta_history2);
- pipeline_reporter_->MissedSubmittedFrame();
- pipeline_reporter_->TerminateFrame(
- CompositorFrameReporter::FrameTerminationStatus::kPresentedFrame,
- Now());
- }
- pipeline_reporter_ = nullptr;
- EXPECT_EQ((size_t)16, time_delta_history.sample_count());
- EXPECT_EQ((size_t)16, time_delta_history2.sample_count());
- DCHECK_EQ(time_delta_history.sample_count(), (size_t)16);
- histogram_tester.ExpectTotalCount(
- "CompositorLatency.MissedFrameLatencyIncrease.Commit", 0);
- histogram_tester.ExpectTotalCount(
- "CompositorLatency.MissedFrameLatencyIncrease.EndCommitToActivation", 0);
- histogram_tester.ExpectTotalCount("CompositorLatency.MissedFrame.Commit", 3);
- histogram_tester.ExpectTotalCount(
- "CompositorLatency.MissedFrame.EndCommitToActivation", 3);
-
- // Submit 5 frame so that missed frame duration increases would be reported.
- for (int i = 0; i < 5; ++i) {
- pipeline_reporter_ = std::make_unique<CompositorFrameReporter>();
- pipeline_reporter_->StartStage(CompositorFrameReporter::StageType::kCommit,
- Now(), &time_delta_history);
- AdvanceNowByMs(1);
- pipeline_reporter_->StartStage(
- CompositorFrameReporter::StageType::kEndCommitToActivation, Now(),
- &time_delta_history2);
- pipeline_reporter_->TerminateFrame(
- CompositorFrameReporter::FrameTerminationStatus::kPresentedFrame,
- Now());
- }
- pipeline_reporter_ = nullptr;
- EXPECT_EQ((size_t)21, time_delta_history.sample_count());
- EXPECT_EQ((size_t)21, time_delta_history2.sample_count());
-
- histogram_tester.ExpectTotalCount("CompositorLatency.Commit", 24);
- histogram_tester.ExpectTotalCount("CompositorLatency.EndCommitToActivation",
- 24);
-
- // Submit missed frame that is not abnormal (more than 95 percentile of the
- // frame history). This brings down the time delta history count to 20.
- pipeline_reporter_ = std::make_unique<CompositorFrameReporter>();
- pipeline_reporter_->StartStage(CompositorFrameReporter::StageType::kCommit,
- Now(), &time_delta_history);
- AdvanceNowByMs(1);
- pipeline_reporter_->StartStage(
- CompositorFrameReporter::StageType::kEndCommitToActivation, Now(),
- &time_delta_history2);
- pipeline_reporter_->MissedSubmittedFrame();
- pipeline_reporter_->TerminateFrame(
- CompositorFrameReporter::FrameTerminationStatus::kPresentedFrame, Now());
- pipeline_reporter_ = nullptr;
- histogram_tester.ExpectTotalCount(
- "CompositorLatency.MissedFrameLatencyIncrease.Commit", 0);
- histogram_tester.ExpectTotalCount("CompositorLatency.MissedFrame.Commit", 4);
- histogram_tester.ExpectTotalCount(
- "CompositorLatency.MissedFrame.EndCommitToActivation", 4);
-
- EXPECT_EQ((size_t)20, time_delta_history.sample_count());
- EXPECT_EQ((size_t)20, time_delta_history2.sample_count());
-
- // Submit missed frame that is abnormal (more than 95 percentile of the
- // frame history).
- pipeline_reporter_ = std::make_unique<CompositorFrameReporter>();
- pipeline_reporter_->StartStage(CompositorFrameReporter::StageType::kCommit,
- Now(), &time_delta_history);
- AdvanceNowByMs(3);
- pipeline_reporter_->StartStage(
- CompositorFrameReporter::StageType::kEndCommitToActivation, Now(),
- &time_delta_history2);
- pipeline_reporter_->MissedSubmittedFrame();
- pipeline_reporter_->TerminateFrame(
- CompositorFrameReporter::FrameTerminationStatus::kPresentedFrame, Now());
- pipeline_reporter_ = nullptr;
- histogram_tester.ExpectTotalCount(
- "CompositorLatency.MissedFrameLatencyIncrease.Commit", 1);
- histogram_tester.ExpectTotalCount("CompositorLatency.MissedFrame.Commit", 5);
- histogram_tester.ExpectTotalCount(
- "CompositorLatency.MissedFrame.EndCommitToActivation", 5);
-
- // Submit not-missed frame with abnormal times.
- pipeline_reporter_ = std::make_unique<CompositorFrameReporter>();
- pipeline_reporter_->StartStage(CompositorFrameReporter::StageType::kCommit,
- Now(), &time_delta_history);
- AdvanceNowByMs(3);
- pipeline_reporter_->StartStage(
- CompositorFrameReporter::StageType::kEndCommitToActivation, Now(),
- &time_delta_history2);
- pipeline_reporter_->TerminateFrame(
- CompositorFrameReporter::FrameTerminationStatus::kPresentedFrame, Now());
- pipeline_reporter_ = nullptr;
- histogram_tester.ExpectTotalCount(
- "CompositorLatency.MissedFrameLatencyIncrease.Commit", 1);
- histogram_tester.ExpectTotalCount("CompositorLatency.Commit", 25);
- histogram_tester.ExpectTotalCount("CompositorLatency.EndCommitToActivation",
- 25);
-}
-
-} // namespace
-} // namespace cc
diff --git a/chromium/cc/scheduler/compositor_frame_reporting_controller.cc b/chromium/cc/scheduler/compositor_frame_reporting_controller.cc
deleted file mode 100644
index dd74268707a..00000000000
--- a/chromium/cc/scheduler/compositor_frame_reporting_controller.cc
+++ /dev/null
@@ -1,217 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/scheduler/compositor_frame_reporting_controller.h"
-
-#include "cc/scheduler/compositor_frame_reporter.h"
-#include "components/viz/common/quads/compositor_frame_metadata.h"
-
-namespace cc {
-namespace {
-using StageType = CompositorFrameReporter::StageType;
-RollingTimeDeltaHistory* GetStageHistory(
- std::unique_ptr<RollingTimeDeltaHistory> stage_history_[],
- StageType stage_type) {
- return stage_history_[static_cast<int>(stage_type)].get();
-}
-
-static constexpr size_t kMaxHistorySize = 50;
-} // namespace
-
-CompositorFrameReportingController::CompositorFrameReportingController(
- bool is_single_threaded)
- : is_single_threaded_(is_single_threaded) {
- for (int i = 0; i < static_cast<int>(
- CompositorFrameReporter::StageType::kStageTypeCount);
- ++i) {
- stage_history_[i] =
- std::make_unique<RollingTimeDeltaHistory>(kMaxHistorySize);
- }
-}
-
-CompositorFrameReportingController::~CompositorFrameReportingController() {
- base::TimeTicks now = Now();
- for (int i = 0; i < PipelineStage::kNumPipelineStages; ++i) {
- if (reporters_[i]) {
- reporters_[i]->TerminateFrame(
- CompositorFrameReporter::FrameTerminationStatus::kDidNotProduceFrame,
- now);
- }
- }
- for (auto& pair : submitted_compositor_frames_) {
- pair.reporter->TerminateFrame(
- CompositorFrameReporter::FrameTerminationStatus::kDidNotPresentFrame,
- Now());
- }
-}
-
-CompositorFrameReportingController::SubmittedCompositorFrame::
- SubmittedCompositorFrame() = default;
-CompositorFrameReportingController::SubmittedCompositorFrame::
- SubmittedCompositorFrame(uint32_t frame_token,
- std::unique_ptr<CompositorFrameReporter> reporter)
- : frame_token(frame_token), reporter(std::move(reporter)) {}
-CompositorFrameReportingController::SubmittedCompositorFrame::
- ~SubmittedCompositorFrame() = default;
-
-CompositorFrameReportingController::SubmittedCompositorFrame::
- SubmittedCompositorFrame(SubmittedCompositorFrame&& other) = default;
-
-base::TimeTicks CompositorFrameReportingController::Now() const {
- return base::TimeTicks::Now();
-}
-
-void CompositorFrameReportingController::WillBeginImplFrame() {
- base::TimeTicks begin_time = Now();
- if (reporters_[PipelineStage::kBeginImplFrame]) {
- reporters_[PipelineStage::kBeginImplFrame]->TerminateFrame(
- CompositorFrameReporter::FrameTerminationStatus::kReplacedByNewReporter,
- begin_time);
- }
- std::unique_ptr<CompositorFrameReporter> reporter =
- std::make_unique<CompositorFrameReporter>(is_single_threaded_);
- reporter->StartStage(
- CompositorFrameReporter::StageType::kBeginImplFrameToSendBeginMainFrame,
- begin_time,
- GetStageHistory(stage_history_, CompositorFrameReporter::StageType::
- kBeginImplFrameToSendBeginMainFrame));
- reporters_[PipelineStage::kBeginImplFrame] = std::move(reporter);
-}
-
-void CompositorFrameReportingController::WillBeginMainFrame() {
- DCHECK(reporters_[PipelineStage::kBeginImplFrame]);
- // We need to use .get() below because operator<< in std::unique_ptr is a
- // C++20 feature.
- DCHECK_NE(reporters_[PipelineStage::kBeginMainFrame].get(),
- reporters_[PipelineStage::kBeginImplFrame].get());
- reporters_[PipelineStage::kBeginImplFrame]->StartStage(
- CompositorFrameReporter::StageType::kSendBeginMainFrameToCommit, Now(),
- GetStageHistory(
- stage_history_,
- CompositorFrameReporter::StageType::kSendBeginMainFrameToCommit));
- AdvanceReporterStage(PipelineStage::kBeginImplFrame,
- PipelineStage::kBeginMainFrame);
-}
-
-void CompositorFrameReportingController::BeginMainFrameAborted() {
- DCHECK(reporters_[PipelineStage::kBeginMainFrame]);
- std::unique_ptr<CompositorFrameReporter> aborted_frame_reporter =
- std::move(reporters_[PipelineStage::kBeginMainFrame]);
- aborted_frame_reporter->TerminateFrame(
- CompositorFrameReporter::FrameTerminationStatus::kMainFrameAborted,
- Now());
-}
-
-void CompositorFrameReportingController::WillCommit() {
- DCHECK(reporters_[PipelineStage::kBeginMainFrame]);
- reporters_[PipelineStage::kBeginMainFrame]->StartStage(
- CompositorFrameReporter::StageType::kCommit, Now(),
- GetStageHistory(stage_history_,
- CompositorFrameReporter::StageType::kCommit));
-}
-
-void CompositorFrameReportingController::DidCommit() {
- DCHECK(reporters_[PipelineStage::kBeginMainFrame]);
- reporters_[PipelineStage::kBeginMainFrame]->StartStage(
- CompositorFrameReporter::StageType::kEndCommitToActivation, Now(),
- GetStageHistory(
- stage_history_,
- CompositorFrameReporter::StageType::kEndCommitToActivation));
- AdvanceReporterStage(PipelineStage::kBeginMainFrame, PipelineStage::kCommit);
-}
-
-void CompositorFrameReportingController::WillInvalidateOnImplSide() {
- // Allows for activation without committing.
- // TODO(alsan): Report latency of impl side invalidations.
- next_activate_has_invalidation_ = true;
-}
-
-void CompositorFrameReportingController::WillActivate() {
- DCHECK(reporters_[PipelineStage::kCommit] || next_activate_has_invalidation_);
- if (!reporters_[PipelineStage::kCommit])
- return;
- reporters_[PipelineStage::kCommit]->StartStage(
- CompositorFrameReporter::StageType::kActivation, Now(),
- GetStageHistory(stage_history_,
- CompositorFrameReporter::StageType::kActivation));
-}
-
-void CompositorFrameReportingController::DidActivate() {
- DCHECK(reporters_[PipelineStage::kCommit] || next_activate_has_invalidation_);
- next_activate_has_invalidation_ = false;
- if (!reporters_[PipelineStage::kCommit])
- return;
- reporters_[PipelineStage::kCommit]->StartStage(
- CompositorFrameReporter::StageType::kEndActivateToSubmitCompositorFrame,
- Now(),
- GetStageHistory(stage_history_, CompositorFrameReporter::StageType::
- kEndActivateToSubmitCompositorFrame));
- AdvanceReporterStage(PipelineStage::kCommit, PipelineStage::kActivate);
-}
-
-void CompositorFrameReportingController::DidSubmitCompositorFrame(
- uint32_t frame_token) {
- if (!reporters_[PipelineStage::kActivate])
- return;
- std::unique_ptr<CompositorFrameReporter> submitted_reporter =
- std::move(reporters_[PipelineStage::kActivate]);
- // If there are any other reporters active on the other stages of the
- // pipeline then that means a new frame was started during the duration of
- // this reporter and therefore the frame being tracked missed the deadline.
- if (reporters_[PipelineStage::kBeginImplFrame] ||
- reporters_[PipelineStage::kBeginMainFrame] ||
- reporters_[PipelineStage::kCommit]) {
- submitted_reporter->MissedSubmittedFrame();
- }
- submitted_reporter->StartStage(
- CompositorFrameReporter::StageType::
- kSubmitCompositorFrameToPresentationCompositorFrame,
- Now(),
- GetStageHistory(stage_history_,
- CompositorFrameReporter::StageType::
- kSubmitCompositorFrameToPresentationCompositorFrame));
- submitted_compositor_frames_.emplace_back(frame_token,
- std::move(submitted_reporter));
-}
-
-void CompositorFrameReportingController::DidNotProduceFrame() {
- if (!reporters_[PipelineStage::kActivate])
- return;
- reporters_[PipelineStage::kActivate]->TerminateFrame(
- CompositorFrameReporter::FrameTerminationStatus::kDidNotProduceFrame,
- Now());
- reporters_[PipelineStage::kActivate] = nullptr;
-}
-
-void CompositorFrameReportingController::DidPresentCompositorFrame(
- uint32_t frame_token,
- base::TimeTicks presentation_time) {
- while (!submitted_compositor_frames_.empty()) {
- auto submitted_frame = submitted_compositor_frames_.begin();
- if (viz::FrameTokenGT(submitted_frame->frame_token, frame_token))
- break;
-
- auto termination_status =
- CompositorFrameReporter::FrameTerminationStatus::kPresentedFrame;
- if (submitted_frame->frame_token != frame_token)
- termination_status =
- CompositorFrameReporter::FrameTerminationStatus::kDidNotPresentFrame;
-
- submitted_frame->reporter->TerminateFrame(termination_status,
- presentation_time);
- submitted_compositor_frames_.erase(submitted_frame);
- }
-}
-
-void CompositorFrameReportingController::AdvanceReporterStage(
- PipelineStage start,
- PipelineStage target) {
- if (reporters_[target]) {
- reporters_[target]->TerminateFrame(
- CompositorFrameReporter::FrameTerminationStatus::kReplacedByNewReporter,
- Now());
- }
- reporters_[target] = std::move(reporters_[start]);
-}
-} // namespace cc
diff --git a/chromium/cc/scheduler/compositor_frame_reporting_controller.h b/chromium/cc/scheduler/compositor_frame_reporting_controller.h
deleted file mode 100644
index a481593c592..00000000000
--- a/chromium/cc/scheduler/compositor_frame_reporting_controller.h
+++ /dev/null
@@ -1,93 +0,0 @@
-// Copyright 2019 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_SCHEDULER_COMPOSITOR_FRAME_REPORTING_CONTROLLER_H_
-#define CC_SCHEDULER_COMPOSITOR_FRAME_REPORTING_CONTROLLER_H_
-
-#include <memory>
-#include <vector>
-
-#include "base/time/time.h"
-#include "cc/base/base_export.h"
-#include "cc/base/rolling_time_delta_history.h"
-#include "cc/cc_export.h"
-#include "cc/scheduler/compositor_frame_reporter.h"
-
-namespace cc {
-class RollingTimeDeltaHistory;
-
-// This is used for managing simultaneous CompositorFrameReporter instances
-// in the case that the compositor has high latency. Calling one of the
-// event functions will begin recording the time of the corresponding
-// phase and trace it. If the frame is eventually submitted, then the
-// recorded times of each phase will be reported in UMA.
-// See CompositorFrameReporter.
-class CC_EXPORT CompositorFrameReportingController {
- public:
- // Used as indices for accessing CompositorFrameReporters.
- enum PipelineStage {
- kBeginImplFrame = 0,
- kBeginMainFrame,
- kCommit,
- kActivate,
- kNumPipelineStages
- };
-
- explicit CompositorFrameReportingController(bool is_single_threaded = false);
- virtual ~CompositorFrameReportingController();
-
- CompositorFrameReportingController(
- const CompositorFrameReportingController&) = delete;
- CompositorFrameReportingController& operator=(
- const CompositorFrameReportingController&) = delete;
-
- // Events to signal Beginning/Ending of phases.
- virtual void WillBeginImplFrame();
- virtual void WillBeginMainFrame();
- virtual void BeginMainFrameAborted();
- virtual void WillInvalidateOnImplSide();
- virtual void WillCommit();
- virtual void DidCommit();
- virtual void WillActivate();
- virtual void DidActivate();
- virtual void DidSubmitCompositorFrame(uint32_t frame_token);
- virtual void DidNotProduceFrame();
- virtual void DidPresentCompositorFrame(uint32_t frame_token,
- base::TimeTicks presentation_time);
-
- protected:
- struct SubmittedCompositorFrame {
- uint32_t frame_token;
- std::unique_ptr<CompositorFrameReporter> reporter;
- SubmittedCompositorFrame();
- SubmittedCompositorFrame(uint32_t frame_token,
- std::unique_ptr<CompositorFrameReporter> reporter);
- SubmittedCompositorFrame(SubmittedCompositorFrame&& other);
- ~SubmittedCompositorFrame();
- };
- base::TimeTicks Now() const;
- std::unique_ptr<CompositorFrameReporter>
- reporters_[PipelineStage::kNumPipelineStages];
-
- private:
- void AdvanceReporterStage(PipelineStage start, PipelineStage target);
-
- // Used by the managed reporters to differentiate the histogram names when
- // reporting to UMA.
- const bool is_single_threaded_;
- bool next_activate_has_invalidation_ = false;
-
- // Mapping of frame token to pipeline reporter for submitted compositor
- // frames.
- base::circular_deque<SubmittedCompositorFrame> submitted_compositor_frames_;
-
- // These keep track of stage durations for when a frame did not miss a
- // deadline. The history is used by reporter instances to determine if a
- // missed frame had a stage duration that was abnormally large.
- std::unique_ptr<RollingTimeDeltaHistory> stage_history_[static_cast<size_t>(
- CompositorFrameReporter::StageType::kStageTypeCount)];
-};
-} // namespace cc
-
-#endif // CC_SCHEDULER_COMPOSITOR_FRAME_REPORTING_CONTROLLER_H_
diff --git a/chromium/cc/scheduler/compositor_frame_reporting_controller_unittest.cc b/chromium/cc/scheduler/compositor_frame_reporting_controller_unittest.cc
deleted file mode 100644
index 8210d247bcc..00000000000
--- a/chromium/cc/scheduler/compositor_frame_reporting_controller_unittest.cc
+++ /dev/null
@@ -1,234 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/scheduler/compositor_frame_reporting_controller.h"
-
-#include "base/macros.h"
-#include "base/test/metrics/histogram_tester.h"
-#include "components/viz/common/quads/compositor_frame_metadata.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-namespace {
-
-class CompositorFrameReportingControllerTest;
-
-class TestCompositorFrameReportingController
- : public CompositorFrameReportingController {
- public:
- TestCompositorFrameReportingController(
- CompositorFrameReportingControllerTest* test)
- : CompositorFrameReportingController(), test_(test) {}
-
- TestCompositorFrameReportingController(
- const TestCompositorFrameReportingController& controller) = delete;
-
- TestCompositorFrameReportingController& operator=(
- const TestCompositorFrameReportingController& controller) = delete;
-
- std::unique_ptr<CompositorFrameReporter>* reporters() { return reporters_; }
-
- int ActiveReporters() {
- int count = 0;
- for (int i = 0; i < PipelineStage::kNumPipelineStages; ++i) {
- if (reporters_[i])
- ++count;
- }
- return count;
- }
-
- protected:
- CompositorFrameReportingControllerTest* test_;
-};
-
-class CompositorFrameReportingControllerTest : public testing::Test {
- public:
- CompositorFrameReportingControllerTest() : reporting_controller_(this) {}
-
- // The following functions simulate the actions that would
- // occur for each phase of the reporting controller.
- void SimulateBeginImplFrame() { reporting_controller_.WillBeginImplFrame(); }
-
- void SimulateBeginMainFrame() {
- if (!reporting_controller_.reporters()[CompositorFrameReportingController::
- PipelineStage::kBeginImplFrame])
- SimulateBeginImplFrame();
- CHECK(
- reporting_controller_.reporters()[CompositorFrameReportingController::
- PipelineStage::kBeginImplFrame]);
- reporting_controller_.WillBeginMainFrame();
- }
-
- void SimulateCommit() {
- if (!reporting_controller_.reporters()[CompositorFrameReportingController::
- PipelineStage::kBeginMainFrame])
- SimulateBeginMainFrame();
- CHECK(
- reporting_controller_.reporters()[CompositorFrameReportingController::
- PipelineStage::kBeginMainFrame]);
- reporting_controller_.WillCommit();
- reporting_controller_.DidCommit();
- }
-
- void SimulateActivate() {
- if (!reporting_controller_.reporters()
- [CompositorFrameReportingController::PipelineStage::kCommit])
- SimulateCommit();
- CHECK(reporting_controller_.reporters()
- [CompositorFrameReportingController::PipelineStage::kCommit]);
- reporting_controller_.WillActivate();
- reporting_controller_.DidActivate();
- }
-
- void SimulateSubmitCompositorFrame(uint32_t frame_token) {
- if (!reporting_controller_.reporters()
- [CompositorFrameReportingController::PipelineStage::kActivate])
- SimulateActivate();
- CHECK(reporting_controller_.reporters()
- [CompositorFrameReportingController::PipelineStage::kActivate]);
- reporting_controller_.DidSubmitCompositorFrame(frame_token);
- }
-
- void SimulatePresentCompositorFrame() {
- ++next_token_;
- SimulateSubmitCompositorFrame(*next_token_);
- reporting_controller_.DidPresentCompositorFrame(*next_token_,
- base::TimeTicks::Now());
- }
-
- protected:
- TestCompositorFrameReportingController reporting_controller_;
-
- private:
- viz::FrameTokenGenerator next_token_;
-};
-
-TEST_F(CompositorFrameReportingControllerTest, ActiveReporterCounts) {
- // Check that there are no leaks with the CompositorFrameReporter
- // objects no matter what the sequence of scheduled actions is
- // Note that due to DCHECKs in WillCommit(), WillActivate(), etc., it
- // is impossible to have 2 reporters both in BMF or Commit
-
- // Tests Cases:
- // - 2 Reporters at Activate phase
- // - 2 back-to-back BeginImplFrames
- // - 4 Simultaneous Reporters
-
- // BF
- reporting_controller_.WillBeginImplFrame();
- EXPECT_EQ(1, reporting_controller_.ActiveReporters());
-
- // BF -> BF
- // Should replace previous reporter.
- reporting_controller_.WillBeginImplFrame();
- EXPECT_EQ(1, reporting_controller_.ActiveReporters());
-
- // BF -> BMF -> BF
- // Should add new reporter.
- reporting_controller_.WillBeginMainFrame();
- reporting_controller_.WillBeginImplFrame();
- EXPECT_EQ(2, reporting_controller_.ActiveReporters());
-
- // BF -> BMF -> BF -> Commit
- // Should stay same.
- reporting_controller_.WillCommit();
- reporting_controller_.DidCommit();
- EXPECT_EQ(2, reporting_controller_.ActiveReporters());
-
- // BF -> BMF -> BF -> Commit -> BMF -> Activate -> Commit -> Activation
- // Having two reporters at Activate phase should delete the older one.
- reporting_controller_.WillBeginMainFrame();
- reporting_controller_.WillActivate();
- reporting_controller_.DidActivate();
- reporting_controller_.WillCommit();
- reporting_controller_.DidCommit();
- reporting_controller_.WillActivate();
- reporting_controller_.DidActivate();
- EXPECT_EQ(1, reporting_controller_.ActiveReporters());
-
- reporting_controller_.DidSubmitCompositorFrame(0);
- EXPECT_EQ(0, reporting_controller_.ActiveReporters());
-
- // 4 simultaneous reporters active.
- SimulateActivate();
-
- SimulateCommit();
-
- SimulateBeginMainFrame();
-
- SimulateBeginImplFrame();
- EXPECT_EQ(4, reporting_controller_.ActiveReporters());
-
- // Any additional BeginImplFrame's would be ignored.
- SimulateBeginImplFrame();
- EXPECT_EQ(4, reporting_controller_.ActiveReporters());
-}
-
-TEST_F(CompositorFrameReportingControllerTest,
- SubmittedFrameHistogramReporting) {
- base::HistogramTester histogram_tester;
-
- // 2 reporters active.
- SimulateActivate();
- SimulateBeginImplFrame();
-
- // Submitting and Presenting the next reporter should be a missed.
- SimulatePresentCompositorFrame();
-
- histogram_tester.ExpectTotalCount(
- "CompositorLatency.MissedFrame.BeginImplFrameToSendBeginMainFrame", 1);
- histogram_tester.ExpectTotalCount(
- "CompositorLatency.MissedFrame.SendBeginMainFrameToCommit", 1);
- histogram_tester.ExpectTotalCount("CompositorLatency.MissedFrame.Commit", 1);
- histogram_tester.ExpectTotalCount(
- "CompositorLatency.MissedFrame.EndCommitToActivation", 1);
- histogram_tester.ExpectTotalCount("CompositorLatency.MissedFrame.Activation",
- 1);
- histogram_tester.ExpectTotalCount(
- "CompositorLatency.MissedFrame.EndActivateToSubmitCompositorFrame", 1);
-
- // Other histograms should not be reported.
- histogram_tester.ExpectTotalCount(
- "CompositorLatency.BeginImplFrameToSendBeginMainFrame", 0);
- histogram_tester.ExpectTotalCount(
- "CompositorLatency.SendBeginMainFrameToCommit", 0);
- histogram_tester.ExpectTotalCount("CompositorLatency.Commit", 0);
- histogram_tester.ExpectTotalCount("CompositorLatency.EndCommitToActivation",
- 0);
- histogram_tester.ExpectTotalCount("CompositorLatency.Activation", 0);
- histogram_tester.ExpectTotalCount(
- "CompositorLatency.EndActivateToSubmitCompositorFrame", 0);
-
- // Submitting the next reporter will not be counted as missed.
- // In practice this submitted frame should be considered as missed because a
- // new BeginFrame would have been issued, which is the cause for this frame
- // submission.
- SimulatePresentCompositorFrame();
- // Other histograms should not be reported.
- histogram_tester.ExpectTotalCount(
- "CompositorLatency.BeginImplFrameToSendBeginMainFrame", 1);
- histogram_tester.ExpectTotalCount(
- "CompositorLatency.SendBeginMainFrameToCommit", 1);
- histogram_tester.ExpectTotalCount("CompositorLatency.Commit", 1);
- histogram_tester.ExpectTotalCount("CompositorLatency.EndCommitToActivation",
- 1);
- histogram_tester.ExpectTotalCount("CompositorLatency.Activation", 1);
- histogram_tester.ExpectTotalCount(
- "CompositorLatency.EndActivateToSubmitCompositorFrame", 1);
-
- // Missed frame histogram counts should not change.
- histogram_tester.ExpectTotalCount(
- "CompositorLatency.MissedFrame.BeginImplFrameToSendBeginMainFrame", 1);
- histogram_tester.ExpectTotalCount(
- "CompositorLatency.MissedFrame.SendBeginMainFrameToCommit", 1);
- histogram_tester.ExpectTotalCount("CompositorLatency.MissedFrame.Commit", 1);
- histogram_tester.ExpectTotalCount(
- "CompositorLatency.MissedFrame.EndCommitToActivation", 1);
- histogram_tester.ExpectTotalCount("CompositorLatency.MissedFrame.Activation",
- 1);
- histogram_tester.ExpectTotalCount(
- "CompositorLatency.MissedFrame.EndActivateToSubmitCompositorFrame", 1);
-}
-} // namespace
-} // namespace cc
diff --git a/chromium/cc/scheduler/compositor_timing_history.cc b/chromium/cc/scheduler/compositor_timing_history.cc
deleted file mode 100644
index 0b509c097da..00000000000
--- a/chromium/cc/scheduler/compositor_timing_history.cc
+++ /dev/null
@@ -1,954 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/scheduler/compositor_timing_history.h"
-
-#include <stddef.h>
-#include <stdint.h>
-
-#include "base/memory/ptr_util.h"
-#include "base/metrics/histogram_macros.h"
-#include "base/stl_util.h"
-#include "base/trace_event/trace_event.h"
-#include "cc/debug/rendering_stats_instrumentation.h"
-#include "cc/scheduler/compositor_frame_reporting_controller.h"
-
-namespace cc {
-
-class CompositorTimingHistory::UMAReporter {
- public:
- virtual ~UMAReporter() = default;
-
- // Throughput measurements
- virtual void AddBeginMainFrameIntervalCritical(base::TimeDelta interval) = 0;
- virtual void AddBeginMainFrameIntervalNotCritical(
- base::TimeDelta interval) = 0;
- virtual void AddCommitInterval(base::TimeDelta interval) = 0;
- virtual void AddDrawInterval(base::TimeDelta interval) = 0;
-
- // Latency measurements
- virtual void AddBeginImplFrameLatency(base::TimeDelta delta) = 0;
- virtual void AddBeginMainFrameQueueDurationCriticalDuration(
- base::TimeDelta duration) = 0;
- virtual void AddBeginMainFrameQueueDurationNotCriticalDuration(
- base::TimeDelta duration) = 0;
- virtual void AddBeginMainFrameStartToCommitDuration(
- base::TimeDelta duration) = 0;
- virtual void AddCommitToReadyToActivateDuration(base::TimeDelta duration,
- TreePriority priority) = 0;
- virtual void AddInvalidationToReadyToActivateDuration(
- base::TimeDelta duration,
- TreePriority priority) = 0;
- virtual void AddReadyToActivateToWillActivateDuration(
- base::TimeDelta duration,
- bool pending_tree_is_impl_side) = 0;
- virtual void AddPrepareTilesDuration(base::TimeDelta duration) = 0;
- virtual void AddActivateDuration(base::TimeDelta duration) = 0;
- virtual void AddDrawDuration(base::TimeDelta duration) = 0;
- virtual void AddSubmitToAckLatency(base::TimeDelta duration) = 0;
-
- // crbug.com/758439: the following 3 functions are used to report timing in
- // certain conditions targeting blink / compositor animations.
- // Only the renderer would get the meaningful data.
- virtual void AddDrawIntervalWithCompositedAnimations(
- base::TimeDelta duration) = 0;
- virtual void AddDrawIntervalWithMainThreadAnimations(
- base::TimeDelta duration) = 0;
-
- // Synchronization measurements
- virtual void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) = 0;
-};
-
-namespace {
-
-// Using the 90th percentile will disable latency recovery
-// if we are missing the deadline approximately ~6 times per
-// second.
-// TODO(brianderson): Fine tune the percentiles below.
-const size_t kDurationHistorySize = 60;
-const double kBeginMainFrameQueueDurationEstimationPercentile = 90.0;
-const double kBeginMainFrameQueueDurationCriticalEstimationPercentile = 90.0;
-const double kBeginMainFrameQueueDurationNotCriticalEstimationPercentile = 90.0;
-const double kBeginMainFrameStartToReadyToCommitEstimationPercentile = 90.0;
-const double kCommitEstimatePercentile = 90.0;
-const double kCommitToReadyToActivateEstimationPercentile = 90.0;
-const double kPrepareTilesEstimationPercentile = 90.0;
-const double kActivateEstimationPercentile = 90.0;
-const double kDrawEstimationPercentile = 90.0;
-
-// This macro is deprecated since its bucket count uses too much bandwidth.
-// It also has sub-optimal range and bucket distribution.
-// TODO(brianderson): Delete this macro and associated UMAs once there is
-// sufficient overlap with the re-bucketed UMAs.
-#define UMA_HISTOGRAM_CUSTOM_TIMES_MICROS(name, sample) \
- UMA_HISTOGRAM_CUSTOM_COUNTS(name, sample.InMicroseconds(), \
- kUmaDurationMinMicros, kUmaDurationMaxMicros, \
- kUmaDurationBucketCount);
-
-// ~90 VSync aligned UMA buckets.
-const int kUMAVSyncBuckets[] = {
- // Powers of two from 0 to 2048 us @ 50% precision
- 1, 2, 4, 8, 16, 32, 64, 128, 256, 512, 1024, 2048,
- // Every 8 Hz from 256 Hz to 128 Hz @ 3-6% precision
- 3906, 4032, 4167, 4310, 4464, 4630, 4808, 5000, 5208, 5435, 5682, 5952,
- 6250, 6579, 6944, 7353,
- // Every 4 Hz from 128 Hz to 64 Hz @ 3-6% precision
- 7813, 8065, 8333, 8621, 8929, 9259, 9615, 10000, 10417, 10870, 11364, 11905,
- 12500, 13158, 13889, 14706,
- // Every 2 Hz from 64 Hz to 32 Hz @ 3-6% precision
- 15625, 16129, 16667, 17241, 17857, 18519, 19231, 20000, 20833, 21739, 22727,
- 23810, 25000, 26316, 27778, 29412,
- // Every 1 Hz from 32 Hz to 1 Hz @ 3-33% precision
- 31250, 32258, 33333, 34483, 35714, 37037, 38462, 40000, 41667, 43478, 45455,
- 47619, 50000, 52632, 55556, 58824, 62500, 66667, 71429, 76923, 83333, 90909,
- 100000, 111111, 125000, 142857, 166667, 200000, 250000, 333333, 500000,
- // Powers of two from 1s to 32s @ 50% precision
- 1000000, 2000000, 4000000, 8000000, 16000000, 32000000,
-};
-
-// ~50 UMA buckets with high precision from ~100 us to 1s.
-const int kUMADurationBuckets[] = {
- // Powers of 2 from 1 us to 64 us @ 50% precision.
- 1, 2, 4, 8, 16, 32, 64,
- // 1.25^20, 1.25^21, ..., 1.25^62 @ 20% precision.
- 87, 108, 136, 169, 212, 265, 331, 414, 517, 646, 808, 1010, 1262, 1578,
- 1972, 2465, 3081, 3852, 4815, 6019, 7523, 9404, 11755, 14694, 18367, 22959,
- 28699, 35873, 44842, 56052, 70065, 87581, 109476, 136846, 171057, 213821,
- 267276, 334096, 417619, 522024, 652530, 815663, 1019579,
- // Powers of 2 from 2s to 32s @ 50% precision.
- 2000000, 4000000, 8000000, 16000000, 32000000,
-};
-
-#define UMA_HISTOGRAM_CUSTOM_TIMES_VSYNC_ALIGNED(name, sample) \
- do { \
- UMA_HISTOGRAM_CUSTOM_ENUMERATION( \
- name "2", sample.InMicroseconds(), \
- std::vector<int>(kUMAVSyncBuckets, \
- kUMAVSyncBuckets + base::size(kUMAVSyncBuckets))); \
- } while (false)
-
-#define UMA_HISTOGRAM_CUSTOM_TIMES_DURATION_SUFFIX(name, suffix, sample) \
- do { \
- UMA_HISTOGRAM_CUSTOM_ENUMERATION( \
- name "2" suffix, sample.InMicroseconds(), \
- std::vector<int>( \
- kUMADurationBuckets, \
- kUMADurationBuckets + base::size(kUMADurationBuckets))); \
- } while (false)
-
-#define UMA_HISTOGRAM_CUSTOM_TIMES_DURATION(name, sample) \
- UMA_HISTOGRAM_CUSTOM_TIMES_DURATION_SUFFIX(name, "", sample)
-
-#define UMA_HISTOGRAM_READY_TO_ACTIVATE(name, sample, priority) \
- do { \
- UMA_HISTOGRAM_CUSTOM_TIMES_DURATION(name, sample); \
- switch (priority) { \
- case SAME_PRIORITY_FOR_BOTH_TREES: \
- UMA_HISTOGRAM_CUSTOM_TIMES_DURATION_SUFFIX(name, ".Same", sample); \
- break; \
- case SMOOTHNESS_TAKES_PRIORITY: \
- UMA_HISTOGRAM_CUSTOM_TIMES_DURATION_SUFFIX(name, ".Smoothness", \
- sample); \
- break; \
- case NEW_CONTENT_TAKES_PRIORITY: \
- UMA_HISTOGRAM_CUSTOM_TIMES_DURATION_SUFFIX(name, ".NewContent", \
- sample); \
- break; \
- } \
- } while (false)
-
-class RendererUMAReporter : public CompositorTimingHistory::UMAReporter {
- public:
- ~RendererUMAReporter() override = default;
-
- void AddBeginMainFrameIntervalCritical(base::TimeDelta interval) override {
- UMA_HISTOGRAM_CUSTOM_TIMES_VSYNC_ALIGNED(
- "Scheduling.Renderer.BeginMainFrameIntervalCritical", interval);
- }
-
- void AddBeginMainFrameIntervalNotCritical(base::TimeDelta interval) override {
- UMA_HISTOGRAM_CUSTOM_TIMES_VSYNC_ALIGNED(
- "Scheduling.Renderer.BeginMainFrameIntervalNotCritical", interval);
- }
-
- void AddCommitInterval(base::TimeDelta interval) override {
- UMA_HISTOGRAM_CUSTOM_TIMES_VSYNC_ALIGNED(
- "Scheduling.Renderer.CommitInterval", interval);
- }
-
- void AddDrawInterval(base::TimeDelta interval) override {
- UMA_HISTOGRAM_CUSTOM_TIMES_VSYNC_ALIGNED("Scheduling.Renderer.DrawInterval",
- interval);
- }
-
- void AddDrawIntervalWithCompositedAnimations(
- base::TimeDelta interval) override {
- UMA_HISTOGRAM_CUSTOM_TIMES_VSYNC_ALIGNED(
- "Scheduling.Renderer.DrawIntervalWithCompositedAnimations", interval);
- }
-
- void AddDrawIntervalWithMainThreadAnimations(
- base::TimeDelta interval) override {
- UMA_HISTOGRAM_CUSTOM_TIMES_VSYNC_ALIGNED(
- "Scheduling.Renderer.DrawIntervalWithMainThreadAnimations", interval);
- }
-
- void AddBeginImplFrameLatency(base::TimeDelta delta) override {
- UMA_HISTOGRAM_CUSTOM_TIMES_DURATION(
- "Scheduling.Renderer.BeginImplFrameLatency", delta);
- }
-
- void AddBeginMainFrameQueueDurationCriticalDuration(
- base::TimeDelta duration) override {
- UMA_HISTOGRAM_CUSTOM_TIMES_DURATION(
- "Scheduling.Renderer.BeginMainFrameQueueDurationCritical", duration);
- }
-
- void AddBeginMainFrameQueueDurationNotCriticalDuration(
- base::TimeDelta duration) override {
- UMA_HISTOGRAM_CUSTOM_TIMES_DURATION(
- "Scheduling.Renderer.BeginMainFrameQueueDurationNotCritical", duration);
- }
-
- void AddBeginMainFrameStartToCommitDuration(
- base::TimeDelta duration) override {
- UMA_HISTOGRAM_CUSTOM_TIMES_DURATION(
- "Scheduling.Renderer.BeginMainFrameStartToCommitDuration", duration);
- }
-
- void AddCommitToReadyToActivateDuration(base::TimeDelta duration,
- TreePriority priority) override {
- UMA_HISTOGRAM_READY_TO_ACTIVATE(
- "Scheduling.Renderer.CommitToReadyToActivateDuration", duration,
- priority);
- }
-
- void AddInvalidationToReadyToActivateDuration(
- base::TimeDelta duration,
- TreePriority priority) override {
- UMA_HISTOGRAM_READY_TO_ACTIVATE(
- "Scheduling.Renderer.InvalidationToReadyToActivateDuration", duration,
- priority);
- }
-
- void AddReadyToActivateToWillActivateDuration(
- base::TimeDelta duration,
- bool pending_tree_is_impl_side) override {
- if (pending_tree_is_impl_side) {
- UMA_HISTOGRAM_CUSTOM_TIMES_DURATION_SUFFIX(
- "Scheduling.Renderer.ReadyToActivateToActivationDuration", ".Impl",
- duration);
- } else {
- UMA_HISTOGRAM_CUSTOM_TIMES_DURATION_SUFFIX(
- "Scheduling.Renderer.ReadyToActivateToActivationDuration", ".Main",
- duration);
- }
- }
-
- void AddPrepareTilesDuration(base::TimeDelta duration) override {
- UMA_HISTOGRAM_CUSTOM_TIMES_DURATION(
- "Scheduling.Renderer.PrepareTilesDuration", duration);
- }
-
- void AddActivateDuration(base::TimeDelta duration) override {
- UMA_HISTOGRAM_CUSTOM_TIMES_DURATION("Scheduling.Renderer.ActivateDuration",
- duration);
- }
-
- void AddDrawDuration(base::TimeDelta duration) override {
- UMA_HISTOGRAM_CUSTOM_TIMES_DURATION("Scheduling.Renderer.DrawDuration",
- duration);
- }
-
- void AddSubmitToAckLatency(base::TimeDelta duration) override {
- UMA_HISTOGRAM_CUSTOM_TIMES_DURATION("Scheduling.Renderer.SwapToAckLatency",
- duration);
- }
-
- void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) override {
- UMA_HISTOGRAM_CUSTOM_TIMES_VSYNC_ALIGNED(
- "Scheduling.Renderer.MainAndImplFrameTimeDelta", delta);
- }
-};
-
-class BrowserUMAReporter : public CompositorTimingHistory::UMAReporter {
- public:
- ~BrowserUMAReporter() override = default;
-
- // BeginMainFrameIntervalCritical is not meaningful to measure on browser
- // side because browser rendering fps is not at 60.
- void AddBeginMainFrameIntervalCritical(base::TimeDelta interval) override {}
-
- void AddBeginMainFrameIntervalNotCritical(base::TimeDelta interval) override {
- }
-
- // CommitInterval is not meaningful to measure on browser side because
- // browser rendering fps is not at 60.
- void AddCommitInterval(base::TimeDelta interval) override {}
-
- // DrawInterval is not meaningful to measure on browser side because
- // browser rendering fps is not at 60.
- void AddDrawInterval(base::TimeDelta interval) override {}
-
- void AddDrawIntervalWithCompositedAnimations(
- base::TimeDelta interval) override {}
-
- void AddDrawIntervalWithMainThreadAnimations(
- base::TimeDelta interval) override {}
-
- void AddBeginImplFrameLatency(base::TimeDelta delta) override {
- UMA_HISTOGRAM_CUSTOM_TIMES_DURATION(
- "Scheduling.Browser.BeginImplFrameLatency", delta);
- }
-
- void AddBeginMainFrameQueueDurationCriticalDuration(
- base::TimeDelta duration) override {
- UMA_HISTOGRAM_CUSTOM_TIMES_DURATION(
- "Scheduling.Browser.BeginMainFrameQueueDurationCritical", duration);
- }
-
- void AddBeginMainFrameQueueDurationNotCriticalDuration(
- base::TimeDelta duration) override {}
-
- void AddBeginMainFrameStartToCommitDuration(
- base::TimeDelta duration) override {
- UMA_HISTOGRAM_CUSTOM_TIMES_DURATION(
- "Scheduling.Browser.BeginMainFrameStartToCommitDuration", duration);
- }
-
- void AddCommitToReadyToActivateDuration(base::TimeDelta duration,
- TreePriority priority) override {
- UMA_HISTOGRAM_READY_TO_ACTIVATE(
- "Scheduling.Browser.CommitToReadyToActivateDuration", duration,
- priority);
- }
-
- void AddInvalidationToReadyToActivateDuration(
- base::TimeDelta duration,
- TreePriority priority) override {
- UMA_HISTOGRAM_READY_TO_ACTIVATE(
- "Scheduling.Browser.InvalidationToReadyToActivateDuration", duration,
- priority);
- }
-
- void AddReadyToActivateToWillActivateDuration(
- base::TimeDelta duration,
- bool pending_tree_is_impl_side) override {
- UMA_HISTOGRAM_CUSTOM_TIMES_DURATION_SUFFIX(
- "Scheduling.Browser.ReadyToActivateToActivationDuration", ".Main",
- duration);
- }
-
- void AddPrepareTilesDuration(base::TimeDelta duration) override {
- UMA_HISTOGRAM_CUSTOM_TIMES_DURATION(
- "Scheduling.Browser.PrepareTilesDuration", duration);
- }
-
- void AddActivateDuration(base::TimeDelta duration) override {}
-
- void AddDrawDuration(base::TimeDelta duration) override {
- UMA_HISTOGRAM_CUSTOM_TIMES_DURATION("Scheduling.Browser.DrawDuration",
- duration);
- }
-
- void AddSubmitToAckLatency(base::TimeDelta duration) override {
- UMA_HISTOGRAM_CUSTOM_TIMES_DURATION("Scheduling.Browser.SwapToAckLatency",
- duration);
- }
-
- void AddMainAndImplFrameTimeDelta(base::TimeDelta delta) override {}
-};
-
-class NullUMAReporter : public CompositorTimingHistory::UMAReporter {
- public:
- ~NullUMAReporter() override = default;
- void AddBeginMainFrameIntervalCritical(base::TimeDelta interval) override {}
- void AddBeginMainFrameIntervalNotCritical(base::TimeDelta interval) override {
- }
- void AddCommitInterval(base::TimeDelta interval) override {}
- void AddDrawInterval(base::TimeDelta interval) override {}
- void AddDrawIntervalWithCompositedAnimations(
- base::TimeDelta inverval) override {}
- void AddDrawIntervalWithMainThreadAnimations(
- base::TimeDelta inverval) override {}
- void AddBeginImplFrameLatency(base::TimeDelta delta) override {}
- void AddBeginMainFrameQueueDurationCriticalDuration(
- base::TimeDelta duration) override {}
- void AddBeginMainFrameQueueDurationNotCriticalDuration(
- base::TimeDelta duration) override {}
- void AddBeginMainFrameStartToCommitDuration(
- base::TimeDelta duration) override {}
- void AddCommitToReadyToActivateDuration(base::TimeDelta duration,
- TreePriority priority) override {}
- void AddInvalidationToReadyToActivateDuration(
- base::TimeDelta duration,
- TreePriority priority) override {}
- void AddReadyToActivateToWillActivateDuration(
- base::TimeDelta duration,
- bool pending_tree_is_impl_side) override {}
- void AddPrepareTilesDuration(base::TimeDelta duration) override {}
- void AddActivateDuration(base::TimeDelta duration) override {}
- void AddDrawDuration(base::TimeDelta duration) override {}
- void AddSubmitToAckLatency(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,
- CompositorFrameReportingController* compositor_frame_reporting_controller)
- : 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),
- compositor_drawing_continuously_(false),
- begin_main_frame_queue_duration_history_(kDurationHistorySize),
- begin_main_frame_queue_duration_critical_history_(kDurationHistorySize),
- begin_main_frame_queue_duration_not_critical_history_(
- kDurationHistorySize),
- begin_main_frame_start_to_ready_to_commit_duration_history_(
- kDurationHistorySize),
- commit_duration_history_(kDurationHistorySize),
- commit_to_ready_to_activate_duration_history_(kDurationHistorySize),
- prepare_tiles_duration_history_(kDurationHistorySize),
- activate_duration_history_(kDurationHistorySize),
- draw_duration_history_(kDurationHistorySize),
- begin_main_frame_on_critical_path_(false),
- uma_reporter_(CreateUMAReporter(uma_category)),
- rendering_stats_instrumentation_(rendering_stats_instrumentation),
- compositor_frame_reporting_controller_(
- compositor_frame_reporting_controller) {}
-
-CompositorTimingHistory::~CompositorTimingHistory() = default;
-
-std::unique_ptr<CompositorTimingHistory::UMAReporter>
-CompositorTimingHistory::CreateUMAReporter(UMACategory category) {
- switch (category) {
- case RENDERER_UMA:
- return base::WrapUnique(new RendererUMAReporter);
- break;
- case BROWSER_UMA:
- return base::WrapUnique(new BrowserUMAReporter);
- break;
- case NULL_UMA:
- return base::WrapUnique(new NullUMAReporter);
- break;
- }
- NOTREACHED();
- return base::WrapUnique<CompositorTimingHistory::UMAReporter>(nullptr);
-}
-
-void CompositorTimingHistory::AsValueInto(
- base::trace_event::TracedValue* state) const {
- state->SetDouble(
- "begin_main_frame_queue_critical_estimate_ms",
- BeginMainFrameQueueDurationCriticalEstimate().InMillisecondsF());
- state->SetDouble(
- "begin_main_frame_queue_not_critical_estimate_ms",
- BeginMainFrameQueueDurationNotCriticalEstimate().InMillisecondsF());
- state->SetDouble(
- "begin_main_frame_start_to_ready_to_commit_estimate_ms",
- BeginMainFrameStartToReadyToCommitDurationEstimate().InMillisecondsF());
- state->SetDouble("commit_to_ready_to_activate_estimate_ms",
- CommitToReadyToActivateDurationEstimate().InMillisecondsF());
- state->SetDouble("prepare_tiles_estimate_ms",
- PrepareTilesDurationEstimate().InMillisecondsF());
- state->SetDouble("activate_estimate_ms",
- ActivateDurationEstimate().InMillisecondsF());
- state->SetDouble("draw_estimate_ms",
- DrawDurationEstimate().InMillisecondsF());
-}
-
-base::TimeTicks CompositorTimingHistory::Now() const {
- return base::TimeTicks::Now();
-}
-
-void CompositorTimingHistory::SetRecordingEnabled(bool enabled) {
- enabled_ = enabled;
-}
-
-void CompositorTimingHistory::SetBeginMainFrameNeededContinuously(bool active) {
- if (active == begin_main_frame_needed_continuously_)
- return;
- begin_main_frame_end_time_prev_ = base::TimeTicks();
- begin_main_frame_needed_continuously_ = active;
-}
-
-void CompositorTimingHistory::SetBeginMainFrameCommittingContinuously(
- bool active) {
- if (active == begin_main_frame_committing_continuously_)
- return;
- new_active_tree_draw_end_time_prev_committing_continuously_ =
- base::TimeTicks();
- begin_main_frame_committing_continuously_ = active;
-}
-
-void CompositorTimingHistory::SetCompositorDrawingContinuously(bool active) {
- if (active == compositor_drawing_continuously_)
- return;
- draw_end_time_prev_ = base::TimeTicks();
- compositor_drawing_continuously_ = active;
-}
-
-base::TimeDelta
-CompositorTimingHistory::BeginMainFrameQueueDurationCriticalEstimate() const {
- base::TimeDelta all = begin_main_frame_queue_duration_history_.Percentile(
- kBeginMainFrameQueueDurationEstimationPercentile);
- base::TimeDelta critical =
- begin_main_frame_queue_duration_critical_history_.Percentile(
- kBeginMainFrameQueueDurationCriticalEstimationPercentile);
- // Return the min since critical BeginMainFrames are likely fast if
- // the non critical ones are.
- return std::min(critical, all);
-}
-
-base::TimeDelta
-CompositorTimingHistory::BeginMainFrameQueueDurationNotCriticalEstimate()
- const {
- base::TimeDelta all = begin_main_frame_queue_duration_history_.Percentile(
- kBeginMainFrameQueueDurationEstimationPercentile);
- base::TimeDelta not_critical =
- begin_main_frame_queue_duration_not_critical_history_.Percentile(
- kBeginMainFrameQueueDurationNotCriticalEstimationPercentile);
- // Return the max since, non critical BeginMainFrames are likely slow if
- // the critical ones are.
- return std::max(not_critical, all);
-}
-
-base::TimeDelta
-CompositorTimingHistory::BeginMainFrameStartToReadyToCommitDurationEstimate()
- const {
- return begin_main_frame_start_to_ready_to_commit_duration_history_.Percentile(
- kBeginMainFrameStartToReadyToCommitEstimationPercentile);
-}
-
-base::TimeDelta CompositorTimingHistory::CommitDurationEstimate() const {
- return commit_duration_history_.Percentile(kCommitEstimatePercentile);
-}
-
-base::TimeDelta
-CompositorTimingHistory::CommitToReadyToActivateDurationEstimate() const {
- return commit_to_ready_to_activate_duration_history_.Percentile(
- kCommitToReadyToActivateEstimationPercentile);
-}
-
-base::TimeDelta CompositorTimingHistory::PrepareTilesDurationEstimate() const {
- return prepare_tiles_duration_history_.Percentile(
- kPrepareTilesEstimationPercentile);
-}
-
-base::TimeDelta CompositorTimingHistory::ActivateDurationEstimate() const {
- return activate_duration_history_.Percentile(kActivateEstimationPercentile);
-}
-
-base::TimeDelta CompositorTimingHistory::DrawDurationEstimate() const {
- return draw_duration_history_.Percentile(kDrawEstimationPercentile);
-}
-
-void CompositorTimingHistory::DidCreateAndInitializeLayerTreeFrameSink() {
- // After we get a new output surface, we won't get a spurious
- // CompositorFrameAck from the old output surface.
- submit_start_time_ = base::TimeTicks();
-}
-
-void CompositorTimingHistory::WillBeginImplFrame(
- const viz::BeginFrameArgs& args,
- bool new_active_tree_is_likely,
- base::TimeTicks now) {
- viz::BeginFrameArgs::BeginFrameArgsType frame_type = args.type;
- base::TimeTicks frame_time = args.frame_time;
-
- compositor_frame_reporting_controller_->WillBeginImplFrame();
-
- // The check for whether a BeginMainFrame was sent anytime between two
- // BeginImplFrames protects us from not detecting a fast main thread that
- // does all it's work and goes idle in between BeginImplFrames.
- // For example, this may happen if an animation is being driven with
- // setInterval(17) or if input events just happen to arrive in the
- // middle of every frame.
- if (!new_active_tree_is_likely && !did_send_begin_main_frame_) {
- SetBeginMainFrameNeededContinuously(false);
- SetBeginMainFrameCommittingContinuously(false);
- }
-
- if (frame_type == viz::BeginFrameArgs::NORMAL)
- uma_reporter_->AddBeginImplFrameLatency(now - frame_time);
-
- did_send_begin_main_frame_ = false;
-}
-
-void CompositorTimingHistory::WillFinishImplFrame(bool needs_redraw) {
- if (!needs_redraw)
- SetCompositorDrawingContinuously(false);
-}
-
-void CompositorTimingHistory::BeginImplFrameNotExpectedSoon() {
- SetBeginMainFrameNeededContinuously(false);
- SetBeginMainFrameCommittingContinuously(false);
- SetCompositorDrawingContinuously(false);
-}
-
-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_);
-
- compositor_frame_reporting_controller_->WillBeginMainFrame();
-
- 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);
-}
-
-void CompositorTimingHistory::BeginMainFrameStarted(
- base::TimeTicks main_thread_start_time) {
- DCHECK_NE(base::TimeTicks(), begin_main_frame_sent_time_);
- DCHECK_EQ(base::TimeTicks(), begin_main_frame_start_time_);
- begin_main_frame_start_time_ = main_thread_start_time;
-}
-
-void CompositorTimingHistory::BeginMainFrameAborted() {
- compositor_frame_reporting_controller_->BeginMainFrameAborted();
- SetBeginMainFrameCommittingContinuously(false);
- base::TimeTicks begin_main_frame_end_time = Now();
- DidBeginMainFrame(begin_main_frame_end_time);
- begin_main_frame_frame_time_ = base::TimeTicks();
-}
-
-void CompositorTimingHistory::NotifyReadyToCommit() {
- DCHECK_NE(begin_main_frame_start_time_, base::TimeTicks());
- begin_main_frame_start_to_ready_to_commit_duration_history_.InsertSample(
- Now() - begin_main_frame_start_time_);
-}
-
-void CompositorTimingHistory::WillCommit() {
- DCHECK_NE(begin_main_frame_start_time_, base::TimeTicks());
- compositor_frame_reporting_controller_->WillCommit();
- commit_start_time_ = Now();
-}
-
-void CompositorTimingHistory::DidCommit() {
- DCHECK_EQ(base::TimeTicks(), pending_tree_main_frame_time_);
- DCHECK_EQ(pending_tree_creation_time_, base::TimeTicks());
- DCHECK_NE(commit_start_time_, base::TimeTicks());
-
- compositor_frame_reporting_controller_->DidCommit();
-
- SetBeginMainFrameCommittingContinuously(true);
- base::TimeTicks begin_main_frame_end_time = Now();
- DidBeginMainFrame(begin_main_frame_end_time);
- commit_duration_history_.InsertSample(begin_main_frame_end_time -
- commit_start_time_);
-
- pending_tree_is_impl_side_ = false;
- pending_tree_creation_time_ = begin_main_frame_end_time;
- pending_tree_main_frame_time_ = begin_main_frame_frame_time_;
- begin_main_frame_frame_time_ = base::TimeTicks();
-}
-
-void CompositorTimingHistory::DidBeginMainFrame(
- base::TimeTicks begin_main_frame_end_time) {
- DCHECK_NE(base::TimeTicks(), begin_main_frame_sent_time_);
-
- // If the BeginMainFrame start time isn't know, assume it was immediate
- // for scheduling purposes, but don't report it for UMA to avoid skewing
- // the results.
- bool begin_main_frame_start_time_is_valid =
- !begin_main_frame_start_time_.is_null();
- if (!begin_main_frame_start_time_is_valid)
- begin_main_frame_start_time_ = begin_main_frame_sent_time_;
-
- base::TimeDelta begin_main_frame_sent_to_commit_duration =
- begin_main_frame_end_time - begin_main_frame_sent_time_;
- base::TimeDelta begin_main_frame_queue_duration =
- begin_main_frame_start_time_ - begin_main_frame_sent_time_;
- base::TimeDelta begin_main_frame_start_to_commit_duration =
- begin_main_frame_end_time - begin_main_frame_start_time_;
-
- rendering_stats_instrumentation_->AddBeginMainFrameToCommitDuration(
- begin_main_frame_sent_to_commit_duration);
-
- if (begin_main_frame_start_time_is_valid) {
- if (begin_main_frame_on_critical_path_) {
- uma_reporter_->AddBeginMainFrameQueueDurationCriticalDuration(
- begin_main_frame_queue_duration);
- } else {
- uma_reporter_->AddBeginMainFrameQueueDurationNotCriticalDuration(
- begin_main_frame_queue_duration);
- }
- }
-
- uma_reporter_->AddBeginMainFrameStartToCommitDuration(
- begin_main_frame_start_to_commit_duration);
-
- if (enabled_) {
- begin_main_frame_queue_duration_history_.InsertSample(
- begin_main_frame_queue_duration);
- if (begin_main_frame_on_critical_path_) {
- begin_main_frame_queue_duration_critical_history_.InsertSample(
- begin_main_frame_queue_duration);
- } else {
- begin_main_frame_queue_duration_not_critical_history_.InsertSample(
- begin_main_frame_queue_duration);
- }
- }
-
- if (begin_main_frame_needed_continuously_) {
- if (!begin_main_frame_end_time_prev_.is_null()) {
- base::TimeDelta commit_interval =
- begin_main_frame_end_time - begin_main_frame_end_time_prev_;
- if (begin_main_frame_on_critical_path_)
- uma_reporter_->AddBeginMainFrameIntervalCritical(commit_interval);
- else
- uma_reporter_->AddBeginMainFrameIntervalNotCritical(commit_interval);
- }
- begin_main_frame_end_time_prev_ = begin_main_frame_end_time;
- }
-
- begin_main_frame_sent_time_ = base::TimeTicks();
- begin_main_frame_start_time_ = base::TimeTicks();
-}
-
-void CompositorTimingHistory::WillInvalidateOnImplSide() {
- DCHECK(!pending_tree_is_impl_side_);
- DCHECK_EQ(pending_tree_creation_time_, base::TimeTicks());
-
- compositor_frame_reporting_controller_->WillInvalidateOnImplSide();
- pending_tree_is_impl_side_ = true;
- pending_tree_creation_time_ = base::TimeTicks::Now();
-}
-
-void CompositorTimingHistory::WillPrepareTiles() {
- DCHECK_EQ(base::TimeTicks(), prepare_tiles_start_time_);
- prepare_tiles_start_time_ = Now();
-}
-
-void CompositorTimingHistory::DidPrepareTiles() {
- DCHECK_NE(base::TimeTicks(), prepare_tiles_start_time_);
-
- base::TimeDelta prepare_tiles_duration = Now() - prepare_tiles_start_time_;
- uma_reporter_->AddPrepareTilesDuration(prepare_tiles_duration);
- if (enabled_)
- prepare_tiles_duration_history_.InsertSample(prepare_tiles_duration);
-
- prepare_tiles_start_time_ = base::TimeTicks();
-}
-
-void CompositorTimingHistory::ReadyToActivate() {
- DCHECK_NE(pending_tree_creation_time_, base::TimeTicks());
- DCHECK_EQ(pending_tree_ready_to_activate_time_, base::TimeTicks());
-
- pending_tree_ready_to_activate_time_ = Now();
- if (pending_tree_is_impl_side_) {
- base::TimeDelta time_since_invalidation =
- pending_tree_ready_to_activate_time_ - pending_tree_creation_time_;
- uma_reporter_->AddInvalidationToReadyToActivateDuration(
- time_since_invalidation, tree_priority_);
- } else {
- base::TimeDelta time_since_commit =
- pending_tree_ready_to_activate_time_ - pending_tree_creation_time_;
-
- // Before adding the new data point to the timing history, see what we would
- // have predicted for this frame. This allows us to keep track of the
- // accuracy of our predictions.
-
- base::TimeDelta commit_to_ready_to_activate_estimate =
- CommitToReadyToActivateDurationEstimate();
- uma_reporter_->AddCommitToReadyToActivateDuration(time_since_commit,
- tree_priority_);
- rendering_stats_instrumentation_->AddCommitToActivateDuration(
- time_since_commit, commit_to_ready_to_activate_estimate);
-
- if (enabled_) {
- commit_to_ready_to_activate_duration_history_.InsertSample(
- time_since_commit);
- }
- }
-}
-
-void CompositorTimingHistory::WillActivate() {
- DCHECK_EQ(base::TimeTicks(), activate_start_time_);
-
- compositor_frame_reporting_controller_->WillActivate();
- activate_start_time_ = Now();
-
- // Its possible to activate the pending tree before it is ready for
- // activation, for instance in the case of a context loss or visibility
- // changes.
- if (pending_tree_ready_to_activate_time_ != base::TimeTicks()) {
- base::TimeDelta time_since_ready =
- activate_start_time_ - pending_tree_ready_to_activate_time_;
- uma_reporter_->AddReadyToActivateToWillActivateDuration(
- time_since_ready, pending_tree_is_impl_side_);
- }
-
- pending_tree_is_impl_side_ = false;
- pending_tree_creation_time_ = base::TimeTicks();
- pending_tree_ready_to_activate_time_ = base::TimeTicks();
-}
-
-void CompositorTimingHistory::DidActivate() {
- DCHECK_NE(base::TimeTicks(), activate_start_time_);
- compositor_frame_reporting_controller_->DidActivate();
- base::TimeDelta activate_duration = Now() - activate_start_time_;
-
- uma_reporter_->AddActivateDuration(activate_duration);
- 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() {
- DCHECK_EQ(base::TimeTicks(), draw_start_time_);
- draw_start_time_ = Now();
-}
-
-void CompositorTimingHistory::DrawAborted() {
- active_tree_main_frame_time_ = base::TimeTicks();
-}
-
-void CompositorTimingHistory::DidDraw(
- bool used_new_active_tree,
- base::TimeTicks impl_frame_time,
- size_t composited_animations_count,
- size_t main_thread_animations_count,
- bool current_frame_had_raf,
- bool next_frame_has_pending_raf) {
- DCHECK_NE(base::TimeTicks(), draw_start_time_);
- base::TimeTicks draw_end_time = Now();
- base::TimeDelta draw_duration = draw_end_time - draw_start_time_;
-
- // Before adding the new data point to the timing history, see what we would
- // have predicted for this frame. This allows us to keep track of the accuracy
- // of our predictions.
- base::TimeDelta draw_estimate = DrawDurationEstimate();
- rendering_stats_instrumentation_->AddDrawDuration(draw_duration,
- draw_estimate);
-
- uma_reporter_->AddDrawDuration(draw_duration);
-
- if (enabled_) {
- draw_duration_history_.InsertSample(draw_duration);
- }
-
- SetCompositorDrawingContinuously(true);
- if (!draw_end_time_prev_.is_null()) {
- base::TimeDelta draw_interval = draw_end_time - draw_end_time_prev_;
- uma_reporter_->AddDrawInterval(draw_interval);
- if (composited_animations_count > 0 &&
- previous_frame_had_composited_animations_)
- uma_reporter_->AddDrawIntervalWithCompositedAnimations(draw_interval);
- }
- previous_frame_had_composited_animations_ = composited_animations_count > 0;
- draw_end_time_prev_ = draw_end_time;
-
- 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());
- TRACE_EVENT2(TRACE_DISABLED_BY_DEFAULT("cc.debug.scheduler.frames"),
- "CompositorTimingHistory::DidDraw",
- "active_tree_main_frame_time", active_tree_main_frame_time_,
- "impl_frame_time", impl_frame_time);
- uma_reporter_->AddMainAndImplFrameTimeDelta(main_and_impl_delta);
- active_tree_main_frame_time_ = base::TimeTicks();
-
- bool current_main_frame_had_visual_update =
- main_thread_animations_count > 0 || current_frame_had_raf;
- bool previous_main_frame_had_visual_update =
- previous_frame_had_main_thread_animations_ || previous_frame_had_raf_;
- if (current_main_frame_had_visual_update &&
- previous_main_frame_had_visual_update) {
- base::TimeDelta draw_interval =
- draw_end_time - new_active_tree_draw_end_time_prev_;
- uma_reporter_->AddDrawIntervalWithMainThreadAnimations(draw_interval);
- }
- previous_frame_had_main_thread_animations_ =
- main_thread_animations_count > 0;
- // It's possible that two consecutive main frames both run a rAF but are
- // separated by idle time (for example: calling requestAnimationFrame from a
- // setInterval function, with nothing else producing a main frame
- // in-between). To avoid incorrectly counting those cases as long draw
- // intervals, we only update previous_frame_had_raf_ if the current frame
- // also already has a future raf scheduled.
- previous_frame_had_raf_ =
- current_frame_had_raf && next_frame_has_pending_raf;
-
- new_active_tree_draw_end_time_prev_ = draw_end_time;
-
- if (begin_main_frame_committing_continuously_) {
- if (!new_active_tree_draw_end_time_prev_committing_continuously_
- .is_null()) {
- base::TimeDelta draw_interval =
- draw_end_time -
- new_active_tree_draw_end_time_prev_committing_continuously_;
- uma_reporter_->AddCommitInterval(draw_interval);
- }
- new_active_tree_draw_end_time_prev_committing_continuously_ =
- draw_end_time;
- }
- }
- draw_start_time_ = base::TimeTicks();
-}
-
-void CompositorTimingHistory::DidSubmitCompositorFrame(uint32_t frame_token) {
- DCHECK_EQ(base::TimeTicks(), submit_start_time_);
- compositor_frame_reporting_controller_->DidSubmitCompositorFrame(frame_token);
- submit_start_time_ = Now();
-}
-
-void CompositorTimingHistory::DidNotProduceFrame() {
- compositor_frame_reporting_controller_->DidNotProduceFrame();
-}
-
-void CompositorTimingHistory::DidReceiveCompositorFrameAck() {
- DCHECK_NE(base::TimeTicks(), submit_start_time_);
- base::TimeDelta submit_to_ack_duration = Now() - submit_start_time_;
- uma_reporter_->AddSubmitToAckLatency(submit_to_ack_duration);
- submit_start_time_ = base::TimeTicks();
-}
-
-void CompositorTimingHistory::DidPresentCompositorFrame(
- uint32_t frame_token,
- base::TimeTicks presentation_time) {
- compositor_frame_reporting_controller_->DidPresentCompositorFrame(
- frame_token, presentation_time);
-}
-
-void CompositorTimingHistory::SetTreePriority(TreePriority priority) {
- tree_priority_ = priority;
-}
-
-void CompositorTimingHistory::ClearHistory() {
- TRACE_EVENT0("cc,benchmark", "CompositorTimingHistory::ClearHistory");
-
- begin_main_frame_queue_duration_history_.Clear();
- begin_main_frame_queue_duration_critical_history_.Clear();
- begin_main_frame_queue_duration_not_critical_history_.Clear();
- begin_main_frame_start_to_ready_to_commit_duration_history_.Clear();
- commit_duration_history_.Clear();
- commit_to_ready_to_activate_duration_history_.Clear();
- prepare_tiles_duration_history_.Clear();
- activate_duration_history_.Clear();
- draw_duration_history_.Clear();
-}
-
-} // namespace cc
diff --git a/chromium/cc/scheduler/compositor_timing_history.h b/chromium/cc/scheduler/compositor_timing_history.h
deleted file mode 100644
index 7dff0c9335c..00000000000
--- a/chromium/cc/scheduler/compositor_timing_history.h
+++ /dev/null
@@ -1,183 +0,0 @@
-// Copyright 2014 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#ifndef CC_SCHEDULER_COMPOSITOR_TIMING_HISTORY_H_
-#define CC_SCHEDULER_COMPOSITOR_TIMING_HISTORY_H_
-
-#include <memory>
-
-#include "cc/base/rolling_time_delta_history.h"
-#include "cc/cc_export.h"
-#include "cc/tiles/tile_priority.h"
-#include "components/viz/common/frame_sinks/begin_frame_args.h"
-
-namespace base {
-namespace trace_event {
-class TracedValue;
-} // namespace trace_event
-} // namespace base
-
-namespace cc {
-
-class CompositorFrameReportingController;
-class RenderingStatsInstrumentation;
-
-class CC_EXPORT CompositorTimingHistory {
- public:
- enum UMACategory {
- RENDERER_UMA,
- BROWSER_UMA,
- NULL_UMA,
- };
- class UMAReporter;
-
- CompositorTimingHistory(
- bool using_synchronous_renderer_compositor,
- UMACategory uma_category,
- RenderingStatsInstrumentation* rendering_stats_instrumentation,
- CompositorFrameReportingController*
- compositor_frame_reporting_controller);
- CompositorTimingHistory(const CompositorTimingHistory&) = delete;
- virtual ~CompositorTimingHistory();
-
- CompositorTimingHistory& operator=(const CompositorTimingHistory&) = delete;
-
- void AsValueInto(base::trace_event::TracedValue* state) const;
-
- // The main thread responsiveness depends heavily on whether or not the
- // on_critical_path flag is set, so we record response times separately.
- virtual base::TimeDelta BeginMainFrameQueueDurationCriticalEstimate() const;
- virtual base::TimeDelta BeginMainFrameQueueDurationNotCriticalEstimate()
- const;
- virtual base::TimeDelta BeginMainFrameStartToReadyToCommitDurationEstimate()
- const;
- virtual base::TimeDelta CommitDurationEstimate() const;
- virtual base::TimeDelta CommitToReadyToActivateDurationEstimate() const;
- virtual base::TimeDelta PrepareTilesDurationEstimate() const;
- 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 DidCreateAndInitializeLayerTreeFrameSink();
-
- // Events to be timed.
- void WillBeginImplFrame(const viz::BeginFrameArgs& args,
- bool new_active_tree_is_likely,
- base::TimeTicks now);
- void WillFinishImplFrame(bool needs_redraw);
- void BeginImplFrameNotExpectedSoon();
- void WillBeginMainFrame(bool on_critical_path,
- base::TimeTicks main_frame_time);
- void BeginMainFrameStarted(base::TimeTicks main_thread_start_time);
- void BeginMainFrameAborted();
- void NotifyReadyToCommit();
- void WillCommit();
- void DidCommit();
- void WillPrepareTiles();
- void DidPrepareTiles();
- void ReadyToActivate();
- void WillActivate();
- void DidActivate();
- void DrawAborted();
- void WillDraw();
- void DidDraw(bool used_new_active_tree,
- base::TimeTicks impl_frame_time,
- size_t composited_animations_count,
- size_t main_thread_animations_count,
- bool current_frame_had_raf,
- bool next_frame_has_pending_raf);
- void DidSubmitCompositorFrame(uint32_t frame_token);
- void DidNotProduceFrame();
- void DidReceiveCompositorFrameAck();
- void DidPresentCompositorFrame(uint32_t frame_token,
- base::TimeTicks presentation_time);
- void WillInvalidateOnImplSide();
- void SetTreePriority(TreePriority priority);
-
- base::TimeTicks begin_main_frame_sent_time() const {
- return begin_main_frame_sent_time_;
- }
-
- void ClearHistory();
- size_t begin_main_frame_start_to_ready_to_commit_sample_count() const {
- return begin_main_frame_start_to_ready_to_commit_duration_history_
- .sample_count();
- }
- size_t commit_to_ready_to_activate_sample_count() const {
- return commit_to_ready_to_activate_duration_history_.sample_count();
- }
-
- protected:
- void DidBeginMainFrame(base::TimeTicks begin_main_frame_end_time);
-
- void SetBeginMainFrameNeededContinuously(bool active);
- void SetBeginMainFrameCommittingContinuously(bool active);
- void SetCompositorDrawingContinuously(bool active);
-
- static std::unique_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.
- bool did_send_begin_main_frame_;
- bool begin_main_frame_needed_continuously_;
- bool begin_main_frame_committing_continuously_;
- bool compositor_drawing_continuously_;
- base::TimeTicks begin_main_frame_end_time_prev_;
- base::TimeTicks new_active_tree_draw_end_time_prev_;
- base::TimeTicks new_active_tree_draw_end_time_prev_committing_continuously_;
- base::TimeTicks draw_end_time_prev_;
-
- // If you add any history here, please remember to reset it in
- // ClearHistory.
- RollingTimeDeltaHistory begin_main_frame_queue_duration_history_;
- RollingTimeDeltaHistory begin_main_frame_queue_duration_critical_history_;
- RollingTimeDeltaHistory begin_main_frame_queue_duration_not_critical_history_;
- RollingTimeDeltaHistory
- begin_main_frame_start_to_ready_to_commit_duration_history_;
- RollingTimeDeltaHistory commit_duration_history_;
- RollingTimeDeltaHistory commit_to_ready_to_activate_duration_history_;
- RollingTimeDeltaHistory prepare_tiles_duration_history_;
- RollingTimeDeltaHistory activate_duration_history_;
- 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 commit_start_time_;
- base::TimeTicks pending_tree_main_frame_time_;
- base::TimeTicks pending_tree_creation_time_;
- base::TimeTicks pending_tree_ready_to_activate_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 submit_start_time_;
-
- bool pending_tree_is_impl_side_;
-
- std::unique_ptr<UMAReporter> uma_reporter_;
-
- // Owned by LayerTreeHost and is destroyed when LayerTreeHost is destroyed.
- RenderingStatsInstrumentation* rendering_stats_instrumentation_;
-
- // Owned by LayerTreeHostImpl and is destroyed when LayerTreeHostImpl is
- // destroyed.
- CompositorFrameReportingController* compositor_frame_reporting_controller_;
-
- // Used only for reporting animation targeted UMA.
- bool previous_frame_had_composited_animations_ = false;
- bool previous_frame_had_main_thread_animations_ = false;
- bool previous_frame_had_raf_ = false;
-
- TreePriority tree_priority_ = SAME_PRIORITY_FOR_BOTH_TREES;
-};
-
-} // namespace cc
-
-#endif // CC_SCHEDULER_COMPOSITOR_TIMING_HISTORY_H_
diff --git a/chromium/cc/scheduler/compositor_timing_history_unittest.cc b/chromium/cc/scheduler/compositor_timing_history_unittest.cc
deleted file mode 100644
index 187c65b1a48..00000000000
--- a/chromium/cc/scheduler/compositor_timing_history_unittest.cc
+++ /dev/null
@@ -1,455 +0,0 @@
-// Copyright 2015 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "cc/scheduler/compositor_timing_history.h"
-
-#include "base/test/metrics/histogram_tester.h"
-#include "cc/debug/rendering_stats_instrumentation.h"
-#include "cc/test/fake_compositor_frame_reporting_controller.h"
-#include "testing/gtest/include/gtest/gtest.h"
-
-namespace cc {
-namespace {
-
-class CompositorTimingHistoryTest;
-
-class TestCompositorTimingHistory : public CompositorTimingHistory {
- public:
- TestCompositorTimingHistory(
- CompositorTimingHistoryTest* test,
- RenderingStatsInstrumentation* rendering_stats,
- CompositorFrameReportingController* reporting_controller)
- : CompositorTimingHistory(false,
- RENDERER_UMA,
- rendering_stats,
- reporting_controller),
- test_(test) {}
-
- TestCompositorTimingHistory(const TestCompositorTimingHistory&) = delete;
- TestCompositorTimingHistory& operator=(const TestCompositorTimingHistory&) =
- delete;
-
- protected:
- base::TimeTicks Now() const override;
-
- CompositorTimingHistoryTest* test_;
-};
-
-class CompositorTimingHistoryTest : public testing::Test {
- public:
- CompositorTimingHistoryTest()
- : rendering_stats_(RenderingStatsInstrumentation::Create()),
- reporting_controller_(
- std::make_unique<FakeCompositorFrameReportingController>()),
- timing_history_(this,
- rendering_stats_.get(),
- reporting_controller_.get()) {
- AdvanceNowBy(base::TimeDelta::FromMilliseconds(1));
- timing_history_.SetRecordingEnabled(true);
- }
-
- void AdvanceNowBy(base::TimeDelta delta) { now_ += delta; }
-
- base::TimeTicks Now() { return now_; }
-
- void DrawMainFrame(int advance_ms,
- int composited_animations_count,
- int main_thread_animations_count,
- bool current_frame_had_raf = false,
- bool next_frame_has_pending_raf = false) {
- timing_history_.WillBeginMainFrame(true, Now());
- timing_history_.BeginMainFrameStarted(Now());
- timing_history_.WillCommit();
- timing_history_.DidCommit();
- timing_history_.ReadyToActivate();
- timing_history_.WillActivate();
- timing_history_.DidActivate();
- timing_history_.WillDraw();
- AdvanceNowBy(base::TimeDelta::FromMicroseconds(advance_ms));
- timing_history_.DidDraw(true, Now(), composited_animations_count,
- main_thread_animations_count,
- current_frame_had_raf, next_frame_has_pending_raf);
- }
-
- void DrawImplFrame(int advance_ms,
- int composited_animations_count,
- int main_thread_animations_count) {
- timing_history_.WillBeginMainFrame(true, Now());
- timing_history_.BeginMainFrameStarted(Now());
- timing_history_.BeginMainFrameAborted();
- timing_history_.WillActivate();
- timing_history_.DidActivate();
- timing_history_.WillDraw();
- AdvanceNowBy(base::TimeDelta::FromMicroseconds(advance_ms));
- timing_history_.DidDraw(false, Now(), composited_animations_count,
- main_thread_animations_count, false, false);
- }
-
- protected:
- std::unique_ptr<RenderingStatsInstrumentation> rendering_stats_;
- std::unique_ptr<CompositorFrameReportingController> reporting_controller_;
- TestCompositorTimingHistory timing_history_;
- base::TimeTicks now_;
-};
-
-base::TimeTicks TestCompositorTimingHistory::Now() const {
- return test_->Now();
-}
-
-TEST_F(CompositorTimingHistoryTest, AllSequential_Commit) {
- base::TimeDelta one_second = base::TimeDelta::FromSeconds(1);
-
- // Critical BeginMainFrames are faster than non critical ones,
- // as expected.
- base::TimeDelta begin_main_frame_queue_duration =
- base::TimeDelta::FromMilliseconds(1);
- base::TimeDelta begin_main_frame_start_to_ready_to_commit_duration =
- base::TimeDelta::FromMilliseconds(1);
- base::TimeDelta prepare_tiles_duration = base::TimeDelta::FromMilliseconds(2);
- base::TimeDelta prepare_tiles_end_to_ready_to_activate_duration =
- base::TimeDelta::FromMilliseconds(1);
- base::TimeDelta commit_to_ready_to_activate_duration =
- base::TimeDelta::FromMilliseconds(3);
- base::TimeDelta commit_duration = base::TimeDelta::FromMilliseconds(1);
- base::TimeDelta activate_duration = base::TimeDelta::FromMilliseconds(4);
- base::TimeDelta draw_duration = base::TimeDelta::FromMilliseconds(5);
-
- timing_history_.WillBeginMainFrame(true, Now());
- AdvanceNowBy(begin_main_frame_queue_duration);
- timing_history_.BeginMainFrameStarted(Now());
- AdvanceNowBy(begin_main_frame_start_to_ready_to_commit_duration);
- timing_history_.NotifyReadyToCommit();
- timing_history_.WillCommit();
- AdvanceNowBy(commit_duration);
- timing_history_.DidCommit();
- timing_history_.WillPrepareTiles();
- AdvanceNowBy(prepare_tiles_duration);
- timing_history_.DidPrepareTiles();
- AdvanceNowBy(prepare_tiles_end_to_ready_to_activate_duration);
- timing_history_.ReadyToActivate();
- // Do not count idle time between notification and actual activation.
- AdvanceNowBy(one_second);
- timing_history_.WillActivate();
- AdvanceNowBy(activate_duration);
- timing_history_.DidActivate();
- // Do not count idle time between activate and draw.
- AdvanceNowBy(one_second);
- timing_history_.WillDraw();
- AdvanceNowBy(draw_duration);
- timing_history_.DidDraw(true, Now(), 0, 0, false, false);
-
- EXPECT_EQ(begin_main_frame_queue_duration,
- timing_history_.BeginMainFrameQueueDurationCriticalEstimate());
- EXPECT_EQ(begin_main_frame_queue_duration,
- timing_history_.BeginMainFrameQueueDurationNotCriticalEstimate());
-
- EXPECT_EQ(
- begin_main_frame_start_to_ready_to_commit_duration,
- timing_history_.BeginMainFrameStartToReadyToCommitDurationEstimate());
- EXPECT_EQ(commit_duration, timing_history_.CommitDurationEstimate());
- EXPECT_EQ(commit_to_ready_to_activate_duration,
- timing_history_.CommitToReadyToActivateDurationEstimate());
- EXPECT_EQ(prepare_tiles_duration,
- timing_history_.PrepareTilesDurationEstimate());
- EXPECT_EQ(activate_duration, timing_history_.ActivateDurationEstimate());
- EXPECT_EQ(draw_duration, timing_history_.DrawDurationEstimate());
-}
-
-TEST_F(CompositorTimingHistoryTest, AllSequential_BeginMainFrameAborted) {
- base::TimeDelta one_second = base::TimeDelta::FromSeconds(1);
-
- base::TimeDelta begin_main_frame_queue_duration =
- base::TimeDelta::FromMilliseconds(1);
- base::TimeDelta begin_main_frame_start_to_ready_to_commit_duration =
- base::TimeDelta::FromMilliseconds(1);
- base::TimeDelta prepare_tiles_duration = base::TimeDelta::FromMilliseconds(2);
- base::TimeDelta prepare_tiles_end_to_ready_to_activate_duration =
- base::TimeDelta::FromMilliseconds(1);
- base::TimeDelta activate_duration = base::TimeDelta::FromMilliseconds(4);
- base::TimeDelta draw_duration = base::TimeDelta::FromMilliseconds(5);
-
- timing_history_.WillBeginMainFrame(false, Now());
- AdvanceNowBy(begin_main_frame_queue_duration);
- timing_history_.BeginMainFrameStarted(Now());
- AdvanceNowBy(begin_main_frame_start_to_ready_to_commit_duration);
- // BeginMainFrameAborted counts as a commit complete.
- timing_history_.BeginMainFrameAborted();
- timing_history_.WillPrepareTiles();
- AdvanceNowBy(prepare_tiles_duration);
- timing_history_.DidPrepareTiles();
- AdvanceNowBy(prepare_tiles_end_to_ready_to_activate_duration);
- // Do not count idle time between notification and actual activation.
- AdvanceNowBy(one_second);
- timing_history_.WillActivate();
- AdvanceNowBy(activate_duration);
- timing_history_.DidActivate();
- // Do not count idle time between activate and draw.
- AdvanceNowBy(one_second);
- timing_history_.WillDraw();
- AdvanceNowBy(draw_duration);
- timing_history_.DidDraw(false, Now(), 0, 0, false, false);
-
- EXPECT_EQ(base::TimeDelta(),
- timing_history_.BeginMainFrameQueueDurationCriticalEstimate());
- EXPECT_EQ(begin_main_frame_queue_duration,
- timing_history_.BeginMainFrameQueueDurationNotCriticalEstimate());
-
- EXPECT_EQ(prepare_tiles_duration,
- timing_history_.PrepareTilesDurationEstimate());
- EXPECT_EQ(activate_duration, timing_history_.ActivateDurationEstimate());
- EXPECT_EQ(draw_duration, timing_history_.DrawDurationEstimate());
-}
-
-TEST_F(CompositorTimingHistoryTest, BeginMainFrame_CriticalFaster) {
- // Critical BeginMainFrames are faster than non critical ones.
- base::TimeDelta begin_main_frame_queue_duration_critical =
- base::TimeDelta::FromMilliseconds(1);
- base::TimeDelta begin_main_frame_queue_duration_not_critical =
- base::TimeDelta::FromMilliseconds(2);
- base::TimeDelta begin_main_frame_start_to_ready_to_commit_duration =
- base::TimeDelta::FromMilliseconds(1);
-
- timing_history_.WillBeginMainFrame(true, Now());
- AdvanceNowBy(begin_main_frame_queue_duration_critical);
- timing_history_.BeginMainFrameStarted(Now());
- AdvanceNowBy(begin_main_frame_start_to_ready_to_commit_duration);
- timing_history_.BeginMainFrameAborted();
-
- timing_history_.WillBeginMainFrame(false, Now());
- AdvanceNowBy(begin_main_frame_queue_duration_not_critical);
- timing_history_.BeginMainFrameStarted(Now());
- AdvanceNowBy(begin_main_frame_start_to_ready_to_commit_duration);
- timing_history_.BeginMainFrameAborted();
-
- // Since the critical BeginMainFrames are faster than non critical ones,
- // the expectations are straightforward.
- EXPECT_EQ(begin_main_frame_queue_duration_critical,
- timing_history_.BeginMainFrameQueueDurationCriticalEstimate());
- EXPECT_EQ(begin_main_frame_queue_duration_not_critical,
- timing_history_.BeginMainFrameQueueDurationNotCriticalEstimate());
-}
-
-TEST_F(CompositorTimingHistoryTest, BeginMainFrames_OldCriticalSlower) {
- // Critical BeginMainFrames are slower than non critical ones,
- // which is unexpected, but could occur if one type of frame
- // hasn't been sent for a significant amount of time.
- base::TimeDelta begin_main_frame_queue_duration_critical =
- base::TimeDelta::FromMilliseconds(2);
- base::TimeDelta begin_main_frame_queue_duration_not_critical =
- base::TimeDelta::FromMilliseconds(1);
- base::TimeDelta begin_main_frame_start_to_ready_to_commit_duration =
- base::TimeDelta::FromMilliseconds(1);
-
- // A single critical frame that is slow.
- timing_history_.WillBeginMainFrame(true, Now());
- AdvanceNowBy(begin_main_frame_queue_duration_critical);
- timing_history_.BeginMainFrameStarted(Now());
- AdvanceNowBy(begin_main_frame_start_to_ready_to_commit_duration);
- // BeginMainFrameAborted counts as a commit complete.
- timing_history_.BeginMainFrameAborted();
-
- // A bunch of faster non critical frames that are newer.
- for (int i = 0; i < 100; i++) {
- timing_history_.WillBeginMainFrame(false, Now());
- AdvanceNowBy(begin_main_frame_queue_duration_not_critical);
- timing_history_.BeginMainFrameStarted(Now());
- AdvanceNowBy(begin_main_frame_start_to_ready_to_commit_duration);
- // BeginMainFrameAborted counts as a commit complete.
- timing_history_.BeginMainFrameAborted();
- }
-
- // Recent fast non critical BeginMainFrames should result in the
- // critical estimate also being fast.
- EXPECT_EQ(begin_main_frame_queue_duration_not_critical,
- timing_history_.BeginMainFrameQueueDurationCriticalEstimate());
- EXPECT_EQ(begin_main_frame_queue_duration_not_critical,
- timing_history_.BeginMainFrameQueueDurationNotCriticalEstimate());
-}
-
-TEST_F(CompositorTimingHistoryTest, BeginMainFrames_NewCriticalSlower) {
- // Critical BeginMainFrames are slower than non critical ones,
- // which is unexpected, but could occur if one type of frame
- // hasn't been sent for a significant amount of time.
- base::TimeDelta begin_main_frame_queue_duration_critical =
- base::TimeDelta::FromMilliseconds(2);
- base::TimeDelta begin_main_frame_queue_duration_not_critical =
- base::TimeDelta::FromMilliseconds(1);
- base::TimeDelta begin_main_frame_start_to_ready_to_commit_duration =
- base::TimeDelta::FromMilliseconds(1);
-
- // A single non critical frame that is fast.
- timing_history_.WillBeginMainFrame(false, Now());
- AdvanceNowBy(begin_main_frame_queue_duration_not_critical);
- timing_history_.BeginMainFrameStarted(Now());
- AdvanceNowBy(begin_main_frame_start_to_ready_to_commit_duration);
- timing_history_.BeginMainFrameAborted();
-
- // A bunch of slower critical frames that are newer.
- for (int i = 0; i < 100; i++) {
- timing_history_.WillBeginMainFrame(true, Now());
- AdvanceNowBy(begin_main_frame_queue_duration_critical);
- timing_history_.BeginMainFrameStarted(Now());
- AdvanceNowBy(begin_main_frame_start_to_ready_to_commit_duration);
- timing_history_.BeginMainFrameAborted();
- }
-
- // Recent slow critical BeginMainFrames should result in the
- // not critical estimate also being slow.
- EXPECT_EQ(begin_main_frame_queue_duration_critical,
- timing_history_.BeginMainFrameQueueDurationCriticalEstimate());
- EXPECT_EQ(begin_main_frame_queue_duration_critical,
- timing_history_.BeginMainFrameQueueDurationNotCriticalEstimate());
-}
-
-void TestAnimationUMA(const base::HistogramTester& histogram_tester,
- base::HistogramBase::Count composited_animation_frames,
- base::HistogramBase::Count main_thread_animation_frames) {
- histogram_tester.ExpectTotalCount(
- "Scheduling.Renderer.DrawIntervalWithCompositedAnimations2",
- composited_animation_frames);
- histogram_tester.ExpectTotalCount(
- "Scheduling.Renderer.DrawIntervalWithMainThreadAnimations2",
- main_thread_animation_frames);
-}
-
-TEST_F(CompositorTimingHistoryTest, AnimationNotReported) {
- base::HistogramTester histogram_tester;
-
- // Initial frame has no main-thread animations or rAF.
- DrawMainFrame(123, 0, 0);
- TestAnimationUMA(histogram_tester, 0, 0);
-
- // The next frame has one composited and one main thread animation running,
- // but as the previous frame had no animation we shouldn't report anything.
- DrawMainFrame(456, 1, 1);
- TestAnimationUMA(histogram_tester, 0, 0);
-
- DrawMainFrame(123, 0, 0);
- TestAnimationUMA(histogram_tester, 0, 0);
-
- // The next frame has just one main thread animation running, but again as the
- // previous frame had no animation we shouldn't report anything.
- DrawMainFrame(456, 0, 1);
- TestAnimationUMA(histogram_tester, 0, 0);
-
- DrawMainFrame(123, 0, 0);
- TestAnimationUMA(histogram_tester, 0, 0);
-
- // The next frame has no main thread animations but did have a rAF callback.
- // Again as the previous frame had no visual change we shouldn't report.
- DrawMainFrame(123, 0, 0, true);
- TestAnimationUMA(histogram_tester, 0, 0);
-
- DrawMainFrame(123, 0, 0);
- TestAnimationUMA(histogram_tester, 0, 0);
-
- // Finally, test the combination of both main thread animations and rAF
- // callbacks being called.
- DrawMainFrame(123, 1, 2, true);
- TestAnimationUMA(histogram_tester, 0, 0);
-}
-
-TEST_F(CompositorTimingHistoryTest, ConsecutiveFramesAnimationsReported) {
- base::HistogramTester histogram_tester;
-
- DrawMainFrame(123, 1, 0);
- TestAnimationUMA(histogram_tester, 0, 0);
-
- DrawMainFrame(456, 1, 0);
- TestAnimationUMA(histogram_tester, 1, 0);
- histogram_tester.ExpectBucketCount(
- "Scheduling.Renderer.DrawIntervalWithCompositedAnimations2", 456, 1);
-
- DrawMainFrame(321, 0, 1);
- TestAnimationUMA(histogram_tester, 1, 0);
-
- DrawMainFrame(654, 0, 1);
- TestAnimationUMA(histogram_tester, 1, 1);
- histogram_tester.ExpectBucketCount(
- "Scheduling.Renderer.DrawIntervalWithMainThreadAnimations2", 654, 1);
-
- DrawMainFrame(123, 0, 1);
- TestAnimationUMA(histogram_tester, 1, 2);
-
- DrawMainFrame(456, 0, 1);
- TestAnimationUMA(histogram_tester, 1, 3);
-
- // Main thread and rAF animations are both considered to be part of the same
- // animation type.
- DrawMainFrame(789, 0, 0, true, true);
- TestAnimationUMA(histogram_tester, 1, 4);
-
- DrawMainFrame(987, 0, 1, false);
- TestAnimationUMA(histogram_tester, 1, 5);
-
- // However if there is no pending rAF for a frame, we don't count the one
- // after it as being linked.
- DrawMainFrame(789, 0, 0, true, false);
- TestAnimationUMA(histogram_tester, 1, 6);
-
- DrawMainFrame(987, 0, 0, true, true);
- TestAnimationUMA(histogram_tester, 1, 6);
-}
-
-TEST_F(CompositorTimingHistoryTest, InterFrameAnimationsNotReported) {
- base::HistogramTester histogram_tester;
-
- DrawMainFrame(123, 0, 1);
- TestAnimationUMA(histogram_tester, 0, 0);
-
- // The previous frame had a main thread animation, where the current one is
- // main thread compositable animation, we don't measure the timing from a
- // different animation type.
- DrawMainFrame(456, 0, 1);
- TestAnimationUMA(histogram_tester, 0, 1);
-
- DrawMainFrame(321, 1, 0);
- TestAnimationUMA(histogram_tester, 0, 1);
-
- DrawMainFrame(654, 0, 1);
- TestAnimationUMA(histogram_tester, 0, 1);
-
- DrawMainFrame(123, 1, 0);
- TestAnimationUMA(histogram_tester, 0, 1);
-}
-
-TEST_F(CompositorTimingHistoryTest, AnimationsWithNewActiveTreeNotUsed) {
- base::HistogramTester histogram_tester;
-
- DrawImplFrame(123, 1, 1);
- TestAnimationUMA(histogram_tester, 0, 0);
-
- DrawImplFrame(456, 1, 0);
- TestAnimationUMA(histogram_tester, 1, 0);
- histogram_tester.ExpectBucketCount(
- "Scheduling.Renderer.DrawIntervalWithCompositedAnimations2", 456, 1);
-
- DrawMainFrame(321, 0, 1);
- TestAnimationUMA(histogram_tester, 1, 0);
-
- // This frame verifies that we record that there is a composited animation,
- // so in the next frame when there is a composited animation, we report it.
- DrawImplFrame(234, 1, 1);
- TestAnimationUMA(histogram_tester, 1, 0);
-
- // Even though the previous frame had no main thread animation, we report it
- // in this frame because the previous main frame had a main thread animation
- // with the time between main frame draws.
- DrawMainFrame(654, 1, 1);
- TestAnimationUMA(histogram_tester, 2, 1);
- histogram_tester.ExpectBucketCount(
- "Scheduling.Renderer.DrawIntervalWithCompositedAnimations2", 654, 1);
- // The recorded time for this main thread animation should be the total time
- // between the two new tree activations, which is 234 + 654 = 888.
- histogram_tester.ExpectBucketCount(
- "Scheduling.Renderer.DrawIntervalWithMainThreadAnimations2", 888, 1);
-
- DrawImplFrame(123, 1, 0);
- TestAnimationUMA(histogram_tester, 3, 1);
- histogram_tester.ExpectBucketCount(
- "Scheduling.Renderer.DrawIntervalWithCompositedAnimations2", 123, 1);
-}
-
-} // namespace
-} // namespace cc
diff --git a/chromium/cc/scheduler/scheduler.cc b/chromium/cc/scheduler/scheduler.cc
index 61073cebb06..6a14640dcbb 100644
--- a/chromium/cc/scheduler/scheduler.cc
+++ b/chromium/cc/scheduler/scheduler.cc
@@ -13,7 +13,7 @@
#include "base/trace_event/trace_event.h"
#include "base/trace_event/traced_value.h"
#include "cc/base/devtools_instrumentation.h"
-#include "cc/scheduler/compositor_timing_history.h"
+#include "cc/metrics/compositor_timing_history.h"
#include "components/viz/common/frame_sinks/delay_based_time_source.h"
namespace cc {
diff --git a/chromium/cc/scheduler/scheduler_state_machine.cc b/chromium/cc/scheduler/scheduler_state_machine.cc
index 7ec7152365a..dbbe56848fa 100644
--- a/chromium/cc/scheduler/scheduler_state_machine.cc
+++ b/chromium/cc/scheduler/scheduler_state_machine.cc
@@ -1234,13 +1234,13 @@ bool SchedulerStateMachine::ShouldBlockDeadlineIndefinitely() const {
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_begin_main_frame_, as this may negatively
- // affect animation smoothness during resize or orientation changes.
+ // Do not wait for main frame to be ready for commits if in full-pipe mode,
+ // if we're deferring commits, as the main thread may be blocked on paused
+ // virtual time, causing deadlock against external frame control.
if (defer_begin_main_frame_ &&
- settings_.wait_for_all_pipeline_stages_before_draw)
- return true;
+ settings_.wait_for_all_pipeline_stages_before_draw) {
+ return false;
+ }
// Wait for main frame if one is in progress or about to be started.
if (ShouldSendBeginMainFrame())
diff --git a/chromium/cc/scheduler/scheduler_state_machine_unittest.cc b/chromium/cc/scheduler/scheduler_state_machine_unittest.cc
index 9e1adff48c4..6e080e666fe 100644
--- a/chromium/cc/scheduler/scheduler_state_machine_unittest.cc
+++ b/chromium/cc/scheduler/scheduler_state_machine_unittest.cc
@@ -2540,13 +2540,12 @@ TEST(SchedulerStateMachineTest, TestFullPipelineMode) {
// Begin the frame.
state.OnBeginImplFrame(0, 10, kAnimateOnly);
- // We are blocking because we need a main frame.
EXPECT_EQ(SchedulerStateMachine::BeginImplFrameDeadlineMode::BLOCKED,
state.CurrentBeginImplFrameDeadlineMode());
- // Even if main thread defers commits, we still need to wait for it.
+ // If main thread defers commits, don't wait for it.
state.SetDeferBeginMainFrame(true);
- EXPECT_EQ(SchedulerStateMachine::BeginImplFrameDeadlineMode::BLOCKED,
+ EXPECT_EQ(SchedulerStateMachine::BeginImplFrameDeadlineMode::IMMEDIATE,
state.CurrentBeginImplFrameDeadlineMode());
state.SetDeferBeginMainFrame(false);
diff --git a/chromium/cc/scheduler/scheduler_unittest.cc b/chromium/cc/scheduler/scheduler_unittest.cc
index 46882a54cc4..5f9a7223698 100644
--- a/chromium/cc/scheduler/scheduler_unittest.cc
+++ b/chromium/cc/scheduler/scheduler_unittest.cc
@@ -699,7 +699,7 @@ TEST_F(SchedulerTest, RequestCommit) {
client_->Reset();
}
-TEST_F(SchedulerTest, RequestCommitAfterSetDeferCommit) {
+TEST_F(SchedulerTest, RequestCommitAfterSetDeferBeginMainFrame) {
SetUpScheduler(EXTERNAL_BFS);
scheduler_->SetDeferBeginMainFrame(true);
@@ -724,7 +724,7 @@ TEST_F(SchedulerTest, RequestCommitAfterSetDeferCommit) {
EXPECT_TRUE(client_->IsInsideBeginImplFrame());
}
-TEST_F(SchedulerTest, DeferCommitWithRedraw) {
+TEST_F(SchedulerTest, DeferBeginMainFrameWithRedraw) {
SetUpScheduler(EXTERNAL_BFS);
scheduler_->SetDeferBeginMainFrame(true);
@@ -4056,10 +4056,10 @@ TEST_F(SchedulerTest, WaitForAllPipelineStagesAlwaysObservesBeginFrames) {
EXPECT_TRUE(client_->IsInsideBeginImplFrame());
client_->Reset();
- // BeginFrame deadline is blocked because commits are deferred.
+ // BeginFrame deadline is not blocked because commits are deferred.
task_runner_->RunPendingTasks();
EXPECT_ACTIONS();
- EXPECT_TRUE(client_->IsInsideBeginImplFrame());
+ EXPECT_TRUE(!client_->IsInsideBeginImplFrame());
client_->Reset();
}