Chromium Code Reviews| Index: cc/worker_pool.cc |
| diff --git a/cc/worker_pool.cc b/cc/worker_pool.cc |
| index 7d3428aa74d2f8bde286b73cb418549fb1504a70..ec1602e548586a490b58115f37b8d4127322116a 100644 |
| --- a/cc/worker_pool.cc |
| +++ b/cc/worker_pool.cc |
| @@ -7,6 +7,7 @@ |
| #include <algorithm> |
| #include "base/bind.h" |
| +#include "base/debug/trace_event.h" |
| #include "base/stl_util.h" |
| #include "base/stringprintf.h" |
| @@ -30,6 +31,8 @@ class WorkerPoolTaskImpl : public internal::WorkerPoolTask { |
| task_.Run(rendering_stats); |
| } |
| + virtual void DeferToThread(base::Thread* thread) OVERRIDE {} |
| + |
| private: |
| WorkerPool::Callback task_; |
| }; |
| @@ -40,6 +43,12 @@ const char* kWorkerThreadNamePrefix = "Compositor"; |
| // low while making sure workers aren't unnecessarily idle. |
| const int kNumPendingTasksPerWorker = 2; |
| +// Limits for the total number of cheap tasks we are allowed to perform |
| +// during a single frame and the time spent running those tasks. |
| +// TODO(skyostil): Determine these limits more dynamically. |
| +const int kMaxCheapTaskCount = 6; |
| +const int kMaxCheapTaskMilliseconds = 6; |
|
reveman
2013/02/13 22:17:36
maybe you can use the same time limit for this as
|
| + |
| } // namespace |
| namespace internal { |
| @@ -128,7 +137,9 @@ void WorkerPool::Worker::OnTaskCompleted() { |
| WorkerPool::WorkerPool(size_t num_threads) |
| : workers_need_sorting_(false), |
| - shutdown_(false) { |
| + shutdown_(false), |
| + cheap_tasks_allowed_(true), |
| + running_cheap_tasks_(false) { |
| const std::string thread_name_prefix = kWorkerThreadNamePrefix; |
| while (workers_.size() < num_threads) { |
| int thread_number = workers_.size() + 1; |
| @@ -171,6 +182,11 @@ bool WorkerPool::IsBusy() { |
| } |
| void WorkerPool::SetRecordRenderingStats(bool record_rendering_stats) { |
| + if (record_rendering_stats) |
| + cheap_rendering_stats_.reset(new RenderingStats); |
| + else |
| + cheap_rendering_stats_.reset(); |
| + |
| for (WorkerVector::iterator it = workers_.begin(); |
| it != workers_.end(); ++it) { |
| Worker* worker = *it; |
| @@ -183,6 +199,16 @@ void WorkerPool::GetRenderingStats(RenderingStats* stats) { |
| stats->totalPixelsRasterized = 0; |
| stats->totalDeferredImageDecodeCount = 0; |
| stats->totalDeferredImageDecodeTime = base::TimeDelta(); |
| + if (cheap_rendering_stats_) { |
| + stats->totalRasterizeTime += |
| + cheap_rendering_stats_->totalRasterizeTime; |
| + stats->totalPixelsRasterized += |
| + cheap_rendering_stats_->totalPixelsRasterized; |
| + stats->totalDeferredImageDecodeCount += |
| + cheap_rendering_stats_->totalDeferredImageDecodeCount; |
| + stats->totalDeferredImageDecodeTime += |
| + cheap_rendering_stats_->totalDeferredImageDecodeTime; |
| + } |
| for (WorkerVector::iterator it = workers_.begin(); |
| it != workers_.end(); ++it) { |
| Worker* worker = *it; |
| @@ -216,4 +242,52 @@ void WorkerPool::SortWorkersIfNeeded() { |
| workers_need_sorting_ = false; |
| } |
| +void WorkerPool::SetCheapTasksAllowed(bool allowed) { |
| + cheap_tasks_allowed_ = allowed; |
| +} |
| + |
| +bool WorkerPool::CanPostCheapTask() const { |
| + return cheap_tasks_allowed_ && |
| + pending_cheap_tasks_.size() < kMaxCheapTaskCount; |
| +} |
| + |
| +void WorkerPool::PostCheapTask(scoped_ptr<internal::WorkerPoolTask> task) { |
| + DCHECK(CanPostCheapTask()); |
| + pending_cheap_tasks_.push_back(task.Pass()); |
| +} |
| + |
| +bool WorkerPool::RunCheapTasks() { |
| + if (running_cheap_tasks_) |
| + return false; |
| + running_cheap_tasks_ = true; |
| + |
| + // Run as many cheap tasks as we can within the time limit. |
| + TRACE_EVENT0("cc", "WorkerPool::RunCheapTasks"); |
| + bool ran_cheap_tasks = false; |
| + base::TimeTicks deadline = base::TimeTicks::Now() + |
| + base::TimeDelta::FromMilliseconds(kMaxCheapTaskMilliseconds); |
| + while (pending_cheap_tasks_.size()) { |
| + ran_cheap_tasks = true; |
| + scoped_ptr<internal::WorkerPoolTask> task = |
| + pending_cheap_tasks_.take_front(); |
| + task->Run(cheap_rendering_stats_.get()); |
| + task->Completed(); |
| + if (base::TimeTicks::Now() >= deadline) { |
| + TRACE_EVENT_INSTANT0("cc", "WorkerPool::RunCheapTasks out of time"); |
| + break; |
| + } |
| + } |
| + |
| + // Defer remaining tasks to worker threads. |
| + while (pending_cheap_tasks_.size()) { |
| + scoped_ptr<internal::WorkerPoolTask> task = |
| + pending_cheap_tasks_.take_front(); |
| + Worker* worker = GetWorkerForNextTask(); |
| + task->DeferToThread(worker); |
| + worker->PostTask(task.Pass()); |
| + } |
| + running_cheap_tasks_ = false; |
| + return ran_cheap_tasks; |
| +} |
| + |
| } // namespace cc |