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 |