1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "cc/resources/pixel_buffer_raster_worker_pool.h" 6 7 #include "base/containers/stack_container.h" 8 #include "base/debug/trace_event.h" 9 #include "base/values.h" 10 #include "cc/debug/traced_value.h" 11 #include "cc/resources/resource.h" 12 #include "third_party/skia/include/core/SkDevice.h" 13 14 namespace cc { 15 16 namespace { 17 18 class PixelBufferWorkerPoolTaskImpl : public internal::WorkerPoolTask { 19 public: 20 typedef base::Callback<void(bool was_canceled, bool needs_upload)> Reply; 21 22 PixelBufferWorkerPoolTaskImpl(internal::RasterWorkerPoolTask* task, 23 uint8_t* buffer, 24 const Reply& reply) 25 : task_(task), 26 buffer_(buffer), 27 reply_(reply), 28 needs_upload_(false) { 29 } 30 31 // Overridden from internal::WorkerPoolTask: 32 virtual void RunOnWorkerThread(unsigned thread_index) OVERRIDE { 33 // |buffer_| can be NULL in lost context situations. 34 if (!buffer_) { 35 // |needs_upload_| still needs to be true as task has not 36 // been canceled. 37 needs_upload_ = true; 38 return; 39 } 40 SkBitmap bitmap; 41 bitmap.setConfig(SkBitmap::kARGB_8888_Config, 42 task_->resource()->size().width(), 43 task_->resource()->size().height()); 44 bitmap.setPixels(buffer_); 45 SkDevice device(bitmap); 46 needs_upload_ = task_->RunOnWorkerThread(&device, thread_index); 47 } 48 virtual void CompleteOnOriginThread() OVERRIDE { 49 // |needs_upload_| must be be false if task didn't run. 50 DCHECK(HasFinishedRunning() || !needs_upload_); 51 reply_.Run(!HasFinishedRunning(), needs_upload_); 52 } 53 54 private: 55 virtual ~PixelBufferWorkerPoolTaskImpl() {} 56 57 scoped_refptr<internal::RasterWorkerPoolTask> task_; 58 uint8_t* buffer_; 59 const Reply reply_; 60 bool needs_upload_; 61 62 DISALLOW_COPY_AND_ASSIGN(PixelBufferWorkerPoolTaskImpl); 63 }; 64 65 // If we raster too fast we become upload bound, and pending 66 // uploads consume memory. For maximum upload throughput, we would 67 // want to allow for upload_throughput * pipeline_time of pending 68 // uploads, after which we are just wasting memory. Since we don't 69 // know our upload throughput yet, this just caps our memory usage. 70 #if defined(OS_ANDROID) 71 // For reference Nexus10 can upload 1MB in about 2.5ms. 72 const size_t kMaxBytesUploadedPerMs = (2 * 1024 * 1024) / 5; 73 #else 74 // For reference Chromebook Pixel can upload 1MB in about 0.5ms. 75 const size_t kMaxBytesUploadedPerMs = 1024 * 1024 * 2; 76 #endif 77 78 // Assuming a two frame deep pipeline. 79 const size_t kMaxPendingUploadBytes = 16 * 2 * kMaxBytesUploadedPerMs; 80 81 const int kCheckForCompletedRasterTasksDelayMs = 6; 82 83 const size_t kMaxScheduledRasterTasks = 48; 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 } 99 100 // Only used as std::find_if predicate for DCHECKs. 101 bool WasCanceled(const internal::RasterWorkerPoolTask* task) { 102 return task->WasCanceled(); 103 } 104 105 } // namespace 106 107 PixelBufferRasterWorkerPool::PixelBufferRasterWorkerPool( 108 ResourceProvider* resource_provider, 109 size_t num_threads) 110 : RasterWorkerPool(resource_provider, num_threads), 111 shutdown_(false), 112 scheduled_raster_task_count_(0), 113 bytes_pending_upload_(0), 114 has_performed_uploads_since_last_flush_(false), 115 check_for_completed_raster_tasks_pending_(false), 116 should_notify_client_if_no_tasks_are_pending_(false), 117 should_notify_client_if_no_tasks_required_for_activation_are_pending_( 118 false) { 119 } 120 121 PixelBufferRasterWorkerPool::~PixelBufferRasterWorkerPool() { 122 DCHECK(shutdown_); 123 DCHECK(!check_for_completed_raster_tasks_pending_); 124 DCHECK_EQ(0u, pixel_buffer_tasks_.size()); 125 DCHECK_EQ(0u, tasks_with_pending_upload_.size()); 126 DCHECK_EQ(0u, completed_tasks_.size()); 127 } 128 129 void PixelBufferRasterWorkerPool::Shutdown() { 130 shutdown_ = true; 131 RasterWorkerPool::Shutdown(); 132 RasterWorkerPool::CheckForCompletedTasks(); 133 CheckForCompletedUploads(); 134 check_for_completed_raster_tasks_callback_.Cancel(); 135 check_for_completed_raster_tasks_pending_ = false; 136 for (TaskMap::iterator it = pixel_buffer_tasks_.begin(); 137 it != pixel_buffer_tasks_.end(); ++it) { 138 internal::RasterWorkerPoolTask* task = it->first; 139 internal::WorkerPoolTask* pixel_buffer_task = it->second.get(); 140 141 // All inactive tasks needs to be canceled. 142 if (!pixel_buffer_task && !task->HasFinishedRunning()) { 143 task->DidRun(true); 144 completed_tasks_.push_back(task); 145 } 146 } 147 DCHECK_EQ(completed_tasks_.size(), pixel_buffer_tasks_.size()); 148 } 149 150 void PixelBufferRasterWorkerPool::ScheduleTasks(RasterTask::Queue* queue) { 151 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleTasks"); 152 153 RasterWorkerPool::SetRasterTasks(queue); 154 155 if (!should_notify_client_if_no_tasks_are_pending_) 156 TRACE_EVENT_ASYNC_BEGIN0("cc", "ScheduledTasks", this); 157 158 should_notify_client_if_no_tasks_are_pending_ = true; 159 should_notify_client_if_no_tasks_required_for_activation_are_pending_ = true; 160 161 // Build new pixel buffer task set. 162 TaskMap new_pixel_buffer_tasks; 163 for (RasterTaskVector::const_iterator it = raster_tasks().begin(); 164 it != raster_tasks().end(); ++it) { 165 internal::RasterWorkerPoolTask* task = it->get(); 166 DCHECK(new_pixel_buffer_tasks.find(task) == new_pixel_buffer_tasks.end()); 167 DCHECK(!task->HasCompleted()); 168 169 // Use existing pixel buffer task if available. 170 TaskMap::iterator pixel_buffer_it = pixel_buffer_tasks_.find(task); 171 if (pixel_buffer_it == pixel_buffer_tasks_.end()) { 172 new_pixel_buffer_tasks[task] = NULL; 173 continue; 174 } 175 176 new_pixel_buffer_tasks[task] = pixel_buffer_it->second; 177 pixel_buffer_tasks_.erase(task); 178 } 179 180 // Transfer remaining pixel buffer tasks to |new_pixel_buffer_tasks| 181 // and cancel all remaining inactive tasks. 182 for (TaskMap::iterator it = pixel_buffer_tasks_.begin(); 183 it != pixel_buffer_tasks_.end(); ++it) { 184 internal::RasterWorkerPoolTask* task = it->first; 185 internal::WorkerPoolTask* pixel_buffer_task = it->second.get(); 186 187 // Move task to |new_pixel_buffer_tasks| 188 new_pixel_buffer_tasks[task] = pixel_buffer_task; 189 190 // Inactive task can be canceled. 191 if (!pixel_buffer_task && !task->HasFinishedRunning()) { 192 task->DidRun(true); 193 DCHECK(std::find(completed_tasks_.begin(), 194 completed_tasks_.end(), 195 task) == completed_tasks_.end()); 196 completed_tasks_.push_back(task); 197 } 198 } 199 200 tasks_required_for_activation_.clear(); 201 for (TaskMap::iterator it = new_pixel_buffer_tasks.begin(); 202 it != new_pixel_buffer_tasks.end(); ++it) { 203 internal::RasterWorkerPoolTask* task = it->first; 204 if (IsRasterTaskRequiredForActivation(task)) 205 tasks_required_for_activation_.insert(task); 206 } 207 208 // |tasks_required_for_activation_| contains all tasks that need to 209 // complete before we can send a "ready to activate" signal. Tasks 210 // that have already completed should not be part of this set. 211 for (TaskDeque::const_iterator it = completed_tasks_.begin(); 212 it != completed_tasks_.end(); ++it) { 213 tasks_required_for_activation_.erase(*it); 214 } 215 216 pixel_buffer_tasks_.swap(new_pixel_buffer_tasks); 217 218 // Check for completed tasks when ScheduleTasks() is called as 219 // priorities might have changed and this maximizes the number 220 // of top priority tasks that are scheduled. 221 RasterWorkerPool::CheckForCompletedTasks(); 222 CheckForCompletedUploads(); 223 FlushUploads(); 224 225 // Schedule new tasks. 226 ScheduleMoreTasks(); 227 228 // Cancel any pending check for completed raster tasks and schedule 229 // another check. 230 check_for_completed_raster_tasks_callback_.Cancel(); 231 check_for_completed_raster_tasks_pending_ = false; 232 ScheduleCheckForCompletedRasterTasks(); 233 234 TRACE_EVENT_ASYNC_STEP1( 235 "cc", "ScheduledTasks", this, StateName(), 236 "state", TracedValue::FromValue(StateAsValue().release())); 237 } 238 239 void PixelBufferRasterWorkerPool::CheckForCompletedTasks() { 240 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::CheckForCompletedTasks"); 241 242 RasterWorkerPool::CheckForCompletedTasks(); 243 CheckForCompletedUploads(); 244 FlushUploads(); 245 246 TaskDeque completed_tasks; 247 completed_tasks_.swap(completed_tasks); 248 249 while (!completed_tasks.empty()) { 250 internal::RasterWorkerPoolTask* task = completed_tasks.front().get(); 251 DCHECK(pixel_buffer_tasks_.find(task) != pixel_buffer_tasks_.end()); 252 253 pixel_buffer_tasks_.erase(task); 254 255 task->WillComplete(); 256 task->CompleteOnOriginThread(); 257 task->DidComplete(); 258 259 completed_tasks.pop_front(); 260 } 261 } 262 263 void PixelBufferRasterWorkerPool::OnRasterTasksFinished() { 264 // |should_notify_client_if_no_tasks_are_pending_| can be set to false as 265 // a result of a scheduled CheckForCompletedRasterTasks() call. No need to 266 // perform another check in that case as we've already notified the client. 267 if (!should_notify_client_if_no_tasks_are_pending_) 268 return; 269 270 // Call CheckForCompletedRasterTasks() when we've finished running all 271 // raster tasks needed since last time ScheduleTasks() was called. 272 // This reduces latency between the time when all tasks have finished 273 // running and the time when the client is notified. 274 CheckForCompletedRasterTasks(); 275 } 276 277 void PixelBufferRasterWorkerPool::OnRasterTasksRequiredForActivationFinished() { 278 // Analogous to OnRasterTasksFinished(), there's no need to call 279 // CheckForCompletedRasterTasks() if the client has already been notified. 280 if (!should_notify_client_if_no_tasks_required_for_activation_are_pending_) 281 return; 282 283 // This reduces latency between the time when all tasks required for 284 // activation have finished running and the time when the client is 285 // notified. 286 CheckForCompletedRasterTasks(); 287 } 288 289 void PixelBufferRasterWorkerPool::FlushUploads() { 290 if (!has_performed_uploads_since_last_flush_) 291 return; 292 293 resource_provider()->ShallowFlushIfSupported(); 294 has_performed_uploads_since_last_flush_ = false; 295 } 296 297 void PixelBufferRasterWorkerPool::CheckForCompletedUploads() { 298 TaskDeque tasks_with_completed_uploads; 299 300 // First check if any have completed. 301 while (!tasks_with_pending_upload_.empty()) { 302 internal::RasterWorkerPoolTask* task = 303 tasks_with_pending_upload_.front().get(); 304 305 // Uploads complete in the order they are issued. 306 if (!resource_provider()->DidSetPixelsComplete(task->resource()->id())) 307 break; 308 309 tasks_with_completed_uploads.push_back(task); 310 tasks_with_pending_upload_.pop_front(); 311 } 312 313 DCHECK(client()); 314 bool should_force_some_uploads_to_complete = 315 shutdown_ || client()->ShouldForceTasksRequiredForActivationToComplete(); 316 317 if (should_force_some_uploads_to_complete) { 318 TaskDeque tasks_with_uploads_to_force; 319 TaskDeque::iterator it = tasks_with_pending_upload_.begin(); 320 while (it != tasks_with_pending_upload_.end()) { 321 internal::RasterWorkerPoolTask* task = it->get(); 322 DCHECK(pixel_buffer_tasks_.find(task) != pixel_buffer_tasks_.end()); 323 324 // Force all uploads required for activation to complete. 325 // During shutdown, force all pending uploads to complete. 326 if (shutdown_ || IsRasterTaskRequiredForActivation(task)) { 327 tasks_with_uploads_to_force.push_back(task); 328 tasks_with_completed_uploads.push_back(task); 329 it = tasks_with_pending_upload_.erase(it); 330 continue; 331 } 332 333 ++it; 334 } 335 336 // Force uploads in reverse order. Since forcing can cause a wait on 337 // all previous uploads, we would rather wait only once downstream. 338 for (TaskDeque::reverse_iterator it = tasks_with_uploads_to_force.rbegin(); 339 it != tasks_with_uploads_to_force.rend(); 340 ++it) { 341 resource_provider()->ForceSetPixelsToComplete((*it)->resource()->id()); 342 has_performed_uploads_since_last_flush_ = true; 343 } 344 } 345 346 // Release shared memory and move tasks with completed uploads 347 // to |completed_tasks_|. 348 while (!tasks_with_completed_uploads.empty()) { 349 internal::RasterWorkerPoolTask* task = 350 tasks_with_completed_uploads.front().get(); 351 352 // It's now safe to release the pixel buffer and the shared memory. 353 resource_provider()->ReleasePixelBuffer(task->resource()->id()); 354 355 bytes_pending_upload_ -= task->resource()->bytes(); 356 357 task->DidRun(false); 358 359 DCHECK(std::find(completed_tasks_.begin(), 360 completed_tasks_.end(), 361 task) == completed_tasks_.end()); 362 completed_tasks_.push_back(task); 363 364 tasks_required_for_activation_.erase(task); 365 366 tasks_with_completed_uploads.pop_front(); 367 } 368 } 369 370 void PixelBufferRasterWorkerPool::ScheduleCheckForCompletedRasterTasks() { 371 if (check_for_completed_raster_tasks_pending_) 372 return; 373 374 check_for_completed_raster_tasks_callback_.Reset( 375 base::Bind(&PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks, 376 base::Unretained(this))); 377 base::MessageLoopProxy::current()->PostDelayedTask( 378 FROM_HERE, 379 check_for_completed_raster_tasks_callback_.callback(), 380 base::TimeDelta::FromMilliseconds(kCheckForCompletedRasterTasksDelayMs)); 381 check_for_completed_raster_tasks_pending_ = true; 382 } 383 384 void PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks() { 385 TRACE_EVENT0( 386 "cc", "PixelBufferRasterWorkerPool::CheckForCompletedRasterTasks"); 387 388 DCHECK(should_notify_client_if_no_tasks_are_pending_); 389 390 check_for_completed_raster_tasks_callback_.Cancel(); 391 check_for_completed_raster_tasks_pending_ = false; 392 393 RasterWorkerPool::CheckForCompletedTasks(); 394 CheckForCompletedUploads(); 395 FlushUploads(); 396 397 // Determine what client notifications to generate. 398 bool will_notify_client_that_no_tasks_required_for_activation_are_pending = 399 (should_notify_client_if_no_tasks_required_for_activation_are_pending_ && 400 !HasPendingTasksRequiredForActivation()); 401 bool will_notify_client_that_no_tasks_are_pending = 402 (should_notify_client_if_no_tasks_are_pending_ && 403 !HasPendingTasks()); 404 405 // Adjust the need to generate notifications before scheduling more tasks. 406 should_notify_client_if_no_tasks_required_for_activation_are_pending_ &= 407 !will_notify_client_that_no_tasks_required_for_activation_are_pending; 408 should_notify_client_if_no_tasks_are_pending_ &= 409 !will_notify_client_that_no_tasks_are_pending; 410 411 scheduled_raster_task_count_ = 0; 412 if (PendingRasterTaskCount()) 413 ScheduleMoreTasks(); 414 415 TRACE_EVENT_ASYNC_STEP1( 416 "cc", "ScheduledTasks", this, StateName(), 417 "state", TracedValue::FromValue(StateAsValue().release())); 418 419 // Schedule another check for completed raster tasks while there are 420 // pending raster tasks or pending uploads. 421 if (HasPendingTasks()) 422 ScheduleCheckForCompletedRasterTasks(); 423 424 // Generate client notifications. 425 if (will_notify_client_that_no_tasks_required_for_activation_are_pending) { 426 DCHECK(std::find_if(raster_tasks_required_for_activation().begin(), 427 raster_tasks_required_for_activation().end(), 428 WasCanceled) == 429 raster_tasks_required_for_activation().end()); 430 client()->DidFinishRunningTasksRequiredForActivation(); 431 } 432 if (will_notify_client_that_no_tasks_are_pending) { 433 TRACE_EVENT_ASYNC_END0("cc", "ScheduledTasks", this); 434 DCHECK(!HasPendingTasksRequiredForActivation()); 435 client()->DidFinishRunningTasks(); 436 } 437 } 438 439 void PixelBufferRasterWorkerPool::ScheduleMoreTasks() { 440 TRACE_EVENT0("cc", "PixelBufferRasterWorkerPool::ScheduleMoreTasks"); 441 442 enum RasterTaskType { 443 PREPAINT_TYPE = 0, 444 REQUIRED_FOR_ACTIVATION_TYPE = 1, 445 NUM_TYPES = 2 446 }; 447 NodeVector tasks[NUM_TYPES]; 448 unsigned priority = 2u; // 0-1 reserved for RasterFinished tasks. 449 TaskGraph graph; 450 451 size_t bytes_pending_upload = bytes_pending_upload_; 452 453 for (RasterTaskVector::const_iterator it = raster_tasks().begin(); 454 it != raster_tasks().end(); ++it) { 455 internal::RasterWorkerPoolTask* task = it->get(); 456 457 // |pixel_buffer_tasks_| contains all tasks that have not yet completed. 458 TaskMap::iterator pixel_buffer_it = pixel_buffer_tasks_.find(task); 459 if (pixel_buffer_it == pixel_buffer_tasks_.end()) 460 continue; 461 462 // HasFinishedRunning() will return true when set pixels has completed. 463 if (task->HasFinishedRunning()) { 464 DCHECK(std::find(completed_tasks_.begin(), 465 completed_tasks_.end(), 466 task) != completed_tasks_.end()); 467 continue; 468 } 469 470 // All raster tasks need to be throttled by bytes of pending uploads. 471 size_t new_bytes_pending_upload = bytes_pending_upload; 472 new_bytes_pending_upload += task->resource()->bytes(); 473 if (new_bytes_pending_upload > kMaxPendingUploadBytes) 474 break; 475 476 internal::WorkerPoolTask* pixel_buffer_task = pixel_buffer_it->second.get(); 477 478 // If raster has finished, just update |bytes_pending_upload|. 479 if (pixel_buffer_task && pixel_buffer_task->HasCompleted()) { 480 bytes_pending_upload = new_bytes_pending_upload; 481 continue; 482 } 483 484 // Throttle raster tasks based on kMaxScheduledRasterTasks. 485 size_t scheduled_raster_task_count = 486 tasks[PREPAINT_TYPE].container().size() + 487 tasks[REQUIRED_FOR_ACTIVATION_TYPE].container().size(); 488 if (scheduled_raster_task_count >= kMaxScheduledRasterTasks) 489 break; 490 491 // Update |bytes_pending_upload| now that task has cleared all 492 // throttling limits. 493 bytes_pending_upload = new_bytes_pending_upload; 494 495 RasterTaskType type = IsRasterTaskRequiredForActivation(task) ? 496 REQUIRED_FOR_ACTIVATION_TYPE : 497 PREPAINT_TYPE; 498 499 // Use existing pixel buffer task if available. 500 if (pixel_buffer_task) { 501 tasks[type].container().push_back( 502 CreateGraphNodeForRasterTask(pixel_buffer_task, 503 task->dependencies(), 504 priority++, 505 &graph)); 506 continue; 507 } 508 509 // Request a pixel buffer. This will reserve shared memory. 510 resource_provider()->AcquirePixelBuffer(task->resource()->id()); 511 512 // MapPixelBuffer() returns NULL if context was lost at the time 513 // AcquirePixelBuffer() was called. For simplicity we still post 514 // a raster task that is essentially a noop in these situations. 515 uint8* buffer = resource_provider()->MapPixelBuffer( 516 task->resource()->id()); 517 518 scoped_refptr<internal::WorkerPoolTask> new_pixel_buffer_task( 519 new PixelBufferWorkerPoolTaskImpl( 520 task, 521 buffer, 522 base::Bind(&PixelBufferRasterWorkerPool::OnRasterTaskCompleted, 523 base::Unretained(this), 524 make_scoped_refptr(task)))); 525 pixel_buffer_tasks_[task] = new_pixel_buffer_task; 526 tasks[type].container().push_back( 527 CreateGraphNodeForRasterTask(new_pixel_buffer_task.get(), 528 task->dependencies(), 529 priority++, 530 &graph)); 531 } 532 533 scoped_refptr<internal::WorkerPoolTask> 534 new_raster_required_for_activation_finished_task; 535 536 size_t scheduled_raster_task_required_for_activation_count = 537 tasks[REQUIRED_FOR_ACTIVATION_TYPE].container().size(); 538 DCHECK_LE(scheduled_raster_task_required_for_activation_count, 539 tasks_required_for_activation_.size()); 540 // Schedule OnRasterTasksRequiredForActivationFinished call only when 541 // notification is pending and throttling is not preventing all pending 542 // tasks required for activation from being scheduled. 543 if (scheduled_raster_task_required_for_activation_count == 544 tasks_required_for_activation_.size() && 545 should_notify_client_if_no_tasks_required_for_activation_are_pending_) { 546 new_raster_required_for_activation_finished_task = 547 CreateRasterRequiredForActivationFinishedTask(); 548 internal::GraphNode* raster_required_for_activation_finished_node = 549 CreateGraphNodeForTask( 550 new_raster_required_for_activation_finished_task.get(), 551 0u, // Priority 0 552 &graph); 553 AddDependenciesToGraphNode( 554 raster_required_for_activation_finished_node, 555 tasks[REQUIRED_FOR_ACTIVATION_TYPE].container()); 556 } 557 558 scoped_refptr<internal::WorkerPoolTask> new_raster_finished_task; 559 560 size_t scheduled_raster_task_count = 561 tasks[PREPAINT_TYPE].container().size() + 562 tasks[REQUIRED_FOR_ACTIVATION_TYPE].container().size(); 563 DCHECK_LE(scheduled_raster_task_count, PendingRasterTaskCount()); 564 // Schedule OnRasterTasksFinished call only when notification is pending 565 // and throttling is not preventing all pending tasks from being scheduled. 566 if (scheduled_raster_task_count == PendingRasterTaskCount() && 567 should_notify_client_if_no_tasks_are_pending_) { 568 new_raster_finished_task = CreateRasterFinishedTask(); 569 internal::GraphNode* raster_finished_node = 570 CreateGraphNodeForTask(new_raster_finished_task.get(), 571 1u, // Priority 1 572 &graph); 573 for (unsigned type = 0; type < NUM_TYPES; ++type) { 574 AddDependenciesToGraphNode( 575 raster_finished_node, 576 tasks[type].container()); 577 } 578 } 579 580 SetTaskGraph(&graph); 581 582 scheduled_raster_task_count_ = scheduled_raster_task_count; 583 584 set_raster_finished_task(new_raster_finished_task); 585 set_raster_required_for_activation_finished_task( 586 new_raster_required_for_activation_finished_task); 587 } 588 589 void PixelBufferRasterWorkerPool::OnRasterTaskCompleted( 590 scoped_refptr<internal::RasterWorkerPoolTask> task, 591 bool was_canceled, 592 bool needs_upload) { 593 DCHECK(pixel_buffer_tasks_.find(task.get()) != pixel_buffer_tasks_.end()); 594 595 // Balanced with MapPixelBuffer() call in ScheduleMoreTasks(). 596 resource_provider()->UnmapPixelBuffer(task->resource()->id()); 597 598 if (!needs_upload) { 599 resource_provider()->ReleasePixelBuffer(task->resource()->id()); 600 601 if (was_canceled) { 602 // When priorites change, a raster task can be canceled as a result of 603 // no longer being of high enough priority to fit in our throttled 604 // raster task budget. The task has not yet completed in this case. 605 RasterTaskVector::const_iterator it = std::find(raster_tasks().begin(), 606 raster_tasks().end(), 607 task); 608 if (it != raster_tasks().end()) { 609 pixel_buffer_tasks_[task.get()] = NULL; 610 return; 611 } 612 } 613 614 task->DidRun(was_canceled); 615 DCHECK(std::find(completed_tasks_.begin(), 616 completed_tasks_.end(), 617 task) == completed_tasks_.end()); 618 completed_tasks_.push_back(task); 619 tasks_required_for_activation_.erase(task); 620 return; 621 } 622 623 DCHECK(!was_canceled); 624 625 resource_provider()->BeginSetPixels(task->resource()->id()); 626 has_performed_uploads_since_last_flush_ = true; 627 628 bytes_pending_upload_ += task->resource()->bytes(); 629 tasks_with_pending_upload_.push_back(task); 630 } 631 632 unsigned PixelBufferRasterWorkerPool::PendingRasterTaskCount() const { 633 unsigned num_completed_raster_tasks = 634 tasks_with_pending_upload_.size() + completed_tasks_.size(); 635 DCHECK_GE(pixel_buffer_tasks_.size(), num_completed_raster_tasks); 636 return pixel_buffer_tasks_.size() - num_completed_raster_tasks; 637 } 638 639 bool PixelBufferRasterWorkerPool::HasPendingTasks() const { 640 return PendingRasterTaskCount() || !tasks_with_pending_upload_.empty(); 641 } 642 643 bool PixelBufferRasterWorkerPool::HasPendingTasksRequiredForActivation() const { 644 return !tasks_required_for_activation_.empty(); 645 } 646 647 const char* PixelBufferRasterWorkerPool::StateName() const { 648 if (scheduled_raster_task_count_) 649 return "rasterizing"; 650 if (PendingRasterTaskCount()) 651 return "throttled"; 652 if (!tasks_with_pending_upload_.empty()) 653 return "waiting_for_uploads"; 654 655 return "finishing"; 656 } 657 658 scoped_ptr<base::Value> PixelBufferRasterWorkerPool::StateAsValue() const { 659 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue); 660 661 state->SetInteger("completed_count", completed_tasks_.size()); 662 state->SetInteger("pending_count", pixel_buffer_tasks_.size()); 663 state->SetInteger("pending_upload_count", tasks_with_pending_upload_.size()); 664 state->SetInteger("required_for_activation_count", 665 tasks_required_for_activation_.size()); 666 state->Set("scheduled_state", ScheduledStateAsValue().release()); 667 state->Set("throttle_state", ThrottleStateAsValue().release()); 668 return state.PassAs<base::Value>(); 669 } 670 671 scoped_ptr<base::Value> PixelBufferRasterWorkerPool::ThrottleStateAsValue() 672 const { 673 scoped_ptr<base::DictionaryValue> throttle_state(new base::DictionaryValue); 674 675 throttle_state->SetInteger("bytes_available_for_upload", 676 kMaxPendingUploadBytes - bytes_pending_upload_); 677 throttle_state->SetInteger("bytes_pending_upload", bytes_pending_upload_); 678 throttle_state->SetInteger("scheduled_raster_task_count", 679 scheduled_raster_task_count_); 680 return throttle_state.PassAs<base::Value>(); 681 } 682 683 } // namespace cc 684