Index: content/renderer/raster_worker_pool.cc |
diff --git a/content/renderer/raster_worker_pool.cc b/content/renderer/raster_worker_pool.cc |
deleted file mode 100644 |
index 8c50e01b3b973bb989c8ace4a570f6289b814d5c..0000000000000000000000000000000000000000 |
--- a/content/renderer/raster_worker_pool.cc |
+++ /dev/null |
@@ -1,427 +0,0 @@ |
-// Copyright 2015 The Chromium Authors. All rights reserved. |
-// Use of this source code is governed by a BSD-style license that can be |
-// found in the LICENSE file. |
- |
-#include "content/renderer/raster_worker_pool.h" |
- |
-#include <string> |
-#include <utility> |
-#include <vector> |
- |
-#include "base/strings/stringprintf.h" |
-#include "base/threading/thread_restrictions.h" |
-#include "base/trace_event/trace_event.h" |
-#include "cc/base/math_util.h" |
-#include "cc/raster/task_category.h" |
- |
-namespace content { |
-namespace { |
- |
-// A thread which forwards to RasterWorkerPool::Run with the runnable |
-// categories. |
-class RasterWorkerPoolThread : public base::SimpleThread { |
- public: |
- RasterWorkerPoolThread(const std::string& name_prefix, |
- const Options& options, |
- RasterWorkerPool* pool, |
- std::vector<cc::TaskCategory> categories, |
- base::ConditionVariable* has_ready_to_run_tasks_cv) |
- : SimpleThread(name_prefix, options), |
- pool_(pool), |
- categories_(categories), |
- has_ready_to_run_tasks_cv_(has_ready_to_run_tasks_cv) {} |
- |
- void Run() override { pool_->Run(categories_, has_ready_to_run_tasks_cv_); } |
- |
- private: |
- RasterWorkerPool* const pool_; |
- const std::vector<cc::TaskCategory> categories_; |
- base::ConditionVariable* const has_ready_to_run_tasks_cv_; |
-}; |
- |
-} // namespace |
- |
-// A sequenced task runner which posts tasks to a RasterWorkerPool. |
-class RasterWorkerPool::RasterWorkerPoolSequencedTaskRunner |
- : public base::SequencedTaskRunner { |
- public: |
- explicit RasterWorkerPoolSequencedTaskRunner( |
- cc::TaskGraphRunner* task_graph_runner) |
- : task_graph_runner_(task_graph_runner), |
- namespace_token_(task_graph_runner->GetNamespaceToken()) {} |
- |
- // Overridden from base::TaskRunner: |
- bool PostDelayedTask(const tracked_objects::Location& from_here, |
- const base::Closure& task, |
- base::TimeDelta delay) override { |
- return PostNonNestableDelayedTask(from_here, task, delay); |
- } |
- bool RunsTasksOnCurrentThread() const override { return true; } |
- |
- // Overridden from base::SequencedTaskRunner: |
- bool PostNonNestableDelayedTask(const tracked_objects::Location& from_here, |
- const base::Closure& task, |
- base::TimeDelta delay) override { |
- base::AutoLock lock(lock_); |
- |
- // Remove completed tasks. |
- DCHECK(completed_tasks_.empty()); |
- task_graph_runner_->CollectCompletedTasks(namespace_token_, |
- &completed_tasks_); |
- |
- tasks_.erase(tasks_.begin(), tasks_.begin() + completed_tasks_.size()); |
- |
- tasks_.push_back(make_scoped_refptr(new ClosureTask(task))); |
- graph_.Reset(); |
- for (const auto& graph_task : tasks_) { |
- int dependencies = 0; |
- if (!graph_.nodes.empty()) |
- dependencies = 1; |
- |
- // Treat any tasks that are enqueued through the SequencedTaskRunner as |
- // FOREGROUND priority. We don't have enough information to know the |
- // actual priority of such tasks, so we run them as soon as possible. |
- cc::TaskGraph::Node node(graph_task.get(), cc::TASK_CATEGORY_FOREGROUND, |
- 0u /* priority */, dependencies); |
- if (dependencies) { |
- graph_.edges.push_back( |
- cc::TaskGraph::Edge(graph_.nodes.back().task, node.task)); |
- } |
- graph_.nodes.push_back(node); |
- } |
- task_graph_runner_->ScheduleTasks(namespace_token_, &graph_); |
- completed_tasks_.clear(); |
- return true; |
- } |
- |
- private: |
- ~RasterWorkerPoolSequencedTaskRunner() override { |
- task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_); |
- task_graph_runner_->CollectCompletedTasks(namespace_token_, |
- &completed_tasks_); |
- }; |
- |
- // Lock to exclusively access all the following members that are used to |
- // implement the SequencedTaskRunner interfaces. |
- base::Lock lock_; |
- |
- cc::TaskGraphRunner* task_graph_runner_; |
- // Namespace used to schedule tasks in the task graph runner. |
- cc::NamespaceToken namespace_token_; |
- // List of tasks currently queued up for execution. |
- cc::Task::Vector tasks_; |
- // Graph object used for scheduling tasks. |
- cc::TaskGraph graph_; |
- // Cached vector to avoid allocation when getting the list of complete |
- // tasks. |
- cc::Task::Vector completed_tasks_; |
-}; |
- |
-RasterWorkerPool::RasterWorkerPool() |
- : namespace_token_(GetNamespaceToken()), |
- has_ready_to_run_foreground_tasks_cv_(&lock_), |
- has_ready_to_run_background_tasks_cv_(&lock_), |
- has_namespaces_with_finished_running_tasks_cv_(&lock_), |
- shutdown_(false) {} |
- |
-void RasterWorkerPool::Start(int num_threads) { |
- DCHECK(threads_.empty()); |
- |
- // Start |num_threads| threads for foreground work, including nonconcurrent |
- // foreground work. |
- std::vector<cc::TaskCategory> foreground_categories; |
- foreground_categories.push_back(cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND); |
- foreground_categories.push_back(cc::TASK_CATEGORY_FOREGROUND); |
- |
- for (int i = 0; i < num_threads; i++) { |
- std::unique_ptr<base::SimpleThread> thread(new RasterWorkerPoolThread( |
- base::StringPrintf("CompositorTileWorker%u", |
- static_cast<unsigned>(threads_.size() + 1)) |
- .c_str(), |
- base::SimpleThread::Options(), this, foreground_categories, |
- &has_ready_to_run_foreground_tasks_cv_)); |
- thread->Start(); |
- threads_.push_back(std::move(thread)); |
- } |
- |
- // Start a single thread for background work. |
- std::vector<cc::TaskCategory> background_categories; |
- background_categories.push_back(cc::TASK_CATEGORY_BACKGROUND); |
- |
- // Use background priority for background thread. |
- base::SimpleThread::Options thread_options; |
-#if !defined(OS_MACOSX) |
- thread_options.set_priority(base::ThreadPriority::BACKGROUND); |
-#endif |
- |
- std::unique_ptr<base::SimpleThread> thread(new RasterWorkerPoolThread( |
- "CompositorTileWorkerBackground", thread_options, this, |
- background_categories, &has_ready_to_run_background_tasks_cv_)); |
- thread->Start(); |
- threads_.push_back(std::move(thread)); |
-} |
- |
-void RasterWorkerPool::Shutdown() { |
- WaitForTasksToFinishRunning(namespace_token_); |
- CollectCompletedTasks(namespace_token_, &completed_tasks_); |
- // Shutdown raster threads. |
- { |
- base::AutoLock lock(lock_); |
- |
- DCHECK(!work_queue_.HasReadyToRunTasks()); |
- DCHECK(!work_queue_.HasAnyNamespaces()); |
- |
- DCHECK(!shutdown_); |
- shutdown_ = true; |
- |
- // Wake up all workers so they exit. |
- has_ready_to_run_foreground_tasks_cv_.Broadcast(); |
- has_ready_to_run_background_tasks_cv_.Broadcast(); |
- } |
- while (!threads_.empty()) { |
- threads_.back()->Join(); |
- threads_.pop_back(); |
- } |
-} |
- |
-// Overridden from base::TaskRunner: |
-bool RasterWorkerPool::PostDelayedTask( |
- const tracked_objects::Location& from_here, |
- const base::Closure& task, |
- base::TimeDelta delay) { |
- base::AutoLock lock(lock_); |
- |
- // Remove completed tasks. |
- DCHECK(completed_tasks_.empty()); |
- CollectCompletedTasksWithLockAcquired(namespace_token_, &completed_tasks_); |
- |
- cc::Task::Vector::iterator end = std::remove_if( |
- tasks_.begin(), tasks_.end(), [this](const scoped_refptr<cc::Task>& e) { |
- return std::find(this->completed_tasks_.begin(), |
- this->completed_tasks_.end(), |
- e) != this->completed_tasks_.end(); |
- }); |
- tasks_.erase(end, tasks_.end()); |
- |
- tasks_.push_back(make_scoped_refptr(new ClosureTask(task))); |
- graph_.Reset(); |
- for (const auto& graph_task : tasks_) { |
- // Delayed tasks are assigned FOREGROUND category, ensuring that they run as |
- // soon as possible once their delay has expired. |
- graph_.nodes.push_back( |
- cc::TaskGraph::Node(graph_task.get(), cc::TASK_CATEGORY_FOREGROUND, |
- 0u /* priority */, 0u /* dependencies */)); |
- } |
- |
- ScheduleTasksWithLockAcquired(namespace_token_, &graph_); |
- completed_tasks_.clear(); |
- return true; |
-} |
- |
-bool RasterWorkerPool::RunsTasksOnCurrentThread() const { |
- return true; |
-} |
- |
-void RasterWorkerPool::Run(const std::vector<cc::TaskCategory>& categories, |
- base::ConditionVariable* has_ready_to_run_tasks_cv) { |
- base::AutoLock lock(lock_); |
- |
- while (true) { |
- if (!RunTaskWithLockAcquired(categories)) { |
- // We are no longer running tasks, which may allow another category to |
- // start running. Signal other worker threads. |
- SignalHasReadyToRunTasksWithLockAcquired(); |
- |
- // Exit when shutdown is set and no more tasks are pending. |
- if (shutdown_) |
- break; |
- |
- // Wait for more tasks. |
- has_ready_to_run_tasks_cv->Wait(); |
- continue; |
- } |
- } |
-} |
- |
-void RasterWorkerPool::FlushForTesting() { |
- base::AutoLock lock(lock_); |
- |
- while (!work_queue_.HasFinishedRunningTasksInAllNamespaces()) { |
- has_namespaces_with_finished_running_tasks_cv_.Wait(); |
- } |
-} |
- |
-scoped_refptr<base::SequencedTaskRunner> |
-RasterWorkerPool::CreateSequencedTaskRunner() { |
- return new RasterWorkerPoolSequencedTaskRunner(this); |
-} |
- |
-RasterWorkerPool::~RasterWorkerPool() {} |
- |
-cc::NamespaceToken RasterWorkerPool::GetNamespaceToken() { |
- base::AutoLock lock(lock_); |
- return work_queue_.GetNamespaceToken(); |
-} |
- |
-void RasterWorkerPool::ScheduleTasks(cc::NamespaceToken token, |
- cc::TaskGraph* graph) { |
- TRACE_EVENT2("disabled-by-default-cc.debug", |
- "RasterWorkerPool::ScheduleTasks", "num_nodes", |
- graph->nodes.size(), "num_edges", graph->edges.size()); |
- { |
- base::AutoLock lock(lock_); |
- ScheduleTasksWithLockAcquired(token, graph); |
- } |
-} |
- |
-void RasterWorkerPool::ScheduleTasksWithLockAcquired(cc::NamespaceToken token, |
- cc::TaskGraph* graph) { |
- DCHECK(token.IsValid()); |
- DCHECK(!cc::TaskGraphWorkQueue::DependencyMismatch(graph)); |
- DCHECK(!shutdown_); |
- |
- work_queue_.ScheduleTasks(token, graph); |
- |
- // There may be more work available, so wake up another worker thread. |
- SignalHasReadyToRunTasksWithLockAcquired(); |
-} |
- |
-void RasterWorkerPool::WaitForTasksToFinishRunning(cc::NamespaceToken token) { |
- TRACE_EVENT0("disabled-by-default-cc.debug", |
- "RasterWorkerPool::WaitForTasksToFinishRunning"); |
- |
- DCHECK(token.IsValid()); |
- |
- { |
- base::AutoLock lock(lock_); |
- base::ThreadRestrictions::ScopedAllowWait allow_wait; |
- |
- auto* task_namespace = work_queue_.GetNamespaceForToken(token); |
- |
- if (!task_namespace) |
- return; |
- |
- while (!work_queue_.HasFinishedRunningTasksInNamespace(task_namespace)) |
- has_namespaces_with_finished_running_tasks_cv_.Wait(); |
- |
- // There may be other namespaces that have finished running tasks, so wake |
- // up another origin thread. |
- has_namespaces_with_finished_running_tasks_cv_.Signal(); |
- } |
-} |
- |
-void RasterWorkerPool::CollectCompletedTasks( |
- cc::NamespaceToken token, |
- cc::Task::Vector* completed_tasks) { |
- TRACE_EVENT0("disabled-by-default-cc.debug", |
- "RasterWorkerPool::CollectCompletedTasks"); |
- |
- { |
- base::AutoLock lock(lock_); |
- CollectCompletedTasksWithLockAcquired(token, completed_tasks); |
- } |
-} |
- |
-void RasterWorkerPool::CollectCompletedTasksWithLockAcquired( |
- cc::NamespaceToken token, |
- cc::Task::Vector* completed_tasks) { |
- DCHECK(token.IsValid()); |
- work_queue_.CollectCompletedTasks(token, completed_tasks); |
-} |
- |
-bool RasterWorkerPool::RunTaskWithLockAcquired( |
- const std::vector<cc::TaskCategory>& categories) { |
- for (const auto& category : categories) { |
- if (ShouldRunTaskForCategoryWithLockAcquired(category)) { |
- RunTaskInCategoryWithLockAcquired(category); |
- return true; |
- } |
- } |
- return false; |
-} |
- |
-void RasterWorkerPool::RunTaskInCategoryWithLockAcquired( |
- cc::TaskCategory category) { |
- TRACE_EVENT0("toplevel", "TaskGraphRunner::RunTask"); |
- |
- lock_.AssertAcquired(); |
- |
- auto prioritized_task = work_queue_.GetNextTaskToRun(category); |
- cc::Task* task = prioritized_task.task; |
- |
- // There may be more work available, so wake up another worker thread. |
- SignalHasReadyToRunTasksWithLockAcquired(); |
- |
- { |
- base::AutoUnlock unlock(lock_); |
- |
- task->RunOnWorkerThread(); |
- } |
- |
- work_queue_.CompleteTask(prioritized_task); |
- |
- // If namespace has finished running all tasks, wake up origin threads. |
- if (work_queue_.HasFinishedRunningTasksInNamespace( |
- prioritized_task.task_namespace)) |
- has_namespaces_with_finished_running_tasks_cv_.Signal(); |
-} |
- |
-bool RasterWorkerPool::ShouldRunTaskForCategoryWithLockAcquired( |
- cc::TaskCategory category) { |
- lock_.AssertAcquired(); |
- |
- if (!work_queue_.HasReadyToRunTasksForCategory(category)) |
- return false; |
- |
- if (category == cc::TASK_CATEGORY_BACKGROUND) { |
- // Only run background tasks if there are no foreground tasks running or |
- // ready to run. |
- size_t num_running_foreground_tasks = |
- work_queue_.NumRunningTasksForCategory( |
- cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND) + |
- work_queue_.NumRunningTasksForCategory(cc::TASK_CATEGORY_FOREGROUND); |
- bool has_ready_to_run_foreground_tasks = |
- work_queue_.HasReadyToRunTasksForCategory( |
- cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND) || |
- work_queue_.HasReadyToRunTasksForCategory(cc::TASK_CATEGORY_FOREGROUND); |
- |
- if (num_running_foreground_tasks > 0 || has_ready_to_run_foreground_tasks) |
- return false; |
- } |
- |
- // Enforce that only one nonconcurrent task runs at a time. |
- if (category == cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND && |
- work_queue_.NumRunningTasksForCategory( |
- cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND) > 0) { |
- return false; |
- } |
- |
- return true; |
-} |
- |
-void RasterWorkerPool::SignalHasReadyToRunTasksWithLockAcquired() { |
- lock_.AssertAcquired(); |
- |
- if (ShouldRunTaskForCategoryWithLockAcquired(cc::TASK_CATEGORY_FOREGROUND) || |
- ShouldRunTaskForCategoryWithLockAcquired( |
- cc::TASK_CATEGORY_NONCONCURRENT_FOREGROUND)) { |
- has_ready_to_run_foreground_tasks_cv_.Signal(); |
- } |
- |
- if (ShouldRunTaskForCategoryWithLockAcquired(cc::TASK_CATEGORY_BACKGROUND)) { |
- has_ready_to_run_background_tasks_cv_.Signal(); |
- } |
-} |
- |
-RasterWorkerPool::ClosureTask::ClosureTask(const base::Closure& closure) |
- : closure_(closure) {} |
- |
-// Overridden from cc::Task: |
-void RasterWorkerPool::ClosureTask::RunOnWorkerThread() { |
- closure_.Run(); |
- closure_.Reset(); |
-} |
- |
-RasterWorkerPool::ClosureTask::~ClosureTask() {} |
- |
-} // namespace content |