OLD | NEW |
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/resources/raster_worker_pool.h" | 5 #include "cc/resources/raster_worker_pool.h" |
6 | 6 |
7 #include "base/json/json_writer.h" | 7 #include "base/json/json_writer.h" |
8 #include "base/metrics/histogram.h" | 8 #include "base/metrics/histogram.h" |
9 #include "base/values.h" | 9 #include "base/values.h" |
10 #include "cc/debug/devtools_instrumentation.h" | 10 #include "cc/debug/devtools_instrumentation.h" |
(...skipping 209 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
220 skia::LazyPixelRef* pixel_ref_; | 220 skia::LazyPixelRef* pixel_ref_; |
221 int layer_id_; | 221 int layer_id_; |
222 RenderingStatsInstrumentation* rendering_stats_; | 222 RenderingStatsInstrumentation* rendering_stats_; |
223 const RasterWorkerPool::Task::Reply reply_; | 223 const RasterWorkerPool::Task::Reply reply_; |
224 | 224 |
225 DISALLOW_COPY_AND_ASSIGN(ImageDecodeWorkerPoolTaskImpl); | 225 DISALLOW_COPY_AND_ASSIGN(ImageDecodeWorkerPoolTaskImpl); |
226 }; | 226 }; |
227 | 227 |
228 class RasterFinishedWorkerPoolTaskImpl : public internal::WorkerPoolTask { | 228 class RasterFinishedWorkerPoolTaskImpl : public internal::WorkerPoolTask { |
229 public: | 229 public: |
| 230 typedef base::Callback<void(const internal::WorkerPoolTask* source)> |
| 231 Callback; |
| 232 |
230 RasterFinishedWorkerPoolTaskImpl( | 233 RasterFinishedWorkerPoolTaskImpl( |
231 base::MessageLoopProxy* origin_loop, | 234 const Callback& on_raster_finished_callback) |
232 const base::Closure& on_raster_finished_callback) | 235 : origin_loop_(base::MessageLoopProxy::current().get()), |
233 : origin_loop_(origin_loop), | 236 run_on_origin_thread_callback_( |
234 on_raster_finished_callback_(on_raster_finished_callback) { | 237 base::Bind(&RasterFinishedWorkerPoolTaskImpl::RunOnOriginThread, |
| 238 base::Unretained(this), |
| 239 on_raster_finished_callback)) { |
235 } | 240 } |
236 | 241 |
237 // Overridden from internal::WorkerPoolTask: | 242 // Overridden from internal::WorkerPoolTask: |
238 virtual void RunOnWorkerThread(unsigned thread_index) OVERRIDE { | 243 virtual void RunOnWorkerThread(unsigned thread_index) OVERRIDE { |
239 origin_loop_->PostTask(FROM_HERE, on_raster_finished_callback_); | 244 TRACE_EVENT0("cc", "RasterFinishedWorkerPoolTaskImpl::RunOnWorkerThread"); |
| 245 origin_loop_->PostTask(FROM_HERE, run_on_origin_thread_callback_); |
240 } | 246 } |
241 virtual void CompleteOnOriginThread() OVERRIDE {} | 247 virtual void CompleteOnOriginThread() OVERRIDE {} |
242 | 248 |
243 private: | 249 private: |
244 virtual ~RasterFinishedWorkerPoolTaskImpl() {} | 250 virtual ~RasterFinishedWorkerPoolTaskImpl() {} |
245 | 251 |
| 252 static void RunOnOriginThread( |
| 253 const internal::WorkerPoolTask* source, |
| 254 const Callback& on_raster_finished_callback) { |
| 255 on_raster_finished_callback.Run(source); |
| 256 } |
| 257 |
246 scoped_refptr<base::MessageLoopProxy> origin_loop_; | 258 scoped_refptr<base::MessageLoopProxy> origin_loop_; |
247 const base::Closure on_raster_finished_callback_; | 259 const base::Closure run_on_origin_thread_callback_; |
248 | 260 |
249 DISALLOW_COPY_AND_ASSIGN(RasterFinishedWorkerPoolTaskImpl); | 261 DISALLOW_COPY_AND_ASSIGN(RasterFinishedWorkerPoolTaskImpl); |
250 }; | 262 }; |
251 | 263 |
252 void Noop() {} | |
253 | |
254 const char* kWorkerThreadNamePrefix = "CompositorRaster"; | 264 const char* kWorkerThreadNamePrefix = "CompositorRaster"; |
255 | 265 |
256 } // namespace | 266 } // namespace |
257 | 267 |
258 namespace internal { | 268 namespace internal { |
259 | 269 |
260 RasterWorkerPoolTask::RasterWorkerPoolTask( | 270 RasterWorkerPoolTask::RasterWorkerPoolTask( |
261 const Resource* resource, TaskVector* dependencies) | 271 const Resource* resource, TaskVector* dependencies) |
262 : did_run_(false), | 272 : did_run_(false), |
263 did_complete_(false), | 273 did_complete_(false), |
(...skipping 91 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
355 : internal_(internal) { | 365 : internal_(internal) { |
356 } | 366 } |
357 | 367 |
358 void RasterWorkerPool::RasterTask::Reset() { | 368 void RasterWorkerPool::RasterTask::Reset() { |
359 internal_ = NULL; | 369 internal_ = NULL; |
360 } | 370 } |
361 | 371 |
362 RasterWorkerPool::RasterTask::~RasterTask() { | 372 RasterWorkerPool::RasterTask::~RasterTask() { |
363 } | 373 } |
364 | 374 |
365 RasterWorkerPool::RasterTaskGraph::RasterTaskGraph() | |
366 : raster_finished_node_(new GraphNode), | |
367 next_priority_(1u) { | |
368 } | |
369 | |
370 RasterWorkerPool::RasterTaskGraph::~RasterTaskGraph() { | |
371 } | |
372 | |
373 void RasterWorkerPool::RasterTaskGraph::InsertRasterTask( | |
374 internal::WorkerPoolTask* raster_task, | |
375 const TaskVector& decode_tasks) { | |
376 DCHECK(!raster_task->HasCompleted()); | |
377 DCHECK(graph_.find(raster_task) == graph_.end()); | |
378 | |
379 scoped_ptr<GraphNode> raster_node(new GraphNode); | |
380 raster_node->set_task(raster_task); | |
381 raster_node->set_priority(next_priority_++); | |
382 | |
383 // Insert image decode tasks. | |
384 for (TaskVector::const_iterator it = decode_tasks.begin(); | |
385 it != decode_tasks.end(); ++it) { | |
386 internal::WorkerPoolTask* decode_task = it->get(); | |
387 | |
388 // Skip if already decoded. | |
389 if (decode_task->HasCompleted()) | |
390 continue; | |
391 | |
392 raster_node->add_dependency(); | |
393 | |
394 // Check if decode task already exists in graph. | |
395 GraphNodeMap::iterator decode_it = graph_.find(decode_task); | |
396 if (decode_it != graph_.end()) { | |
397 GraphNode* decode_node = decode_it->second; | |
398 decode_node->add_dependent(raster_node.get()); | |
399 continue; | |
400 } | |
401 | |
402 scoped_ptr<GraphNode> decode_node(new GraphNode); | |
403 decode_node->set_task(decode_task); | |
404 decode_node->set_priority(next_priority_++); | |
405 decode_node->add_dependent(raster_node.get()); | |
406 graph_.set(decode_task, decode_node.Pass()); | |
407 } | |
408 | |
409 raster_finished_node_->add_dependency(); | |
410 raster_node->add_dependent(raster_finished_node_.get()); | |
411 | |
412 graph_.set(raster_task, raster_node.Pass()); | |
413 } | |
414 | |
415 // static | 375 // static |
416 RasterWorkerPool::RasterTask RasterWorkerPool::CreateRasterTask( | 376 RasterWorkerPool::RasterTask RasterWorkerPool::CreateRasterTask( |
417 const Resource* resource, | 377 const Resource* resource, |
418 PicturePileImpl* picture_pile, | 378 PicturePileImpl* picture_pile, |
419 gfx::Rect content_rect, | 379 gfx::Rect content_rect, |
420 float contents_scale, | 380 float contents_scale, |
421 RasterMode raster_mode, | 381 RasterMode raster_mode, |
422 bool use_color_estimator, | 382 bool use_color_estimator, |
423 const RasterTaskMetadata& metadata, | 383 const RasterTaskMetadata& metadata, |
424 RenderingStatsInstrumentation* rendering_stats, | 384 RenderingStatsInstrumentation* rendering_stats, |
(...skipping 21 matching lines...) Expand all Loading... |
446 layer_id, | 406 layer_id, |
447 stats_instrumentation, | 407 stats_instrumentation, |
448 reply)); | 408 reply)); |
449 } | 409 } |
450 | 410 |
451 RasterWorkerPool::RasterWorkerPool(ResourceProvider* resource_provider, | 411 RasterWorkerPool::RasterWorkerPool(ResourceProvider* resource_provider, |
452 size_t num_threads) | 412 size_t num_threads) |
453 : WorkerPool(num_threads, kWorkerThreadNamePrefix), | 413 : WorkerPool(num_threads, kWorkerThreadNamePrefix), |
454 client_(NULL), | 414 client_(NULL), |
455 resource_provider_(resource_provider), | 415 resource_provider_(resource_provider), |
456 weak_ptr_factory_(this), | 416 weak_ptr_factory_(this) { |
457 schedule_raster_tasks_count_(0) { | |
458 } | 417 } |
459 | 418 |
460 RasterWorkerPool::~RasterWorkerPool() { | 419 RasterWorkerPool::~RasterWorkerPool() { |
461 } | 420 } |
462 | 421 |
463 void RasterWorkerPool::SetClient(RasterWorkerPoolClient* client) { | 422 void RasterWorkerPool::SetClient(RasterWorkerPoolClient* client) { |
464 client_ = client; | 423 client_ = client; |
465 } | 424 } |
466 | 425 |
467 void RasterWorkerPool::Shutdown() { | 426 void RasterWorkerPool::Shutdown() { |
| 427 raster_tasks_.clear(); |
468 TaskGraph empty; | 428 TaskGraph empty; |
469 SetTaskGraph(&empty); | 429 SetTaskGraph(&empty); |
470 WorkerPool::Shutdown(); | 430 WorkerPool::Shutdown(); |
471 raster_tasks_.clear(); | |
472 // Cancel any pending OnRasterFinished callback. | |
473 weak_ptr_factory_.InvalidateWeakPtrs(); | 431 weak_ptr_factory_.InvalidateWeakPtrs(); |
474 } | 432 } |
475 | 433 |
476 void RasterWorkerPool::SetRasterTasks(RasterTask::Queue* queue) { | 434 void RasterWorkerPool::SetRasterTasks(RasterTask::Queue* queue) { |
477 raster_tasks_.swap(queue->tasks_); | 435 raster_tasks_.swap(queue->tasks_); |
478 raster_tasks_required_for_activation_.swap( | 436 raster_tasks_required_for_activation_.swap( |
479 queue->tasks_required_for_activation_); | 437 queue->tasks_required_for_activation_); |
480 } | 438 } |
481 | 439 |
482 void RasterWorkerPool::SetRasterTaskGraph(RasterTaskGraph* graph) { | |
483 scoped_ptr<GraphNode> raster_finished_node( | |
484 graph->raster_finished_node_.Pass()); | |
485 TaskGraph new_graph; | |
486 new_graph.swap(graph->graph_); | |
487 | |
488 if (new_graph.empty()) { | |
489 SetTaskGraph(&new_graph); | |
490 raster_finished_task_ = NULL; | |
491 return; | |
492 } | |
493 | |
494 ++schedule_raster_tasks_count_; | |
495 | |
496 scoped_refptr<internal::WorkerPoolTask> new_raster_finished_task( | |
497 new RasterFinishedWorkerPoolTaskImpl( | |
498 base::MessageLoopProxy::current().get(), | |
499 base::Bind(&RasterWorkerPool::OnRasterFinished, | |
500 weak_ptr_factory_.GetWeakPtr(), | |
501 schedule_raster_tasks_count_))); | |
502 raster_finished_node->set_task(new_raster_finished_task.get()); | |
503 // Insert "raster finished" task before switching to new graph. | |
504 new_graph.set(new_raster_finished_task.get(), raster_finished_node.Pass()); | |
505 SetTaskGraph(&new_graph); | |
506 raster_finished_task_.swap(new_raster_finished_task); | |
507 } | |
508 | |
509 bool RasterWorkerPool::IsRasterTaskRequiredForActivation( | 440 bool RasterWorkerPool::IsRasterTaskRequiredForActivation( |
510 internal::RasterWorkerPoolTask* task) const { | 441 internal::RasterWorkerPoolTask* task) const { |
511 return | 442 return |
512 raster_tasks_required_for_activation_.find(task) != | 443 raster_tasks_required_for_activation_.find(task) != |
513 raster_tasks_required_for_activation_.end(); | 444 raster_tasks_required_for_activation_.end(); |
514 } | 445 } |
515 | 446 |
516 void RasterWorkerPool::OnRasterFinished(int64 schedule_raster_tasks_count) { | 447 scoped_refptr<internal::WorkerPoolTask> |
517 TRACE_EVENT1("cc", "RasterWorkerPool::OnRasterFinished", | 448 RasterWorkerPool::CreateRasterFinishedTask() { |
518 "schedule_raster_tasks_count", schedule_raster_tasks_count); | 449 return make_scoped_refptr( |
519 DCHECK_GE(schedule_raster_tasks_count_, schedule_raster_tasks_count); | 450 new RasterFinishedWorkerPoolTaskImpl( |
520 // Call OnRasterTasksFinished() when we've finished running all raster | 451 base::Bind(&RasterWorkerPool::OnRasterFinished, |
521 // tasks needed since last time SetRasterTaskGraph() was called. | 452 weak_ptr_factory_.GetWeakPtr()))); |
522 if (schedule_raster_tasks_count_ == schedule_raster_tasks_count) | 453 } |
523 OnRasterTasksFinished(); | 454 |
| 455 scoped_refptr<internal::WorkerPoolTask> |
| 456 RasterWorkerPool::CreateRasterRequiredForActivationFinishedTask() { |
| 457 return make_scoped_refptr( |
| 458 new RasterFinishedWorkerPoolTaskImpl( |
| 459 base::Bind(&RasterWorkerPool::OnRasterRequiredForActivationFinished, |
| 460 weak_ptr_factory_.GetWeakPtr()))); |
| 461 } |
| 462 |
| 463 void RasterWorkerPool::OnRasterFinished( |
| 464 const internal::WorkerPoolTask* source) { |
| 465 TRACE_EVENT0("cc", "RasterWorkerPool::OnRasterFinished"); |
| 466 |
| 467 // Early out if current |raster_finished_task_| is not the source. |
| 468 if (source != raster_finished_task_.get()) |
| 469 return; |
| 470 |
| 471 OnRasterTasksFinished(); |
| 472 } |
| 473 |
| 474 void RasterWorkerPool::OnRasterRequiredForActivationFinished( |
| 475 const internal::WorkerPoolTask* source) { |
| 476 TRACE_EVENT0("cc", "RasterWorkerPool::OnRasterRequiredForActivationFinished"); |
| 477 |
| 478 // Early out if current |raster_required_for_activation_finished_task_| |
| 479 // is not the source. |
| 480 if (source != raster_required_for_activation_finished_task_.get()) |
| 481 return; |
| 482 |
| 483 OnRasterTasksRequiredForActivationFinished(); |
| 484 } |
| 485 |
| 486 // static |
| 487 WorkerPool::GraphNode* RasterWorkerPool::CreateGraphNodeForTask( |
| 488 internal::WorkerPoolTask* task, |
| 489 unsigned priority, |
| 490 TaskGraph* graph) { |
| 491 GraphNode* node = new GraphNode(task, priority); |
| 492 DCHECK(graph->find(task) == graph->end()); |
| 493 graph->set(task, make_scoped_ptr(node)); |
| 494 return node; |
| 495 } |
| 496 |
| 497 // static |
| 498 WorkerPool::GraphNode* RasterWorkerPool::CreateGraphNodeForRasterTask( |
| 499 internal::WorkerPoolTask* raster_task, |
| 500 const TaskVector& decode_tasks, |
| 501 unsigned priority, |
| 502 TaskGraph* graph) { |
| 503 DCHECK(!raster_task->HasCompleted()); |
| 504 |
| 505 GraphNode* raster_node = CreateGraphNodeForTask( |
| 506 raster_task, priority, graph); |
| 507 |
| 508 // Insert image decode tasks. |
| 509 for (TaskVector::const_iterator it = decode_tasks.begin(); |
| 510 it != decode_tasks.end(); ++it) { |
| 511 internal::WorkerPoolTask* decode_task = it->get(); |
| 512 |
| 513 // Skip if already decoded. |
| 514 if (decode_task->HasCompleted()) |
| 515 continue; |
| 516 |
| 517 raster_node->add_dependency(); |
| 518 |
| 519 // Check if decode task already exists in graph. |
| 520 GraphNodeMap::iterator decode_it = graph->find(decode_task); |
| 521 if (decode_it != graph->end()) { |
| 522 GraphNode* decode_node = decode_it->second; |
| 523 decode_node->add_dependent(raster_node); |
| 524 continue; |
| 525 } |
| 526 |
| 527 GraphNode* decode_node = CreateGraphNodeForTask( |
| 528 decode_task, priority, graph); |
| 529 decode_node->add_dependent(raster_node); |
| 530 } |
| 531 |
| 532 return raster_node; |
524 } | 533 } |
525 | 534 |
526 } // namespace cc | 535 } // namespace cc |
OLD | NEW |