| 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 |