Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(361)

Side by Side Diff: cc/resources/pixel_buffer_raster_worker_pool.cc

Issue 17351017: Re-land: cc: Add raster finished signals to RasterWorkerPool. (Closed) Base URL: http://git.chromium.org/chromium/src.git@new-graph-build
Patch Set: fix flaky unit tests Created 7 years, 5 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
« no previous file with comments | « cc/resources/pixel_buffer_raster_worker_pool.h ('k') | cc/resources/raster_worker_pool.h » ('j') | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/containers/stack_container.h"
7 #include "base/debug/trace_event.h" 8 #include "base/debug/trace_event.h"
9 #include "base/values.h"
10 #include "cc/debug/traced_value.h"
8 #include "cc/resources/resource.h" 11 #include "cc/resources/resource.h"
9 #include "third_party/skia/include/core/SkDevice.h" 12 #include "third_party/skia/include/core/SkDevice.h"
10 13
11 namespace cc { 14 namespace cc {
12 15
13 namespace { 16 namespace {
14 17
15 class PixelBufferWorkerPoolTaskImpl : public internal::WorkerPoolTask { 18 class PixelBufferWorkerPoolTaskImpl : public internal::WorkerPoolTask {
16 public: 19 public:
17 typedef base::Callback<void(bool was_canceled, bool needs_upload)> Reply; 20 typedef base::Callback<void(bool was_canceled, bool needs_upload)> Reply;
(...skipping 52 matching lines...) Expand 10 before | Expand all | Expand 10 after
70 #else 73 #else
71 // For reference Chromebook Pixel can upload 1MB in about 0.5ms. 74 // For reference Chromebook Pixel can upload 1MB in about 0.5ms.
72 const size_t kMaxBytesUploadedPerMs = 1024 * 1024 * 2; 75 const size_t kMaxBytesUploadedPerMs = 1024 * 1024 * 2;
73 #endif 76 #endif
74 77
75 // Assuming a two frame deep pipeline. 78 // Assuming a two frame deep pipeline.
76 const size_t kMaxPendingUploadBytes = 16 * 2 * kMaxBytesUploadedPerMs; 79 const size_t kMaxPendingUploadBytes = 16 * 2 * kMaxBytesUploadedPerMs;
77 80
78 const int kCheckForCompletedRasterTasksDelayMs = 6; 81 const int kCheckForCompletedRasterTasksDelayMs = 6;
79 82
80 const size_t kMaxPendingRasterBytes = 83 const size_t kMaxScheduledRasterTasks = 48;
81 kMaxBytesUploadedPerMs * kCheckForCompletedRasterTasksDelayMs; 84
85 typedef base::StackVector<internal::GraphNode*,
86 kMaxScheduledRasterTasks> NodeVector;
87
88 void AddDependenciesToGraphNode(
89 internal::GraphNode* node,
90 const NodeVector::ContainerType& dependencies) {
91 for (NodeVector::ContainerType::const_iterator it = dependencies.begin();
92 it != dependencies.end(); ++it) {
93 internal::GraphNode* dependency = *it;
94
95 node->add_dependency();
96 dependency->add_dependent(node);
97 }
98 }
82 99
83 } // namespace 100 } // namespace
84 101
85 PixelBufferRasterWorkerPool::PixelBufferRasterWorkerPool( 102 PixelBufferRasterWorkerPool::PixelBufferRasterWorkerPool(
86 ResourceProvider* resource_provider, 103 ResourceProvider* resource_provider,
87 size_t num_threads) : RasterWorkerPool(resource_provider, num_threads), 104 size_t num_threads)
88 shutdown_(false), 105 : RasterWorkerPool(resource_provider, num_threads),
89 bytes_pending_upload_(0), 106 shutdown_(false),
90 has_performed_uploads_since_last_flush_(false), 107 scheduled_raster_task_count_(0),
91 check_for_completed_raster_tasks_pending_(false) { 108 bytes_pending_upload_(0),
109 has_performed_uploads_since_last_flush_(false),
110 check_for_completed_raster_tasks_pending_(false),
111 should_notify_client_if_no_tasks_are_pending_(false),
112 should_notify_client_if_no_tasks_required_for_activation_are_pending_(
113 false) {
92 } 114 }
93 115
94 PixelBufferRasterWorkerPool::~PixelBufferRasterWorkerPool() { 116 PixelBufferRasterWorkerPool::~PixelBufferRasterWorkerPool() {
95 DCHECK(shutdown_); 117 DCHECK(shutdown_);
96 DCHECK(!check_for_completed_raster_tasks_pending_); 118 DCHECK(!check_for_completed_raster_tasks_pending_);
97 DCHECK_EQ(0u, pixel_buffer_tasks_.size()); 119 DCHECK_EQ(0u, pixel_buffer_tasks_.size());
98 DCHECK_EQ(0u, tasks_with_pending_upload_.size()); 120 DCHECK_EQ(0u, tasks_with_pending_upload_.size());
99 DCHECK_EQ(0u, completed_tasks_.size()); 121 DCHECK_EQ(0u, completed_tasks_.size());
100 } 122 }
101 123
102 void PixelBufferRasterWorkerPool::Shutdown() { 124 void PixelBufferRasterWorkerPool::Shutdown() {
103 shutdown_ = true; 125 shutdown_ = true;
104 RasterWorkerPool::Shutdown(); 126 RasterWorkerPool::Shutdown();
105 CheckForCompletedRasterTasks(); 127 RasterWorkerPool::CheckForCompletedTasks();
128 CheckForCompletedUploads();
129 check_for_completed_raster_tasks_callback_.Cancel();
130 check_for_completed_raster_tasks_pending_ = false;
106 for (TaskMap::iterator it = pixel_buffer_tasks_.begin(); 131 for (TaskMap::iterator it = pixel_buffer_tasks_.begin();
107 it != pixel_buffer_tasks_.end(); ++it) { 132 it != pixel_buffer_tasks_.end(); ++it) {
108 internal::RasterWorkerPoolTask* task = it->first; 133 internal::RasterWorkerPoolTask* task = it->first;
109 internal::WorkerPoolTask* pixel_buffer_task = it->second.get(); 134 internal::WorkerPoolTask* pixel_buffer_task = it->second.get();
110 135
111 // All inactive tasks needs to be canceled. 136 // All inactive tasks needs to be canceled.
112 if (!pixel_buffer_task && !task->HasFinishedRunning()) { 137 if (!pixel_buffer_task && !task->HasFinishedRunning()) {
113 task->DidRun(true); 138 task->DidRun(true);
114 completed_tasks_.push_back(task); 139 completed_tasks_.push_back(task);
115 } 140 }
116 } 141 }
142 DCHECK_EQ(completed_tasks_.size(), pixel_buffer_tasks_.size());
117 } 143 }
118 144
119 void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTask::Queue* queue) { 145 void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTask::Queue* queue) {
120 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleTasks"); 146 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleTasks");
121 147
122 RasterWorkerPool::SetRasterTasks(queue); 148 RasterWorkerPool::SetRasterTasks(queue);
123 149
150 if (!should_notify_client_if_no_tasks_are_pending_)
151 TRACE_EVENT_ASYNC_BEGIN0("cc", "ScheduledTasks", this);
152
153 should_notify_client_if_no_tasks_are_pending_ = true;
154 should_notify_client_if_no_tasks_required_for_activation_are_pending_ = true;
155
124 // Build new pixel buffer task set. 156 // Build new pixel buffer task set.
125 TaskMap new_pixel_buffer_tasks; 157 TaskMap new_pixel_buffer_tasks;
126 for (RasterTaskVector::const_iterator it = raster_tasks().begin(); 158 for (RasterTaskVector::const_iterator it = raster_tasks().begin();
127 it != raster_tasks().end(); ++it) { 159 it != raster_tasks().end(); ++it) {
128 internal::RasterWorkerPoolTask* task = it->get(); 160 internal::RasterWorkerPoolTask* task = it->get();
129 DCHECK(new_pixel_buffer_tasks.find(task) == new_pixel_buffer_tasks.end()); 161 DCHECK(new_pixel_buffer_tasks.find(task) == new_pixel_buffer_tasks.end());
130 DCHECK(!task->HasCompleted()); 162 DCHECK(!task->HasCompleted());
131 163
132 // Use existing pixel buffer task if available. 164 // Use existing pixel buffer task if available.
133 TaskMap::iterator pixel_buffer_it = pixel_buffer_tasks_.find(task); 165 TaskMap::iterator pixel_buffer_it = pixel_buffer_tasks_.find(task);
(...skipping 19 matching lines...) Expand all
153 // Inactive task can be canceled. 185 // Inactive task can be canceled.
154 if (!pixel_buffer_task && !task->HasFinishedRunning()) { 186 if (!pixel_buffer_task && !task->HasFinishedRunning()) {
155 task->DidRun(true); 187 task->DidRun(true);
156 DCHECK(std::find(completed_tasks_.begin(), 188 DCHECK(std::find(completed_tasks_.begin(),
157 completed_tasks_.end(), 189 completed_tasks_.end(),
158 task) == completed_tasks_.end()); 190 task) == completed_tasks_.end());
159 completed_tasks_.push_back(task); 191 completed_tasks_.push_back(task);
160 } 192 }
161 } 193 }
162 194
195 tasks_required_for_activation_.clear();
196 for (TaskMap::iterator it = new_pixel_buffer_tasks.begin();
197 it != new_pixel_buffer_tasks.end(); ++it) {
198 internal::RasterWorkerPoolTask* task = it->first;
199 if (IsRasterTaskRequiredForActivation(task))
200 tasks_required_for_activation_.insert(task);
201 }
202
163 pixel_buffer_tasks_.swap(new_pixel_buffer_tasks); 203 pixel_buffer_tasks_.swap(new_pixel_buffer_tasks);
164 204
165 // This will schedule more tasks after checking for completed raster 205 // Check for completed tasks when ScheduleTasks() is called as
166 // tasks. It's worth checking for completed tasks when ScheduleTasks() 206 // priorities might have changed and this maximizes the number
167 // is called as priorities might have changed and this allows us to 207 // of top priority tasks that are scheduled.
168 // schedule as many new top priority tasks as possible. 208 RasterWorkerPool::CheckForCompletedTasks();
169 CheckForCompletedRasterTasks(); 209 CheckForCompletedUploads();
210 FlushUploads();
211
212 // Schedule new tasks.
213 ScheduleMoreTasks();
214
215 // Cancel any pending check for completed raster tasks and schedule
216 // another check.
217 check_for_completed_raster_tasks_callback_.Cancel();
218 check_for_completed_raster_tasks_pending_ = false;
219 ScheduleCheckForCompletedRasterTasks();
220
221 TRACE_EVENT_ASYNC_STEP1(
222 "cc", "ScheduledTasks", this, StateName(),
223 "state", TracedValue::FromValue(StateAsValue().release()));
170 } 224 }
171 225
172 void PixelBufferRasterWorkerPool::CheckForCompletedTasks() { 226 void PixelBufferRasterWorkerPool::CheckForCompletedTasks() {
173 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::CheckForCompletedTasks"); 227 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::CheckForCompletedTasks");
174 228
175 RasterWorkerPool::CheckForCompletedTasks(); 229 RasterWorkerPool::CheckForCompletedTasks();
176 CheckForCompletedUploads(); 230 CheckForCompletedUploads();
177 FlushUploads(); 231 FlushUploads();
178 232
179 while (!completed_tasks_.empty()) { 233 TaskDeque completed_tasks;
180 internal::RasterWorkerPoolTask* task = completed_tasks_.front().get(); 234 completed_tasks_.swap(completed_tasks);
235
236 while (!completed_tasks.empty()) {
237 internal::RasterWorkerPoolTask* task = completed_tasks.front().get();
181 DCHECK(pixel_buffer_tasks_.find(task) != pixel_buffer_tasks_.end()); 238 DCHECK(pixel_buffer_tasks_.find(task) != pixel_buffer_tasks_.end());
182 239
183 pixel_buffer_tasks_.erase(task); 240 pixel_buffer_tasks_.erase(task);
184 241
185 task->WillComplete(); 242 task->WillComplete();
186 task->CompleteOnOriginThread(); 243 task->CompleteOnOriginThread();
187 task->DidComplete(); 244 task->DidComplete();
188 245
189 completed_tasks_.pop_front(); 246 completed_tasks.pop_front();
190 } 247 }
191 } 248 }
192 249
193 void PixelBufferRasterWorkerPool::OnRasterTasksFinished() { 250 void PixelBufferRasterWorkerPool::OnRasterTasksFinished() {
194 // Call CheckForCompletedTasks() when we've finished running all raster 251 // |should_notify_client_if_no_tasks_are_pending_| can be set to false as
195 // tasks needed since last time ScheduleMoreTasks() was called. This 252 // a result of a scheduled CheckForCompletedRasterTasks() call. No need to
196 // reduces latency when processing only a small number of raster tasks. 253 // perform another check in that case as we've already notified the client.
254 if (!should_notify_client_if_no_tasks_are_pending_)
255 return;
256
257 // Call CheckForCompletedRasterTasks() when we've finished running all
258 // raster tasks needed since last time ScheduleTasks() was called.
259 // This reduces latency between the time when all tasks have finished
260 // running and the time when the client is notified.
197 CheckForCompletedRasterTasks(); 261 CheckForCompletedRasterTasks();
198 } 262 }
199 263
264 void PixelBufferRasterWorkerPool::OnRasterTasksRequiredForActivationFinished() {
265 // Analogous to OnRasterTasksFinished(), there's no need to call
266 // CheckForCompletedRasterTasks() if the client has already been notified.
267 if (!should_notify_client_if_no_tasks_required_for_activation_are_pending_)
268 return;
269
270 // This reduces latency between the time when all tasks required for
271 // activation have finished running and the time when the client is
272 // notified.
273 CheckForCompletedRasterTasks();
274 }
275
200 void PixelBufferRasterWorkerPool::FlushUploads() { 276 void PixelBufferRasterWorkerPool::FlushUploads() {
201 if (!has_performed_uploads_since_last_flush_) 277 if (!has_performed_uploads_since_last_flush_)
202 return; 278 return;
203 279
204 resource_provider()->ShallowFlushIfSupported(); 280 resource_provider()->ShallowFlushIfSupported();
205 has_performed_uploads_since_last_flush_ = false; 281 has_performed_uploads_since_last_flush_ = false;
206 } 282 }
207 283
208 void PixelBufferRasterWorkerPool::CheckForCompletedUploads() { 284 void PixelBufferRasterWorkerPool::CheckForCompletedUploads() {
209 TaskDeque tasks_with_completed_uploads; 285 TaskDeque tasks_with_completed_uploads;
(...skipping 55 matching lines...) Expand 10 before | Expand all | Expand 10 after
265 341
266 bytes_pending_upload_ -= task->resource()->bytes(); 342 bytes_pending_upload_ -= task->resource()->bytes();
267 343
268 task->DidRun(false); 344 task->DidRun(false);
269 345
270 DCHECK(std::find(completed_tasks_.begin(), 346 DCHECK(std::find(completed_tasks_.begin(),
271 completed_tasks_.end(), 347 completed_tasks_.end(),
272 task) == completed_tasks_.end()); 348 task) == completed_tasks_.end());
273 completed_tasks_.push_back(task); 349 completed_tasks_.push_back(task);
274 350
351 tasks_required_for_activation_.erase(task);
352
275 tasks_with_completed_uploads.pop_front(); 353 tasks_with_completed_uploads.pop_front();
276 } 354 }
277 } 355 }
278 356
279 void PixelBufferRasterWorkerPool::ScheduleCheckForCompletedRasterTasks() { 357 void PixelBufferRasterWorkerPool::ScheduleCheckForCompletedRasterTasks() {
280 if (check_for_completed_raster_tasks_pending_) 358 if (check_for_completed_raster_tasks_pending_)
281 return; 359 return;
282 360
283 check_for_completed_raster_tasks_callback_.Reset( 361 check_for_completed_raster_tasks_callback_.Reset(
284 base::Bind(&PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks, 362 base::Bind(&PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks,
285 base::Unretained(this))); 363 base::Unretained(this)));
286 base::MessageLoopProxy::current()->PostDelayedTask( 364 base::MessageLoopProxy::current()->PostDelayedTask(
287 FROM_HERE, 365 FROM_HERE,
288 check_for_completed_raster_tasks_callback_.callback(), 366 check_for_completed_raster_tasks_callback_.callback(),
289 base::TimeDelta::FromMilliseconds(kCheckForCompletedRasterTasksDelayMs)); 367 base::TimeDelta::FromMilliseconds(kCheckForCompletedRasterTasksDelayMs));
290 check_for_completed_raster_tasks_pending_ = true; 368 check_for_completed_raster_tasks_pending_ = true;
291 } 369 }
292 370
293 void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() { 371 void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() {
294 TRACE_EVENT0( 372 TRACE_EVENT0(
295 "cc", "PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks"); 373 "cc", "PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks");
296 374
375 DCHECK(should_notify_client_if_no_tasks_are_pending_);
376
297 check_for_completed_raster_tasks_callback_.Cancel(); 377 check_for_completed_raster_tasks_callback_.Cancel();
298 check_for_completed_raster_tasks_pending_ = false; 378 check_for_completed_raster_tasks_pending_ = false;
299 379
300 RasterWorkerPool::CheckForCompletedTasks(); 380 RasterWorkerPool::CheckForCompletedTasks();
301 CheckForCompletedUploads(); 381 CheckForCompletedUploads();
302 FlushUploads(); 382 FlushUploads();
303 383
304 ScheduleMoreTasks(); 384 // Determine what client notifications to generate.
385 bool will_notify_client_that_no_tasks_required_for_activation_are_pending =
386 (should_notify_client_if_no_tasks_required_for_activation_are_pending_ &&
387 !HasPendingTasksRequiredForActivation());
388 bool will_notify_client_that_no_tasks_are_pending =
389 (should_notify_client_if_no_tasks_are_pending_ &&
390 !HasPendingTasks());
305 391
306 // Make sure another check for completed uploads is scheduled 392 // Adjust the need to generate notifications before scheduling more tasks.
307 // while there is still pending uploads left. 393 should_notify_client_if_no_tasks_required_for_activation_are_pending_ &=
308 if (!tasks_with_pending_upload_.empty()) 394 !will_notify_client_that_no_tasks_required_for_activation_are_pending;
395 should_notify_client_if_no_tasks_are_pending_ &=
396 !will_notify_client_that_no_tasks_are_pending;
397
398 if (PendingRasterTaskCount())
399 ScheduleMoreTasks();
400
401 TRACE_EVENT_ASYNC_STEP1(
402 "cc", "ScheduledTasks", this, StateName(),
403 "state", TracedValue::FromValue(StateAsValue().release()));
404
405 // Schedule another check for completed raster tasks while there are
406 // pending raster tasks or pending uploads.
407 if (HasPendingTasks())
309 ScheduleCheckForCompletedRasterTasks(); 408 ScheduleCheckForCompletedRasterTasks();
409
410 // Generate client notifications.
411 if (will_notify_client_that_no_tasks_required_for_activation_are_pending)
412 client()->DidFinishedRunningTasksRequiredForActivation();
413 if (will_notify_client_that_no_tasks_are_pending) {
414 TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this);
415 client()->DidFinishedRunningTasks();
416 }
310 } 417 }
311 418
312 void PixelBufferRasterWorkerPool::ScheduleMoreTasks() { 419 void PixelBufferRasterWorkerPool::ScheduleMoreTasks() {
313 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleMoreTasks"); 420 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleMoreTasks");
314 421
422 enum RasterTaskType {
423 PREPAINT_TYPE = 0,
424 REQUIRED_FOR_ACTIVATION_TYPE = 1,
425 NUM_TYPES = 2
426 };
427 NodeVector tasks[NUM_TYPES];
428 unsigned priority = 2u; // 0-1 reserved for RasterFinished tasks.
429 TaskGraph graph;
430
315 size_t bytes_pending_upload = bytes_pending_upload_; 431 size_t bytes_pending_upload = bytes_pending_upload_;
316 size_t bytes_pending_raster = 0;
317 432
318 RasterTaskGraph graph;
319 for (RasterTaskVector::const_iterator it = raster_tasks().begin(); 433 for (RasterTaskVector::const_iterator it = raster_tasks().begin();
320 it != raster_tasks().end(); ++it) { 434 it != raster_tasks().end(); ++it) {
321 internal::RasterWorkerPoolTask* task = it->get(); 435 internal::RasterWorkerPoolTask* task = it->get();
322 436
323 // |pixel_buffer_tasks_| contains all tasks that have not yet completed. 437 // |pixel_buffer_tasks_| contains all tasks that have not yet completed.
324 TaskMap::iterator pixel_buffer_it = pixel_buffer_tasks_.find(task); 438 TaskMap::iterator pixel_buffer_it = pixel_buffer_tasks_.find(task);
325 if (pixel_buffer_it == pixel_buffer_tasks_.end()) 439 if (pixel_buffer_it == pixel_buffer_tasks_.end())
326 continue; 440 continue;
327 441
328 // HasFinishedRunning() will return true when set pixels has completed. 442 // HasFinishedRunning() will return true when set pixels has completed.
(...skipping 11 matching lines...) Expand all
340 break; 454 break;
341 455
342 internal::WorkerPoolTask* pixel_buffer_task = pixel_buffer_it->second.get(); 456 internal::WorkerPoolTask* pixel_buffer_task = pixel_buffer_it->second.get();
343 457
344 // If raster has finished, just update |bytes_pending_upload|. 458 // If raster has finished, just update |bytes_pending_upload|.
345 if (pixel_buffer_task && pixel_buffer_task->HasCompleted()) { 459 if (pixel_buffer_task && pixel_buffer_task->HasCompleted()) {
346 bytes_pending_upload = new_bytes_pending_upload; 460 bytes_pending_upload = new_bytes_pending_upload;
347 continue; 461 continue;
348 } 462 }
349 463
350 // Throttle raster tasks based on bytes pending if raster has not 464 // Throttle raster tasks based on kMaxScheduledRasterTasks.
351 // finished. 465 size_t scheduled_raster_task_count =
352 size_t new_bytes_pending_raster = bytes_pending_raster; 466 tasks[PREPAINT_TYPE].container().size() +
353 new_bytes_pending_raster += task->resource()->bytes(); 467 tasks[REQUIRED_FOR_ACTIVATION_TYPE].container().size();
354 if (new_bytes_pending_raster > kMaxPendingRasterBytes) 468 if (scheduled_raster_task_count >= kMaxScheduledRasterTasks)
355 break; 469 break;
356 470
357 // Update both |bytes_pending_raster| and |bytes_pending_upload| 471 // Update |bytes_pending_upload| now that task has cleared all
358 // now that task has cleared all throttling limits. 472 // throttling limits.
359 bytes_pending_raster = new_bytes_pending_raster;
360 bytes_pending_upload = new_bytes_pending_upload; 473 bytes_pending_upload = new_bytes_pending_upload;
361 474
475 RasterTaskType type = IsRasterTaskRequiredForActivation(task) ?
476 REQUIRED_FOR_ACTIVATION_TYPE :
477 PREPAINT_TYPE;
478
362 // Use existing pixel buffer task if available. 479 // Use existing pixel buffer task if available.
363 if (pixel_buffer_task) { 480 if (pixel_buffer_task) {
364 graph.InsertRasterTask(pixel_buffer_task, task->dependencies()); 481 tasks[type].container().push_back(
482 CreateGraphNodeForRasterTask(pixel_buffer_task,
483 task->dependencies(),
484 priority++,
485 &graph));
365 continue; 486 continue;
366 } 487 }
367 488
368 // Request a pixel buffer. This will reserve shared memory. 489 // Request a pixel buffer. This will reserve shared memory.
369 resource_provider()->AcquirePixelBuffer(task->resource()->id()); 490 resource_provider()->AcquirePixelBuffer(task->resource()->id());
370 491
371 // MapPixelBuffer() returns NULL if context was lost at the time 492 // MapPixelBuffer() returns NULL if context was lost at the time
372 // AcquirePixelBuffer() was called. For simplicity we still post 493 // AcquirePixelBuffer() was called. For simplicity we still post
373 // a raster task that is essentially a noop in these situations. 494 // a raster task that is essentially a noop in these situations.
374 uint8* buffer = resource_provider()->MapPixelBuffer( 495 uint8* buffer = resource_provider()->MapPixelBuffer(
375 task->resource()->id()); 496 task->resource()->id());
376 497
377 scoped_refptr<internal::WorkerPoolTask> new_pixel_buffer_task( 498 scoped_refptr<internal::WorkerPoolTask> new_pixel_buffer_task(
378 new PixelBufferWorkerPoolTaskImpl( 499 new PixelBufferWorkerPoolTaskImpl(
379 task, 500 task,
380 buffer, 501 buffer,
381 base::Bind(&PixelBufferRasterWorkerPool::OnRasterTaskCompleted, 502 base::Bind(&PixelBufferRasterWorkerPool::OnRasterTaskCompleted,
382 base::Unretained(this), 503 base::Unretained(this),
383 make_scoped_refptr(task)))); 504 make_scoped_refptr(task))));
384 pixel_buffer_tasks_[task] = new_pixel_buffer_task; 505 pixel_buffer_tasks_[task] = new_pixel_buffer_task;
385 graph.InsertRasterTask(new_pixel_buffer_task.get(), task->dependencies()); 506 tasks[type].container().push_back(
507 CreateGraphNodeForRasterTask(new_pixel_buffer_task.get(),
508 task->dependencies(),
509 priority++,
510 &graph));
386 } 511 }
387 512
388 SetRasterTaskGraph(&graph); 513 scoped_refptr<internal::WorkerPoolTask>
514 new_raster_required_for_activation_finished_task;
389 515
390 // At least one task that could need an upload is now pending, schedule 516 size_t scheduled_raster_task_required_for_activation_count =
391 // a check for completed raster tasks to ensure this upload is dispatched 517 tasks[REQUIRED_FOR_ACTIVATION_TYPE].container().size();
392 // without too much latency. 518 DCHECK_LE(scheduled_raster_task_required_for_activation_count,
393 if (bytes_pending_raster) 519 tasks_required_for_activation_.size());
394 ScheduleCheckForCompletedRasterTasks(); 520 // Schedule OnRasterTasksRequiredForActivationFinished call only when
521 // notification is pending and throttling is not preventing all pending
522 // tasks required for activation from being scheduled.
523 if (scheduled_raster_task_required_for_activation_count ==
524 tasks_required_for_activation_.size() &&
525 should_notify_client_if_no_tasks_required_for_activation_are_pending_) {
526 new_raster_required_for_activation_finished_task =
527 CreateRasterRequiredForActivationFinishedTask();
528 internal::GraphNode* raster_required_for_activation_finished_node =
529 CreateGraphNodeForTask(
530 new_raster_required_for_activation_finished_task.get(),
531 0u, // Priority 0
532 &graph);
533 AddDependenciesToGraphNode(
534 raster_required_for_activation_finished_node,
535 tasks[REQUIRED_FOR_ACTIVATION_TYPE].container());
536 }
537
538 scoped_refptr<internal::WorkerPoolTask> new_raster_finished_task;
539
540 size_t scheduled_raster_task_count =
541 tasks[PREPAINT_TYPE].container().size() +
542 tasks[REQUIRED_FOR_ACTIVATION_TYPE].container().size();
543 DCHECK_LE(scheduled_raster_task_count, PendingRasterTaskCount());
544 // Schedule OnRasterTasksFinished call only when notification is pending
545 // and throttling is not preventing all pending tasks from being scheduled.
546 if (scheduled_raster_task_count == PendingRasterTaskCount() &&
547 should_notify_client_if_no_tasks_are_pending_) {
548 new_raster_finished_task = CreateRasterFinishedTask();
549 internal::GraphNode* raster_finished_node =
550 CreateGraphNodeForTask(new_raster_finished_task.get(),
551 1u, // Priority 1
552 &graph);
553 for (unsigned type = 0; type < NUM_TYPES; ++type) {
554 AddDependenciesToGraphNode(
555 raster_finished_node,
556 tasks[type].container());
557 }
558 }
559
560 SetTaskGraph(&graph);
561
562 scheduled_raster_task_count_ = scheduled_raster_task_count;
563
564 set_raster_finished_task(new_raster_finished_task);
565 set_raster_required_for_activation_finished_task(
566 new_raster_required_for_activation_finished_task);
395 } 567 }
396 568
397 void PixelBufferRasterWorkerPool::OnRasterTaskCompleted( 569 void PixelBufferRasterWorkerPool::OnRasterTaskCompleted(
398 scoped_refptr<internal::RasterWorkerPoolTask> task, 570 scoped_refptr<internal::RasterWorkerPoolTask> task,
399 bool was_canceled, 571 bool was_canceled,
400 bool needs_upload) { 572 bool needs_upload) {
401 TRACE_EVENT2("cc", "PixelBufferRasterWorkerPool::OnRasterTaskCompleted", 573 TRACE_EVENT2("cc", "PixelBufferRasterWorkerPool::OnRasterTaskCompleted",
402 "was_canceled", was_canceled, 574 "was_canceled", was_canceled,
403 "needs_upload", needs_upload); 575 "needs_upload", needs_upload);
404 576
405 DCHECK(pixel_buffer_tasks_.find(task.get()) != pixel_buffer_tasks_.end()); 577 DCHECK(pixel_buffer_tasks_.find(task.get()) != pixel_buffer_tasks_.end());
406 578
407 // Balanced with MapPixelBuffer() call in ScheduleMoreTasks(). 579 // Balanced with MapPixelBuffer() call in ScheduleMoreTasks().
408 resource_provider()->UnmapPixelBuffer(task->resource()->id()); 580 resource_provider()->UnmapPixelBuffer(task->resource()->id());
409 581
410 if (!needs_upload) { 582 if (!needs_upload) {
411 resource_provider()->ReleasePixelBuffer(task->resource()->id()); 583 resource_provider()->ReleasePixelBuffer(task->resource()->id());
412 task->DidRun(was_canceled); 584 task->DidRun(was_canceled);
413 DCHECK(std::find(completed_tasks_.begin(), 585 DCHECK(std::find(completed_tasks_.begin(),
414 completed_tasks_.end(), 586 completed_tasks_.end(),
415 task) == completed_tasks_.end()); 587 task) == completed_tasks_.end());
416 completed_tasks_.push_back(task); 588 completed_tasks_.push_back(task);
589 tasks_required_for_activation_.erase(task);
417 return; 590 return;
418 } 591 }
419 592
420 resource_provider()->BeginSetPixels(task->resource()->id()); 593 resource_provider()->BeginSetPixels(task->resource()->id());
421 has_performed_uploads_since_last_flush_ = true; 594 has_performed_uploads_since_last_flush_ = true;
422 595
423 bytes_pending_upload_ += task->resource()->bytes(); 596 bytes_pending_upload_ += task->resource()->bytes();
424 tasks_with_pending_upload_.push_back(task); 597 tasks_with_pending_upload_.push_back(task);
425 } 598 }
426 599
600 unsigned PixelBufferRasterWorkerPool::PendingRasterTaskCount() const {
601 unsigned num_completed_raster_tasks =
602 tasks_with_pending_upload_.size() + completed_tasks_.size();
603 DCHECK_GE(pixel_buffer_tasks_.size(), num_completed_raster_tasks);
604 return pixel_buffer_tasks_.size() - num_completed_raster_tasks;
605 }
606
607 bool PixelBufferRasterWorkerPool::HasPendingTasks() const {
608 return PendingRasterTaskCount() || !tasks_with_pending_upload_.empty();
609 }
610
611 bool PixelBufferRasterWorkerPool::HasPendingTasksRequiredForActivation() const {
612 return !tasks_required_for_activation_.empty();
613 }
614
615 const char* PixelBufferRasterWorkerPool::StateName() const {
616 if (scheduled_raster_task_count_)
617 return "rasterizing";
618 if (PendingRasterTaskCount())
619 return "throttled";
620 if (!tasks_with_pending_upload_.empty())
621 return "waiting_for_uploads";
622
623 return "finishing";
624 }
625
626 scoped_ptr<base::Value> PixelBufferRasterWorkerPool::StateAsValue() const {
627 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue);
628
629 state->SetInteger("completed_count", completed_tasks_.size());
630 state->SetInteger("pending_count", pixel_buffer_tasks_.size());
631 state->SetInteger("pending_upload_count", tasks_with_pending_upload_.size());
632 state->SetInteger("required_for_activation_count",
633 tasks_required_for_activation_.size());
634 state->Set("scheduled_state", ScheduledStateAsValue().release());
635 state->Set("throttle_state", ThrottleStateAsValue().release());
636 return state.PassAs<base::Value>();
637 }
638
639 scoped_ptr<base::Value> PixelBufferRasterWorkerPool::ThrottleStateAsValue()
640 const {
641 scoped_ptr<base::DictionaryValue> throttle_state(new base::DictionaryValue);
642
643 throttle_state->SetInteger("bytes_available_for_upload",
644 kMaxPendingUploadBytes - bytes_pending_upload_);
645 throttle_state->SetInteger("bytes_pending_upload", bytes_pending_upload_);
646 throttle_state->SetInteger("scheduled_raster_task_count",
647 scheduled_raster_task_count_);
648 return throttle_state.PassAs<base::Value>();
649 }
650
427 } // namespace cc 651 } // namespace cc
OLDNEW
« no previous file with comments | « cc/resources/pixel_buffer_raster_worker_pool.h ('k') | cc/resources/raster_worker_pool.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698