Commit 6be7ecdc authored by Nicolas Pena's avatar Nicolas Pena Committed by Commit Bot

EQT: Skip steps when renderer is backgrounded

In this CL, the QueueingTimeEstimator only uses visible steps for
calculating Expected Queueing Time. A step is considered visible if
the renderer was never backgrounded throughout the step (excluding
possible changes at exact start or end of step). A window may thus be
made up of steps that are not contiguous in time. The objective of this
CL is to start reducing the massive concentration of the UMA stats for
Expected Queueing Time on the 0-1 ms bucket, because that is not very
useful and not a good indicator of latency.

Bug: chromium:729033
Change-Id: I3cfd4d3268d0f2858fc77de25c08d35a7a1cfc36
Reviewed-on: https://chromium-review.googlesource.com/587588
Commit-Queue: Nicolás Peña <npm@chromium.org>
Reviewed-by: default avatarTimothy Dresser <tdresser@chromium.org>
Reviewed-by: default avatarAlexander Timin <altimin@chromium.org>
Cr-Commit-Position: refs/heads/master@{#491773}
parent 64a33c33
......@@ -29,25 +29,28 @@ constexpr base::TimeDelta kInvalidTaskThreshold =
// duration if R does fall in this range.
base::TimeDelta ExpectedQueueingTimeFromTask(base::TimeTicks task_start,
base::TimeTicks task_end,
base::TimeTicks window_start,
base::TimeTicks window_end) {
DCHECK(task_start <= task_end);
DCHECK(task_start <= window_end);
DCHECK(window_start < window_end);
DCHECK(task_end >= window_start);
base::TimeTicks task_in_window_start_time =
std::max(task_start, window_start);
base::TimeTicks task_in_window_end_time = std::min(task_end, window_end);
DCHECK(task_in_window_end_time <= task_in_window_end_time);
base::TimeTicks step_start,
base::TimeTicks step_end) {
DCHECK_LE(task_start, task_end);
DCHECK_LE(task_start, step_end);
DCHECK_LT(step_start, step_end);
// Because we skip steps when the renderer is backgrounded, we may have gone
// into the future, and in that case we ignore this task completely.
if (task_end < step_start)
return base::TimeDelta();
base::TimeTicks task_in_step_start_time = std::max(task_start, step_start);
base::TimeTicks task_in_step_end_time = std::min(task_end, step_end);
DCHECK_LE(task_in_step_end_time, task_in_step_end_time);
double probability_of_this_task =
static_cast<double>((task_in_window_end_time - task_in_window_start_time)
.InMicroseconds()) /
(window_end - window_start).InMicroseconds();
static_cast<double>(
(task_in_step_end_time - task_in_step_start_time).InMicroseconds()) /
(step_end - step_start).InMicroseconds();
base::TimeDelta expected_queueing_duration_within_task =
((task_end - task_in_window_start_time) +
(task_end - task_in_window_end_time)) /
((task_end - task_in_step_start_time) +
(task_end - task_in_step_end_time)) /
2;
return base::TimeDelta::FromMillisecondsD(
......@@ -62,7 +65,7 @@ QueueingTimeEstimator::QueueingTimeEstimator(
base::TimeDelta window_duration,
int steps_per_window)
: client_(client), state_(steps_per_window) {
DCHECK(steps_per_window >= 1);
DCHECK_GE(steps_per_window, 1);
state_.window_duration = window_duration;
state_.window_step_width = window_duration / steps_per_window;
}
......@@ -72,7 +75,7 @@ QueueingTimeEstimator::QueueingTimeEstimator(const State& state)
void QueueingTimeEstimator::OnTopLevelTaskStarted(
base::TimeTicks task_start_time) {
state_.OnTopLevelTaskStarted(task_start_time);
state_.OnTopLevelTaskStarted(client_, task_start_time);
}
void QueueingTimeEstimator::OnTopLevelTaskCompleted(
......@@ -84,58 +87,103 @@ void QueueingTimeEstimator::OnBeginNestedRunLoop() {
state_.OnBeginNestedRunLoop();
}
void QueueingTimeEstimator::OnRendererStateChanged(
bool backgrounded,
base::TimeTicks transition_time) {
state_.OnRendererStateChanged(client_, backgrounded, transition_time);
}
QueueingTimeEstimator::State::State(int steps_per_window)
: step_queueing_times(steps_per_window) {}
void QueueingTimeEstimator::State::OnTopLevelTaskStarted(
QueueingTimeEstimator::Client* client,
base::TimeTicks task_start_time) {
AdvanceTime(client, task_start_time);
current_task_start_time = task_start_time;
processing_task = true;
}
void QueueingTimeEstimator::State::OnTopLevelTaskCompleted(
QueueingTimeEstimator::Client* client,
base::TimeTicks task_end_time) {
if (in_nested_message_loop_) {
in_nested_message_loop_ = false;
DCHECK(processing_task);
AdvanceTime(client, task_end_time);
processing_task = false;
current_task_start_time = base::TimeTicks();
in_nested_message_loop_ = false;
}
void QueueingTimeEstimator::State::OnBeginNestedRunLoop() {
in_nested_message_loop_ = true;
}
void QueueingTimeEstimator::State::OnRendererStateChanged(
QueueingTimeEstimator::Client* client,
bool backgrounded,
base::TimeTicks transition_time) {
DCHECK_NE(backgrounded, renderer_backgrounded);
if (!processing_task)
AdvanceTime(client, transition_time);
renderer_backgrounded = backgrounded;
}
void QueueingTimeEstimator::State::AdvanceTime(
QueueingTimeEstimator::Client* client,
base::TimeTicks current_time) {
if (in_nested_message_loop_)
return;
if (step_start_time.is_null()) {
// Ignore any time before the first task.
if (!processing_task)
return;
step_start_time = current_task_start_time;
}
if (renderer_backgrounded) {
// Skip steps when the renderer was backgrounded. May cause
// |step_start_time| to go slightly into the future.
step_start_time =
current_time.SnappedToNextTick(step_start_time, window_step_width);
step_expected_queueing_time = base::TimeDelta();
return;
}
if (window_start_time.is_null())
window_start_time = current_task_start_time;
if (task_end_time - current_task_start_time > kInvalidTaskThreshold) {
if (processing_task &&
current_time - current_task_start_time > kInvalidTaskThreshold) {
// This task took too long, so we'll pretend it never happened. This could
// be because the user's machine went to sleep during a task.
current_task_start_time = base::TimeTicks();
return;
}
while (TimePastWindowEnd(task_end_time)) {
if (!TimePastWindowEnd(current_task_start_time)) {
while (TimePastStepEnd(current_time)) {
if (processing_task) {
// Include the current task in this window.
step_expected_queueing_time += ExpectedQueueingTimeFromTask(
current_task_start_time, task_end_time, window_start_time,
window_start_time + window_step_width);
current_task_start_time, current_time, step_start_time,
step_start_time + window_step_width);
}
step_queueing_times.Add(step_expected_queueing_time);
// RendererScheduler reports the queueing time once per disjoint window.
// |stepEQT|stepEQT|stepEQT|stepEQT|stepEQT|stepEQT|
// Report: |-------window EQT------|
// Discard: |-------window EQT------|
// Discard: |-------window EQT------|
// Report: |-------window EQT------|
client->OnQueueingTimeForWindowEstimated(step_queueing_times.GetAverage(),
window_start_time);
window_start_time += window_step_width;
step_queueing_times.IndexIsZero());
step_start_time += window_step_width;
step_expected_queueing_time = base::TimeDelta();
}
if (processing_task) {
step_expected_queueing_time += ExpectedQueueingTimeFromTask(
current_task_start_time, task_end_time, window_start_time,
window_start_time + window_step_width);
current_task_start_time = base::TimeTicks();
}
void QueueingTimeEstimator::State::OnBeginNestedRunLoop() {
in_nested_message_loop_ = true;
current_task_start_time, current_time, step_start_time,
step_start_time + window_step_width);
}
}
bool QueueingTimeEstimator::State::TimePastWindowEnd(base::TimeTicks time) {
return time > window_start_time + window_step_width;
bool QueueingTimeEstimator::State::TimePastStepEnd(base::TimeTicks time) {
return time >= step_start_time + window_step_width;
}
QueueingTimeEstimator::RunningAverage::RunningAverage(int size) {
......@@ -158,13 +206,16 @@ base::TimeDelta QueueingTimeEstimator::RunningAverage::GetAverage() const {
return running_sum_ / circular_buffer_.size();
}
bool QueueingTimeEstimator::RunningAverage::IndexIsZero() const {
return index_ == 0;
}
// Keeps track of the queueing time.
class RecordQueueingTimeClient : public QueueingTimeEstimator::Client {
public:
// QueueingTimeEstimator::Client implementation:
void OnQueueingTimeForWindowEstimated(
base::TimeDelta queueing_time,
base::TimeTicks window_start_time) override {
void OnQueueingTimeForWindowEstimated(base::TimeDelta queueing_time,
bool is_disjoint_window) override {
queueing_time_ = queueing_time;
}
......@@ -189,8 +240,11 @@ base::TimeDelta QueueingTimeEstimator::EstimateQueueingTimeIncludingCurrentTask(
// If there's a task in progress, pretend it ends now, and include it in the
// computation. If there's no task in progress, add an empty task to flush any
// stale windows.
if (temporary_queueing_time_estimator_state.current_task_start_time.is_null())
temporary_queueing_time_estimator_state.OnTopLevelTaskStarted(now);
if (temporary_queueing_time_estimator_state.current_task_start_time
.is_null()) {
temporary_queueing_time_estimator_state.OnTopLevelTaskStarted(
&record_queueing_time_client, now);
}
temporary_queueing_time_estimator_state.OnTopLevelTaskCompleted(
&record_queueing_time_client, now);
......
......@@ -20,9 +20,8 @@ class PLATFORM_EXPORT QueueingTimeEstimator {
public:
class PLATFORM_EXPORT Client {
public:
virtual void OnQueueingTimeForWindowEstimated(
base::TimeDelta queueing_time,
base::TimeTicks window_start_time) = 0;
virtual void OnQueueingTimeForWindowEstimated(base::TimeDelta queueing_time,
bool is_disjoint_window) = 0;
Client() {}
virtual ~Client() {}
......@@ -36,9 +35,10 @@ class PLATFORM_EXPORT QueueingTimeEstimator {
int GetStepsPerWindow() const;
void Add(base::TimeDelta bin_value);
base::TimeDelta GetAverage() const;
bool IndexIsZero() const;
private:
int index_;
size_t index_;
std::vector<base::TimeDelta> circular_buffer_;
base::TimeDelta running_sum_;
};
......@@ -46,9 +46,12 @@ class PLATFORM_EXPORT QueueingTimeEstimator {
class State {
public:
explicit State(int steps_per_window);
void OnTopLevelTaskStarted(base::TimeTicks task_start_time);
void OnTopLevelTaskStarted(Client* client, base::TimeTicks task_start_time);
void OnTopLevelTaskCompleted(Client* client, base::TimeTicks task_end_time);
void OnBeginNestedRunLoop();
void OnRendererStateChanged(Client* client,
bool backgrounded,
base::TimeTicks transition_time);
// |step_expected_queueing_time| is the expected queuing time of a
// smaller window of a step's width. By combining these step EQTs through a
......@@ -83,12 +86,16 @@ class PLATFORM_EXPORT QueueingTimeEstimator {
// sliding window's step width, and the number of bins of the circular
// buffer.
int steps_per_window;
base::TimeTicks window_start_time;
base::TimeTicks step_start_time;
base::TimeTicks current_task_start_time;
RunningAverage step_queueing_times;
// |renderer_backgrounded| is the renderer's current status.
bool renderer_backgrounded = false;
bool processing_task = false;
private:
bool TimePastWindowEnd(base::TimeTicks task_end_time);
void AdvanceTime(Client* client, base::TimeTicks current_time);
bool TimePastStepEnd(base::TimeTicks task_end_time);
bool in_nested_message_loop_ = false;
};
......@@ -100,6 +107,8 @@ class PLATFORM_EXPORT QueueingTimeEstimator {
void OnTopLevelTaskStarted(base::TimeTicks task_start_time);
void OnTopLevelTaskCompleted(base::TimeTicks task_end_time);
void OnBeginNestedRunLoop();
void OnRendererStateChanged(bool backgrounded,
base::TimeTicks transition_time);
// Returns all state except for the current |client_|.
const State& GetState() const { return state_; }
......
......@@ -15,9 +15,8 @@ using QueueingTimeEstimatorTest = ::testing::Test;
class TestQueueingTimeEstimatorClient : public QueueingTimeEstimator::Client {
public:
void OnQueueingTimeForWindowEstimated(
base::TimeDelta queueing_time,
base::TimeTicks window_start_time) override {
void OnQueueingTimeForWindowEstimated(base::TimeDelta queueing_time,
bool is_disjoint_window) override {
expected_queueing_times_.push_back(queueing_time);
}
const std::vector<base::TimeDelta>& expected_queueing_times() {
......@@ -329,8 +328,8 @@ TEST_F(QueueingTimeEstimatorTest, SlidingWindowOverOneTask) {
estimator.OnTopLevelTaskStarted(time);
estimator.OnTopLevelTaskCompleted(time);
EXPECT_THAT(client.expected_queueing_times(),
::testing::ElementsAre(base::TimeDelta::FromMilliseconds(900),
std::vector<base::TimeDelta> expected_durations = {
base::TimeDelta::FromMilliseconds(900),
base::TimeDelta::FromMilliseconds(1600),
base::TimeDelta::FromMilliseconds(2100),
base::TimeDelta::FromMilliseconds(2400),
......@@ -339,7 +338,10 @@ TEST_F(QueueingTimeEstimatorTest, SlidingWindowOverOneTask) {
base::TimeDelta::FromMilliseconds(900),
base::TimeDelta::FromMilliseconds(400),
base::TimeDelta::FromMilliseconds(100),
base::TimeDelta::FromMilliseconds(0)));
base::TimeDelta::FromMilliseconds(0),
base::TimeDelta::FromMilliseconds(0)};
EXPECT_THAT(client.expected_queueing_times(),
::testing::ElementsAreArray(expected_durations));
}
// ^ Instantaneous queuing time
......@@ -386,6 +388,7 @@ TEST_F(QueueingTimeEstimatorTest, SlidingWindowOverTwoTasksWithinFirstWindow) {
base::TimeDelta::FromMilliseconds(325),
base::TimeDelta::FromMilliseconds(125),
base::TimeDelta::FromMilliseconds(100),
base::TimeDelta::FromMilliseconds(0),
base::TimeDelta::FromMilliseconds(0)};
EXPECT_THAT(client.expected_queueing_times(),
::testing::ElementsAreArray(expected_durations));
......@@ -448,5 +451,142 @@ TEST_F(QueueingTimeEstimatorTest,
::testing::ElementsAreArray(expected_durations));
}
// There are multiple windows, but some of the EQTs are not reported due to
// backgrounded renderer. EQT(win1) = 0. EQT(win3) = (1500+500)/2 = 1000.
// EQT(win4) = 1/2*500/2 = 250. EQT(win7) = 1/5*200/2 = 20.
TEST_F(QueueingTimeEstimatorTest, BackgroundedEQTsWithSingleStepPerWindow) {
TestQueueingTimeEstimatorClient client;
QueueingTimeEstimatorForTest estimator(&client,
base::TimeDelta::FromSeconds(1), 1);
base::TimeTicks time;
time += base::TimeDelta::FromMilliseconds(1000);
estimator.OnTopLevelTaskStarted(time);
estimator.OnTopLevelTaskCompleted(time);
time += base::TimeDelta::FromMilliseconds(1001);
// Second window should not be reported.
estimator.OnRendererStateChanged(true, time);
estimator.OnTopLevelTaskStarted(time);
time += base::TimeDelta::FromMilliseconds(456);
estimator.OnTopLevelTaskCompleted(time);
time += base::TimeDelta::FromMilliseconds(200);
estimator.OnRendererStateChanged(false, time);
time += base::TimeDelta::FromMilliseconds(343);
// Third, fourth windows should be reported
estimator.OnTopLevelTaskStarted(time);
time += base::TimeDelta::FromMilliseconds(1500);
estimator.OnTopLevelTaskCompleted(time);
time += base::TimeDelta::FromMilliseconds(501);
// Fifth, sixth task should not be reported
estimator.OnTopLevelTaskStarted(time);
time += base::TimeDelta::FromMilliseconds(800);
estimator.OnTopLevelTaskCompleted(time);
estimator.OnRendererStateChanged(true, time);
time += base::TimeDelta::FromMilliseconds(200);
estimator.OnRendererStateChanged(false, time);
estimator.OnTopLevelTaskStarted(time);
time += base::TimeDelta::FromMilliseconds(999);
// Seventh task should be reported.
time += base::TimeDelta::FromMilliseconds(200);
estimator.OnTopLevelTaskCompleted(time);
time += base::TimeDelta::FromMilliseconds(1000);
estimator.OnTopLevelTaskStarted(time);
estimator.OnTopLevelTaskCompleted(time);
EXPECT_THAT(client.expected_queueing_times(),
::testing::ElementsAre(base::TimeDelta::FromMilliseconds(0),
base::TimeDelta::FromMilliseconds(1000),
base::TimeDelta::FromMilliseconds(125),
base::TimeDelta::FromMilliseconds(20)));
}
// We only ignore steps that contain some part that is backgrounded. Thus a
// window could be made up of non-contiguous steps. The following are EQTs, with
// time deltas with respect to the end of the first, 0-time task:
// Win1: [0-1000]. EQT of step [0-1000]: 500/2*1/2 = 125. EQT(win1) = 125/5 =
// 25.
// Win2: [0-1000],[2000-3000]. EQT of [2000-3000]: (1000+200)/2*4/5 = 480.
// EQT(win2) = (125+480)/5 = 121.
// Win3: [0-1000],[2000-3000],[11000-12000]. EQT of [11000-12000]: 0. EQT(win3)
// = 121.
// Win4: [0-1000],[2000-3000],[11000-13000]. EQT of [12000-13000]:
// (1500+1400)/2*1/10 = 145. EQT(win4) = (125+480+0+145)/5 = 150.
// Win5: [0-1000],[2000-3000],[11000-14000]. EQT of [13000-14000]: (1400+400)/2
// = 900. EQT(win5) = (125+480+0+145+900)/5 = 330.
// Win6: [2000-3000],[11000-15000]. EQT of [14000-15000]: 400/2*2/5 = 80.
// EQT(win6) = (480+0+145+900+80)/5 = 321.
// Win7: [11000-16000]. EQT of [15000-16000]: (2500+1700)/2*4/5 = 1680.
// EQT(win7) = (0+145+900+80+1680)/5 = 561.
// Win8: [12000-17000]. EQT of [16000-17000]: (1700+700)/2 = 1200. EQT(win8) =
// (145+900+80+1680+1200)/5 = 801.
TEST_F(QueueingTimeEstimatorTest, BackgroundedEQTsWithMutipleStepsPerWindow) {
TestQueueingTimeEstimatorClient client;
QueueingTimeEstimatorForTest estimator(&client,
base::TimeDelta::FromSeconds(5), 5);
base::TimeTicks time;
time += base::TimeDelta::FromMilliseconds(5000);
estimator.OnTopLevelTaskStarted(time);
estimator.OnTopLevelTaskCompleted(time);
time += base::TimeDelta::FromMilliseconds(500);
estimator.OnTopLevelTaskStarted(time);
time += base::TimeDelta::FromMilliseconds(500);
estimator.OnTopLevelTaskCompleted(time);
estimator.OnRendererStateChanged(true, time);
// This task should be ignored.
estimator.OnTopLevelTaskStarted(time);
time += base::TimeDelta::FromMilliseconds(800);
estimator.OnTopLevelTaskCompleted(time);
estimator.OnRendererStateChanged(false, time);
time += base::TimeDelta::FromMilliseconds(400);
estimator.OnTopLevelTaskStarted(time);
time += base::TimeDelta::FromMilliseconds(1000);
estimator.OnTopLevelTaskCompleted(time);
time += base::TimeDelta::FromMilliseconds(300);
estimator.OnRendererStateChanged(true, time);
time += base::TimeDelta::FromMilliseconds(2000);
// These tasks should be ignored.
estimator.OnTopLevelTaskStarted(time);
time += base::TimeDelta::FromMilliseconds(2000);
estimator.OnTopLevelTaskCompleted(time);
estimator.OnTopLevelTaskStarted(time);
time += base::TimeDelta::FromMilliseconds(3400);
estimator.OnTopLevelTaskCompleted(time);
estimator.OnRendererStateChanged(false, time);
time += base::TimeDelta::FromMilliseconds(2000);
estimator.OnTopLevelTaskStarted(time);
time += base::TimeDelta::FromMilliseconds(1500);
estimator.OnTopLevelTaskCompleted(time);
time += base::TimeDelta::FromMilliseconds(800);
estimator.OnTopLevelTaskStarted(time);
time += base::TimeDelta::FromMilliseconds(2500);
estimator.OnTopLevelTaskCompleted(time);
// Window with last step should not be reported.
estimator.OnRendererStateChanged(true, time);
time += base::TimeDelta::FromMilliseconds(1000);
estimator.OnTopLevelTaskStarted(time);
estimator.OnTopLevelTaskCompleted(time);
EXPECT_THAT(client.expected_queueing_times(),
::testing::ElementsAre(base::TimeDelta::FromMilliseconds(25),
base::TimeDelta::FromMilliseconds(121),
base::TimeDelta::FromMilliseconds(121),
base::TimeDelta::FromMilliseconds(150),
base::TimeDelta::FromMilliseconds(330),
base::TimeDelta::FromMilliseconds(321),
base::TimeDelta::FromMilliseconds(561),
base::TimeDelta::FromMilliseconds(801)));
}
} // namespace scheduler
} // namespace blink
......@@ -599,6 +599,10 @@ void RendererSchedulerImpl::SetRendererBackgrounded(bool backgrounded) {
main_thread_only().renderer_paused = false;
main_thread_only().background_status_changed_at = tick_clock()->NowTicks();
seqlock_queueing_time_estimator_.seqlock.WriteBegin();
seqlock_queueing_time_estimator_.data.OnRendererStateChanged(
backgrounded, main_thread_only().background_status_changed_at);
seqlock_queueing_time_estimator_.seqlock.WriteEnd();
UpdatePolicy();
......@@ -1933,6 +1937,7 @@ void RendererSchedulerImpl::WillProcessTask(double start_time) {
base::TimeTicks start_time_ticks =
MonotonicTimeInSecondsToTimeTicks(start_time);
main_thread_only().current_task_start_time = start_time_ticks;
seqlock_queueing_time_estimator_.seqlock.WriteBegin();
seqlock_queueing_time_estimator_.data.OnTopLevelTaskStarted(start_time_ticks);
seqlock_queueing_time_estimator_.seqlock.WriteEnd();
......@@ -2216,7 +2221,7 @@ void RendererSchedulerImpl::RemoveTaskTimeObserver(
void RendererSchedulerImpl::OnQueueingTimeForWindowEstimated(
base::TimeDelta queueing_time,
base::TimeTicks window_start_time) {
bool is_disjoint_window) {
main_thread_only().most_recent_expected_queueing_time = queueing_time;
if (main_thread_only().has_navigated) {
......@@ -2231,24 +2236,14 @@ void RendererSchedulerImpl::OnQueueingTimeForWindowEstimated(
}
}
// RendererScheduler reports the queueing time once per window's duration.
// |stepEQT|stepEQT|stepEQT|stepEQT|stepEQT|stepEQT|
// Report: |-------window EQT------|
// Discard: |-------window EQT------|
// Discard: |-------window EQT------|
// Report: |-------window EQT------|
if (window_start_time -
main_thread_only().uma_last_queueing_time_report_window_start_time <
kQueueingTimeWindowDuration) {
if (!is_disjoint_window)
return;
}
UMA_HISTOGRAM_TIMES("RendererScheduler.ExpectedTaskQueueingDuration",
queueing_time);
TRACE_COUNTER1(TRACE_DISABLED_BY_DEFAULT("renderer.scheduler"),
"estimated_queueing_time_for_window",
queueing_time.InMillisecondsF());
main_thread_only().uma_last_queueing_time_report_window_start_time =
window_start_time;
}
AutoAdvancingVirtualTimeDomain* RendererSchedulerImpl::GetVirtualTimeDomain() {
......
......@@ -142,9 +142,8 @@ class PLATFORM_EXPORT RendererSchedulerImpl
void OnBeginNestedRunLoop() override;
// QueueingTimeEstimator::Client implementation:
void OnQueueingTimeForWindowEstimated(
base::TimeDelta queueing_time,
base::TimeTicks window_start_time) override;
void OnQueueingTimeForWindowEstimated(base::TimeDelta queueing_time,
bool is_disjoint_window) override;
scoped_refptr<MainThreadTaskQueue> DefaultTaskQueue();
scoped_refptr<MainThreadTaskQueue> CompositorTaskQueue();
......@@ -568,7 +567,6 @@ class PLATFORM_EXPORT RendererSchedulerImpl
base::TimeTicks current_policy_expiration_time;
base::TimeTicks estimated_next_frame_begin;
base::TimeTicks current_task_start_time;
base::TimeTicks uma_last_queueing_time_report_window_start_time;
base::TimeDelta most_recent_expected_queueing_time;
base::TimeDelta compositor_frame_interval;
base::TimeDelta longest_jank_free_task_duration;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment