1 // Copyright 2014 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "cc/resources/bitmap_raster_worker_pool.h" 6 7 #include <algorithm> 8 9 #include "base/debug/trace_event.h" 10 #include "base/debug/trace_event_argument.h" 11 #include "base/strings/stringprintf.h" 12 #include "cc/debug/traced_value.h" 13 #include "cc/resources/raster_buffer.h" 14 #include "cc/resources/resource.h" 15 16 namespace cc { 17 namespace { 18 19 class RasterBufferImpl : public RasterBuffer { 20 public: 21 RasterBufferImpl(ResourceProvider* resource_provider, 22 const Resource* resource) 23 : lock_(resource_provider, resource->id()) {} 24 25 // Overridden from RasterBuffer: 26 virtual skia::RefPtr<SkCanvas> AcquireSkCanvas() OVERRIDE { 27 return skia::SharePtr(lock_.sk_canvas()); 28 } 29 virtual void ReleaseSkCanvas(const skia::RefPtr<SkCanvas>& canvas) OVERRIDE {} 30 31 private: 32 ResourceProvider::ScopedWriteLockSoftware lock_; 33 34 DISALLOW_COPY_AND_ASSIGN(RasterBufferImpl); 35 }; 36 37 } // namespace 38 39 // static 40 scoped_ptr<RasterWorkerPool> BitmapRasterWorkerPool::Create( 41 base::SequencedTaskRunner* task_runner, 42 TaskGraphRunner* task_graph_runner, 43 ResourceProvider* resource_provider) { 44 return make_scoped_ptr<RasterWorkerPool>(new BitmapRasterWorkerPool( 45 task_runner, task_graph_runner, resource_provider)); 46 } 47 48 BitmapRasterWorkerPool::BitmapRasterWorkerPool( 49 base::SequencedTaskRunner* task_runner, 50 TaskGraphRunner* task_graph_runner, 51 ResourceProvider* resource_provider) 52 : task_runner_(task_runner), 53 task_graph_runner_(task_graph_runner), 54 namespace_token_(task_graph_runner->GetNamespaceToken()), 55 resource_provider_(resource_provider), 56 raster_finished_weak_ptr_factory_(this) { 57 } 58 59 BitmapRasterWorkerPool::~BitmapRasterWorkerPool() { 60 } 61 62 Rasterizer* BitmapRasterWorkerPool::AsRasterizer() { 63 return this; 64 } 65 66 void BitmapRasterWorkerPool::SetClient(RasterizerClient* client) { 67 client_ = client; 68 } 69 70 void BitmapRasterWorkerPool::Shutdown() { 71 TRACE_EVENT0("cc", "BitmapRasterWorkerPool::Shutdown"); 72 73 TaskGraph empty; 74 task_graph_runner_->ScheduleTasks(namespace_token_, &empty); 75 task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_); 76 } 77 78 void BitmapRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) { 79 TRACE_EVENT0("cc", "BitmapRasterWorkerPool::ScheduleTasks"); 80 81 if (raster_pending_.none()) 82 TRACE_EVENT_ASYNC_BEGIN0("cc", "ScheduledTasks", this); 83 84 // Mark all task sets as pending. 85 raster_pending_.set(); 86 87 unsigned priority = kRasterTaskPriorityBase; 88 89 graph_.Reset(); 90 91 // Cancel existing OnRasterFinished callbacks. 92 raster_finished_weak_ptr_factory_.InvalidateWeakPtrs(); 93 94 scoped_refptr<RasterizerTask> new_raster_finished_tasks[kNumberOfTaskSets]; 95 96 size_t task_count[kNumberOfTaskSets] = {0}; 97 98 for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) { 99 new_raster_finished_tasks[task_set] = CreateRasterFinishedTask( 100 task_runner_.get(), 101 base::Bind(&BitmapRasterWorkerPool::OnRasterFinished, 102 raster_finished_weak_ptr_factory_.GetWeakPtr(), 103 task_set)); 104 } 105 106 for (RasterTaskQueue::Item::Vector::const_iterator it = queue->items.begin(); 107 it != queue->items.end(); 108 ++it) { 109 const RasterTaskQueue::Item& item = *it; 110 RasterTask* task = item.task; 111 DCHECK(!task->HasCompleted()); 112 113 for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) { 114 if (!item.task_sets[task_set]) 115 continue; 116 117 ++task_count[task_set]; 118 119 graph_.edges.push_back( 120 TaskGraph::Edge(task, new_raster_finished_tasks[task_set].get())); 121 } 122 123 InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++); 124 } 125 126 for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) { 127 InsertNodeForTask(&graph_, 128 new_raster_finished_tasks[task_set].get(), 129 kRasterFinishedTaskPriority, 130 task_count[task_set]); 131 } 132 133 ScheduleTasksOnOriginThread(this, &graph_); 134 task_graph_runner_->ScheduleTasks(namespace_token_, &graph_); 135 136 std::copy(new_raster_finished_tasks, 137 new_raster_finished_tasks + kNumberOfTaskSets, 138 raster_finished_tasks_); 139 140 TRACE_EVENT_ASYNC_STEP_INTO1( 141 "cc", "ScheduledTasks", this, "rasterizing", "state", StateAsValue()); 142 } 143 144 void BitmapRasterWorkerPool::CheckForCompletedTasks() { 145 TRACE_EVENT0("cc", "BitmapRasterWorkerPool::CheckForCompletedTasks"); 146 147 task_graph_runner_->CollectCompletedTasks(namespace_token_, 148 &completed_tasks_); 149 for (Task::Vector::const_iterator it = completed_tasks_.begin(); 150 it != completed_tasks_.end(); 151 ++it) { 152 RasterizerTask* task = static_cast<RasterizerTask*>(it->get()); 153 154 task->WillComplete(); 155 task->CompleteOnOriginThread(this); 156 task->DidComplete(); 157 158 task->RunReplyOnOriginThread(); 159 } 160 completed_tasks_.clear(); 161 } 162 163 scoped_ptr<RasterBuffer> BitmapRasterWorkerPool::AcquireBufferForRaster( 164 const Resource* resource) { 165 return make_scoped_ptr<RasterBuffer>( 166 new RasterBufferImpl(resource_provider_, resource)); 167 } 168 169 void BitmapRasterWorkerPool::ReleaseBufferForRaster( 170 scoped_ptr<RasterBuffer> buffer) { 171 // Nothing to do here. RasterBufferImpl destructor cleans up after itself. 172 } 173 174 void BitmapRasterWorkerPool::OnRasterFinished(TaskSet task_set) { 175 TRACE_EVENT1( 176 "cc", "BitmapRasterWorkerPool::OnRasterFinished", "task_set", task_set); 177 178 DCHECK(raster_pending_[task_set]); 179 raster_pending_[task_set] = false; 180 if (raster_pending_.any()) { 181 TRACE_EVENT_ASYNC_STEP_INTO1( 182 "cc", "ScheduledTasks", this, "rasterizing", "state", StateAsValue()); 183 } else { 184 TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this); 185 } 186 client_->DidFinishRunningTasks(task_set); 187 } 188 189 scoped_refptr<base::debug::ConvertableToTraceFormat> 190 BitmapRasterWorkerPool::StateAsValue() const { 191 scoped_refptr<base::debug::TracedValue> state = 192 new base::debug::TracedValue(); 193 194 state->BeginArray("tasks_pending"); 195 for (TaskSet task_set = 0; task_set < kNumberOfTaskSets; ++task_set) 196 state->AppendBoolean(raster_pending_[task_set]); 197 state->EndArray(); 198 return state; 199 } 200 201 } // namespace cc 202