Chromium Code Reviews| 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/image_raster_worker_pool.h" | 5 #include "cc/resources/image_raster_worker_pool.h" |
| 6 | 6 |
| 7 #include "base/debug/trace_event.h" | 7 #include "base/debug/trace_event.h" |
| 8 #include "cc/base/scoped_ptr_deque.h" | |
| 8 #include "cc/resources/resource.h" | 9 #include "cc/resources/resource.h" |
| 9 #include "third_party/skia/include/core/SkDevice.h" | 10 #include "third_party/skia/include/core/SkDevice.h" |
| 10 | 11 |
| 11 namespace cc { | 12 namespace cc { |
| 12 | 13 |
| 13 namespace { | 14 namespace { |
| 14 | 15 |
| 15 class ImageWorkerPoolTaskImpl : public internal::WorkerPoolTask { | 16 class ImageWorkerPoolTaskImpl : public internal::WorkerPoolTask { |
| 16 public: | 17 public: |
| 17 typedef base::Callback<void(bool was_canceled)> Reply; | 18 typedef base::Callback<void(bool was_canceled)> Reply; |
| 18 | 19 |
| 19 ImageWorkerPoolTaskImpl(internal::RasterWorkerPoolTask* task, | 20 ImageWorkerPoolTaskImpl(internal::RasterWorkerPoolTask* task, |
| 20 uint8_t* buffer, | 21 uint8_t* buffer, |
| 21 int stride, | 22 int stride, |
| 22 const Reply& reply) | 23 const Reply& reply) |
| 23 : task_(task), | 24 : task_(task), |
| 24 buffer_(buffer), | 25 buffer_(buffer), |
| 25 stride_(stride), | 26 stride_(stride), |
| 26 reply_(reply) { | 27 reply_(reply) { |
| 27 } | 28 } |
| 28 | 29 |
| 29 // Overridden from internal::WorkerPoolTask: | 30 // Overridden from internal::WorkerPoolTask: |
| 30 virtual void RunOnWorkerThread(unsigned thread_index) OVERRIDE { | 31 virtual void RunOnWorkerThread(unsigned thread_index) OVERRIDE { |
| 32 TRACE_EVENT0("cc", "ImageWorkerPoolTaskImpl::RunOnWorkerThread"); | |
| 31 if (!buffer_) | 33 if (!buffer_) |
| 32 return; | 34 return; |
| 33 | 35 |
| 34 SkBitmap bitmap; | 36 SkBitmap bitmap; |
| 35 bitmap.setConfig(SkBitmap::kARGB_8888_Config, | 37 bitmap.setConfig(SkBitmap::kARGB_8888_Config, |
| 36 task_->resource()->size().width(), | 38 task_->resource()->size().width(), |
| 37 task_->resource()->size().height(), | 39 task_->resource()->size().height(), |
| 38 stride_); | 40 stride_); |
| 39 bitmap.setPixels(buffer_); | 41 bitmap.setPixels(buffer_); |
| 40 SkDevice device(bitmap); | 42 SkDevice device(bitmap); |
| 41 task_->RunOnWorkerThread(&device, thread_index); | 43 task_->RunOnWorkerThread(&device, thread_index); |
| 42 } | 44 } |
| 43 virtual void CompleteOnOriginThread() OVERRIDE { | 45 virtual void CompleteOnOriginThread() OVERRIDE { |
| 44 reply_.Run(!HasFinishedRunning()); | 46 reply_.Run(!HasFinishedRunning()); |
| 45 } | 47 } |
| 46 | 48 |
| 47 private: | 49 private: |
| 48 virtual ~ImageWorkerPoolTaskImpl() {} | 50 virtual ~ImageWorkerPoolTaskImpl() {} |
| 49 | 51 |
| 50 scoped_refptr<internal::RasterWorkerPoolTask> task_; | 52 scoped_refptr<internal::RasterWorkerPoolTask> task_; |
| 51 uint8_t* buffer_; | 53 uint8_t* buffer_; |
| 52 int stride_; | 54 int stride_; |
| 53 const Reply reply_; | 55 const Reply reply_; |
| 54 | 56 |
| 55 DISALLOW_COPY_AND_ASSIGN(ImageWorkerPoolTaskImpl); | 57 DISALLOW_COPY_AND_ASSIGN(ImageWorkerPoolTaskImpl); |
| 56 }; | 58 }; |
| 57 | 59 |
| 60 class RasterFinishedWorkerPoolTaskImpl : public internal::WorkerPoolTask { | |
| 61 public: | |
| 62 RasterFinishedWorkerPoolTaskImpl( | |
| 63 base::MessageLoopProxy* origin_loop, | |
| 64 const base::Closure& on_raster_finished_callback) | |
| 65 : origin_loop_(origin_loop), | |
| 66 on_raster_finished_callback_(on_raster_finished_callback) { | |
| 67 } | |
| 68 | |
| 69 // Overridden from internal::WorkerPoolTask: | |
| 70 virtual void RunOnWorkerThread(unsigned thread_index) OVERRIDE { | |
| 71 TRACE_EVENT0("cc", "RasterFinishedWorkerPoolTaskImpl::RunOnWorkerThread"); | |
| 72 origin_loop_->PostTask(FROM_HERE, on_raster_finished_callback_); | |
| 73 } | |
| 74 virtual void CompleteOnOriginThread() OVERRIDE {} | |
| 75 | |
| 76 private: | |
| 77 virtual ~RasterFinishedWorkerPoolTaskImpl() {} | |
| 78 | |
| 79 scoped_refptr<base::MessageLoopProxy> origin_loop_; | |
| 80 const base::Closure on_raster_finished_callback_; | |
| 81 | |
| 82 DISALLOW_COPY_AND_ASSIGN(RasterFinishedWorkerPoolTaskImpl); | |
| 83 }; | |
| 84 | |
| 58 } // namespace | 85 } // namespace |
| 59 | 86 |
| 60 ImageRasterWorkerPool::ImageRasterWorkerPool( | 87 ImageRasterWorkerPool::ImageRasterWorkerPool( |
| 61 ResourceProvider* resource_provider, size_t num_threads) | 88 ResourceProvider* resource_provider, size_t num_threads) |
| 62 : RasterWorkerPool(resource_provider, num_threads) { | 89 : RasterWorkerPool(resource_provider, num_threads), |
| 90 weak_ptr_factory_(this), | |
| 91 schedule_raster_tasks_count_(0) { | |
| 63 } | 92 } |
| 64 | 93 |
| 65 ImageRasterWorkerPool::~ImageRasterWorkerPool() { | 94 ImageRasterWorkerPool::~ImageRasterWorkerPool() { |
| 66 DCHECK_EQ(0u, image_tasks_.size()); | 95 DCHECK_EQ(0u, image_tasks_.size()); |
| 67 } | 96 } |
| 68 | 97 |
| 98 void ImageRasterWorkerPool::Shutdown() { | |
| 99 weak_ptr_factory_.InvalidateWeakPtrs(); | |
| 100 RasterWorkerPool::Shutdown(); | |
| 101 } | |
| 102 | |
| 69 void ImageRasterWorkerPool::ScheduleTasks(RasterTask::Queue* queue) { | 103 void ImageRasterWorkerPool::ScheduleTasks(RasterTask::Queue* queue) { |
| 70 TRACE_EVENT0("cc", "ImageRasterWorkerPool::ScheduleTasks"); | 104 TRACE_EVENT0("cc", "ImageRasterWorkerPool::ScheduleTasks"); |
| 71 | 105 |
| 72 RasterWorkerPool::SetRasterTasks(queue); | 106 RasterWorkerPool::SetRasterTasks(queue); |
| 73 | 107 |
| 74 RasterTaskGraph graph; | 108 ++schedule_raster_tasks_count_; |
| 109 | |
| 110 enum RasterTaskType { | |
| 111 PREPAINT_TYPE = 0, | |
| 112 REQUIRED_FOR_ACTIVATION_TYPE = 1, | |
| 113 NUM_TYPES = 2 | |
| 114 }; | |
| 115 ScopedPtrDeque<GraphNode> tasks[NUM_TYPES]; | |
| 116 unsigned priority = 2u; // 0-1 reserved for RasterFinished tasks. | |
| 117 TaskGraph graph; | |
| 118 | |
| 75 for (RasterTaskVector::const_iterator it = raster_tasks().begin(); | 119 for (RasterTaskVector::const_iterator it = raster_tasks().begin(); |
| 76 it != raster_tasks().end(); ++it) { | 120 it != raster_tasks().end(); ++it) { |
| 77 internal::RasterWorkerPoolTask* task = it->get(); | 121 internal::RasterWorkerPoolTask* task = it->get(); |
| 78 | 122 |
| 123 RasterTaskType type = IsRasterTaskRequiredForActivation(task) ? | |
| 124 REQUIRED_FOR_ACTIVATION_TYPE : | |
| 125 PREPAINT_TYPE; | |
| 126 | |
| 79 TaskMap::iterator image_it = image_tasks_.find(task); | 127 TaskMap::iterator image_it = image_tasks_.find(task); |
| 80 if (image_it != image_tasks_.end()) { | 128 if (image_it != image_tasks_.end()) { |
| 81 internal::WorkerPoolTask* image_task = image_it->second.get(); | 129 internal::WorkerPoolTask* image_task = image_it->second.get(); |
| 82 graph.InsertRasterTask(image_task, task->dependencies()); | 130 tasks[type].push_back( |
| 131 CreateRasterTaskGraphNode(image_task, | |
| 132 task->dependencies(), | |
| 133 priority++, | |
| 134 &graph)); | |
| 83 continue; | 135 continue; |
| 84 } | 136 } |
| 85 | 137 |
| 86 // Acquire image for resource. | 138 // Acquire image for resource. |
| 87 resource_provider()->AcquireImage(task->resource()->id()); | 139 resource_provider()->AcquireImage(task->resource()->id()); |
| 88 | 140 |
| 89 // Map image for raster. | 141 // Map image for raster. |
| 90 uint8* buffer = resource_provider()->MapImage(task->resource()->id()); | 142 uint8* buffer = resource_provider()->MapImage(task->resource()->id()); |
| 91 int stride = resource_provider()->GetImageStride(task->resource()->id()); | 143 int stride = resource_provider()->GetImageStride(task->resource()->id()); |
| 92 | 144 |
| 93 scoped_refptr<internal::WorkerPoolTask> new_image_task( | 145 scoped_refptr<internal::WorkerPoolTask> new_image_task( |
| 94 new ImageWorkerPoolTaskImpl( | 146 new ImageWorkerPoolTaskImpl( |
| 95 task, | 147 task, |
| 96 buffer, | 148 buffer, |
| 97 stride, | 149 stride, |
| 98 base::Bind(&ImageRasterWorkerPool::OnRasterTaskCompleted, | 150 base::Bind(&ImageRasterWorkerPool::OnRasterTaskCompleted, |
| 99 base::Unretained(this), | 151 base::Unretained(this), |
| 100 make_scoped_refptr(task)))); | 152 make_scoped_refptr(task)))); |
| 101 image_tasks_[task] = new_image_task; | 153 image_tasks_[task] = new_image_task; |
| 102 graph.InsertRasterTask(new_image_task.get(), task->dependencies()); | 154 tasks[type].push_back(CreateRasterTaskGraphNode(new_image_task.get(), |
| 155 task->dependencies(), | |
| 156 priority++, | |
| 157 &graph)); | |
| 103 } | 158 } |
| 104 | 159 |
| 105 SetRasterTaskGraph(&graph); | 160 scoped_refptr<internal::WorkerPoolTask> new_raster_finished_task( |
|
vmpstr
2013/06/27 23:31:21
Can you either add some comments in the code from
| |
| 161 new RasterFinishedWorkerPoolTaskImpl( | |
| 162 base::MessageLoopProxy::current(), | |
| 163 base::Bind(&ImageRasterWorkerPool::OnRasterFinished, | |
| 164 weak_ptr_factory_.GetWeakPtr(), | |
| 165 schedule_raster_tasks_count_))); | |
| 166 scoped_ptr<GraphNode> raster_finished_node( | |
| 167 new GraphNode(new_raster_finished_task.get(), | |
| 168 1u)); // Priority 1 | |
| 169 for (unsigned i = 0; i < NUM_TYPES; ++i) { | |
|
vmpstr
2013/06/27 23:31:21
nit: type (to be consistent with the loop above)
reveman
2013/06/28 17:26:07
Done.
| |
| 170 for (unsigned j = 0; j < tasks[i].size(); ++j) { | |
|
vmpstr
2013/06/27 23:31:21
This can be a small anonymous namespace function l
reveman
2013/06/28 17:26:07
Latest patch reduces code duplication significantl
| |
| 171 raster_finished_node->add_dependency(); | |
| 172 tasks[i][j]->add_dependent(raster_finished_node.get()); | |
| 173 } | |
| 174 } | |
| 175 graph.set(new_raster_finished_task.get(), raster_finished_node.Pass()); | |
| 176 | |
| 177 scoped_refptr<internal::WorkerPoolTask> | |
| 178 new_raster_required_for_activation_finished_task( | |
| 179 new RasterFinishedWorkerPoolTaskImpl( | |
| 180 base::MessageLoopProxy::current(), | |
| 181 base::Bind(&ImageRasterWorkerPool:: | |
| 182 OnRasterRequiredForActivationFinished, | |
| 183 weak_ptr_factory_.GetWeakPtr(), | |
| 184 schedule_raster_tasks_count_))); | |
| 185 scoped_ptr<GraphNode> raster_required_for_activation_finished_node( | |
| 186 new GraphNode(new_raster_required_for_activation_finished_task.get(), | |
| 187 0u)); // Priority 0 | |
| 188 for (unsigned j = 0; | |
| 189 j < tasks[REQUIRED_FOR_ACTIVATION_TYPE].size(); | |
| 190 ++j) { | |
| 191 raster_required_for_activation_finished_node->add_dependency(); | |
| 192 tasks[REQUIRED_FOR_ACTIVATION_TYPE][j]->add_dependent( | |
| 193 raster_required_for_activation_finished_node.get()); | |
| 194 } | |
| 195 graph.set(new_raster_required_for_activation_finished_task.get(), | |
| 196 raster_required_for_activation_finished_node.Pass()); | |
| 197 | |
| 198 for (unsigned i = 0; i < NUM_TYPES; ++i) { | |
|
vmpstr
2013/06/27 23:31:21
I wonder if it's better to have tasks[i][j] as a r
reveman
2013/06/28 17:26:07
Done.
| |
| 199 while (!tasks[i].empty()) { | |
| 200 scoped_ptr<GraphNode> node = tasks[i].take_front(); | |
| 201 internal::WorkerPoolTask* task = node->task(); | |
| 202 graph.set(task, node.Pass()); | |
| 203 } | |
| 204 } | |
| 205 | |
| 206 SetTaskGraph(&graph); | |
| 207 | |
| 208 raster_finished_task_.swap(new_raster_finished_task); | |
| 209 raster_required_for_activation_finished_task_.swap( | |
| 210 new_raster_required_for_activation_finished_task); | |
| 211 } | |
| 212 | |
| 213 void ImageRasterWorkerPool::OnRasterFinished( | |
| 214 int64 schedule_raster_tasks_count) { | |
| 215 TRACE_EVENT1("cc", "ImageRasterWorkerPool::OnRasterFinished", | |
| 216 "schedule_raster_tasks_count", schedule_raster_tasks_count); | |
| 217 DCHECK_GE(schedule_raster_tasks_count_, schedule_raster_tasks_count); | |
| 218 // Call DidFinishedRunningTasks() if this callback is | |
|
vmpstr
2013/06/27 23:31:21
nit: blank line above this, please
reveman
2013/06/28 17:26:07
code doesn't exist in latest patch.
| |
| 219 // associated with the last call to SetRasterTaskGraph(). | |
| 220 if (schedule_raster_tasks_count_ == schedule_raster_tasks_count) | |
| 221 client()->DidFinishedRunningTasks(); | |
| 222 } | |
| 223 | |
| 224 void ImageRasterWorkerPool::OnRasterRequiredForActivationFinished( | |
| 225 int64 schedule_raster_tasks_count) { | |
| 226 TRACE_EVENT1("cc", | |
| 227 "ImageRasterWorkerPool::OnRasterRequiredForActivationFinished", | |
| 228 "schedule_raster_tasks_count", schedule_raster_tasks_count); | |
| 229 DCHECK_GE(schedule_raster_tasks_count_, schedule_raster_tasks_count); | |
| 230 // Call DidFinishedRunningTasksRequiredForActivation() if this callback is | |
|
vmpstr
2013/06/27 23:31:21
nit: blank line above this, please
reveman
2013/06/28 17:26:07
code doesn't exist in latest patch.
| |
| 231 // associated with the last call to SetRasterTaskGraph(). | |
| 232 if (schedule_raster_tasks_count_ == schedule_raster_tasks_count) | |
| 233 client()->DidFinishedRunningTasksRequiredForActivation(); | |
| 106 } | 234 } |
| 107 | 235 |
| 108 void ImageRasterWorkerPool::OnRasterTaskCompleted( | 236 void ImageRasterWorkerPool::OnRasterTaskCompleted( |
| 109 scoped_refptr<internal::RasterWorkerPoolTask> task, | 237 scoped_refptr<internal::RasterWorkerPoolTask> task, |
| 110 bool was_canceled) { | 238 bool was_canceled) { |
| 111 TRACE_EVENT1("cc", "ImageRasterWorkerPool::OnRasterTaskCompleted", | 239 TRACE_EVENT1("cc", "ImageRasterWorkerPool::OnRasterTaskCompleted", |
| 112 "was_canceled", was_canceled); | 240 "was_canceled", was_canceled); |
| 113 | 241 |
| 114 DCHECK(image_tasks_.find(task.get()) != image_tasks_.end()); | 242 DCHECK(image_tasks_.find(task.get()) != image_tasks_.end()); |
| 115 | 243 |
| 116 // Balanced with MapImage() call in ScheduleTasks(). | 244 // Balanced with MapImage() call in ScheduleTasks(). |
| 117 resource_provider()->UnmapImage(task->resource()->id()); | 245 resource_provider()->UnmapImage(task->resource()->id()); |
| 118 | 246 |
| 119 // Bind image to resource. | 247 // Bind image to resource. |
| 120 resource_provider()->BindImage(task->resource()->id()); | 248 resource_provider()->BindImage(task->resource()->id()); |
| 121 | 249 |
| 122 task->DidRun(was_canceled); | 250 task->DidRun(was_canceled); |
| 123 task->WillComplete(); | 251 task->WillComplete(); |
| 124 task->CompleteOnOriginThread(); | 252 task->CompleteOnOriginThread(); |
| 125 task->DidComplete(); | 253 task->DidComplete(); |
| 126 | 254 |
| 127 image_tasks_.erase(task.get()); | 255 image_tasks_.erase(task.get()); |
| 128 } | 256 } |
| 129 | 257 |
| 130 } // namespace cc | 258 } // namespace cc |
| OLD | NEW |