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/pixel_buffer_raster_worker_pool.h" | 5 #include "cc/resources/pixel_buffer_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 PixelBufferWorkerPoolTaskImpl : public internal::WorkerPoolTask { | 16 class PixelBufferWorkerPoolTaskImpl : public internal::WorkerPoolTask { |
16 public: | 17 public: |
17 typedef base::Callback<void(bool was_canceled, bool needs_upload)> Reply; | 18 typedef base::Callback<void(bool was_canceled, bool needs_upload)> Reply; |
(...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
52 virtual ~PixelBufferWorkerPoolTaskImpl() {} | 53 virtual ~PixelBufferWorkerPoolTaskImpl() {} |
53 | 54 |
54 scoped_refptr<internal::RasterWorkerPoolTask> task_; | 55 scoped_refptr<internal::RasterWorkerPoolTask> task_; |
55 uint8_t* buffer_; | 56 uint8_t* buffer_; |
56 const Reply reply_; | 57 const Reply reply_; |
57 bool needs_upload_; | 58 bool needs_upload_; |
58 | 59 |
59 DISALLOW_COPY_AND_ASSIGN(PixelBufferWorkerPoolTaskImpl); | 60 DISALLOW_COPY_AND_ASSIGN(PixelBufferWorkerPoolTaskImpl); |
60 }; | 61 }; |
61 | 62 |
63 class RasterFinishedWorkerPoolTaskImpl : public internal::WorkerPoolTask { | |
64 public: | |
65 RasterFinishedWorkerPoolTaskImpl( | |
66 base::MessageLoopProxy* origin_loop, | |
67 const base::Closure& on_raster_finished_callback) | |
68 : origin_loop_(origin_loop), | |
69 on_raster_finished_callback_(on_raster_finished_callback) { | |
70 } | |
71 | |
72 // Overridden from internal::WorkerPoolTask: | |
73 virtual void RunOnWorkerThread(unsigned thread_index) OVERRIDE { | |
74 TRACE_EVENT0("cc", "RasterFinishedWorkerPoolTaskImpl::RunOnWorkerThread"); | |
75 origin_loop_->PostTask(FROM_HERE, on_raster_finished_callback_); | |
76 } | |
77 virtual void CompleteOnOriginThread() OVERRIDE {} | |
78 | |
79 private: | |
80 virtual ~RasterFinishedWorkerPoolTaskImpl() {} | |
81 | |
82 scoped_refptr<base::MessageLoopProxy> origin_loop_; | |
83 const base::Closure on_raster_finished_callback_; | |
84 | |
85 DISALLOW_COPY_AND_ASSIGN(RasterFinishedWorkerPoolTaskImpl); | |
86 }; | |
87 | |
62 // If we raster too fast we become upload bound, and pending | 88 // If we raster too fast we become upload bound, and pending |
63 // uploads consume memory. For maximum upload throughput, we would | 89 // uploads consume memory. For maximum upload throughput, we would |
64 // want to allow for upload_throughput * pipeline_time of pending | 90 // want to allow for upload_throughput * pipeline_time of pending |
65 // uploads, after which we are just wasting memory. Since we don't | 91 // uploads, after which we are just wasting memory. Since we don't |
66 // know our upload throughput yet, this just caps our memory usage. | 92 // know our upload throughput yet, this just caps our memory usage. |
67 #if defined(OS_ANDROID) | 93 #if defined(OS_ANDROID) |
68 // For reference Nexus10 can upload 1MB in about 2.5ms. | 94 // For reference Nexus10 can upload 1MB in about 2.5ms. |
69 const size_t kMaxBytesUploadedPerMs = (2 * 1024 * 1024) / 5; | 95 const size_t kMaxBytesUploadedPerMs = (2 * 1024 * 1024) / 5; |
70 #else | 96 #else |
71 // For reference Chromebook Pixel can upload 1MB in about 0.5ms. | 97 // For reference Chromebook Pixel can upload 1MB in about 0.5ms. |
72 const size_t kMaxBytesUploadedPerMs = 1024 * 1024 * 2; | 98 const size_t kMaxBytesUploadedPerMs = 1024 * 1024 * 2; |
73 #endif | 99 #endif |
74 | 100 |
75 // Assuming a two frame deep pipeline. | 101 // Assuming a two frame deep pipeline. |
76 const size_t kMaxPendingUploadBytes = 16 * 2 * kMaxBytesUploadedPerMs; | 102 const size_t kMaxPendingUploadBytes = 16 * 2 * kMaxBytesUploadedPerMs; |
77 | 103 |
78 const int kCheckForCompletedRasterTasksDelayMs = 6; | 104 const int kCheckForCompletedRasterTasksDelayMs = 6; |
79 | 105 |
80 const size_t kMaxPendingRasterBytes = | 106 const size_t kMaxPendingRasterBytes = |
81 kMaxBytesUploadedPerMs * kCheckForCompletedRasterTasksDelayMs; | 107 kMaxBytesUploadedPerMs * kCheckForCompletedRasterTasksDelayMs; |
82 | 108 |
83 } // namespace | 109 } // namespace |
84 | 110 |
85 PixelBufferRasterWorkerPool::PixelBufferRasterWorkerPool( | 111 PixelBufferRasterWorkerPool::PixelBufferRasterWorkerPool( |
86 ResourceProvider* resource_provider, | 112 ResourceProvider* resource_provider, |
87 size_t num_threads) : RasterWorkerPool(resource_provider, num_threads), | 113 size_t num_threads) |
88 shutdown_(false), | 114 : RasterWorkerPool(resource_provider, num_threads), |
89 bytes_pending_upload_(0), | 115 shutdown_(false), |
90 has_performed_uploads_since_last_flush_(false), | 116 bytes_pending_upload_(0), |
91 check_for_completed_raster_tasks_pending_(false) { | 117 has_performed_uploads_since_last_flush_(false), |
118 check_for_completed_raster_tasks_pending_(false), | |
119 weak_ptr_factory_(this), | |
120 schedule_raster_tasks_count_(0), | |
121 finished_running_tasks_pending_(false), | |
122 finished_running_tasks_required_for_activation_pending_(false) { | |
92 } | 123 } |
93 | 124 |
94 PixelBufferRasterWorkerPool::~PixelBufferRasterWorkerPool() { | 125 PixelBufferRasterWorkerPool::~PixelBufferRasterWorkerPool() { |
95 DCHECK(shutdown_); | 126 DCHECK(shutdown_); |
96 DCHECK(!check_for_completed_raster_tasks_pending_); | 127 DCHECK(!check_for_completed_raster_tasks_pending_); |
97 DCHECK_EQ(0u, pixel_buffer_tasks_.size()); | 128 DCHECK_EQ(0u, pixel_buffer_tasks_.size()); |
98 DCHECK_EQ(0u, tasks_with_pending_upload_.size()); | 129 DCHECK_EQ(0u, tasks_with_pending_upload_.size()); |
99 DCHECK_EQ(0u, completed_tasks_.size()); | 130 DCHECK_EQ(0u, completed_tasks_.size()); |
100 } | 131 } |
101 | 132 |
102 void PixelBufferRasterWorkerPool::Shutdown() { | 133 void PixelBufferRasterWorkerPool::Shutdown() { |
103 shutdown_ = true; | 134 shutdown_ = true; |
135 weak_ptr_factory_.InvalidateWeakPtrs(); | |
104 RasterWorkerPool::Shutdown(); | 136 RasterWorkerPool::Shutdown(); |
105 CheckForCompletedRasterTasks(); | 137 RasterWorkerPool::CheckForCompletedTasks(); |
138 CheckForCompletedUploads(); | |
139 check_for_completed_raster_tasks_callback_.Cancel(); | |
140 check_for_completed_raster_tasks_pending_ = false; | |
106 for (TaskMap::iterator it = pixel_buffer_tasks_.begin(); | 141 for (TaskMap::iterator it = pixel_buffer_tasks_.begin(); |
107 it != pixel_buffer_tasks_.end(); ++it) { | 142 it != pixel_buffer_tasks_.end(); ++it) { |
108 internal::RasterWorkerPoolTask* task = it->first; | 143 internal::RasterWorkerPoolTask* task = it->first; |
109 internal::WorkerPoolTask* pixel_buffer_task = it->second.get(); | 144 internal::WorkerPoolTask* pixel_buffer_task = it->second.get(); |
110 | 145 |
111 // All inactive tasks needs to be canceled. | 146 // All inactive tasks needs to be canceled. |
112 if (!pixel_buffer_task && !task->HasFinishedRunning()) { | 147 if (!pixel_buffer_task && !task->HasFinishedRunning()) { |
113 task->DidRun(true); | 148 task->DidRun(true); |
114 completed_tasks_.push_back(task); | 149 completed_tasks_.push_back(task); |
115 } | 150 } |
116 } | 151 } |
152 DCHECK_EQ(completed_tasks_.size(), pixel_buffer_tasks_.size()); | |
117 } | 153 } |
118 | 154 |
119 void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTask::Queue* queue) { | 155 void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTask::Queue* queue) { |
120 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleTasks"); | 156 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleTasks"); |
121 | 157 |
122 RasterWorkerPool::SetRasterTasks(queue); | 158 RasterWorkerPool::SetRasterTasks(queue); |
123 | 159 |
160 finished_running_tasks_pending_ = true; | |
161 finished_running_tasks_required_for_activation_pending_ = true; | |
162 | |
124 // Build new pixel buffer task set. | 163 // Build new pixel buffer task set. |
125 TaskMap new_pixel_buffer_tasks; | 164 TaskMap new_pixel_buffer_tasks; |
126 for (RasterTaskVector::const_iterator it = raster_tasks().begin(); | 165 for (RasterTaskVector::const_iterator it = raster_tasks().begin(); |
127 it != raster_tasks().end(); ++it) { | 166 it != raster_tasks().end(); ++it) { |
128 internal::RasterWorkerPoolTask* task = it->get(); | 167 internal::RasterWorkerPoolTask* task = it->get(); |
129 DCHECK(new_pixel_buffer_tasks.find(task) == new_pixel_buffer_tasks.end()); | 168 DCHECK(new_pixel_buffer_tasks.find(task) == new_pixel_buffer_tasks.end()); |
130 DCHECK(!task->HasCompleted()); | 169 DCHECK(!task->HasCompleted()); |
131 | 170 |
132 // Use existing pixel buffer task if available. | 171 // Use existing pixel buffer task if available. |
133 TaskMap::iterator pixel_buffer_it = pixel_buffer_tasks_.find(task); | 172 TaskMap::iterator pixel_buffer_it = pixel_buffer_tasks_.find(task); |
(...skipping 19 matching lines...) Expand all Loading... | |
153 // Inactive task can be canceled. | 192 // Inactive task can be canceled. |
154 if (!pixel_buffer_task && !task->HasFinishedRunning()) { | 193 if (!pixel_buffer_task && !task->HasFinishedRunning()) { |
155 task->DidRun(true); | 194 task->DidRun(true); |
156 DCHECK(std::find(completed_tasks_.begin(), | 195 DCHECK(std::find(completed_tasks_.begin(), |
157 completed_tasks_.end(), | 196 completed_tasks_.end(), |
158 task) == completed_tasks_.end()); | 197 task) == completed_tasks_.end()); |
159 completed_tasks_.push_back(task); | 198 completed_tasks_.push_back(task); |
160 } | 199 } |
161 } | 200 } |
162 | 201 |
202 tasks_required_for_activation_.clear(); | |
203 for (TaskMap::iterator it = new_pixel_buffer_tasks.begin(); | |
204 it != new_pixel_buffer_tasks.end(); ++it) { | |
205 internal::RasterWorkerPoolTask* task = it->first; | |
206 if (IsRasterTaskRequiredForActivation(task)) | |
207 tasks_required_for_activation_.insert(task); | |
208 } | |
209 | |
163 pixel_buffer_tasks_.swap(new_pixel_buffer_tasks); | 210 pixel_buffer_tasks_.swap(new_pixel_buffer_tasks); |
164 | 211 |
165 // This will schedule more tasks after checking for completed raster | 212 // Check for completed tasks when ScheduleTasks() is called as |
166 // tasks. It's worth checking for completed tasks when ScheduleTasks() | 213 // priorities might have changed and this maximizes the number |
167 // is called as priorities might have changed and this allows us to | 214 // of top priority tasks that are scheduled. |
168 // schedule as many new top priority tasks as possible. | 215 RasterWorkerPool::CheckForCompletedTasks(); |
169 CheckForCompletedRasterTasks(); | 216 CheckForCompletedUploads(); |
217 FlushUploads(); | |
218 | |
219 // Schedule new tasks. | |
220 ScheduleMoreTasks(); | |
221 | |
222 // Cancel any pending check for completed raster tasks and schedule | |
223 // another check. | |
224 check_for_completed_raster_tasks_callback_.Cancel(); | |
225 check_for_completed_raster_tasks_pending_ = false; | |
226 ScheduleCheckForCompletedRasterTasks(); | |
170 } | 227 } |
171 | 228 |
172 void PixelBufferRasterWorkerPool::CheckForCompletedTasks() { | 229 void PixelBufferRasterWorkerPool::CheckForCompletedTasks() { |
173 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::CheckForCompletedTasks"); | 230 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::CheckForCompletedTasks"); |
174 | 231 |
175 RasterWorkerPool::CheckForCompletedTasks(); | 232 RasterWorkerPool::CheckForCompletedTasks(); |
176 CheckForCompletedUploads(); | 233 CheckForCompletedUploads(); |
177 FlushUploads(); | 234 FlushUploads(); |
178 | 235 |
179 while (!completed_tasks_.empty()) { | 236 TaskDeque completed_tasks; |
180 internal::RasterWorkerPoolTask* task = completed_tasks_.front().get(); | 237 completed_tasks_.swap(completed_tasks); |
238 | |
239 while (!completed_tasks.empty()) { | |
240 internal::RasterWorkerPoolTask* task = completed_tasks.front().get(); | |
181 DCHECK(pixel_buffer_tasks_.find(task) != pixel_buffer_tasks_.end()); | 241 DCHECK(pixel_buffer_tasks_.find(task) != pixel_buffer_tasks_.end()); |
182 | 242 |
183 pixel_buffer_tasks_.erase(task); | 243 pixel_buffer_tasks_.erase(task); |
184 | 244 |
185 task->WillComplete(); | 245 task->WillComplete(); |
186 task->CompleteOnOriginThread(); | 246 task->CompleteOnOriginThread(); |
187 task->DidComplete(); | 247 task->DidComplete(); |
188 | 248 |
189 completed_tasks_.pop_front(); | 249 completed_tasks.pop_front(); |
190 } | 250 } |
191 } | 251 } |
192 | 252 |
193 void PixelBufferRasterWorkerPool::OnRasterTasksFinished() { | |
194 // Call CheckForCompletedTasks() when we've finished running all raster | |
195 // tasks needed since last time ScheduleMoreTasks() was called. This | |
196 // reduces latency when processing only a small number of raster tasks. | |
197 CheckForCompletedRasterTasks(); | |
198 } | |
199 | |
200 void PixelBufferRasterWorkerPool::FlushUploads() { | 253 void PixelBufferRasterWorkerPool::FlushUploads() { |
201 if (!has_performed_uploads_since_last_flush_) | 254 if (!has_performed_uploads_since_last_flush_) |
202 return; | 255 return; |
203 | 256 |
204 resource_provider()->ShallowFlushIfSupported(); | 257 resource_provider()->ShallowFlushIfSupported(); |
205 has_performed_uploads_since_last_flush_ = false; | 258 has_performed_uploads_since_last_flush_ = false; |
206 } | 259 } |
207 | 260 |
208 void PixelBufferRasterWorkerPool::CheckForCompletedUploads() { | 261 void PixelBufferRasterWorkerPool::CheckForCompletedUploads() { |
209 TaskDeque tasks_with_completed_uploads; | 262 TaskDeque tasks_with_completed_uploads; |
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
265 | 318 |
266 bytes_pending_upload_ -= task->resource()->bytes(); | 319 bytes_pending_upload_ -= task->resource()->bytes(); |
267 | 320 |
268 task->DidRun(false); | 321 task->DidRun(false); |
269 | 322 |
270 DCHECK(std::find(completed_tasks_.begin(), | 323 DCHECK(std::find(completed_tasks_.begin(), |
271 completed_tasks_.end(), | 324 completed_tasks_.end(), |
272 task) == completed_tasks_.end()); | 325 task) == completed_tasks_.end()); |
273 completed_tasks_.push_back(task); | 326 completed_tasks_.push_back(task); |
274 | 327 |
328 tasks_required_for_activation_.erase(task); | |
329 | |
275 tasks_with_completed_uploads.pop_front(); | 330 tasks_with_completed_uploads.pop_front(); |
276 } | 331 } |
277 } | 332 } |
278 | 333 |
279 void PixelBufferRasterWorkerPool::ScheduleCheckForCompletedRasterTasks() { | 334 void PixelBufferRasterWorkerPool::ScheduleCheckForCompletedRasterTasks() { |
280 if (check_for_completed_raster_tasks_pending_) | 335 if (check_for_completed_raster_tasks_pending_) |
281 return; | 336 return; |
282 | 337 |
283 check_for_completed_raster_tasks_callback_.Reset( | 338 check_for_completed_raster_tasks_callback_.Reset( |
284 base::Bind(&PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks, | 339 base::Bind(&PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks, |
285 base::Unretained(this))); | 340 base::Unretained(this))); |
286 base::MessageLoopProxy::current()->PostDelayedTask( | 341 base::MessageLoopProxy::current()->PostDelayedTask( |
287 FROM_HERE, | 342 FROM_HERE, |
288 check_for_completed_raster_tasks_callback_.callback(), | 343 check_for_completed_raster_tasks_callback_.callback(), |
289 base::TimeDelta::FromMilliseconds(kCheckForCompletedRasterTasksDelayMs)); | 344 base::TimeDelta::FromMilliseconds(kCheckForCompletedRasterTasksDelayMs)); |
290 check_for_completed_raster_tasks_pending_ = true; | 345 check_for_completed_raster_tasks_pending_ = true; |
291 } | 346 } |
292 | 347 |
293 void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() { | 348 void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() { |
294 TRACE_EVENT0( | 349 TRACE_EVENT0( |
295 "cc", "PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks"); | 350 "cc", "PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks"); |
296 | 351 |
297 check_for_completed_raster_tasks_callback_.Cancel(); | 352 check_for_completed_raster_tasks_callback_.Cancel(); |
298 check_for_completed_raster_tasks_pending_ = false; | 353 check_for_completed_raster_tasks_pending_ = false; |
299 | 354 |
300 RasterWorkerPool::CheckForCompletedTasks(); | 355 RasterWorkerPool::CheckForCompletedTasks(); |
301 CheckForCompletedUploads(); | 356 CheckForCompletedUploads(); |
302 FlushUploads(); | 357 FlushUploads(); |
303 | 358 |
304 ScheduleMoreTasks(); | 359 // Determine if client should be notified and update pending notification |
360 // status before scheduling more raster tasks. | |
361 bool notify_client_that_finished_running_tasks_required_for_activation = | |
362 NotifyClientThatFinishedRunningTasksRequiredForActivation(); | |
vmpstr
2013/06/27 23:31:21
ShouldNotify... I think we have to rethink the nam
reveman
2013/06/28 17:26:07
I agree. I'll come up with a better name asap. Let
| |
363 bool notify_client_that_finished_running_tasks = | |
364 NotifyClientThatFinishedRunningTasks(); | |
305 | 365 |
306 // Make sure another check for completed uploads is scheduled | 366 if (PendingRasterTaskCount()) |
307 // while there is still pending uploads left. | 367 ScheduleMoreTasks(); |
308 if (!tasks_with_pending_upload_.empty()) | 368 |
369 // Schedule another check for completed raster tasks while there are | |
370 // pending raster tasks or pending uploads. | |
371 if (PendingRasterTaskCount() || !tasks_with_pending_upload_.empty()) | |
309 ScheduleCheckForCompletedRasterTasks(); | 372 ScheduleCheckForCompletedRasterTasks(); |
373 | |
374 if (notify_client_that_finished_running_tasks_required_for_activation) | |
375 client()->DidFinishedRunningTasksRequiredForActivation(); | |
376 if (notify_client_that_finished_running_tasks) | |
377 client()->DidFinishedRunningTasks(); | |
310 } | 378 } |
311 | 379 |
312 void PixelBufferRasterWorkerPool::ScheduleMoreTasks() { | 380 void PixelBufferRasterWorkerPool::ScheduleMoreTasks() { |
313 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleMoreTasks"); | 381 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleMoreTasks"); |
314 | 382 |
383 ++schedule_raster_tasks_count_; | |
384 | |
385 enum RasterTaskType { | |
386 PREPAINT_TYPE = 0, | |
387 REQUIRED_FOR_ACTIVATION_TYPE = 1, | |
388 NUM_TYPES = 2 | |
389 }; | |
390 ScopedPtrDeque<GraphNode> tasks[NUM_TYPES]; | |
391 unsigned priority = 2u; // 0-1 reserved for RasterFinished tasks. | |
392 TaskGraph graph; | |
393 | |
315 size_t bytes_pending_upload = bytes_pending_upload_; | 394 size_t bytes_pending_upload = bytes_pending_upload_; |
316 size_t bytes_pending_raster = 0; | 395 size_t bytes_pending_raster = 0; |
317 | 396 |
318 RasterTaskGraph graph; | |
319 for (RasterTaskVector::const_iterator it = raster_tasks().begin(); | 397 for (RasterTaskVector::const_iterator it = raster_tasks().begin(); |
320 it != raster_tasks().end(); ++it) { | 398 it != raster_tasks().end(); ++it) { |
321 internal::RasterWorkerPoolTask* task = it->get(); | 399 internal::RasterWorkerPoolTask* task = it->get(); |
322 | 400 |
323 // |pixel_buffer_tasks_| contains all tasks that have not yet completed. | 401 // |pixel_buffer_tasks_| contains all tasks that have not yet completed. |
324 TaskMap::iterator pixel_buffer_it = pixel_buffer_tasks_.find(task); | 402 TaskMap::iterator pixel_buffer_it = pixel_buffer_tasks_.find(task); |
325 if (pixel_buffer_it == pixel_buffer_tasks_.end()) | 403 if (pixel_buffer_it == pixel_buffer_tasks_.end()) |
326 continue; | 404 continue; |
327 | 405 |
328 // HasFinishedRunning() will return true when set pixels has completed. | 406 // HasFinishedRunning() will return true when set pixels has completed. |
(...skipping 23 matching lines...) Expand all Loading... | |
352 size_t new_bytes_pending_raster = bytes_pending_raster; | 430 size_t new_bytes_pending_raster = bytes_pending_raster; |
353 new_bytes_pending_raster += task->resource()->bytes(); | 431 new_bytes_pending_raster += task->resource()->bytes(); |
354 if (new_bytes_pending_raster > kMaxPendingRasterBytes) | 432 if (new_bytes_pending_raster > kMaxPendingRasterBytes) |
355 break; | 433 break; |
356 | 434 |
357 // Update both |bytes_pending_raster| and |bytes_pending_upload| | 435 // Update both |bytes_pending_raster| and |bytes_pending_upload| |
358 // now that task has cleared all throttling limits. | 436 // now that task has cleared all throttling limits. |
359 bytes_pending_raster = new_bytes_pending_raster; | 437 bytes_pending_raster = new_bytes_pending_raster; |
360 bytes_pending_upload = new_bytes_pending_upload; | 438 bytes_pending_upload = new_bytes_pending_upload; |
361 | 439 |
440 RasterTaskType type = IsRasterTaskRequiredForActivation(task) ? | |
441 REQUIRED_FOR_ACTIVATION_TYPE : | |
442 PREPAINT_TYPE; | |
443 | |
362 // Use existing pixel buffer task if available. | 444 // Use existing pixel buffer task if available. |
363 if (pixel_buffer_task) { | 445 if (pixel_buffer_task) { |
364 graph.InsertRasterTask(pixel_buffer_task, task->dependencies()); | 446 tasks[type].push_back( |
447 CreateRasterTaskGraphNode(pixel_buffer_task, | |
448 task->dependencies(), | |
449 priority++, | |
450 &graph)); | |
365 continue; | 451 continue; |
366 } | 452 } |
367 | 453 |
368 // Request a pixel buffer. This will reserve shared memory. | 454 // Request a pixel buffer. This will reserve shared memory. |
369 resource_provider()->AcquirePixelBuffer(task->resource()->id()); | 455 resource_provider()->AcquirePixelBuffer(task->resource()->id()); |
370 | 456 |
371 // MapPixelBuffer() returns NULL if context was lost at the time | 457 // MapPixelBuffer() returns NULL if context was lost at the time |
372 // AcquirePixelBuffer() was called. For simplicity we still post | 458 // AcquirePixelBuffer() was called. For simplicity we still post |
373 // a raster task that is essentially a noop in these situations. | 459 // a raster task that is essentially a noop in these situations. |
374 uint8* buffer = resource_provider()->MapPixelBuffer( | 460 uint8* buffer = resource_provider()->MapPixelBuffer( |
375 task->resource()->id()); | 461 task->resource()->id()); |
376 | 462 |
377 scoped_refptr<internal::WorkerPoolTask> new_pixel_buffer_task( | 463 scoped_refptr<internal::WorkerPoolTask> new_pixel_buffer_task( |
378 new PixelBufferWorkerPoolTaskImpl( | 464 new PixelBufferWorkerPoolTaskImpl( |
379 task, | 465 task, |
380 buffer, | 466 buffer, |
381 base::Bind(&PixelBufferRasterWorkerPool::OnRasterTaskCompleted, | 467 base::Bind(&PixelBufferRasterWorkerPool::OnRasterTaskCompleted, |
382 base::Unretained(this), | 468 base::Unretained(this), |
383 make_scoped_refptr(task)))); | 469 make_scoped_refptr(task)))); |
384 pixel_buffer_tasks_[task] = new_pixel_buffer_task; | 470 pixel_buffer_tasks_[task] = new_pixel_buffer_task; |
385 graph.InsertRasterTask(new_pixel_buffer_task.get(), task->dependencies()); | 471 tasks[type].push_back( |
472 CreateRasterTaskGraphNode(new_pixel_buffer_task.get(), | |
473 task->dependencies(), | |
474 priority++, | |
475 &graph)); | |
386 } | 476 } |
387 | 477 |
388 SetRasterTaskGraph(&graph); | 478 scoped_refptr<internal::WorkerPoolTask> new_raster_finished_task; |
389 | 479 |
390 // At least one task that could need an upload is now pending, schedule | 480 DCHECK_LE(tasks[PREPAINT_TYPE].size() + |
vmpstr
2013/06/27 23:31:21
The comments from irwp apply in in this area as we
reveman
2013/06/28 17:26:07
PTAL.
| |
391 // a check for completed raster tasks to ensure this upload is dispatched | 481 tasks[REQUIRED_FOR_ACTIVATION_TYPE].size(), |
392 // without too much latency. | 482 PendingRasterTaskCount()); |
393 if (bytes_pending_raster) | 483 // Schedule OnRasterFinished call when notification is pending |
394 ScheduleCheckForCompletedRasterTasks(); | 484 // and throttling is not preventing all pending tasks from |
485 // being scheduled. | |
486 if ((tasks[PREPAINT_TYPE].size() + | |
487 tasks[REQUIRED_FOR_ACTIVATION_TYPE].size()) == | |
488 PendingRasterTaskCount() && | |
489 finished_running_tasks_pending_) { | |
490 new_raster_finished_task = make_scoped_refptr( | |
491 new RasterFinishedWorkerPoolTaskImpl( | |
492 base::MessageLoopProxy::current(), | |
493 base::Bind(&PixelBufferRasterWorkerPool::OnRasterFinished, | |
494 weak_ptr_factory_.GetWeakPtr(), | |
495 schedule_raster_tasks_count_))); | |
496 scoped_ptr<GraphNode> raster_finished_node( | |
497 new GraphNode(new_raster_finished_task.get(), | |
498 1u)); // Priority 1 | |
499 for (unsigned i = 0; i < NUM_TYPES; ++i) { | |
500 for (unsigned j = 0; j < tasks[i].size(); ++j) { | |
501 raster_finished_node->add_dependency(); | |
502 tasks[i][j]->add_dependent(raster_finished_node.get()); | |
503 } | |
504 } | |
505 graph.set(new_raster_finished_task.get(), raster_finished_node.Pass()); | |
506 } | |
507 | |
508 scoped_refptr<internal::WorkerPoolTask> | |
509 new_raster_required_for_activation_finished_task; | |
510 | |
511 DCHECK_LE(tasks[REQUIRED_FOR_ACTIVATION_TYPE].size(), | |
512 tasks_required_for_activation_.size()); | |
513 // Schedule OnRasterRequiredForActivationFinished call when | |
514 // notification is pending and throttling is not preventing | |
515 // all pending tasks required for activation from being scheduled. | |
516 if (tasks[REQUIRED_FOR_ACTIVATION_TYPE].size() == | |
517 tasks_required_for_activation_.size() && | |
518 finished_running_tasks_required_for_activation_pending_) { | |
519 new_raster_required_for_activation_finished_task = make_scoped_refptr( | |
520 new RasterFinishedWorkerPoolTaskImpl( | |
521 base::MessageLoopProxy::current(), | |
522 base::Bind(&PixelBufferRasterWorkerPool:: | |
523 OnRasterRequiredForActivationFinished, | |
524 weak_ptr_factory_.GetWeakPtr(), | |
525 schedule_raster_tasks_count_))); | |
526 | |
527 scoped_ptr<GraphNode> raster_required_for_activation_finished_node( | |
528 new GraphNode(new_raster_required_for_activation_finished_task.get(), | |
529 0u)); // Priority 0 | |
530 for (unsigned j = 0; | |
531 j < tasks[REQUIRED_FOR_ACTIVATION_TYPE].size(); | |
532 ++j) { | |
533 raster_required_for_activation_finished_node->add_dependency(); | |
534 tasks[REQUIRED_FOR_ACTIVATION_TYPE][j]->add_dependent( | |
535 raster_required_for_activation_finished_node.get()); | |
536 } | |
537 graph.set(new_raster_required_for_activation_finished_task.get(), | |
538 raster_required_for_activation_finished_node.Pass()); | |
539 } | |
540 | |
541 for (unsigned i = 0; i < NUM_TYPES; ++i) { | |
542 while (!tasks[i].empty()) { | |
543 scoped_ptr<GraphNode> node = tasks[i].take_front(); | |
544 internal::WorkerPoolTask* task = node->task(); | |
545 graph.set(task, node.Pass()); | |
546 } | |
547 } | |
548 | |
549 SetTaskGraph(&graph); | |
550 | |
551 raster_finished_task_.swap(new_raster_finished_task); | |
552 raster_required_for_activation_finished_task_.swap( | |
553 new_raster_required_for_activation_finished_task); | |
554 } | |
555 | |
556 void PixelBufferRasterWorkerPool::OnRasterFinished( | |
557 int64 schedule_raster_tasks_count) { | |
558 TRACE_EVENT1("cc", "PixelBufferRasterWorkerPool::OnRasterFinished", | |
559 "schedule_raster_tasks_count", schedule_raster_tasks_count); | |
560 DCHECK_GE(schedule_raster_tasks_count_, schedule_raster_tasks_count); | |
561 // Call CheckForCompletedRasterTasks() if this callback is | |
562 // associated with the last call to SetRasterTaskGraph(). | |
563 if (schedule_raster_tasks_count_ == schedule_raster_tasks_count) | |
564 CheckForCompletedRasterTasks(); | |
565 } | |
566 | |
567 void PixelBufferRasterWorkerPool::OnRasterRequiredForActivationFinished( | |
568 int64 schedule_raster_tasks_count) { | |
569 TRACE_EVENT1( | |
570 "cc", | |
571 "PixelBufferRasterWorkerPool::OnRasterRequiredForActivationFinished", | |
572 "schedule_raster_tasks_count", schedule_raster_tasks_count); | |
573 DCHECK_GE(schedule_raster_tasks_count_, schedule_raster_tasks_count); | |
574 // Call CheckForCompletedRasterTasks() if this callback is | |
575 // associated with the last call to SetRasterTaskGraph(). | |
576 if (schedule_raster_tasks_count_ == schedule_raster_tasks_count) | |
577 CheckForCompletedRasterTasks(); | |
395 } | 578 } |
396 | 579 |
397 void PixelBufferRasterWorkerPool::OnRasterTaskCompleted( | 580 void PixelBufferRasterWorkerPool::OnRasterTaskCompleted( |
398 scoped_refptr<internal::RasterWorkerPoolTask> task, | 581 scoped_refptr<internal::RasterWorkerPoolTask> task, |
399 bool was_canceled, | 582 bool was_canceled, |
400 bool needs_upload) { | 583 bool needs_upload) { |
401 TRACE_EVENT2("cc", "PixelBufferRasterWorkerPool::OnRasterTaskCompleted", | 584 TRACE_EVENT2("cc", "PixelBufferRasterWorkerPool::OnRasterTaskCompleted", |
402 "was_canceled", was_canceled, | 585 "was_canceled", was_canceled, |
403 "needs_upload", needs_upload); | 586 "needs_upload", needs_upload); |
404 | 587 |
405 DCHECK(pixel_buffer_tasks_.find(task.get()) != pixel_buffer_tasks_.end()); | 588 DCHECK(pixel_buffer_tasks_.find(task.get()) != pixel_buffer_tasks_.end()); |
406 | 589 |
407 // Balanced with MapPixelBuffer() call in ScheduleMoreTasks(). | 590 // Balanced with MapPixelBuffer() call in ScheduleMoreTasks(). |
408 resource_provider()->UnmapPixelBuffer(task->resource()->id()); | 591 resource_provider()->UnmapPixelBuffer(task->resource()->id()); |
409 | 592 |
410 if (!needs_upload) { | 593 if (!needs_upload) { |
411 resource_provider()->ReleasePixelBuffer(task->resource()->id()); | 594 resource_provider()->ReleasePixelBuffer(task->resource()->id()); |
412 task->DidRun(was_canceled); | 595 task->DidRun(was_canceled); |
413 DCHECK(std::find(completed_tasks_.begin(), | 596 DCHECK(std::find(completed_tasks_.begin(), |
414 completed_tasks_.end(), | 597 completed_tasks_.end(), |
415 task) == completed_tasks_.end()); | 598 task) == completed_tasks_.end()); |
416 completed_tasks_.push_back(task); | 599 completed_tasks_.push_back(task); |
600 tasks_required_for_activation_.erase(task); | |
417 return; | 601 return; |
418 } | 602 } |
419 | 603 |
420 resource_provider()->BeginSetPixels(task->resource()->id()); | 604 resource_provider()->BeginSetPixels(task->resource()->id()); |
421 has_performed_uploads_since_last_flush_ = true; | 605 has_performed_uploads_since_last_flush_ = true; |
422 | 606 |
423 bytes_pending_upload_ += task->resource()->bytes(); | 607 bytes_pending_upload_ += task->resource()->bytes(); |
424 tasks_with_pending_upload_.push_back(task); | 608 tasks_with_pending_upload_.push_back(task); |
425 } | 609 } |
426 | 610 |
611 unsigned PixelBufferRasterWorkerPool::PendingRasterTaskCount() const { | |
612 unsigned num_completed_raster_tasks = | |
613 tasks_with_pending_upload_.size() + completed_tasks_.size(); | |
614 DCHECK_GE(pixel_buffer_tasks_.size(), num_completed_raster_tasks); | |
615 return pixel_buffer_tasks_.size() - num_completed_raster_tasks; | |
616 } | |
617 | |
618 bool PixelBufferRasterWorkerPool:: | |
619 NotifyClientThatFinishedRunningTasksRequiredForActivation() { | |
620 if (!finished_running_tasks_required_for_activation_pending_) | |
621 return false; | |
622 | |
623 if (!tasks_required_for_activation_.empty()) | |
624 return false; | |
625 | |
626 finished_running_tasks_required_for_activation_pending_ = false; | |
627 return true; | |
628 } | |
629 | |
630 bool PixelBufferRasterWorkerPool::NotifyClientThatFinishedRunningTasks() { | |
631 if (!finished_running_tasks_pending_) | |
632 return false; | |
633 | |
634 if (PendingRasterTaskCount()) | |
635 return false; | |
636 | |
637 if (!tasks_with_pending_upload_.empty()) | |
638 return false; | |
639 | |
640 finished_running_tasks_pending_ = false; | |
641 return true; | |
642 } | |
643 | |
427 } // namespace cc | 644 } // namespace cc |
OLD | NEW |