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