Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(78)

Side by Side Diff: content/renderer/scheduler/renderer_scheduler_impl.cc

Issue 664963002: content: Add RendererScheduler. (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 6 years, 1 month ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
1 // Copyright 2014 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
4
5 #include "content/renderer/scheduler/renderer_scheduler_impl.h"
6
7 #include "base/bind.h"
8 #include "base/message_loop/message_loop_proxy.h"
9 #include "cc/output/begin_frame_args.h"
10 #include "content/renderer/scheduler/renderer_scheduler_selector.h"
11 #include "ui/gfx/frame_time.h"
12
13 namespace content {
14
15 RendererSchedulerImpl::RendererSchedulerImpl()
16 : RendererSchedulerImpl(base::MessageLoopProxy::current()) {
17 }
18
19 RendererSchedulerImpl::RendererSchedulerImpl(
20 scoped_refptr<base::SingleThreadTaskRunner> main_task_runner)
21 : renderer_scheduler_selector_(new RendererSchedulerSelector()),
22 task_queue_manager_(
23 new TaskQueueManager(kTaskQueueCount,
24 main_task_runner,
25 renderer_scheduler_selector_.get())),
26 control_task_runner_(
27 task_queue_manager_->TaskRunnerForQueue(kControlTaskQueue)),
28 default_task_runner_(
29 task_queue_manager_->TaskRunnerForQueue(kDefaultTaskQueue)),
30 compositor_task_runner_(
31 task_queue_manager_->TaskRunnerForQueue(kCompositorTaskQueue)),
32 current_policy_(kNormalPriorityPolicy),
33 policy_may_need_update_(0),
34 weak_factory_(this) {
35 weak_renderer_scheduler_ptr_ = weak_factory_.GetWeakPtr();
36 idle_task_runner_ = make_scoped_refptr(new SingleThreadIdleTaskRunner(
37 task_queue_manager_->TaskRunnerForQueue(kIdleTaskQueue),
38 weak_factory_.GetWeakPtr()));
39 renderer_scheduler_selector_->SetQueuePriority(
40 kControlTaskQueue, RendererSchedulerSelector::kControlPriority);
41 renderer_scheduler_selector_->DisableQueue(kIdleTaskQueue);
42 task_queue_manager_->SetAutoPump(kIdleTaskQueue, false);
43 }
44
45 RendererSchedulerImpl::~RendererSchedulerImpl() {
46 }
47
48 void RendererSchedulerImpl::Shutdown() {
49 task_queue_manager_.reset();
50 }
51
52 scoped_refptr<base::SingleThreadTaskRunner>
53 RendererSchedulerImpl::DefaultTaskRunner() {
54 return default_task_runner_;
alexclarke 2014/10/27 17:35:29 Maybe add DCHECK(task_queue_manager_). It would b
rmcilroy 2014/10/27 18:18:02 This doesn't really help though - whether or not t
55 }
56
57 scoped_refptr<base::SingleThreadTaskRunner>
58 RendererSchedulerImpl::CompositorTaskRunner() {
59 return compositor_task_runner_;
60 }
61
62 scoped_refptr<SingleThreadIdleTaskRunner>
63 RendererSchedulerImpl::IdleTaskRunner() {
64 return idle_task_runner_;
65 }
66
67 void RendererSchedulerImpl::WillBeginFrame(const cc::BeginFrameArgs& args) {
68 main_thread_checker_.CalledOnValidThread();
69 if (!task_queue_manager_)
70 return;
71
72 EndIdlePeriod();
73 estimated_next_frame_begin_ = args.frame_time + args.interval;
74 }
75
76 void RendererSchedulerImpl::DidCommitFrameToCompositor() {
77 main_thread_checker_.CalledOnValidThread();
78 if (!task_queue_manager_)
79 return;
80
81 if (Now() < estimated_next_frame_begin_) {
82 StartIdlePeriod();
83 }
84 }
85
86 void RendererSchedulerImpl::DidReceiveInputEvent() {
87 if (!task_queue_manager_)
88 return;
89 base::AutoLock lock(incoming_signals_lock_);
90 if (last_input_time_.is_null()) {
91 // Update scheduler policy if should start a new compositor policy mode.
92 base::subtle::Release_Store(&policy_may_need_update_, 1);
93 PostUpdatePolicyOnControlRunner(base::TimeDelta());
94 }
95 last_input_time_ = Now();
96 }
97
98 bool RendererSchedulerImpl::ShouldYieldForHighPriorityWork() {
99 main_thread_checker_.CalledOnValidThread();
100 if (!task_queue_manager_)
101 return false;
102
103 return SchedulerPolicy() == kCompositorPriorityPolicy &&
104 !task_queue_manager_->IsQueueEmpty(kCompositorTaskQueue);
105 }
106
107 base::TimeTicks RendererSchedulerImpl::CurrentIdleTaskDeadline() const {
108 main_thread_checker_.CalledOnValidThread();
109 return estimated_next_frame_begin_;
110 }
111
112 RendererSchedulerImpl::Policy RendererSchedulerImpl::SchedulerPolicy() {
113 main_thread_checker_.CalledOnValidThread();
114 if (base::subtle::Acquire_Load(&policy_may_need_update_)) {
115 UpdatePolicy();
116 }
117 return current_policy_;
118 }
119
120 void RendererSchedulerImpl::PostUpdatePolicyOnControlRunner(
121 base::TimeDelta delay) {
122 base::Closure closure = base::Bind(&RendererSchedulerImpl::UpdatePolicy,
123 weak_renderer_scheduler_ptr_);
alexclarke 2014/10/27 17:35:29 Hmm the weak pointer results in a check that the s
rmcilroy 2014/10/27 18:18:02 Done (although UpdatePolicy doesn't touch task_que
124 if (delay > base::TimeDelta()) {
125 control_task_runner_->PostDelayedTask(FROM_HERE, closure, delay);
126 } else {
127 control_task_runner_->PostTask(FROM_HERE, closure);
128 }
129 }
130
131 void RendererSchedulerImpl::UpdatePolicy() {
132 main_thread_checker_.CalledOnValidThread();
133 base::AutoLock lock(incoming_signals_lock_);
134 base::subtle::Release_Store(&policy_may_need_update_, 0);
135
136 Policy new_policy = kNormalPriorityPolicy;
137 if (!last_input_time_.is_null()) {
138 base::TimeDelta compositor_priority_duration =
139 base::TimeDelta::FromMilliseconds(kCompositorPriorityAfterTouchMillis);
140 base::TimeDelta remaining_compositor_priority_duration =
141 last_input_time_ + compositor_priority_duration - Now();
142 if (remaining_compositor_priority_duration > base::TimeDelta()) {
143 PostUpdatePolicyOnControlRunner(remaining_compositor_priority_duration);
144 new_policy = kCompositorPriorityPolicy;
145 } else {
146 // Null out last_input_time_ to ensure DidReceiveInputEvent will post an
147 // UpdatePolicy task when it's next called.
148 last_input_time_ = base::TimeTicks();
149 }
150 }
151
152 if (new_policy == current_policy_) {
153 return;
154 }
155
156 switch (new_policy) {
157 case kCompositorPriorityPolicy:
158 renderer_scheduler_selector_->SetQueuePriority(
159 kCompositorTaskQueue, RendererSchedulerSelector::kHighPriority);
160 break;
161 case kNormalPriorityPolicy:
162 renderer_scheduler_selector_->SetQueuePriority(
163 kCompositorTaskQueue, RendererSchedulerSelector::kNormalPriority);
164 break;
165 }
166 current_policy_ = new_policy;
167 }
168
169 void RendererSchedulerImpl::StartIdlePeriod() {
170 renderer_scheduler_selector_->EnableQueue(
171 kIdleTaskQueue, RendererSchedulerSelector::kBestEffortPriority);
172 task_queue_manager_->PumpQueue(kIdleTaskQueue);
alexclarke 2014/10/27 17:35:29 Is it worth mentioning that this function assumes
rmcilroy 2014/10/27 18:18:02 I don't think it's necessary to mention it for eve
173 }
174
175 void RendererSchedulerImpl::EndIdlePeriod() {
176 renderer_scheduler_selector_->DisableQueue(kIdleTaskQueue);
177 }
178
179 base::TimeTicks RendererSchedulerImpl::Now() const {
180 return gfx::FrameTime::Now();
181 }
182
183 } // namespace content
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698