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::TestSimpleThread { |
23 public: | 23 public: |
24 RasterWorkerPoolThread(const std::string& name_prefix, | 24 RasterWorkerPoolThread(const TestSimpleThread::PrioritySet& priorities, |
| 25 const std::string& name_prefix, |
25 const Options& options, | 26 const Options& options, |
26 RasterWorkerPool* pool, | 27 RasterWorkerPool* pool, |
27 std::vector<cc::TaskCategory> categories, | 28 std::vector<cc::TaskCategory> categories, |
28 base::ConditionVariable* has_ready_to_run_tasks_cv) | 29 base::ConditionVariable* has_ready_to_run_tasks_cv) |
29 : SimpleThread(name_prefix, options), | 30 : TestSimpleThread(priorities, 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 { |
| 36 pool_->Run(this, categories_, has_ready_to_run_tasks_cv_); |
| 37 } |
35 | 38 |
36 private: | 39 private: |
37 RasterWorkerPool* const pool_; | 40 RasterWorkerPool* const pool_; |
38 const std::vector<cc::TaskCategory> categories_; | 41 const std::vector<cc::TaskCategory> categories_; |
39 base::ConditionVariable* const has_ready_to_run_tasks_cv_; | 42 base::ConditionVariable* const has_ready_to_run_tasks_cv_; |
40 }; | 43 }; |
41 | 44 |
42 } // namespace | 45 } // namespace |
43 | 46 |
44 // A sequenced task runner which posts tasks to a RasterWorkerPool. | 47 // A sequenced task runner which posts tasks to a RasterWorkerPool. |
(...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
126 | 129 |
127 void RasterWorkerPool::Start(int num_threads) { | 130 void RasterWorkerPool::Start(int num_threads) { |
128 DCHECK(threads_.empty()); | 131 DCHECK(threads_.empty()); |
129 | 132 |
130 // Start |num_threads| threads for foreground work, including nonconcurrent | 133 // Start |num_threads| threads for foreground work, including nonconcurrent |
131 // foreground work. | 134 // foreground work. |
132 std::vector<cc::TaskCategory> foreground_categories; | 135 std::vector<cc::TaskCategory> foreground_categories; |
133 foreground_categories.push_back(cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND); | 136 foreground_categories.push_back(cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND); |
134 foreground_categories.push_back(cc::TASK_CATEGORY_FOREGROUND); | 137 foreground_categories.push_back(cc::TASK_CATEGORY_FOREGROUND); |
135 | 138 |
| 139 base::TestSimpleThread::PrioritySet only_foreground( |
| 140 base::ThreadPriority::NORMAL, base::ThreadPriority::NORMAL, |
| 141 base::ThreadPriority::NORMAL); |
| 142 |
| 143 base::TestSimpleThread::PrioritySet dynamic_background( |
| 144 base::ThreadPriority::BACKGROUND, base::ThreadPriority::BACKGROUND, |
| 145 base::ThreadPriority::NORMAL); |
| 146 |
| 147 // Create N normal priority threads and 1 background priority dynamic thread. |
136 for (int i = 0; i < num_threads; i++) { | 148 for (int i = 0; i < num_threads; i++) { |
137 scoped_ptr<base::SimpleThread> thread(new RasterWorkerPoolThread( | 149 scoped_ptr<base::SimpleThread> thread(new RasterWorkerPoolThread( |
| 150 only_foreground, |
138 base::StringPrintf("CompositorTileWorker%u", | 151 base::StringPrintf("CompositorTileWorker%u", |
139 static_cast<unsigned>(threads_.size() + 1)) | 152 static_cast<unsigned>(threads_.size() + 1)) |
140 .c_str(), | 153 .c_str(), |
141 base::SimpleThread::Options(), this, foreground_categories, | 154 base::SimpleThread::Options(), this, foreground_categories, |
142 &has_ready_to_run_foreground_tasks_cv_)); | 155 &has_ready_to_run_foreground_tasks_cv_)); |
143 thread->Start(); | 156 thread->Start(); |
144 threads_.push_back(std::move(thread)); | 157 threads_.push_back(std::move(thread)); |
145 } | 158 } |
146 | 159 |
147 // Start a single thread for background work. | 160 // Start a single thread for background work. |
148 std::vector<cc::TaskCategory> background_categories; | 161 std::vector<cc::TaskCategory> background_categories; |
149 background_categories.push_back(cc::TASK_CATEGORY_BACKGROUND); | 162 background_categories.push_back(cc::TASK_CATEGORY_BACKGROUND); |
150 | 163 |
151 // Use background priority for background thread. | 164 // Use background priority for background thread. |
152 base::SimpleThread::Options thread_options; | 165 base::SimpleThread::Options thread_options; |
153 #if !defined(OS_MACOSX) | 166 #if !defined(OS_MACOSX) |
154 thread_options.set_priority(base::ThreadPriority::BACKGROUND); | 167 thread_options.set_priority(base::ThreadPriority::BACKGROUND); |
155 #endif | 168 #endif |
156 | 169 |
157 scoped_ptr<base::SimpleThread> thread(new RasterWorkerPoolThread( | 170 scoped_ptr<base::SimpleThread> thread(new RasterWorkerPoolThread( |
| 171 dynamic_background, |
158 base::StringPrintf("CompositorTileWorker%u", | 172 base::StringPrintf("CompositorTileWorker%u", |
159 static_cast<unsigned>(threads_.size() + 1)) | 173 static_cast<unsigned>(threads_.size() + 1)) |
160 .c_str(), | 174 .c_str(), |
161 thread_options, this, background_categories, | 175 thread_options, this, background_categories, |
162 &has_ready_to_run_background_tasks_cv_)); | 176 &has_ready_to_run_background_tasks_cv_)); |
163 thread->Start(); | 177 thread->Start(); |
164 threads_.push_back(std::move(thread)); | 178 threads_.push_back(std::move(thread)); |
165 } | 179 } |
166 | 180 |
167 void RasterWorkerPool::Shutdown() { | 181 void RasterWorkerPool::Shutdown() { |
(...skipping 50 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
218 | 232 |
219 ScheduleTasksWithLockAcquired(namespace_token_, &graph_); | 233 ScheduleTasksWithLockAcquired(namespace_token_, &graph_); |
220 completed_tasks_.clear(); | 234 completed_tasks_.clear(); |
221 return true; | 235 return true; |
222 } | 236 } |
223 | 237 |
224 bool RasterWorkerPool::RunsTasksOnCurrentThread() const { | 238 bool RasterWorkerPool::RunsTasksOnCurrentThread() const { |
225 return true; | 239 return true; |
226 } | 240 } |
227 | 241 |
228 void RasterWorkerPool::Run(const std::vector<cc::TaskCategory>& categories, | 242 void RasterWorkerPool::Run(base::TestSimpleThread* runner, |
| 243 const std::vector<cc::TaskCategory>& categories, |
229 base::ConditionVariable* has_ready_to_run_tasks_cv) { | 244 base::ConditionVariable* has_ready_to_run_tasks_cv) { |
230 base::AutoLock lock(lock_); | 245 base::AutoLock lock(lock_); |
231 | 246 |
232 while (true) { | 247 while (true) { |
233 if (!RunTaskWithLockAcquired(categories)) { | 248 if (!RunTaskWithLockAcquired(runner, categories)) { |
234 // We are no longer running tasks, which may allow another category to | 249 // We are no longer running tasks, which may allow another category to |
235 // start running. Signal other worker threads. | 250 // start running. Signal other worker threads. |
236 SignalHasReadyToRunTasksWithLockAcquired(); | 251 SignalHasReadyToRunTasksWithLockAcquired(); |
237 | 252 |
238 // Exit when shutdown is set and no more tasks are pending. | 253 // Exit when shutdown is set and no more tasks are pending. |
239 if (shutdown_) | 254 if (shutdown_) |
240 break; | 255 break; |
241 | 256 |
242 // Wait for more tasks. | 257 // Wait for more tasks. |
243 has_ready_to_run_tasks_cv->Wait(); | 258 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. | 326 // up another origin thread. |
312 has_namespaces_with_finished_running_tasks_cv_.Signal(); | 327 has_namespaces_with_finished_running_tasks_cv_.Signal(); |
313 } | 328 } |
314 } | 329 } |
315 | 330 |
316 void RasterWorkerPool::CollectCompletedTasks( | 331 void RasterWorkerPool::CollectCompletedTasks( |
317 cc::NamespaceToken token, | 332 cc::NamespaceToken token, |
318 cc::Task::Vector* completed_tasks) { | 333 cc::Task::Vector* completed_tasks) { |
319 TRACE_EVENT0("disabled-by-default-cc.debug", | 334 TRACE_EVENT0("disabled-by-default-cc.debug", |
320 "RasterWorkerPool::CollectCompletedTasks"); | 335 "RasterWorkerPool::CollectCompletedTasks"); |
321 | |
322 { | 336 { |
323 base::AutoLock lock(lock_); | 337 base::AutoLock lock(lock_); |
324 CollectCompletedTasksWithLockAcquired(token, completed_tasks); | 338 CollectCompletedTasksWithLockAcquired(token, completed_tasks); |
325 } | 339 } |
326 } | 340 } |
327 | 341 |
328 void RasterWorkerPool::CollectCompletedTasksWithLockAcquired( | 342 void RasterWorkerPool::CollectCompletedTasksWithLockAcquired( |
329 cc::NamespaceToken token, | 343 cc::NamespaceToken token, |
330 cc::Task::Vector* completed_tasks) { | 344 cc::Task::Vector* completed_tasks) { |
331 DCHECK(token.IsValid()); | 345 DCHECK(token.IsValid()); |
332 work_queue_.CollectCompletedTasks(token, completed_tasks); | 346 work_queue_.CollectCompletedTasks(token, completed_tasks); |
333 } | 347 } |
334 | 348 |
335 bool RasterWorkerPool::RunTaskWithLockAcquired( | 349 bool RasterWorkerPool::RunTaskWithLockAcquired( |
| 350 base::TestSimpleThread* runner, |
336 const std::vector<cc::TaskCategory>& categories) { | 351 const std::vector<cc::TaskCategory>& categories) { |
337 for (const auto& category : categories) { | 352 for (const auto& category : categories) { |
338 if (ShouldRunTaskForCategoryWithLockAcquired(category)) { | 353 if (ShouldRunTaskForCategoryWithLockAcquired(category)) { |
339 RunTaskInCategoryWithLockAcquired(category); | 354 RunTaskInCategoryWithLockAcquired(runner, category); |
340 return true; | 355 return true; |
341 } | 356 } |
342 } | 357 } |
343 return false; | 358 return false; |
344 } | 359 } |
345 | 360 |
346 void RasterWorkerPool::RunTaskInCategoryWithLockAcquired( | 361 void RasterWorkerPool::RunTaskInCategoryWithLockAcquired( |
| 362 base::TestSimpleThread* runner, |
347 cc::TaskCategory category) { | 363 cc::TaskCategory category) { |
348 TRACE_EVENT0("toplevel", "TaskGraphRunner::RunTask"); | 364 TRACE_EVENT0("toplevel", "TaskGraphRunner::RunTask"); |
349 | 365 |
350 lock_.AssertAcquired(); | 366 lock_.AssertAcquired(); |
351 | 367 |
352 auto prioritized_task = work_queue_.GetNextTaskToRun(category); | 368 auto prioritized_task = work_queue_.GetNextTaskToRun(category); |
353 cc::Task* task = prioritized_task.task; | 369 cc::Task* task = prioritized_task.task; |
354 | 370 |
355 // There may be more work available, so wake up another worker thread. | 371 // There may be more work available, so wake up another worker thread. |
356 SignalHasReadyToRunTasksWithLockAcquired(); | 372 SignalHasReadyToRunTasksWithLockAcquired(); |
357 | 373 |
| 374 task->SetRunner(runner); |
358 // Call WillRun() before releasing |lock_| and running task. | 375 // Call WillRun() before releasing |lock_| and running task. |
359 task->WillRun(); | 376 task->WillRun(); |
360 | 377 |
361 { | 378 { |
362 base::AutoUnlock unlock(lock_); | 379 base::AutoUnlock unlock(lock_); |
363 | 380 |
364 task->RunOnWorkerThread(); | 381 task->RunOnWorkerThread(); |
365 } | 382 } |
366 | 383 |
367 // This will mark task as finished running. | 384 // This will mark task as finished running. |
368 task->DidRun(); | 385 task->DidRun(); |
369 | 386 |
370 work_queue_.CompleteTask(prioritized_task); | 387 work_queue_.CompleteTask(prioritized_task); |
371 | 388 |
| 389 if (task->IsRasterTask()) |
| 390 runner->Restore(); |
| 391 |
| 392 task->SetRunner(nullptr); |
| 393 |
372 // If namespace has finished running all tasks, wake up origin threads. | 394 // If namespace has finished running all tasks, wake up origin threads. |
373 if (work_queue_.HasFinishedRunningTasksInNamespace( | 395 if (work_queue_.HasFinishedRunningTasksInNamespace( |
374 prioritized_task.task_namespace)) | 396 prioritized_task.task_namespace)) |
375 has_namespaces_with_finished_running_tasks_cv_.Signal(); | 397 has_namespaces_with_finished_running_tasks_cv_.Signal(); |
376 } | 398 } |
377 | 399 |
378 bool RasterWorkerPool::ShouldRunTaskForCategoryWithLockAcquired( | 400 bool RasterWorkerPool::ShouldRunTaskForCategoryWithLockAcquired( |
379 cc::TaskCategory category) { | 401 cc::TaskCategory category) { |
380 lock_.AssertAcquired(); | 402 lock_.AssertAcquired(); |
381 | 403 |
(...skipping 45 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
427 | 449 |
428 // Overridden from cc::Task: | 450 // Overridden from cc::Task: |
429 void RasterWorkerPool::ClosureTask::RunOnWorkerThread() { | 451 void RasterWorkerPool::ClosureTask::RunOnWorkerThread() { |
430 closure_.Run(); | 452 closure_.Run(); |
431 closure_.Reset(); | 453 closure_.Reset(); |
432 } | 454 } |
433 | 455 |
434 RasterWorkerPool::ClosureTask::~ClosureTask() {} | 456 RasterWorkerPool::ClosureTask::~ClosureTask() {} |
435 | 457 |
436 } // namespace content | 458 } // namespace content |
OLD | NEW |