diff options
author | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-01-20 13:40:20 +0100 |
---|---|---|
committer | Allan Sandfeld Jensen <allan.jensen@qt.io> | 2020-01-22 12:41:23 +0000 |
commit | 7961cea6d1041e3e454dae6a1da660b453efd238 (patch) | |
tree | c0eeb4a9ff9ba32986289c1653d9608e53ccb444 /chromium/cc/scheduler | |
parent | b7034d0803538058e5c9d904ef03cf5eab34f6ef (diff) | |
download | qtwebengine-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.cc | 227 | ||||
-rw-r--r-- | chromium/cc/scheduler/compositor_frame_reporter.h | 129 | ||||
-rw-r--r-- | chromium/cc/scheduler/compositor_frame_reporter_unittest.cc | 298 | ||||
-rw-r--r-- | chromium/cc/scheduler/compositor_frame_reporting_controller.cc | 217 | ||||
-rw-r--r-- | chromium/cc/scheduler/compositor_frame_reporting_controller.h | 93 | ||||
-rw-r--r-- | chromium/cc/scheduler/compositor_frame_reporting_controller_unittest.cc | 234 | ||||
-rw-r--r-- | chromium/cc/scheduler/compositor_timing_history.cc | 954 | ||||
-rw-r--r-- | chromium/cc/scheduler/compositor_timing_history.h | 183 | ||||
-rw-r--r-- | chromium/cc/scheduler/compositor_timing_history_unittest.cc | 455 | ||||
-rw-r--r-- | chromium/cc/scheduler/scheduler.cc | 2 | ||||
-rw-r--r-- | chromium/cc/scheduler/scheduler_state_machine.cc | 12 | ||||
-rw-r--r-- | chromium/cc/scheduler/scheduler_state_machine_unittest.cc | 5 | ||||
-rw-r--r-- | chromium/cc/scheduler/scheduler_unittest.cc | 8 |
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(); } |