Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(654)

Side by Side Diff: cc/worker_pool.cc

Issue 12194015: cc: Rasterize cheap tiles immediately (Closed) Base URL: http://git.chromium.org/git/chromium.git@trunk
Patch Set: Schedule cheap tasks in worker pool. Created 7 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« cc/worker_pool.h ('K') | « cc/worker_pool.h ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright 2013 The Chromium Authors. All rights reserved. 1 // Copyright 2013 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 "cc/worker_pool.h" 5 #include "cc/worker_pool.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 8
9 #include "base/bind.h" 9 #include "base/bind.h"
10 #include "base/debug/trace_event.h"
10 #include "base/stl_util.h" 11 #include "base/stl_util.h"
11 #include "base/stringprintf.h" 12 #include "base/stringprintf.h"
12 13
13 #if defined(OS_ANDROID) 14 #if defined(OS_ANDROID)
14 // TODO(epenner): Move thread priorities to base. (crbug.com/170549) 15 // TODO(epenner): Move thread priorities to base. (crbug.com/170549)
15 #include <sys/resource.h> 16 #include <sys/resource.h>
16 #endif 17 #endif
17 18
18 namespace cc { 19 namespace cc {
19 20
20 namespace { 21 namespace {
21 22
22 class WorkerPoolTaskImpl : public internal::WorkerPoolTask { 23 class WorkerPoolTaskImpl : public internal::WorkerPoolTask {
23 public: 24 public:
24 WorkerPoolTaskImpl(const WorkerPool::Callback& task, 25 WorkerPoolTaskImpl(const WorkerPool::Callback& task,
25 const base::Closure& reply) 26 const base::Closure& reply)
26 : internal::WorkerPoolTask(reply), 27 : internal::WorkerPoolTask(reply),
27 task_(task) {} 28 task_(task) {}
28 29
29 virtual void Run(RenderingStats* rendering_stats) OVERRIDE { 30 virtual void Run(RenderingStats* rendering_stats) OVERRIDE {
30 task_.Run(rendering_stats); 31 task_.Run(rendering_stats);
31 } 32 }
32 33
34 virtual void DeferToThread(base::Thread* thread) OVERRIDE {}
35
33 private: 36 private:
34 WorkerPool::Callback task_; 37 WorkerPool::Callback task_;
35 }; 38 };
36 39
37 const char* kWorkerThreadNamePrefix = "Compositor"; 40 const char* kWorkerThreadNamePrefix = "Compositor";
38 41
39 // Allow two pending tasks per worker. This keeps resource usage 42 // Allow two pending tasks per worker. This keeps resource usage
40 // low while making sure workers aren't unnecessarily idle. 43 // low while making sure workers aren't unnecessarily idle.
41 const int kNumPendingTasksPerWorker = 2; 44 const int kNumPendingTasksPerWorker = 2;
42 45
46 // Limits for the total number of cheap tasks we are allowed to perform
47 // during a single frame and the time spent running those tasks.
48 // TODO(skyostil): Determine these limits more dynamically.
49 const int kMaxCheapTaskCount = 6;
50 const int kMaxCheapTaskMilliseconds = 6;
reveman 2013/02/13 22:17:36 maybe you can use the same time limit for this as
51
43 } // namespace 52 } // namespace
44 53
45 namespace internal { 54 namespace internal {
46 55
47 WorkerPoolTask::WorkerPoolTask(const base::Closure& reply) 56 WorkerPoolTask::WorkerPoolTask(const base::Closure& reply)
48 : reply_(reply) { 57 : reply_(reply) {
49 } 58 }
50 59
51 WorkerPoolTask::~WorkerPoolTask() { 60 WorkerPoolTask::~WorkerPoolTask() {
52 } 61 }
(...skipping 68 matching lines...) Expand 10 before | Expand all | Expand 10 after
121 CHECK(!pending_tasks_.empty()); 130 CHECK(!pending_tasks_.empty());
122 131
123 scoped_ptr<internal::WorkerPoolTask> task = pending_tasks_.take_front(); 132 scoped_ptr<internal::WorkerPoolTask> task = pending_tasks_.take_front();
124 task->Completed(); 133 task->Completed();
125 134
126 worker_pool_->DidNumPendingTasksChange(); 135 worker_pool_->DidNumPendingTasksChange();
127 } 136 }
128 137
129 WorkerPool::WorkerPool(size_t num_threads) 138 WorkerPool::WorkerPool(size_t num_threads)
130 : workers_need_sorting_(false), 139 : workers_need_sorting_(false),
131 shutdown_(false) { 140 shutdown_(false),
141 cheap_tasks_allowed_(true),
142 running_cheap_tasks_(false) {
132 const std::string thread_name_prefix = kWorkerThreadNamePrefix; 143 const std::string thread_name_prefix = kWorkerThreadNamePrefix;
133 while (workers_.size() < num_threads) { 144 while (workers_.size() < num_threads) {
134 int thread_number = workers_.size() + 1; 145 int thread_number = workers_.size() + 1;
135 workers_.push_back(new Worker( 146 workers_.push_back(new Worker(
136 this, 147 this,
137 thread_name_prefix + StringPrintf("Worker%d", thread_number).c_str())); 148 thread_name_prefix + StringPrintf("Worker%d", thread_number).c_str()));
138 } 149 }
139 } 150 }
140 151
141 WorkerPool::~WorkerPool() { 152 WorkerPool::~WorkerPool() {
(...skipping 22 matching lines...) Expand all
164 reply)).PassAs<internal::WorkerPoolTask>()); 175 reply)).PassAs<internal::WorkerPoolTask>());
165 } 176 }
166 177
167 bool WorkerPool::IsBusy() { 178 bool WorkerPool::IsBusy() {
168 Worker* worker = GetWorkerForNextTask(); 179 Worker* worker = GetWorkerForNextTask();
169 180
170 return worker->num_pending_tasks() >= kNumPendingTasksPerWorker; 181 return worker->num_pending_tasks() >= kNumPendingTasksPerWorker;
171 } 182 }
172 183
173 void WorkerPool::SetRecordRenderingStats(bool record_rendering_stats) { 184 void WorkerPool::SetRecordRenderingStats(bool record_rendering_stats) {
185 if (record_rendering_stats)
186 cheap_rendering_stats_.reset(new RenderingStats);
187 else
188 cheap_rendering_stats_.reset();
189
174 for (WorkerVector::iterator it = workers_.begin(); 190 for (WorkerVector::iterator it = workers_.begin();
175 it != workers_.end(); ++it) { 191 it != workers_.end(); ++it) {
176 Worker* worker = *it; 192 Worker* worker = *it;
177 worker->set_record_rendering_stats(record_rendering_stats); 193 worker->set_record_rendering_stats(record_rendering_stats);
178 } 194 }
179 } 195 }
180 196
181 void WorkerPool::GetRenderingStats(RenderingStats* stats) { 197 void WorkerPool::GetRenderingStats(RenderingStats* stats) {
182 stats->totalRasterizeTime = base::TimeDelta(); 198 stats->totalRasterizeTime = base::TimeDelta();
183 stats->totalPixelsRasterized = 0; 199 stats->totalPixelsRasterized = 0;
184 stats->totalDeferredImageDecodeCount = 0; 200 stats->totalDeferredImageDecodeCount = 0;
185 stats->totalDeferredImageDecodeTime = base::TimeDelta(); 201 stats->totalDeferredImageDecodeTime = base::TimeDelta();
202 if (cheap_rendering_stats_) {
203 stats->totalRasterizeTime +=
204 cheap_rendering_stats_->totalRasterizeTime;
205 stats->totalPixelsRasterized +=
206 cheap_rendering_stats_->totalPixelsRasterized;
207 stats->totalDeferredImageDecodeCount +=
208 cheap_rendering_stats_->totalDeferredImageDecodeCount;
209 stats->totalDeferredImageDecodeTime +=
210 cheap_rendering_stats_->totalDeferredImageDecodeTime;
211 }
186 for (WorkerVector::iterator it = workers_.begin(); 212 for (WorkerVector::iterator it = workers_.begin();
187 it != workers_.end(); ++it) { 213 it != workers_.end(); ++it) {
188 Worker* worker = *it; 214 Worker* worker = *it;
189 CHECK(worker->rendering_stats()); 215 CHECK(worker->rendering_stats());
190 stats->totalRasterizeTime += 216 stats->totalRasterizeTime +=
191 worker->rendering_stats()->totalRasterizeTime; 217 worker->rendering_stats()->totalRasterizeTime;
192 stats->totalPixelsRasterized += 218 stats->totalPixelsRasterized +=
193 worker->rendering_stats()->totalPixelsRasterized; 219 worker->rendering_stats()->totalPixelsRasterized;
194 stats->totalDeferredImageDecodeCount += 220 stats->totalDeferredImageDecodeCount +=
195 worker->rendering_stats()->totalDeferredImageDecodeCount; 221 worker->rendering_stats()->totalDeferredImageDecodeCount;
(...skipping 13 matching lines...) Expand all
209 } 235 }
210 236
211 void WorkerPool::SortWorkersIfNeeded() { 237 void WorkerPool::SortWorkersIfNeeded() {
212 if (!workers_need_sorting_) 238 if (!workers_need_sorting_)
213 return; 239 return;
214 240
215 std::sort(workers_.begin(), workers_.end(), NumPendingTasksComparator()); 241 std::sort(workers_.begin(), workers_.end(), NumPendingTasksComparator());
216 workers_need_sorting_ = false; 242 workers_need_sorting_ = false;
217 } 243 }
218 244
245 void WorkerPool::SetCheapTasksAllowed(bool allowed) {
246 cheap_tasks_allowed_ = allowed;
247 }
248
249 bool WorkerPool::CanPostCheapTask() const {
250 return cheap_tasks_allowed_ &&
251 pending_cheap_tasks_.size() < kMaxCheapTaskCount;
252 }
253
254 void WorkerPool::PostCheapTask(scoped_ptr<internal::WorkerPoolTask> task) {
255 DCHECK(CanPostCheapTask());
256 pending_cheap_tasks_.push_back(task.Pass());
257 }
258
259 bool WorkerPool::RunCheapTasks() {
260 if (running_cheap_tasks_)
261 return false;
262 running_cheap_tasks_ = true;
263
264 // Run as many cheap tasks as we can within the time limit.
265 TRACE_EVENT0("cc", "WorkerPool::RunCheapTasks");
266 bool ran_cheap_tasks = false;
267 base::TimeTicks deadline = base::TimeTicks::Now() +
268 base::TimeDelta::FromMilliseconds(kMaxCheapTaskMilliseconds);
269 while (pending_cheap_tasks_.size()) {
270 ran_cheap_tasks = true;
271 scoped_ptr<internal::WorkerPoolTask> task =
272 pending_cheap_tasks_.take_front();
273 task->Run(cheap_rendering_stats_.get());
274 task->Completed();
275 if (base::TimeTicks::Now() >= deadline) {
276 TRACE_EVENT_INSTANT0("cc", "WorkerPool::RunCheapTasks out of time");
277 break;
278 }
279 }
280
281 // Defer remaining tasks to worker threads.
282 while (pending_cheap_tasks_.size()) {
283 scoped_ptr<internal::WorkerPoolTask> task =
284 pending_cheap_tasks_.take_front();
285 Worker* worker = GetWorkerForNextTask();
286 task->DeferToThread(worker);
287 worker->PostTask(task.Pass());
288 }
289 running_cheap_tasks_ = false;
290 return ran_cheap_tasks;
291 }
292
219 } // namespace cc 293 } // namespace cc
OLDNEW
« cc/worker_pool.h ('K') | « cc/worker_pool.h ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698