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 3 // found in the LICENSE file. 4 5 #include "cc/resources/image_raster_worker_pool.h" 6 7 #include "base/debug/trace_event.h" 8 #include "cc/debug/traced_value.h" 9 #include "cc/resources/resource.h" 10 11 namespace cc { 12 13 // static 14 scoped_ptr<RasterWorkerPool> ImageRasterWorkerPool::Create( 15 base::SequencedTaskRunner* task_runner, 16 TaskGraphRunner* task_graph_runner, 17 ResourceProvider* resource_provider) { 18 return make_scoped_ptr<RasterWorkerPool>(new ImageRasterWorkerPool( 19 task_runner, task_graph_runner, resource_provider)); 20 } 21 22 ImageRasterWorkerPool::ImageRasterWorkerPool( 23 base::SequencedTaskRunner* task_runner, 24 TaskGraphRunner* task_graph_runner, 25 ResourceProvider* resource_provider) 26 : task_runner_(task_runner), 27 task_graph_runner_(task_graph_runner), 28 namespace_token_(task_graph_runner->GetNamespaceToken()), 29 resource_provider_(resource_provider), 30 raster_tasks_pending_(false), 31 raster_tasks_required_for_activation_pending_(false), 32 raster_finished_weak_ptr_factory_(this) {} 33 34 ImageRasterWorkerPool::~ImageRasterWorkerPool() {} 35 36 Rasterizer* ImageRasterWorkerPool::AsRasterizer() { return this; } 37 38 void ImageRasterWorkerPool::SetClient(RasterizerClient* client) { 39 client_ = client; 40 } 41 42 void ImageRasterWorkerPool::Shutdown() { 43 TRACE_EVENT0("cc", "ImageRasterWorkerPool::Shutdown"); 44 45 TaskGraph empty; 46 task_graph_runner_->ScheduleTasks(namespace_token_, &empty); 47 task_graph_runner_->WaitForTasksToFinishRunning(namespace_token_); 48 } 49 50 void ImageRasterWorkerPool::ScheduleTasks(RasterTaskQueue* queue) { 51 TRACE_EVENT0("cc", "ImageRasterWorkerPool::ScheduleTasks"); 52 53 DCHECK_EQ(queue->required_for_activation_count, 54 static_cast<size_t>( 55 std::count_if(queue->items.begin(), 56 queue->items.end(), 57 RasterTaskQueue::Item::IsRequiredForActivation))); 58 59 if (!raster_tasks_pending_) 60 TRACE_EVENT_ASYNC_BEGIN0("cc", "ScheduledTasks", this); 61 62 raster_tasks_pending_ = true; 63 raster_tasks_required_for_activation_pending_ = true; 64 65 unsigned priority = kRasterTaskPriorityBase; 66 67 graph_.Reset(); 68 69 // Cancel existing OnRasterFinished callbacks. 70 raster_finished_weak_ptr_factory_.InvalidateWeakPtrs(); 71 72 scoped_refptr<RasterizerTask> 73 new_raster_required_for_activation_finished_task( 74 CreateRasterRequiredForActivationFinishedTask( 75 queue->required_for_activation_count, 76 task_runner_.get(), 77 base::Bind( 78 &ImageRasterWorkerPool::OnRasterRequiredForActivationFinished, 79 raster_finished_weak_ptr_factory_.GetWeakPtr()))); 80 scoped_refptr<RasterizerTask> new_raster_finished_task( 81 CreateRasterFinishedTask( 82 task_runner_.get(), 83 base::Bind(&ImageRasterWorkerPool::OnRasterFinished, 84 raster_finished_weak_ptr_factory_.GetWeakPtr()))); 85 86 for (RasterTaskQueue::Item::Vector::const_iterator it = queue->items.begin(); 87 it != queue->items.end(); 88 ++it) { 89 const RasterTaskQueue::Item& item = *it; 90 RasterTask* task = item.task; 91 DCHECK(!task->HasCompleted()); 92 93 if (item.required_for_activation) { 94 graph_.edges.push_back(TaskGraph::Edge( 95 task, new_raster_required_for_activation_finished_task.get())); 96 } 97 98 InsertNodesForRasterTask(&graph_, task, task->dependencies(), priority++); 99 100 graph_.edges.push_back( 101 TaskGraph::Edge(task, new_raster_finished_task.get())); 102 } 103 104 InsertNodeForTask(&graph_, 105 new_raster_required_for_activation_finished_task.get(), 106 kRasterRequiredForActivationFinishedTaskPriority, 107 queue->required_for_activation_count); 108 InsertNodeForTask(&graph_, 109 new_raster_finished_task.get(), 110 kRasterFinishedTaskPriority, 111 queue->items.size()); 112 113 ScheduleTasksOnOriginThread(this, &graph_); 114 task_graph_runner_->ScheduleTasks(namespace_token_, &graph_); 115 116 raster_finished_task_ = new_raster_finished_task; 117 raster_required_for_activation_finished_task_ = 118 new_raster_required_for_activation_finished_task; 119 120 TRACE_EVENT_ASYNC_STEP_INTO1( 121 "cc", 122 "ScheduledTasks", 123 this, 124 "rasterizing", 125 "state", 126 TracedValue::FromValue(StateAsValue().release())); 127 } 128 129 void ImageRasterWorkerPool::CheckForCompletedTasks() { 130 TRACE_EVENT0("cc", "ImageRasterWorkerPool::CheckForCompletedTasks"); 131 132 task_graph_runner_->CollectCompletedTasks(namespace_token_, 133 &completed_tasks_); 134 for (Task::Vector::const_iterator it = completed_tasks_.begin(); 135 it != completed_tasks_.end(); 136 ++it) { 137 RasterizerTask* task = static_cast<RasterizerTask*>(it->get()); 138 139 task->WillComplete(); 140 task->CompleteOnOriginThread(this); 141 task->DidComplete(); 142 143 task->RunReplyOnOriginThread(); 144 } 145 completed_tasks_.clear(); 146 } 147 148 SkCanvas* ImageRasterWorkerPool::AcquireCanvasForRaster(RasterTask* task) { 149 return resource_provider_->MapImageRasterBuffer(task->resource()->id()); 150 } 151 152 void ImageRasterWorkerPool::ReleaseCanvasForRaster(RasterTask* task) { 153 resource_provider_->UnmapImageRasterBuffer(task->resource()->id()); 154 155 // Map/UnmapImageRasterBuffer provides direct access to the memory used by the 156 // GPU. Read lock fences are required to ensure that we're not trying to map a 157 // resource that is currently in-use by the GPU. 158 resource_provider_->EnableReadLockFences(task->resource()->id(), true); 159 } 160 161 void ImageRasterWorkerPool::OnRasterFinished() { 162 TRACE_EVENT0("cc", "ImageRasterWorkerPool::OnRasterFinished"); 163 164 DCHECK(raster_tasks_pending_); 165 raster_tasks_pending_ = false; 166 TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this); 167 client_->DidFinishRunningTasks(); 168 } 169 170 void ImageRasterWorkerPool::OnRasterRequiredForActivationFinished() { 171 TRACE_EVENT0("cc", 172 "ImageRasterWorkerPool::OnRasterRequiredForActivationFinished"); 173 174 DCHECK(raster_tasks_required_for_activation_pending_); 175 raster_tasks_required_for_activation_pending_ = false; 176 TRACE_EVENT_ASYNC_STEP_INTO1( 177 "cc", 178 "ScheduledTasks", 179 this, 180 "rasterizing", 181 "state", 182 TracedValue::FromValue(StateAsValue().release())); 183 client_->DidFinishRunningTasksRequiredForActivation(); 184 } 185 186 scoped_ptr<base::Value> ImageRasterWorkerPool::StateAsValue() const { 187 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue); 188 189 state->SetBoolean("tasks_required_for_activation_pending", 190 raster_tasks_required_for_activation_pending_); 191 return state.PassAs<base::Value>(); 192 } 193 194 } // namespace cc 195