summaryrefslogtreecommitdiff
path: root/chromium/third_party/blink/renderer/platform/scheduler/renderer/idle_time_estimator.cc
blob: 4ee87d3e6cb30184f9833cbc0b3ae56d146d3ec7 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
// 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 "third_party/blink/renderer/platform/scheduler/renderer/idle_time_estimator.h"

#include "base/time/default_tick_clock.h"

namespace blink {
namespace scheduler {

IdleTimeEstimator::IdleTimeEstimator(
    const scoped_refptr<TaskQueue>& compositor_task_runner,
    const base::TickClock* time_source,
    int sample_count,
    double estimation_percentile)
    : compositor_task_queue_(compositor_task_runner),
      per_frame_compositor_task_runtime_(sample_count),
      time_source_(time_source),
      estimation_percentile_(estimation_percentile),
      nesting_level_(0),
      did_commit_(false) {
  compositor_task_queue_->AddTaskObserver(this);
}

IdleTimeEstimator::~IdleTimeEstimator() {
  compositor_task_queue_->RemoveTaskObserver(this);
}

base::TimeDelta IdleTimeEstimator::GetExpectedIdleDuration(
    base::TimeDelta compositor_frame_interval) const {
  base::TimeDelta expected_compositor_task_runtime_ =
      per_frame_compositor_task_runtime_.Percentile(estimation_percentile_);
  return std::max(base::TimeDelta(), compositor_frame_interval -
                                         expected_compositor_task_runtime_);
}

void IdleTimeEstimator::DidCommitFrameToCompositor() {
  // This will run inside of a WillProcessTask / DidProcessTask pair, let
  // DidProcessTask know a frame was comitted.
  if (nesting_level_ == 1)
    did_commit_ = true;
}

void IdleTimeEstimator::Clear() {
  task_start_time_ = base::TimeTicks();
  prev_commit_time_ = base::TimeTicks();
  cumulative_compositor_runtime_ = base::TimeDelta();
  per_frame_compositor_task_runtime_.Clear();
  did_commit_ = false;
}

void IdleTimeEstimator::WillProcessTask(const base::PendingTask& pending_task) {
  nesting_level_++;
  if (nesting_level_ == 1)
    task_start_time_ = time_source_->NowTicks();
}

void IdleTimeEstimator::DidProcessTask(const base::PendingTask& pending_task) {
  nesting_level_--;
  DCHECK_GE(nesting_level_, 0);
  if (nesting_level_ != 0)
    return;

  cumulative_compositor_runtime_ += time_source_->NowTicks() - task_start_time_;

  if (did_commit_) {
    per_frame_compositor_task_runtime_.InsertSample(
        cumulative_compositor_runtime_);
    cumulative_compositor_runtime_ = base::TimeDelta();
    did_commit_ = false;
  }
}

}  // namespace scheduler
}  // namespace blink