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