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/raster_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 RasterWorkerPool::Run with the runnable |
21 // categories. | 21 // categories. |
22 class RasterWorkerPoolThread : public base::SimpleThread { | 22 class RasterWorkerPoolThread : public base::DynamicPriorityThread, |
| 23 public cc::TaskWorker { |
23 public: | 24 public: |
24 RasterWorkerPoolThread(const std::string& name_prefix, | 25 RasterWorkerPoolThread(const DynamicPriorityThread::PrioritySet& priorities, |
| 26 const std::string& name_prefix, |
25 const Options& options, | 27 const Options& options, |
26 RasterWorkerPool* pool, | 28 RasterWorkerPool* pool, |
27 std::vector<cc::TaskCategory> categories, | 29 std::vector<cc::TaskCategory> categories, |
28 base::ConditionVariable* has_ready_to_run_tasks_cv) | 30 base::ConditionVariable* has_ready_to_run_tasks_cv) |
29 : SimpleThread(name_prefix, options), | 31 : DynamicPriorityThread(priorities, name_prefix, options), |
30 pool_(pool), | 32 pool_(pool), |
31 categories_(categories), | 33 categories_(categories), |
32 has_ready_to_run_tasks_cv_(has_ready_to_run_tasks_cv) {} | 34 has_ready_to_run_tasks_cv_(has_ready_to_run_tasks_cv) {} |
33 | 35 |
34 void Run() override { pool_->Run(categories_, has_ready_to_run_tasks_cv_); } | 36 // Overridden from cc::TaskWorker: |
| 37 bool TaskSpeedup() override { Speedup(); } |
| 38 bool TaskSlowdown() override { SlowDown(); } |
| 39 bool TaskDone() override { RestoreDefaultPriority(); } |
| 40 |
| 41 // Overridden from base::DynamicPriorityThread: |
| 42 void Run() override { |
| 43 pool_->Run(this, categories_, has_ready_to_run_tasks_cv_); |
| 44 } |
35 | 45 |
36 private: | 46 private: |
37 RasterWorkerPool* const pool_; | 47 RasterWorkerPool* const pool_; |
38 const std::vector<cc::TaskCategory> categories_; | 48 const std::vector<cc::TaskCategory> categories_; |
39 base::ConditionVariable* const has_ready_to_run_tasks_cv_; | 49 base::ConditionVariable* const has_ready_to_run_tasks_cv_; |
40 }; | 50 }; |
41 | 51 |
42 } // namespace | 52 } // namespace |
43 | 53 |
| 54 void RasterWorkerPool::AdjustWorkerPriorityForTask(cc::Task* task, |
| 55 uint16_t old_category, |
| 56 uint16_t new_category) { |
| 57 if (old_category == new_category) |
| 58 return; |
| 59 |
| 60 // TODO(prashant.n): Handle slowing down of tasks either by setting background |
| 61 // priority for worker OR cancelling the task. |
| 62 if (new_category == cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND || |
| 63 new_category == cc::TASK_CATEGORY_FOREGROUND) { |
| 64 if (task->GetWorker()->TaskSpeedup()) { |
| 65 // LOG(ERROR) << "\nPRAS:: [" << std::hex << runner << "] " |
| 66 // << runner->GetPrioritySetForDebugging() |
| 67 // << ". Runner speeded up ^^^^^^^^^"; |
| 68 } |
| 69 } |
| 70 } |
| 71 |
44 // A sequenced task runner which posts tasks to a RasterWorkerPool. | 72 // A sequenced task runner which posts tasks to a RasterWorkerPool. |
45 class RasterWorkerPool::RasterWorkerPoolSequencedTaskRunner | 73 class RasterWorkerPool::RasterWorkerPoolSequencedTaskRunner |
46 : public base::SequencedTaskRunner { | 74 : public base::SequencedTaskRunner { |
47 public: | 75 public: |
48 explicit RasterWorkerPoolSequencedTaskRunner( | 76 explicit RasterWorkerPoolSequencedTaskRunner( |
49 cc::TaskGraphRunner* task_graph_runner) | 77 cc::TaskGraphRunner* task_graph_runner) |
50 : task_graph_runner_(task_graph_runner), | 78 : task_graph_runner_(task_graph_runner), |
51 namespace_token_(task_graph_runner->GetNamespaceToken()) {} | 79 namespace_token_(task_graph_runner->GetNamespaceToken()) {} |
52 | 80 |
53 // Overridden from base::TaskRunner: | 81 // Overridden from base::TaskRunner: |
(...skipping 57 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
111 // List of tasks currently queued up for execution. | 139 // List of tasks currently queued up for execution. |
112 cc::Task::Vector tasks_; | 140 cc::Task::Vector tasks_; |
113 // Graph object used for scheduling tasks. | 141 // Graph object used for scheduling tasks. |
114 cc::TaskGraph graph_; | 142 cc::TaskGraph graph_; |
115 // Cached vector to avoid allocation when getting the list of complete | 143 // Cached vector to avoid allocation when getting the list of complete |
116 // tasks. | 144 // tasks. |
117 cc::Task::Vector completed_tasks_; | 145 cc::Task::Vector completed_tasks_; |
118 }; | 146 }; |
119 | 147 |
120 RasterWorkerPool::RasterWorkerPool() | 148 RasterWorkerPool::RasterWorkerPool() |
121 : namespace_token_(GetNamespaceToken()), | 149 : work_queue_(this), |
| 150 namespace_token_(GetNamespaceToken()), |
122 has_ready_to_run_foreground_tasks_cv_(&lock_), | 151 has_ready_to_run_foreground_tasks_cv_(&lock_), |
123 has_ready_to_run_background_tasks_cv_(&lock_), | 152 has_ready_to_run_background_tasks_cv_(&lock_), |
124 has_namespaces_with_finished_running_tasks_cv_(&lock_), | 153 has_namespaces_with_finished_running_tasks_cv_(&lock_), |
125 shutdown_(false) {} | 154 shutdown_(false) {} |
126 | 155 |
127 void RasterWorkerPool::Start(int num_threads) { | 156 void RasterWorkerPool::Start(int num_threads) { |
128 DCHECK(threads_.empty()); | 157 DCHECK(threads_.empty()); |
129 | 158 |
130 // Start |num_threads| threads for foreground work, including nonconcurrent | 159 // Start |num_threads| threads for foreground work, including nonconcurrent |
131 // foreground work. | 160 // foreground work. |
132 std::vector<cc::TaskCategory> foreground_categories; | 161 std::vector<cc::TaskCategory> foreground_categories; |
133 foreground_categories.push_back(cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND); | 162 foreground_categories.push_back(cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND); |
134 foreground_categories.push_back(cc::TASK_CATEGORY_FOREGROUND); | 163 foreground_categories.push_back(cc::TASK_CATEGORY_FOREGROUND); |
135 | 164 |
| 165 base::DynamicPriorityThread::PrioritySet only_foreground( |
| 166 base::ThreadPriority::NORMAL, base::ThreadPriority::NORMAL, |
| 167 base::ThreadPriority::NORMAL); |
| 168 |
| 169 base::DynamicPriorityThread::PrioritySet dynamic_background( |
| 170 base::ThreadPriority::BACKGROUND, base::ThreadPriority::BACKGROUND, |
| 171 base::ThreadPriority::NORMAL); |
| 172 |
| 173 // Create N normal priority threads and 1 background priority dynamic thread. |
136 for (int i = 0; i < num_threads; i++) { | 174 for (int i = 0; i < num_threads; i++) { |
137 scoped_ptr<base::SimpleThread> thread(new RasterWorkerPoolThread( | 175 scoped_ptr<base::SimpleThread> thread(new RasterWorkerPoolThread( |
| 176 only_foreground, |
138 base::StringPrintf("CompositorTileWorker%u", | 177 base::StringPrintf("CompositorTileWorker%u", |
139 static_cast<unsigned>(threads_.size() + 1)) | 178 static_cast<unsigned>(threads_.size() + 1)) |
140 .c_str(), | 179 .c_str(), |
141 base::SimpleThread::Options(), this, foreground_categories, | 180 base::SimpleThread::Options(), this, foreground_categories, |
142 &has_ready_to_run_foreground_tasks_cv_)); | 181 &has_ready_to_run_foreground_tasks_cv_)); |
143 thread->Start(); | 182 thread->Start(); |
144 threads_.push_back(std::move(thread)); | 183 threads_.push_back(std::move(thread)); |
145 } | 184 } |
146 | 185 |
147 // Start a single thread for background work. | 186 // Start a single thread for background work. |
148 std::vector<cc::TaskCategory> background_categories; | 187 std::vector<cc::TaskCategory> background_categories; |
149 background_categories.push_back(cc::TASK_CATEGORY_BACKGROUND); | 188 background_categories.push_back(cc::TASK_CATEGORY_BACKGROUND); |
150 | 189 |
151 // Use background priority for background thread. | 190 // Use background priority for background thread. |
152 base::SimpleThread::Options thread_options; | 191 base::SimpleThread::Options thread_options; |
153 #if !defined(OS_MACOSX) | 192 #if !defined(OS_MACOSX) |
154 thread_options.set_priority(base::ThreadPriority::BACKGROUND); | 193 thread_options.set_priority(base::ThreadPriority::BACKGROUND); |
155 #endif | 194 #endif |
156 | 195 |
157 scoped_ptr<base::SimpleThread> thread(new RasterWorkerPoolThread( | 196 scoped_ptr<base::SimpleThread> thread(new RasterWorkerPoolThread( |
| 197 dynamic_background, |
158 base::StringPrintf("CompositorTileWorker%u", | 198 base::StringPrintf("CompositorTileWorker%u", |
159 static_cast<unsigned>(threads_.size() + 1)) | 199 static_cast<unsigned>(threads_.size() + 1)) |
160 .c_str(), | 200 .c_str(), |
161 thread_options, this, background_categories, | 201 thread_options, this, background_categories, |
162 &has_ready_to_run_background_tasks_cv_)); | 202 &has_ready_to_run_background_tasks_cv_)); |
163 thread->Start(); | 203 thread->Start(); |
164 threads_.push_back(std::move(thread)); | 204 threads_.push_back(std::move(thread)); |
165 } | 205 } |
166 | 206 |
167 void RasterWorkerPool::Shutdown() { | 207 void RasterWorkerPool::Shutdown() { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 | 258 |
219 ScheduleTasksWithLockAcquired(namespace_token_, &graph_); | 259 ScheduleTasksWithLockAcquired(namespace_token_, &graph_); |
220 completed_tasks_.clear(); | 260 completed_tasks_.clear(); |
221 return true; | 261 return true; |
222 } | 262 } |
223 | 263 |
224 bool RasterWorkerPool::RunsTasksOnCurrentThread() const { | 264 bool RasterWorkerPool::RunsTasksOnCurrentThread() const { |
225 return true; | 265 return true; |
226 } | 266 } |
227 | 267 |
228 void RasterWorkerPool::Run(const std::vector<cc::TaskCategory>& categories, | 268 void RasterWorkerPool::Run(cc::TaskWorker* worker, |
| 269 const std::vector<cc::TaskCategory>& categories, |
229 base::ConditionVariable* has_ready_to_run_tasks_cv) { | 270 base::ConditionVariable* has_ready_to_run_tasks_cv) { |
230 base::AutoLock lock(lock_); | 271 base::AutoLock lock(lock_); |
231 | 272 |
232 while (true) { | 273 while (true) { |
233 if (!RunTaskWithLockAcquired(categories)) { | 274 if (!RunTaskWithLockAcquired(worker, categories)) { |
234 // We are no longer running tasks, which may allow another category to | 275 // We are no longer running tasks, which may allow another category to |
235 // start running. Signal other worker threads. | 276 // start running. Signal other worker threads. |
236 SignalHasReadyToRunTasksWithLockAcquired(); | 277 SignalHasReadyToRunTasksWithLockAcquired(); |
237 | 278 |
238 // Exit when shutdown is set and no more tasks are pending. | 279 // Exit when shutdown is set and no more tasks are pending. |
239 if (shutdown_) | 280 if (shutdown_) |
240 break; | 281 break; |
241 | 282 |
242 // Wait for more tasks. | 283 // Wait for more tasks. |
243 has_ready_to_run_tasks_cv->Wait(); | 284 has_ready_to_run_tasks_cv->Wait(); |
(...skipping 67 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
311 // up another origin thread. | 352 // up another origin thread. |
312 has_namespaces_with_finished_running_tasks_cv_.Signal(); | 353 has_namespaces_with_finished_running_tasks_cv_.Signal(); |
313 } | 354 } |
314 } | 355 } |
315 | 356 |
316 void RasterWorkerPool::CollectCompletedTasks( | 357 void RasterWorkerPool::CollectCompletedTasks( |
317 cc::NamespaceToken token, | 358 cc::NamespaceToken token, |
318 cc::Task::Vector* completed_tasks) { | 359 cc::Task::Vector* completed_tasks) { |
319 TRACE_EVENT0("disabled-by-default-cc.debug", | 360 TRACE_EVENT0("disabled-by-default-cc.debug", |
320 "RasterWorkerPool::CollectCompletedTasks"); | 361 "RasterWorkerPool::CollectCompletedTasks"); |
321 | |
322 { | 362 { |
323 base::AutoLock lock(lock_); | 363 base::AutoLock lock(lock_); |
324 CollectCompletedTasksWithLockAcquired(token, completed_tasks); | 364 CollectCompletedTasksWithLockAcquired(token, completed_tasks); |
325 } | 365 } |
326 } | 366 } |
327 | 367 |
328 void RasterWorkerPool::CollectCompletedTasksWithLockAcquired( | 368 void RasterWorkerPool::CollectCompletedTasksWithLockAcquired( |
329 cc::NamespaceToken token, | 369 cc::NamespaceToken token, |
330 cc::Task::Vector* completed_tasks) { | 370 cc::Task::Vector* completed_tasks) { |
331 DCHECK(token.IsValid()); | 371 DCHECK(token.IsValid()); |
332 work_queue_.CollectCompletedTasks(token, completed_tasks); | 372 work_queue_.CollectCompletedTasks(token, completed_tasks); |
333 } | 373 } |
334 | 374 |
335 bool RasterWorkerPool::RunTaskWithLockAcquired( | 375 bool RasterWorkerPool::RunTaskWithLockAcquired( |
| 376 cc::TaskWorker* worker, |
336 const std::vector<cc::TaskCategory>& categories) { | 377 const std::vector<cc::TaskCategory>& categories) { |
337 for (const auto& category : categories) { | 378 for (const auto& category : categories) { |
338 if (ShouldRunTaskForCategoryWithLockAcquired(category)) { | 379 if (ShouldRunTaskForCategoryWithLockAcquired(category)) { |
339 RunTaskInCategoryWithLockAcquired(category); | 380 RunTaskInCategoryWithLockAcquired(worker, category); |
340 return true; | 381 return true; |
341 } | 382 } |
342 } | 383 } |
343 return false; | 384 return false; |
344 } | 385 } |
345 | 386 |
346 void RasterWorkerPool::RunTaskInCategoryWithLockAcquired( | 387 void RasterWorkerPool::RunTaskInCategoryWithLockAcquired( |
| 388 cc::TaskWorker* worker, |
347 cc::TaskCategory category) { | 389 cc::TaskCategory category) { |
348 TRACE_EVENT0("toplevel", "TaskGraphRunner::RunTask"); | 390 TRACE_EVENT0("toplevel", "TaskGraphRunner::RunTask"); |
349 | 391 |
350 lock_.AssertAcquired(); | 392 lock_.AssertAcquired(); |
351 | 393 |
352 auto prioritized_task = work_queue_.GetNextTaskToRun(category); | 394 auto prioritized_task = work_queue_.GetNextTaskToRun(category); |
353 cc::Task* task = prioritized_task.task; | 395 cc::Task* task = prioritized_task.task; |
354 | 396 |
| 397 // Attach the worker to the task. |
| 398 AutoDetachTaskWorker task_worker(task, worker); |
| 399 |
355 // There may be more work available, so wake up another worker thread. | 400 // There may be more work available, so wake up another worker thread. |
356 SignalHasReadyToRunTasksWithLockAcquired(); | 401 SignalHasReadyToRunTasksWithLockAcquired(); |
357 | 402 |
358 // Call WillRun() before releasing |lock_| and running task. | 403 // Call WillRun() before releasing |lock_| and running task. |
359 task->WillRun(); | 404 task->WillRun(); |
360 | 405 |
361 { | 406 { |
362 base::AutoUnlock unlock(lock_); | 407 base::AutoUnlock unlock(lock_); |
363 | 408 |
364 task->RunOnWorkerThread(); | 409 task->RunOnWorkerThread(); |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
427 | 472 |
428 // Overridden from cc::Task: | 473 // Overridden from cc::Task: |
429 void RasterWorkerPool::ClosureTask::RunOnWorkerThread() { | 474 void RasterWorkerPool::ClosureTask::RunOnWorkerThread() { |
430 closure_.Run(); | 475 closure_.Run(); |
431 closure_.Reset(); | 476 closure_.Reset(); |
432 } | 477 } |
433 | 478 |
434 RasterWorkerPool::ClosureTask::~ClosureTask() {} | 479 RasterWorkerPool::ClosureTask::~ClosureTask() {} |
435 | 480 |
436 } // namespace content | 481 } // namespace content |
OLD | NEW |