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/debug/trace_event_synthetic_delay.h" | 7 #include "base/debug/trace_event_synthetic_delay.h" |
8 #include "base/json/json_writer.h" | 8 #include "base/json/json_writer.h" |
9 #include "base/lazy_instance.h" | 9 #include "base/lazy_instance.h" |
10 #include "base/metrics/histogram.h" | 10 #include "base/metrics/histogram.h" |
11 #include "base/values.h" | 11 #include "base/values.h" |
12 #include "cc/debug/devtools_instrumentation.h" | 12 #include "cc/debug/devtools_instrumentation.h" |
13 #include "cc/debug/traced_value.h" | 13 #include "cc/debug/traced_value.h" |
14 #include "cc/resources/picture_pile_impl.h" | 14 #include "cc/resources/picture_pile_impl.h" |
15 #include "cc/resources/resource.h" | 15 #include "cc/resources/resource.h" |
16 #include "cc/resources/resource_provider.h" | 16 #include "cc/resources/resource_provider.h" |
17 #include "skia/ext/paint_simplifier.h" | 17 #include "skia/ext/paint_simplifier.h" |
18 #include "third_party/skia/include/core/SkBitmap.h" | 18 #include "third_party/skia/include/core/SkBitmap.h" |
19 #include "third_party/skia/include/core/SkPixelRef.h" | 19 #include "third_party/skia/include/core/SkPixelRef.h" |
20 #include "third_party/skia/include/gpu/GrContext.h" | 20 #include "third_party/skia/include/gpu/GrContext.h" |
21 #include "third_party/skia/include/gpu/SkGpuDevice.h" | 21 #include "third_party/skia/include/gpu/SkGpuDevice.h" |
22 | 22 |
23 namespace cc { | 23 namespace cc { |
24 | |
25 namespace { | 24 namespace { |
26 | 25 |
27 // Subclass of Allocator that takes a suitably allocated pointer and uses | 26 // Subclass of Allocator that takes a suitably allocated pointer and uses |
28 // it as the pixel memory for the bitmap. | 27 // it as the pixel memory for the bitmap. |
29 class IdentityAllocator : public SkBitmap::Allocator { | 28 class IdentityAllocator : public SkBitmap::Allocator { |
30 public: | 29 public: |
31 explicit IdentityAllocator(void* buffer) : buffer_(buffer) {} | 30 explicit IdentityAllocator(void* buffer) : buffer_(buffer) {} |
32 virtual bool allocPixelRef(SkBitmap* dst, SkColorTable*) OVERRIDE { | 31 virtual bool allocPixelRef(SkBitmap* dst, SkColorTable*) OVERRIDE { |
33 dst->setPixels(buffer_); | 32 dst->setPixels(buffer_); |
34 return true; | 33 return true; |
(...skipping 186 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
221 skia::RefPtr<GrTexture> texture = | 220 skia::RefPtr<GrTexture> texture = |
222 skia::AdoptRef(gr_context->wrapBackendTexture(desc)); | 221 skia::AdoptRef(gr_context->wrapBackendTexture(desc)); |
223 skia::RefPtr<SkGpuDevice> device = | 222 skia::RefPtr<SkGpuDevice> device = |
224 skia::AdoptRef(SkGpuDevice::Create(texture.get())); | 223 skia::AdoptRef(SkGpuDevice::Create(texture.get())); |
225 skia::RefPtr<SkCanvas> canvas = skia::AdoptRef(new SkCanvas(device.get())); | 224 skia::RefPtr<SkCanvas> canvas = skia::AdoptRef(new SkCanvas(device.get())); |
226 | 225 |
227 Raster(picture_pile_, canvas.get()); | 226 Raster(picture_pile_, canvas.get()); |
228 } | 227 } |
229 | 228 |
230 protected: | 229 protected: |
231 virtual ~RasterWorkerPoolTaskImpl() {} | 230 virtual ~RasterWorkerPoolTaskImpl() { DCHECK(!buffer_); } |
232 | 231 |
233 private: | 232 private: |
234 scoped_ptr<base::Value> DataAsValue() const { | 233 scoped_ptr<base::Value> DataAsValue() const { |
235 scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue()); | 234 scoped_ptr<base::DictionaryValue> res(new base::DictionaryValue()); |
236 res->Set("tile_id", TracedValue::CreateIDRef(tile_id_).release()); | 235 res->Set("tile_id", TracedValue::CreateIDRef(tile_id_).release()); |
237 res->Set("resolution", TileResolutionAsValue(tile_resolution_).release()); | 236 res->Set("resolution", TileResolutionAsValue(tile_resolution_).release()); |
238 res->SetInteger("source_frame_number", source_frame_number_); | 237 res->SetInteger("source_frame_number", source_frame_number_); |
239 res->SetInteger("layer_id", layer_id_); | 238 res->SetInteger("layer_id", layer_id_); |
240 return res.PassAs<base::Value>(); | 239 return res.PassAs<base::Value>(); |
241 } | 240 } |
(...skipping 288 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
530 RasterWorkerPool::RasterTask::RasterTask() {} | 529 RasterWorkerPool::RasterTask::RasterTask() {} |
531 | 530 |
532 RasterWorkerPool::RasterTask::RasterTask( | 531 RasterWorkerPool::RasterTask::RasterTask( |
533 internal::RasterWorkerPoolTask* internal) | 532 internal::RasterWorkerPoolTask* internal) |
534 : internal_(internal) {} | 533 : internal_(internal) {} |
535 | 534 |
536 void RasterWorkerPool::RasterTask::Reset() { internal_ = NULL; } | 535 void RasterWorkerPool::RasterTask::Reset() { internal_ = NULL; } |
537 | 536 |
538 RasterWorkerPool::RasterTask::~RasterTask() {} | 537 RasterWorkerPool::RasterTask::~RasterTask() {} |
539 | 538 |
| 539 // Task priorities that make sure raster finished tasks run before any |
| 540 // remaining raster tasks. |
| 541 unsigned RasterWorkerPool::kRasterFinishedTaskPriority = 1u; |
| 542 unsigned RasterWorkerPool::kRasterRequiredForActivationFinishedTaskPriority = |
| 543 0u; |
| 544 unsigned RasterWorkerPool::kRasterTaskPriorityBase = 2u; |
| 545 |
540 RasterWorkerPool::RasterWorkerPool(ResourceProvider* resource_provider, | 546 RasterWorkerPool::RasterWorkerPool(ResourceProvider* resource_provider, |
541 ContextProvider* context_provider) | 547 ContextProvider* context_provider) |
542 : namespace_token_(g_task_graph_runner.Pointer()->GetNamespaceToken()), | 548 : namespace_token_(g_task_graph_runner.Pointer()->GetNamespaceToken()), |
543 client_(NULL), | 549 client_(NULL), |
544 resource_provider_(resource_provider), | 550 resource_provider_(resource_provider), |
545 context_provider_(context_provider), | 551 context_provider_(context_provider), |
546 weak_ptr_factory_(this) {} | 552 weak_ptr_factory_(this) {} |
547 | 553 |
548 RasterWorkerPool::~RasterWorkerPool() {} | 554 RasterWorkerPool::~RasterWorkerPool() {} |
549 | 555 |
(...skipping 54 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
604 } | 610 } |
605 | 611 |
606 void RasterWorkerPool::SetClient(RasterWorkerPoolClient* client) { | 612 void RasterWorkerPool::SetClient(RasterWorkerPoolClient* client) { |
607 client_ = client; | 613 client_ = client; |
608 } | 614 } |
609 | 615 |
610 void RasterWorkerPool::Shutdown() { | 616 void RasterWorkerPool::Shutdown() { |
611 TRACE_EVENT0("cc", "RasterWorkerPool::Shutdown"); | 617 TRACE_EVENT0("cc", "RasterWorkerPool::Shutdown"); |
612 | 618 |
613 raster_tasks_.clear(); | 619 raster_tasks_.clear(); |
614 TaskGraph empty; | 620 internal::TaskGraph empty; |
615 SetTaskGraph(&empty); | 621 SetTaskGraph(&empty); |
616 g_task_graph_runner.Pointer()->WaitForTasksToFinishRunning(namespace_token_); | 622 g_task_graph_runner.Pointer()->WaitForTasksToFinishRunning(namespace_token_); |
617 weak_ptr_factory_.InvalidateWeakPtrs(); | 623 weak_ptr_factory_.InvalidateWeakPtrs(); |
618 } | 624 } |
619 | 625 |
620 void RasterWorkerPool::SetRasterTasks(RasterTask::Queue* queue) { | 626 void RasterWorkerPool::SetRasterTasks(RasterTask::Queue* queue) { |
621 raster_tasks_.swap(queue->tasks_); | 627 raster_tasks_.swap(queue->tasks_); |
622 raster_tasks_required_for_activation_.swap( | 628 raster_tasks_required_for_activation_.swap( |
623 queue->tasks_required_for_activation_); | 629 queue->tasks_required_for_activation_); |
624 } | 630 } |
625 | 631 |
626 bool RasterWorkerPool::IsRasterTaskRequiredForActivation( | 632 bool RasterWorkerPool::IsRasterTaskRequiredForActivation( |
627 internal::RasterWorkerPoolTask* task) const { | 633 internal::RasterWorkerPoolTask* task) const { |
628 return raster_tasks_required_for_activation_.find(task) != | 634 return raster_tasks_required_for_activation_.find(task) != |
629 raster_tasks_required_for_activation_.end(); | 635 raster_tasks_required_for_activation_.end(); |
630 } | 636 } |
631 | 637 |
632 void RasterWorkerPool::SetTaskGraph(TaskGraph* graph) { | 638 void RasterWorkerPool::SetTaskGraph(internal::TaskGraph* graph) { |
633 TRACE_EVENT1( | 639 TRACE_EVENT0("cc", "RasterWorkerPool::SetTaskGraph"); |
634 "cc", "RasterWorkerPool::SetTaskGraph", "num_tasks", graph->size()); | |
635 | 640 |
636 for (internal::GraphNode::Map::iterator it = graph->begin(); | 641 for (internal::TaskGraph::Node::Vector::iterator it = graph->nodes.begin(); |
637 it != graph->end(); | 642 it != graph->nodes.end(); |
638 ++it) { | 643 ++it) { |
| 644 internal::TaskGraph::Node& node = *it; |
639 internal::WorkerPoolTask* task = | 645 internal::WorkerPoolTask* task = |
640 static_cast<internal::WorkerPoolTask*>(it->first); | 646 static_cast<internal::WorkerPoolTask*>(node.task); |
641 | 647 |
642 if (!task->HasBeenScheduled()) { | 648 if (!task->HasBeenScheduled()) { |
643 task->WillSchedule(); | 649 task->WillSchedule(); |
644 task->ScheduleOnOriginThread(this); | 650 task->ScheduleOnOriginThread(this); |
645 task->DidSchedule(); | 651 task->DidSchedule(); |
646 } | 652 } |
647 } | 653 } |
648 | 654 |
649 g_task_graph_runner.Pointer()->SetTaskGraph(namespace_token_, graph); | 655 g_task_graph_runner.Pointer()->SetTaskGraph(namespace_token_, graph); |
650 } | 656 } |
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
741 | 747 |
742 scoped_ptr<base::Value> RasterWorkerPool::ScheduledStateAsValue() const { | 748 scoped_ptr<base::Value> RasterWorkerPool::ScheduledStateAsValue() const { |
743 scoped_ptr<base::DictionaryValue> scheduled_state(new base::DictionaryValue); | 749 scoped_ptr<base::DictionaryValue> scheduled_state(new base::DictionaryValue); |
744 scheduled_state->SetInteger("task_count", raster_tasks_.size()); | 750 scheduled_state->SetInteger("task_count", raster_tasks_.size()); |
745 scheduled_state->SetInteger("task_required_for_activation_count", | 751 scheduled_state->SetInteger("task_required_for_activation_count", |
746 raster_tasks_required_for_activation_.size()); | 752 raster_tasks_required_for_activation_.size()); |
747 return scheduled_state.PassAs<base::Value>(); | 753 return scheduled_state.PassAs<base::Value>(); |
748 } | 754 } |
749 | 755 |
750 // static | 756 // static |
751 internal::GraphNode* RasterWorkerPool::CreateGraphNodeForTask( | 757 void RasterWorkerPool::InsertNodeForTask(internal::TaskGraph* graph, |
752 internal::WorkerPoolTask* task, | 758 internal::WorkerPoolTask* task, |
753 unsigned priority, | 759 unsigned priority, |
754 TaskGraph* graph) { | 760 size_t dependencies) { |
755 internal::GraphNode* node = new internal::GraphNode(task, priority); | 761 DCHECK(std::find_if(graph->nodes.begin(), |
756 DCHECK(graph->find(task) == graph->end()); | 762 graph->nodes.end(), |
757 graph->set(task, make_scoped_ptr(node)); | 763 internal::TaskGraph::Node::TaskComparator(task)) == |
758 return node; | 764 graph->nodes.end()); |
| 765 graph->nodes.push_back( |
| 766 internal::TaskGraph::Node(task, priority, dependencies)); |
759 } | 767 } |
760 | 768 |
761 // static | 769 // static |
762 internal::GraphNode* RasterWorkerPool::CreateGraphNodeForRasterTask( | 770 void RasterWorkerPool::InsertNodeForRasterTask( |
| 771 internal::TaskGraph* graph, |
763 internal::WorkerPoolTask* raster_task, | 772 internal::WorkerPoolTask* raster_task, |
764 const internal::Task::Vector& decode_tasks, | 773 const internal::Task::Vector& decode_tasks, |
765 unsigned priority, | 774 unsigned priority) { |
766 TaskGraph* graph) { | 775 size_t dependencies = 0u; |
767 internal::GraphNode* raster_node = | |
768 CreateGraphNodeForTask(raster_task, priority, graph); | |
769 | 776 |
770 // Insert image decode tasks. | 777 // Insert image decode tasks. |
771 for (internal::Task::Vector::const_iterator it = decode_tasks.begin(); | 778 for (internal::Task::Vector::const_iterator it = decode_tasks.begin(); |
772 it != decode_tasks.end(); | 779 it != decode_tasks.end(); |
773 ++it) { | 780 ++it) { |
774 internal::WorkerPoolTask* decode_task = | 781 internal::WorkerPoolTask* decode_task = |
775 static_cast<internal::WorkerPoolTask*>(it->get()); | 782 static_cast<internal::WorkerPoolTask*>(it->get()); |
776 | 783 |
777 // Skip if already decoded. | 784 // Skip if already decoded. |
778 if (decode_task->HasCompleted()) | 785 if (decode_task->HasCompleted()) |
779 continue; | 786 continue; |
780 | 787 |
781 raster_node->add_dependency(); | 788 dependencies++; |
782 | 789 |
783 // Check if decode task already exists in graph. | 790 // Add decode task if it doesn't already exists in graph. |
784 internal::GraphNode::Map::iterator decode_it = graph->find(decode_task); | 791 internal::TaskGraph::Node::Vector::iterator decode_it = |
785 if (decode_it != graph->end()) { | 792 std::find_if(graph->nodes.begin(), |
786 internal::GraphNode* decode_node = decode_it->second; | 793 graph->nodes.end(), |
787 decode_node->add_dependent(raster_node); | 794 internal::TaskGraph::Node::TaskComparator(decode_task)); |
788 continue; | 795 if (decode_it == graph->nodes.end()) |
789 } | 796 InsertNodeForTask(graph, decode_task, priority, 0u); |
790 | 797 |
791 internal::GraphNode* decode_node = | 798 graph->edges.push_back(internal::TaskGraph::Edge(decode_task, raster_task)); |
792 CreateGraphNodeForTask(decode_task, priority, graph); | |
793 decode_node->add_dependent(raster_node); | |
794 } | 799 } |
795 | 800 |
796 return raster_node; | 801 InsertNodeForTask(graph, raster_task, priority, dependencies); |
797 } | 802 } |
798 | 803 |
799 } // namespace cc | 804 } // namespace cc |
OLD | NEW |