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