OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "content/renderer/raster_worker_pool.h" | 5 #include "content/renderer/categorized_worker_pool.h" |
6 | 6 |
7 #include <string> | 7 #include <string> |
8 #include <utility> | 8 #include <utility> |
9 #include <vector> | 9 #include <vector> |
10 | 10 |
11 #include "base/strings/stringprintf.h" | 11 #include "base/strings/stringprintf.h" |
12 #include "base/threading/thread_restrictions.h" | 12 #include "base/threading/thread_restrictions.h" |
13 #include "base/trace_event/trace_event.h" | 13 #include "base/trace_event/trace_event.h" |
14 #include "cc/base/math_util.h" | 14 #include "cc/base/math_util.h" |
15 #include "cc/raster/task_category.h" | 15 #include "cc/raster/task_category.h" |
16 | 16 |
17 namespace content { | 17 namespace content { |
18 namespace { | 18 namespace { |
19 | 19 |
20 // A thread which forwards to RasterWorkerPool::Run with the runnable | 20 // A thread which forwards to CategorizedWorkerPool::Run with the runnable |
21 // categories. | 21 // categories. |
22 class RasterWorkerPoolThread : public base::SimpleThread { | 22 class CategorizedWorkerPoolThread : public base::SimpleThread { |
23 public: | 23 public: |
24 RasterWorkerPoolThread(const std::string& name_prefix, | 24 CategorizedWorkerPoolThread( |
25 const Options& options, | 25 const std::string& name_prefix, |
26 RasterWorkerPool* pool, | 26 const Options& options, |
27 std::vector<cc::TaskCategory> categories, | 27 CategorizedWorkerPool* pool, |
28 base::ConditionVariable* has_ready_to_run_tasks_cv) | 28 std::vector<cc::TaskCategory> categories, |
| 29 base::ConditionVariable* has_ready_to_run_tasks_cv) |
29 : SimpleThread(name_prefix, options), | 30 : SimpleThread(name_prefix, options), |
30 pool_(pool), | 31 pool_(pool), |
31 categories_(categories), | 32 categories_(categories), |
32 has_ready_to_run_tasks_cv_(has_ready_to_run_tasks_cv) {} | 33 has_ready_to_run_tasks_cv_(has_ready_to_run_tasks_cv) {} |
33 | 34 |
34 void Run() override { pool_->Run(categories_, has_ready_to_run_tasks_cv_); } | 35 void Run() override { pool_->Run(categories_, has_ready_to_run_tasks_cv_); } |
35 | 36 |
36 private: | 37 private: |
37 RasterWorkerPool* const pool_; | 38 CategorizedWorkerPool* const pool_; |
38 const std::vector<cc::TaskCategory> categories_; | 39 const std::vector<cc::TaskCategory> categories_; |
39 base::ConditionVariable* const has_ready_to_run_tasks_cv_; | 40 base::ConditionVariable* const has_ready_to_run_tasks_cv_; |
40 }; | 41 }; |
41 | 42 |
42 } // namespace | 43 } // namespace |
43 | 44 |
44 // A sequenced task runner which posts tasks to a RasterWorkerPool. | 45 // A sequenced task runner which posts tasks to a CategorizedWorkerPool. |
45 class RasterWorkerPool::RasterWorkerPoolSequencedTaskRunner | 46 class CategorizedWorkerPool::CategorizedWorkerPoolSequencedTaskRunner |
46 : public base::SequencedTaskRunner { | 47 : public base::SequencedTaskRunner { |
47 public: | 48 public: |
48 explicit RasterWorkerPoolSequencedTaskRunner( | 49 explicit CategorizedWorkerPoolSequencedTaskRunner( |
49 cc::TaskGraphRunner* task_graph_runner) | 50 cc::TaskGraphRunner* task_graph_runner) |
50 : task_graph_runner_(task_graph_runner), | 51 : task_graph_runner_(task_graph_runner), |
51 namespace_token_(task_graph_runner->GetNamespaceToken()) {} | 52 namespace_token_(task_graph_runner->GetNamespaceToken()) {} |
52 | 53 |
53 // Overridden from base::TaskRunner: | 54 // Overridden from base::TaskRunner: |
54 bool PostDelayedTask(const tracked_objects::Location& from_here, | 55 bool PostDelayedTask(const tracked_objects::Location& from_here, |
55 const base::Closure& task, | 56 const base::Closure& task, |
56 base::TimeDelta delay) override { | 57 base::TimeDelta delay) override { |
57 return PostNonNestableDelayedTask(from_here, task, delay); | 58 return PostNonNestableDelayedTask(from_here, task, delay); |
58 } | 59 } |
(...skipping 29 matching lines...) Expand all Loading... |
88 cc::TaskGraph::Edge(graph_.nodes.back().task, node.task)); | 89 cc::TaskGraph::Edge(graph_.nodes.back().task, node.task)); |
89 } | 90 } |
90 graph_.nodes.push_back(node); | 91 graph_.nodes.push_back(node); |
91 } | 92 } |
92 task_graph_runner_->ScheduleTasks(namespace_token_, &graph_); | 93 task_graph_runner_->ScheduleTasks(namespace_token_, &graph_); |
93 completed_tasks_.clear(); | 94 completed_tasks_.clear(); |
94 return true; | 95 return true; |
95 } | 96 } |
96 | 97 |
97 private: | 98 private: |
98 ~RasterWorkerPoolSequencedTaskRunner() override { | 99 ~CategorizedWorkerPoolSequencedTaskRunner() override { |
99 task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_); | 100 task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_); |
100 task_graph_runner_->CollectCompletedTasks(namespace_token_, | 101 task_graph_runner_->CollectCompletedTasks(namespace_token_, |
101 &completed_tasks_); | 102 &completed_tasks_); |
102 }; | 103 }; |
103 | 104 |
104 // Lock to exclusively access all the following members that are used to | 105 // Lock to exclusively access all the following members that are used to |
105 // implement the SequencedTaskRunner interfaces. | 106 // implement the SequencedTaskRunner interfaces. |
106 base::Lock lock_; | 107 base::Lock lock_; |
107 | 108 |
108 cc::TaskGraphRunner* task_graph_runner_; | 109 cc::TaskGraphRunner* task_graph_runner_; |
109 // Namespace used to schedule tasks in the task graph runner. | 110 // Namespace used to schedule tasks in the task graph runner. |
110 cc::NamespaceToken namespace_token_; | 111 cc::NamespaceToken namespace_token_; |
111 // List of tasks currently queued up for execution. | 112 // List of tasks currently queued up for execution. |
112 cc::Task::Vector tasks_; | 113 cc::Task::Vector tasks_; |
113 // Graph object used for scheduling tasks. | 114 // Graph object used for scheduling tasks. |
114 cc::TaskGraph graph_; | 115 cc::TaskGraph graph_; |
115 // Cached vector to avoid allocation when getting the list of complete | 116 // Cached vector to avoid allocation when getting the list of complete |
116 // tasks. | 117 // tasks. |
117 cc::Task::Vector completed_tasks_; | 118 cc::Task::Vector completed_tasks_; |
118 }; | 119 }; |
119 | 120 |
120 RasterWorkerPool::RasterWorkerPool() | 121 CategorizedWorkerPool::CategorizedWorkerPool() |
121 : namespace_token_(GetNamespaceToken()), | 122 : namespace_token_(GetNamespaceToken()), |
122 has_ready_to_run_foreground_tasks_cv_(&lock_), | 123 has_ready_to_run_foreground_tasks_cv_(&lock_), |
123 has_ready_to_run_background_tasks_cv_(&lock_), | 124 has_ready_to_run_background_tasks_cv_(&lock_), |
124 has_namespaces_with_finished_running_tasks_cv_(&lock_), | 125 has_namespaces_with_finished_running_tasks_cv_(&lock_), |
125 shutdown_(false) {} | 126 shutdown_(false) {} |
126 | 127 |
127 void RasterWorkerPool::Start(int num_threads) { | 128 void CategorizedWorkerPool::Start(int num_threads) { |
128 DCHECK(threads_.empty()); | 129 DCHECK(threads_.empty()); |
129 | 130 |
130 // Start |num_threads| threads for foreground work, including nonconcurrent | 131 // Start |num_threads| threads for foreground work, including nonconcurrent |
131 // foreground work. | 132 // foreground work. |
132 std::vector<cc::TaskCategory> foreground_categories; | 133 std::vector<cc::TaskCategory> foreground_categories; |
133 foreground_categories.push_back(cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND); | 134 foreground_categories.push_back(cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND); |
134 foreground_categories.push_back(cc::TASK_CATEGORY_FOREGROUND); | 135 foreground_categories.push_back(cc::TASK_CATEGORY_FOREGROUND); |
135 | 136 |
136 for (int i = 0; i < num_threads; i++) { | 137 for (int i = 0; i < num_threads; i++) { |
137 std::unique_ptr<base::SimpleThread> thread(new RasterWorkerPoolThread( | 138 std::unique_ptr<base::SimpleThread> thread(new CategorizedWorkerPoolThread( |
138 base::StringPrintf("CompositorTileWorker%u", | 139 base::StringPrintf("CompositorTileWorker%u", |
139 static_cast<unsigned>(threads_.size() + 1)) | 140 static_cast<unsigned>(threads_.size() + 1)) |
140 .c_str(), | 141 .c_str(), |
141 base::SimpleThread::Options(), this, foreground_categories, | 142 base::SimpleThread::Options(), this, foreground_categories, |
142 &has_ready_to_run_foreground_tasks_cv_)); | 143 &has_ready_to_run_foreground_tasks_cv_)); |
143 thread->Start(); | 144 thread->Start(); |
144 threads_.push_back(std::move(thread)); | 145 threads_.push_back(std::move(thread)); |
145 } | 146 } |
146 | 147 |
147 // Start a single thread for background work. | 148 // Start a single thread for background work. |
148 std::vector<cc::TaskCategory> background_categories; | 149 std::vector<cc::TaskCategory> background_categories; |
149 background_categories.push_back(cc::TASK_CATEGORY_BACKGROUND); | 150 background_categories.push_back(cc::TASK_CATEGORY_BACKGROUND); |
150 | 151 |
151 // Use background priority for background thread. | 152 // Use background priority for background thread. |
152 base::SimpleThread::Options thread_options; | 153 base::SimpleThread::Options thread_options; |
153 #if !defined(OS_MACOSX) | 154 #if !defined(OS_MACOSX) |
154 thread_options.set_priority(base::ThreadPriority::BACKGROUND); | 155 thread_options.set_priority(base::ThreadPriority::BACKGROUND); |
155 #endif | 156 #endif |
156 | 157 |
157 std::unique_ptr<base::SimpleThread> thread(new RasterWorkerPoolThread( | 158 std::unique_ptr<base::SimpleThread> thread(new CategorizedWorkerPoolThread( |
158 "CompositorTileWorkerBackground", thread_options, this, | 159 "CompositorTileWorkerBackground", thread_options, this, |
159 background_categories, &has_ready_to_run_background_tasks_cv_)); | 160 background_categories, &has_ready_to_run_background_tasks_cv_)); |
160 thread->Start(); | 161 thread->Start(); |
161 threads_.push_back(std::move(thread)); | 162 threads_.push_back(std::move(thread)); |
162 } | 163 } |
163 | 164 |
164 void RasterWorkerPool::Shutdown() { | 165 void CategorizedWorkerPool::Shutdown() { |
165 WaitForTasksToFinishRunning(namespace_token_); | 166 WaitForTasksToFinishRunning(namespace_token_); |
166 CollectCompletedTasks(namespace_token_, &completed_tasks_); | 167 CollectCompletedTasks(namespace_token_, &completed_tasks_); |
167 // Shutdown raster threads. | 168 // Shutdown raster threads. |
168 { | 169 { |
169 base::AutoLock lock(lock_); | 170 base::AutoLock lock(lock_); |
170 | 171 |
171 DCHECK(!work_queue_.HasReadyToRunTasks()); | 172 DCHECK(!work_queue_.HasReadyToRunTasks()); |
172 DCHECK(!work_queue_.HasAnyNamespaces()); | 173 DCHECK(!work_queue_.HasAnyNamespaces()); |
173 | 174 |
174 DCHECK(!shutdown_); | 175 DCHECK(!shutdown_); |
175 shutdown_ = true; | 176 shutdown_ = true; |
176 | 177 |
177 // Wake up all workers so they exit. | 178 // Wake up all workers so they exit. |
178 has_ready_to_run_foreground_tasks_cv_.Broadcast(); | 179 has_ready_to_run_foreground_tasks_cv_.Broadcast(); |
179 has_ready_to_run_background_tasks_cv_.Broadcast(); | 180 has_ready_to_run_background_tasks_cv_.Broadcast(); |
180 } | 181 } |
181 while (!threads_.empty()) { | 182 while (!threads_.empty()) { |
182 threads_.back()->Join(); | 183 threads_.back()->Join(); |
183 threads_.pop_back(); | 184 threads_.pop_back(); |
184 } | 185 } |
185 } | 186 } |
186 | 187 |
187 // Overridden from base::TaskRunner: | 188 // Overridden from base::TaskRunner: |
188 bool RasterWorkerPool::PostDelayedTask( | 189 bool CategorizedWorkerPool::PostDelayedTask( |
189 const tracked_objects::Location& from_here, | 190 const tracked_objects::Location& from_here, |
190 const base::Closure& task, | 191 const base::Closure& task, |
191 base::TimeDelta delay) { | 192 base::TimeDelta delay) { |
192 base::AutoLock lock(lock_); | 193 base::AutoLock lock(lock_); |
193 | 194 |
194 // Remove completed tasks. | 195 // Remove completed tasks. |
195 DCHECK(completed_tasks_.empty()); | 196 DCHECK(completed_tasks_.empty()); |
196 CollectCompletedTasksWithLockAcquired(namespace_token_, &completed_tasks_); | 197 CollectCompletedTasksWithLockAcquired(namespace_token_, &completed_tasks_); |
197 | 198 |
198 cc::Task::Vector::iterator end = std::remove_if( | 199 cc::Task::Vector::iterator end = std::remove_if( |
(...skipping 12 matching lines...) Expand all Loading... |
211 graph_.nodes.push_back( | 212 graph_.nodes.push_back( |
212 cc::TaskGraph::Node(graph_task.get(), cc::TASK_CATEGORY_FOREGROUND, | 213 cc::TaskGraph::Node(graph_task.get(), cc::TASK_CATEGORY_FOREGROUND, |
213 0u /* priority */, 0u /* dependencies */)); | 214 0u /* priority */, 0u /* dependencies */)); |
214 } | 215 } |
215 | 216 |
216 ScheduleTasksWithLockAcquired(namespace_token_, &graph_); | 217 ScheduleTasksWithLockAcquired(namespace_token_, &graph_); |
217 completed_tasks_.clear(); | 218 completed_tasks_.clear(); |
218 return true; | 219 return true; |
219 } | 220 } |
220 | 221 |
221 bool RasterWorkerPool::RunsTasksOnCurrentThread() const { | 222 bool CategorizedWorkerPool::RunsTasksOnCurrentThread() const { |
222 return true; | 223 return true; |
223 } | 224 } |
224 | 225 |
225 void RasterWorkerPool::Run(const std::vector<cc::TaskCategory>& categories, | 226 void CategorizedWorkerPool::Run( |
226 base::ConditionVariable* has_ready_to_run_tasks_cv) { | 227 const std::vector<cc::TaskCategory>& categories, |
| 228 base::ConditionVariable* has_ready_to_run_tasks_cv) { |
227 base::AutoLock lock(lock_); | 229 base::AutoLock lock(lock_); |
228 | 230 |
229 while (true) { | 231 while (true) { |
230 if (!RunTaskWithLockAcquired(categories)) { | 232 if (!RunTaskWithLockAcquired(categories)) { |
231 // We are no longer running tasks, which may allow another category to | 233 // We are no longer running tasks, which may allow another category to |
232 // start running. Signal other worker threads. | 234 // start running. Signal other worker threads. |
233 SignalHasReadyToRunTasksWithLockAcquired(); | 235 SignalHasReadyToRunTasksWithLockAcquired(); |
234 | 236 |
235 // Exit when shutdown is set and no more tasks are pending. | 237 // Exit when shutdown is set and no more tasks are pending. |
236 if (shutdown_) | 238 if (shutdown_) |
237 break; | 239 break; |
238 | 240 |
239 // Wait for more tasks. | 241 // Wait for more tasks. |
240 has_ready_to_run_tasks_cv->Wait(); | 242 has_ready_to_run_tasks_cv->Wait(); |
241 continue; | 243 continue; |
242 } | 244 } |
243 } | 245 } |
244 } | 246 } |
245 | 247 |
246 void RasterWorkerPool::FlushForTesting() { | 248 void CategorizedWorkerPool::FlushForTesting() { |
247 base::AutoLock lock(lock_); | 249 base::AutoLock lock(lock_); |
248 | 250 |
249 while (!work_queue_.HasFinishedRunningTasksInAllNamespaces()) { | 251 while (!work_queue_.HasFinishedRunningTasksInAllNamespaces()) { |
250 has_namespaces_with_finished_running_tasks_cv_.Wait(); | 252 has_namespaces_with_finished_running_tasks_cv_.Wait(); |
251 } | 253 } |
252 } | 254 } |
253 | 255 |
254 scoped_refptr<base::SequencedTaskRunner> | 256 scoped_refptr<base::SequencedTaskRunner> |
255 RasterWorkerPool::CreateSequencedTaskRunner() { | 257 CategorizedWorkerPool::CreateSequencedTaskRunner() { |
256 return new RasterWorkerPoolSequencedTaskRunner(this); | 258 return new CategorizedWorkerPoolSequencedTaskRunner(this); |
257 } | 259 } |
258 | 260 |
259 RasterWorkerPool::~RasterWorkerPool() {} | 261 CategorizedWorkerPool::~CategorizedWorkerPool() {} |
260 | 262 |
261 cc::NamespaceToken RasterWorkerPool::GetNamespaceToken() { | 263 cc::NamespaceToken CategorizedWorkerPool::GetNamespaceToken() { |
262 base::AutoLock lock(lock_); | 264 base::AutoLock lock(lock_); |
263 return work_queue_.GetNamespaceToken(); | 265 return work_queue_.GetNamespaceToken(); |
264 } | 266 } |
265 | 267 |
266 void RasterWorkerPool::ScheduleTasks(cc::NamespaceToken token, | 268 void CategorizedWorkerPool::ScheduleTasks(cc::NamespaceToken token, |
267 cc::TaskGraph* graph) { | 269 cc::TaskGraph* graph) { |
268 TRACE_EVENT2("disabled-by-default-cc.debug", | 270 TRACE_EVENT2("disabled-by-default-cc.debug", |
269 "RasterWorkerPool::ScheduleTasks", "num_nodes", | 271 "CategorizedWorkerPool::ScheduleTasks", "num_nodes", |
270 graph->nodes.size(), "num_edges", graph->edges.size()); | 272 graph->nodes.size(), "num_edges", graph->edges.size()); |
271 { | 273 { |
272 base::AutoLock lock(lock_); | 274 base::AutoLock lock(lock_); |
273 ScheduleTasksWithLockAcquired(token, graph); | 275 ScheduleTasksWithLockAcquired(token, graph); |
274 } | 276 } |
275 } | 277 } |
276 | 278 |
277 void RasterWorkerPool::ScheduleTasksWithLockAcquired(cc::NamespaceToken token, | 279 void CategorizedWorkerPool::ScheduleTasksWithLockAcquired( |
278 cc::TaskGraph* graph) { | 280 cc::NamespaceToken token, |
| 281 cc::TaskGraph* graph) { |
279 DCHECK(token.IsValid()); | 282 DCHECK(token.IsValid()); |
280 DCHECK(!cc::TaskGraphWorkQueue::DependencyMismatch(graph)); | 283 DCHECK(!cc::TaskGraphWorkQueue::DependencyMismatch(graph)); |
281 DCHECK(!shutdown_); | 284 DCHECK(!shutdown_); |
282 | 285 |
283 work_queue_.ScheduleTasks(token, graph); | 286 work_queue_.ScheduleTasks(token, graph); |
284 | 287 |
285 // There may be more work available, so wake up another worker thread. | 288 // There may be more work available, so wake up another worker thread. |
286 SignalHasReadyToRunTasksWithLockAcquired(); | 289 SignalHasReadyToRunTasksWithLockAcquired(); |
287 } | 290 } |
288 | 291 |
289 void RasterWorkerPool::WaitForTasksToFinishRunning(cc::NamespaceToken token) { | 292 void CategorizedWorkerPool::WaitForTasksToFinishRunning( |
| 293 cc::NamespaceToken token) { |
290 TRACE_EVENT0("disabled-by-default-cc.debug", | 294 TRACE_EVENT0("disabled-by-default-cc.debug", |
291 "RasterWorkerPool::WaitForTasksToFinishRunning"); | 295 "CategorizedWorkerPool::WaitForTasksToFinishRunning"); |
292 | 296 |
293 DCHECK(token.IsValid()); | 297 DCHECK(token.IsValid()); |
294 | 298 |
295 { | 299 { |
296 base::AutoLock lock(lock_); | 300 base::AutoLock lock(lock_); |
297 base::ThreadRestrictions::ScopedAllowWait allow_wait; | 301 base::ThreadRestrictions::ScopedAllowWait allow_wait; |
298 | 302 |
299 auto* task_namespace = work_queue_.GetNamespaceForToken(token); | 303 auto* task_namespace = work_queue_.GetNamespaceForToken(token); |
300 | 304 |
301 if (!task_namespace) | 305 if (!task_namespace) |
302 return; | 306 return; |
303 | 307 |
304 while (!work_queue_.HasFinishedRunningTasksInNamespace(task_namespace)) | 308 while (!work_queue_.HasFinishedRunningTasksInNamespace(task_namespace)) |
305 has_namespaces_with_finished_running_tasks_cv_.Wait(); | 309 has_namespaces_with_finished_running_tasks_cv_.Wait(); |
306 | 310 |
307 // There may be other namespaces that have finished running tasks, so wake | 311 // There may be other namespaces that have finished running tasks, so wake |
308 // up another origin thread. | 312 // up another origin thread. |
309 has_namespaces_with_finished_running_tasks_cv_.Signal(); | 313 has_namespaces_with_finished_running_tasks_cv_.Signal(); |
310 } | 314 } |
311 } | 315 } |
312 | 316 |
313 void RasterWorkerPool::CollectCompletedTasks( | 317 void CategorizedWorkerPool::CollectCompletedTasks( |
314 cc::NamespaceToken token, | 318 cc::NamespaceToken token, |
315 cc::Task::Vector* completed_tasks) { | 319 cc::Task::Vector* completed_tasks) { |
316 TRACE_EVENT0("disabled-by-default-cc.debug", | 320 TRACE_EVENT0("disabled-by-default-cc.debug", |
317 "RasterWorkerPool::CollectCompletedTasks"); | 321 "CategorizedWorkerPool::CollectCompletedTasks"); |
318 | 322 |
319 { | 323 { |
320 base::AutoLock lock(lock_); | 324 base::AutoLock lock(lock_); |
321 CollectCompletedTasksWithLockAcquired(token, completed_tasks); | 325 CollectCompletedTasksWithLockAcquired(token, completed_tasks); |
322 } | 326 } |
323 } | 327 } |
324 | 328 |
325 void RasterWorkerPool::CollectCompletedTasksWithLockAcquired( | 329 void CategorizedWorkerPool::CollectCompletedTasksWithLockAcquired( |
326 cc::NamespaceToken token, | 330 cc::NamespaceToken token, |
327 cc::Task::Vector* completed_tasks) { | 331 cc::Task::Vector* completed_tasks) { |
328 DCHECK(token.IsValid()); | 332 DCHECK(token.IsValid()); |
329 work_queue_.CollectCompletedTasks(token, completed_tasks); | 333 work_queue_.CollectCompletedTasks(token, completed_tasks); |
330 } | 334 } |
331 | 335 |
332 bool RasterWorkerPool::RunTaskWithLockAcquired( | 336 bool CategorizedWorkerPool::RunTaskWithLockAcquired( |
333 const std::vector<cc::TaskCategory>& categories) { | 337 const std::vector<cc::TaskCategory>& categories) { |
334 for (const auto& category : categories) { | 338 for (const auto& category : categories) { |
335 if (ShouldRunTaskForCategoryWithLockAcquired(category)) { | 339 if (ShouldRunTaskForCategoryWithLockAcquired(category)) { |
336 RunTaskInCategoryWithLockAcquired(category); | 340 RunTaskInCategoryWithLockAcquired(category); |
337 return true; | 341 return true; |
338 } | 342 } |
339 } | 343 } |
340 return false; | 344 return false; |
341 } | 345 } |
342 | 346 |
343 void RasterWorkerPool::RunTaskInCategoryWithLockAcquired( | 347 void CategorizedWorkerPool::RunTaskInCategoryWithLockAcquired( |
344 cc::TaskCategory category) { | 348 cc::TaskCategory category) { |
345 TRACE_EVENT0("toplevel", "TaskGraphRunner::RunTask"); | 349 TRACE_EVENT0("toplevel", "TaskGraphRunner::RunTask"); |
346 | 350 |
347 lock_.AssertAcquired(); | 351 lock_.AssertAcquired(); |
348 | 352 |
349 auto prioritized_task = work_queue_.GetNextTaskToRun(category); | 353 auto prioritized_task = work_queue_.GetNextTaskToRun(category); |
350 cc::Task* task = prioritized_task.task; | 354 cc::Task* task = prioritized_task.task; |
351 | 355 |
352 // There may be more work available, so wake up another worker thread. | 356 // There may be more work available, so wake up another worker thread. |
353 SignalHasReadyToRunTasksWithLockAcquired(); | 357 SignalHasReadyToRunTasksWithLockAcquired(); |
354 | 358 |
355 { | 359 { |
356 base::AutoUnlock unlock(lock_); | 360 base::AutoUnlock unlock(lock_); |
357 | 361 |
358 task->RunOnWorkerThread(); | 362 task->RunOnWorkerThread(); |
359 } | 363 } |
360 | 364 |
361 work_queue_.CompleteTask(prioritized_task); | 365 work_queue_.CompleteTask(prioritized_task); |
362 | 366 |
363 // If namespace has finished running all tasks, wake up origin threads. | 367 // If namespace has finished running all tasks, wake up origin threads. |
364 if (work_queue_.HasFinishedRunningTasksInNamespace( | 368 if (work_queue_.HasFinishedRunningTasksInNamespace( |
365 prioritized_task.task_namespace)) | 369 prioritized_task.task_namespace)) |
366 has_namespaces_with_finished_running_tasks_cv_.Signal(); | 370 has_namespaces_with_finished_running_tasks_cv_.Signal(); |
367 } | 371 } |
368 | 372 |
369 bool RasterWorkerPool::ShouldRunTaskForCategoryWithLockAcquired( | 373 bool CategorizedWorkerPool::ShouldRunTaskForCategoryWithLockAcquired( |
370 cc::TaskCategory category) { | 374 cc::TaskCategory category) { |
371 lock_.AssertAcquired(); | 375 lock_.AssertAcquired(); |
372 | 376 |
373 if (!work_queue_.HasReadyToRunTasksForCategory(category)) | 377 if (!work_queue_.HasReadyToRunTasksForCategory(category)) |
374 return false; | 378 return false; |
375 | 379 |
376 if (category == cc::TASK_CATEGORY_BACKGROUND) { | 380 if (category == cc::TASK_CATEGORY_BACKGROUND) { |
377 // Only run background tasks if there are no foreground tasks running or | 381 // Only run background tasks if there are no foreground tasks running or |
378 // ready to run. | 382 // ready to run. |
379 size_t num_running_foreground_tasks = | 383 size_t num_running_foreground_tasks = |
(...skipping 12 matching lines...) Expand all Loading... |
392 // Enforce that only one nonconcurrent task runs at a time. | 396 // Enforce that only one nonconcurrent task runs at a time. |
393 if (category == cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND && | 397 if (category == cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND && |
394 work_queue_.NumRunningTasksForCategory( | 398 work_queue_.NumRunningTasksForCategory( |
395 cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND) > 0) { | 399 cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND) > 0) { |
396 return false; | 400 return false; |
397 } | 401 } |
398 | 402 |
399 return true; | 403 return true; |
400 } | 404 } |
401 | 405 |
402 void RasterWorkerPool::SignalHasReadyToRunTasksWithLockAcquired() { | 406 void CategorizedWorkerPool::SignalHasReadyToRunTasksWithLockAcquired() { |
403 lock_.AssertAcquired(); | 407 lock_.AssertAcquired(); |
404 | 408 |
405 if (ShouldRunTaskForCategoryWithLockAcquired(cc::TASK_CATEGORY_FOREGROUND) || | 409 if (ShouldRunTaskForCategoryWithLockAcquired(cc::TASK_CATEGORY_FOREGROUND) || |
406 ShouldRunTaskForCategoryWithLockAcquired( | 410 ShouldRunTaskForCategoryWithLockAcquired( |
407 cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND)) { | 411 cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND)) { |
408 has_ready_to_run_foreground_tasks_cv_.Signal(); | 412 has_ready_to_run_foreground_tasks_cv_.Signal(); |
409 } | 413 } |
410 | 414 |
411 if (ShouldRunTaskForCategoryWithLockAcquired(cc::TASK_CATEGORY_BACKGROUND)) { | 415 if (ShouldRunTaskForCategoryWithLockAcquired(cc::TASK_CATEGORY_BACKGROUND)) { |
412 has_ready_to_run_background_tasks_cv_.Signal(); | 416 has_ready_to_run_background_tasks_cv_.Signal(); |
413 } | 417 } |
414 } | 418 } |
415 | 419 |
416 RasterWorkerPool::ClosureTask::ClosureTask(const base::Closure& closure) | 420 CategorizedWorkerPool::ClosureTask::ClosureTask(const base::Closure& closure) |
417 : closure_(closure) {} | 421 : closure_(closure) {} |
418 | 422 |
419 // Overridden from cc::Task: | 423 // Overridden from cc::Task: |
420 void RasterWorkerPool::ClosureTask::RunOnWorkerThread() { | 424 void CategorizedWorkerPool::ClosureTask::RunOnWorkerThread() { |
421 closure_.Run(); | 425 closure_.Run(); |
422 closure_.Reset(); | 426 closure_.Reset(); |
423 } | 427 } |
424 | 428 |
425 RasterWorkerPool::ClosureTask::~ClosureTask() {} | 429 CategorizedWorkerPool::ClosureTask::~ClosureTask() {} |
426 | 430 |
427 } // namespace content | 431 } // namespace content |
OLD | NEW |