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

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

Issue 14689004: Re-land: cc: Cancel and re-prioritize worker pool tasks. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Added support for dependencies and tests. Created 7 years, 7 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 | Annotate | Revision Log
OLDNEW
1 // Copyright 2012 The Chromium Authors. All rights reserved. 1 // Copyright 2012 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/tile_manager.h" 5 #include "cc/resources/tile_manager.h"
6 6
7 #include <algorithm> 7 #include <algorithm>
8 #include <string> 8 #include <string>
9 9
10 #include "base/bind.h" 10 #include "base/bind.h"
(...skipping 115 matching lines...) Expand 10 before | Expand all | Expand 10 after
126 TileManagerClient* client, 126 TileManagerClient* client,
127 ResourceProvider* resource_provider, 127 ResourceProvider* resource_provider,
128 scoped_ptr<RasterWorkerPool> raster_worker_pool, 128 scoped_ptr<RasterWorkerPool> raster_worker_pool,
129 size_t num_raster_threads, 129 size_t num_raster_threads,
130 bool use_color_estimator, 130 bool use_color_estimator,
131 RenderingStatsInstrumentation* rendering_stats_instrumentation) 131 RenderingStatsInstrumentation* rendering_stats_instrumentation)
132 : client_(client), 132 : client_(client),
133 resource_pool_(ResourcePool::Create(resource_provider)), 133 resource_pool_(ResourcePool::Create(resource_provider)),
134 raster_worker_pool_(raster_worker_pool.Pass()), 134 raster_worker_pool_(raster_worker_pool.Pass()),
135 manage_tiles_pending_(false), 135 manage_tiles_pending_(false),
136 manage_tiles_call_count_(0),
137 bytes_pending_upload_(0), 136 bytes_pending_upload_(0),
138 has_performed_uploads_since_last_flush_(false), 137 has_performed_uploads_since_last_flush_(false),
139 ever_exceeded_memory_budget_(false), 138 ever_exceeded_memory_budget_(false),
140 rendering_stats_instrumentation_(rendering_stats_instrumentation), 139 rendering_stats_instrumentation_(rendering_stats_instrumentation),
141 use_color_estimator_(use_color_estimator), 140 use_color_estimator_(use_color_estimator),
142 did_initialize_visible_tile_(false), 141 did_initialize_visible_tile_(false),
143 pending_tasks_(0),
144 max_pending_tasks_(kMaxNumPendingTasksPerThread * num_raster_threads) { 142 max_pending_tasks_(kMaxNumPendingTasksPerThread * num_raster_threads) {
145 raster_worker_pool_->SetClient(this); 143 raster_worker_pool_->SetClient(this);
146 } 144 }
147 145
148 TileManager::~TileManager() { 146 TileManager::~TileManager() {
149 // Reset global state and manage. This should cause 147 // Reset global state and manage. This should cause
150 // our memory usage to drop to zero. 148 // our memory usage to drop to zero.
151 global_state_ = GlobalStateThatImpactsTilePriority(); 149 global_state_ = GlobalStateThatImpactsTilePriority();
152 AssignGpuMemoryToTiles(); 150 AssignGpuMemoryToTiles();
153 // This should finish all pending tasks and release any uninitialized 151 // This should finish all pending tasks and release any uninitialized
(...skipping 142 matching lines...) Expand 10 before | Expand all | Expand 10 after
296 294
297 // Sort by bin, resolution and time until needed. 295 // Sort by bin, resolution and time until needed.
298 std::sort(tiles_.begin(), tiles_.end(), BinComparator()); 296 std::sort(tiles_.begin(), tiles_.end(), BinComparator());
299 } 297 }
300 298
301 void TileManager::ManageTiles() { 299 void TileManager::ManageTiles() {
302 TRACE_EVENT0("cc", "TileManager::ManageTiles"); 300 TRACE_EVENT0("cc", "TileManager::ManageTiles");
303 TRACE_COUNTER_ID1("cc", "TileCount", this, tiles_.size()); 301 TRACE_COUNTER_ID1("cc", "TileCount", this, tiles_.size());
304 302
305 manage_tiles_pending_ = false; 303 manage_tiles_pending_ = false;
306 ++manage_tiles_call_count_;
307 304
308 AssignBinsToTiles(); 305 AssignBinsToTiles();
309 SortTiles(); 306 SortTiles();
310 AssignGpuMemoryToTiles(); 307 AssignGpuMemoryToTiles();
311 308
312 TRACE_EVENT_INSTANT1( 309 TRACE_EVENT_INSTANT1(
313 "cc", "DidManage", TRACE_EVENT_SCOPE_THREAD, 310 "cc", "DidManage", TRACE_EVENT_SCOPE_THREAD,
314 "state", TracedValue::FromValue(BasicStateAsValue().release())); 311 "state", TracedValue::FromValue(BasicStateAsValue().release()));
315 312
316 // Finally, kick the rasterizer. 313 // Finally, schedule rasterizer tasks.
317 DispatchMoreTasks(); 314 ScheduleTasks();
318 } 315 }
319 316
320 void TileManager::CheckForCompletedTileUploads() { 317 void TileManager::CheckForCompletedTileUploads() {
321 while (!tiles_with_pending_upload_.empty()) { 318 while (!tiles_with_pending_upload_.empty()) {
322 Tile* tile = tiles_with_pending_upload_.front(); 319 Tile* tile = tiles_with_pending_upload_.front();
323 DCHECK(tile->drawing_info().resource_); 320 DCHECK(tile->drawing_info().resource_);
324 321
325 // Set pixel tasks complete in the order they are posted. 322 // Set pixel tasks complete in the order they are posted.
326 if (!resource_pool_->resource_provider()->DidSetPixelsComplete( 323 if (!resource_pool_->resource_provider()->DidSetPixelsComplete(
327 tile->drawing_info().resource_->id())) { 324 tile->drawing_info().resource_->id())) {
328 break; 325 break;
329 } 326 }
330 327
331 // It's now safe to release the pixel buffer. 328 // It's now safe to release the pixel buffer.
332 resource_pool_->resource_provider()->ReleasePixelBuffer( 329 resource_pool_->resource_provider()->ReleasePixelBuffer(
333 tile->drawing_info().resource_->id()); 330 tile->drawing_info().resource_->id());
334 331
335 bytes_pending_upload_ -= tile->bytes_consumed_if_allocated(); 332 bytes_pending_upload_ -= tile->bytes_consumed_if_allocated();
336 // Reset forced_upload_ since we now got the upload completed notification. 333 // Reset forced_upload_ since we now got the upload completed notification.
337 tile->drawing_info().forced_upload_ = false; 334 tile->drawing_info().forced_upload_ = false;
338 tile->drawing_info().memory_state_ = USING_RELEASABLE_MEMORY; 335 tile->drawing_info().memory_state_ = USING_RELEASABLE_MEMORY;
339 DidFinishTileInitialization(tile); 336 DidFinishTileInitialization(tile);
340 337
341 tiles_with_pending_upload_.pop(); 338 tiles_with_pending_upload_.pop();
342 } 339 }
343 340
344 DispatchMoreTasks(); 341 ScheduleTasks();
345 } 342 }
346 343
347 void TileManager::AbortPendingTileUploads() { 344 void TileManager::AbortPendingTileUploads() {
348 while (!tiles_with_pending_upload_.empty()) { 345 while (!tiles_with_pending_upload_.empty()) {
349 Tile* tile = tiles_with_pending_upload_.front(); 346 Tile* tile = tiles_with_pending_upload_.front();
350 DCHECK(tile->drawing_info().resource_); 347 DCHECK(tile->drawing_info().resource_);
351 348
352 resource_pool_->resource_provider()->AbortSetPixels( 349 resource_pool_->resource_provider()->AbortSetPixels(
353 tile->drawing_info().resource_->id()); 350 tile->drawing_info().resource_->id());
354 resource_pool_->resource_provider()->ReleasePixelBuffer( 351 resource_pool_->resource_provider()->ReleasePixelBuffer(
(...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after
445 return requirements.PassAs<base::Value>(); 442 return requirements.PassAs<base::Value>();
446 } 443 }
447 444
448 void TileManager::DidFinishDispatchingWorkerPoolCompletionCallbacks() { 445 void TileManager::DidFinishDispatchingWorkerPoolCompletionCallbacks() {
449 // If a flush is needed, do it now before starting to dispatch more tasks. 446 // If a flush is needed, do it now before starting to dispatch more tasks.
450 if (has_performed_uploads_since_last_flush_) { 447 if (has_performed_uploads_since_last_flush_) {
451 resource_pool_->resource_provider()->ShallowFlushIfSupported(); 448 resource_pool_->resource_provider()->ShallowFlushIfSupported();
452 has_performed_uploads_since_last_flush_ = false; 449 has_performed_uploads_since_last_flush_ = false;
453 } 450 }
454 451
455 DispatchMoreTasks(); 452 ScheduleTasks();
456 } 453 }
457 454
458 void TileManager::AssignGpuMemoryToTiles() { 455 void TileManager::AssignGpuMemoryToTiles() {
459 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); 456 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles");
460 size_t unreleasable_bytes = 0; 457 size_t unreleasable_bytes = 0;
461 458
462 // Now give memory out to the tiles until we're out, and build 459 // Now give memory out to the tiles until we're out, and build
463 // the needs-to-be-rasterized queue. 460 // the needs-to-be-rasterized queue.
464 tiles_that_need_to_be_rasterized_.clear(); 461 tiles_that_need_to_be_rasterized_.clear();
465 462
466 // By clearing the tiles_that_need_to_be_rasterized_ vector list 463 // By clearing the tiles_that_need_to_be_rasterized_ vector list
467 // above we move all tiles currently waiting for raster to idle state. 464 // above we move all tiles currently waiting for raster to idle state.
468 // Some memory cannot be released. We figure out how much in this 465 // Some memory cannot be released. We figure out how much in this
469 // loop as well. 466 // loop.
470 for (TileVector::const_iterator it = tiles_.begin(); 467 for (TileVector::const_iterator it = tiles_.begin();
471 it != tiles_.end(); 468 it != tiles_.end();
472 ++it) { 469 ++it) {
473 const Tile* tile = *it; 470 const Tile* tile = *it;
474 if (tile->drawing_info().memory_state_ == USING_UNRELEASABLE_MEMORY) 471 if (tile->drawing_info().memory_state_ == USING_UNRELEASABLE_MEMORY)
475 unreleasable_bytes += tile->bytes_consumed_if_allocated(); 472 unreleasable_bytes += tile->bytes_consumed_if_allocated();
476 } 473 }
477 474
478 // Global state's memory limit can decrease, causing 475 // Global state's memory limit can decrease, causing
479 // it to be less than unreleasable_bytes 476 // it to be less than unreleasable_bytes
480 size_t bytes_allocatable = 477 size_t bytes_allocatable =
481 global_state_.memory_limit_in_bytes > unreleasable_bytes ? 478 global_state_.memory_limit_in_bytes > unreleasable_bytes ?
482 global_state_.memory_limit_in_bytes - unreleasable_bytes : 479 global_state_.memory_limit_in_bytes - unreleasable_bytes :
483 0; 480 0;
484 size_t bytes_that_exceeded_memory_budget_in_now_bin = 0; 481 size_t bytes_that_exceeded_memory_budget_in_now_bin = 0;
485 size_t bytes_left = bytes_allocatable; 482 size_t bytes_left = bytes_allocatable;
486 size_t bytes_oom_in_now_bin_on_pending_tree = 0; 483 size_t bytes_oom_in_now_bin_on_pending_tree = 0;
487 TileVector tiles_requiring_memory_but_oomed; 484 TileVector tiles_requiring_memory_but_oomed;
485 bool higher_priority_tile_oomed = false;
488 for (TileVector::iterator it = tiles_.begin(); 486 for (TileVector::iterator it = tiles_.begin();
489 it != tiles_.end(); 487 it != tiles_.end();
490 ++it) { 488 ++it) {
491 Tile* tile = *it; 489 Tile* tile = *it;
492 ManagedTileState& mts = tile->managed_state(); 490 ManagedTileState& mts = tile->managed_state();
493 ManagedTileState::DrawingInfo& drawing_info = tile->drawing_info(); 491 ManagedTileState::DrawingInfo& drawing_info = tile->drawing_info();
494 492
495 // If this tile doesn't need a resource, or if the memory 493 // If this tile doesn't need a resource, then we do not need
496 // is unreleasable, then we do not need to do anything. 494 // to do anything.
497 if (!drawing_info.requires_resource() || 495 if (!drawing_info.requires_resource())
498 drawing_info.memory_state_ == USING_UNRELEASABLE_MEMORY) { 496 continue;
497
498 size_t tile_bytes = tile->bytes_consumed_if_allocated();
499 // Memory is already reserved for tile with unreleasable memory
500 // so adding it to |tiles_that_need_to_be_rasterized_| doesn't
501 // affect bytes_allocatable.
502 if (drawing_info.memory_state_ == USING_UNRELEASABLE_MEMORY)
503 tile_bytes = 0;
504
505 // If the tile is not needed, free it up.
506 if (mts.is_in_never_bin_on_both_trees()) {
507 if (drawing_info.memory_state_ != USING_UNRELEASABLE_MEMORY) {
508 FreeResourcesForTile(tile);
509 drawing_info.memory_state_ = NOT_ALLOWED_TO_USE_MEMORY;
510 }
499 continue; 511 continue;
500 } 512 }
501 513
502 size_t tile_bytes = tile->bytes_consumed_if_allocated();
503 // If the tile is not needed, free it up.
504 if (mts.is_in_never_bin_on_both_trees()) {
505 FreeResourcesForTile(tile);
506 drawing_info.memory_state_ = NOT_ALLOWED_TO_USE_MEMORY;
507 continue;
508 }
509 // Tile is OOM. 514 // Tile is OOM.
510 if (tile_bytes > bytes_left) { 515 if (tile_bytes > bytes_left) {
511 FreeResourcesForTile(tile);
512 tile->drawing_info().set_rasterize_on_demand(); 516 tile->drawing_info().set_rasterize_on_demand();
513 if (mts.tree_bin[PENDING_TREE] == NOW_BIN) { 517 if (mts.tree_bin[PENDING_TREE] == NOW_BIN) {
514 tiles_requiring_memory_but_oomed.push_back(tile); 518 tiles_requiring_memory_but_oomed.push_back(tile);
515 bytes_oom_in_now_bin_on_pending_tree += tile_bytes; 519 bytes_oom_in_now_bin_on_pending_tree += tile_bytes;
516 } 520 }
521 FreeResourcesForTile(tile);
522 higher_priority_tile_oomed = true;
517 continue; 523 continue;
518 } 524 }
525
519 drawing_info.set_use_resource(); 526 drawing_info.set_use_resource();
520 bytes_left -= tile_bytes; 527 bytes_left -= tile_bytes;
521 if (!drawing_info.resource_ && 528
522 drawing_info.memory_state_ == CAN_USE_MEMORY) { 529 // Tile shouldn't be rasterized if we've failed to assign
530 // gpu memory to a higher priority tile. This is important for
531 // two reasons:
532 // 1. Tile size should not impact raster priority.
533 // 2. Tile with unreleasable memory could otherwise incorrectly
534 // be added as it's not affected by |bytes_allocatable|.
535 if (higher_priority_tile_oomed)
536 continue;
537
538 if (!drawing_info.resource_)
523 tiles_that_need_to_be_rasterized_.push_back(tile); 539 tiles_that_need_to_be_rasterized_.push_back(tile);
524 }
525 } 540 }
526 541
527 // In OOM situation, we iterate tiles_, remove the memory for active tree 542 // In OOM situation, we iterate tiles_, remove the memory for active tree
528 // and not the now bin. And give them to bytes_oom_in_now_bin_on_pending_tree 543 // and not the now bin. And give them to bytes_oom_in_now_bin_on_pending_tree
529 if (!tiles_requiring_memory_but_oomed.empty()) { 544 if (!tiles_requiring_memory_but_oomed.empty()) {
530 size_t bytes_freed = 0; 545 size_t bytes_freed = 0;
531 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { 546 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) {
532 Tile* tile = *it; 547 Tile* tile = *it;
533 ManagedTileState& mts = tile->managed_state(); 548 ManagedTileState& mts = tile->managed_state();
534 ManagedTileState::DrawingInfo& drawing_info = tile->drawing_info(); 549 ManagedTileState::DrawingInfo& drawing_info = tile->drawing_info();
(...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after
570 "budget", global_state_.memory_limit_in_bytes, 585 "budget", global_state_.memory_limit_in_bytes,
571 "over", bytes_that_exceeded_memory_budget_in_now_bin); 586 "over", bytes_that_exceeded_memory_budget_in_now_bin);
572 } 587 }
573 memory_stats_from_last_assign_.total_budget_in_bytes = 588 memory_stats_from_last_assign_.total_budget_in_bytes =
574 global_state_.memory_limit_in_bytes; 589 global_state_.memory_limit_in_bytes;
575 memory_stats_from_last_assign_.bytes_allocated = 590 memory_stats_from_last_assign_.bytes_allocated =
576 bytes_allocatable - bytes_left; 591 bytes_allocatable - bytes_left;
577 memory_stats_from_last_assign_.bytes_unreleasable = unreleasable_bytes; 592 memory_stats_from_last_assign_.bytes_unreleasable = unreleasable_bytes;
578 memory_stats_from_last_assign_.bytes_over = 593 memory_stats_from_last_assign_.bytes_over =
579 bytes_that_exceeded_memory_budget_in_now_bin; 594 bytes_that_exceeded_memory_budget_in_now_bin;
580
581 // Reverse two tiles_that_need_* vectors such that pop_back gets
582 // the highest priority tile.
583 std::reverse(
584 tiles_that_need_to_be_rasterized_.begin(),
585 tiles_that_need_to_be_rasterized_.end());
586 } 595 }
587 596
588 void TileManager::FreeResourcesForTile(Tile* tile) { 597 void TileManager::FreeResourcesForTile(Tile* tile) {
589 DCHECK(tile->drawing_info().memory_state_ != USING_UNRELEASABLE_MEMORY); 598 DCHECK_NE(USING_UNRELEASABLE_MEMORY, tile->drawing_info().memory_state_);
590 if (tile->drawing_info().resource_) { 599 if (tile->drawing_info().resource_) {
591 resource_pool_->ReleaseResource( 600 resource_pool_->ReleaseResource(
592 tile->drawing_info().resource_.Pass()); 601 tile->drawing_info().resource_.Pass());
593 } 602 }
594 tile->drawing_info().memory_state_ = NOT_ALLOWED_TO_USE_MEMORY; 603 tile->drawing_info().memory_state_ = NOT_ALLOWED_TO_USE_MEMORY;
595 } 604 }
596 605
597 bool TileManager::CanDispatchRasterTask(Tile* tile) const { 606 void TileManager::ScheduleTasks() {
598 if (pending_tasks_ >= max_pending_tasks_) 607 TRACE_EVENT0("cc", "TileManager::ScheduleTasks");
599 return false; 608 RasterWorkerPool::Task::Schedule task_schedule;
600 size_t new_bytes_pending = bytes_pending_upload_;
601 new_bytes_pending += tile->bytes_consumed_if_allocated();
602 return new_bytes_pending <= kMaxPendingUploadBytes &&
603 tiles_with_pending_upload_.size() < kMaxPendingUploads;
604 }
605 609
606 void TileManager::DispatchMoreTasks() { 610 size_t bytes_pending_upload = bytes_pending_upload_;
607 TileVector tiles_with_image_decoding_tasks; 611 unsigned pending_tasks = 0;
608 612
609 // Process all tiles in the need_to_be_rasterized queue: 613 // Build a new task schedule containing all task currently needed. Tasks
610 // 1. Dispatch image decode tasks. 614 // are added in order of priority, highest priority task first.
611 // 2. If the image decode isn't done, save the tile for later processing. 615 for (TileVector::iterator it = tiles_that_need_to_be_rasterized_.begin();
612 // 3. Attempt to dispatch a raster task, or break out of the loop. 616 it != tiles_that_need_to_be_rasterized_.end();
613 while (!tiles_that_need_to_be_rasterized_.empty()) { 617 ++it) {
614 Tile* tile = tiles_that_need_to_be_rasterized_.back(); 618 Tile* tile = *it;
619 ManagedTileState& mts = tile->managed_state();
615 620
616 DCHECK(tile->drawing_info().requires_resource()); 621 // Skip tile if determined to not require resource.
622 if (!tile->drawing_info().requires_resource())
623 continue;
617 624
618 if (DispatchImageDecodeTasksForTile(tile)) { 625 // Skip tile if already rasterized.
619 tiles_with_image_decoding_tasks.push_back(tile); 626 if (tile->drawing_info().resource_)
620 } else if (!CanDispatchRasterTask(tile)) { 627 continue;
621 break; 628
622 } else { 629 // TODO(reveman): Remove throttling based on max pending tasks.
623 DispatchOneRasterTask(tile); 630 if (pending_tasks >= max_pending_tasks_)
631 break;
632
633 // TODO(reveman): Remove throttling based on max pending uploads.
634 if (tiles_with_pending_upload_.size() >= kMaxPendingUploads)
635 break;
636
637 // TODO(reveman): Throttle based on shared memory usage rather
638 // than bytes pending upload.
639 size_t new_bytes_pending = bytes_pending_upload;
640 new_bytes_pending += tile->bytes_consumed_if_allocated();
641 if (new_bytes_pending > kMaxPendingUploadBytes)
642 break;
643 bytes_pending_upload = new_bytes_pending;
644
645 // Create image decode schedule that his tile depends on.
646 RasterWorkerPool::Task::Schedule decode_task_schedule;
647 for (PicturePileImpl::PixelRefIterator iter(tile->content_rect(),
648 tile->contents_scale(),
649 tile->picture_pile());
650 iter; ++iter) {
651 skia::LazyPixelRef* pixel_ref = *iter;
652 uint32_t id = pixel_ref->getGenerationID();
653
654 // Append existing image decode task if available.
655 PixelRefMap::iterator decode_task_it = pending_decode_tasks_.find(id);
656 if (decode_task_it != pending_decode_tasks_.end()) {
657 decode_task_schedule.Append(decode_task_it->second);
658 continue;
659 }
660
661 // Create and append new image decode task for this pixel ref.
662 RasterWorkerPool::Task decode_task = CreateImageDecodeTask(
663 tile, pixel_ref);
664 decode_task_schedule.Append(decode_task);
665 pending_decode_tasks_[id] = decode_task;
624 } 666 }
625 tiles_that_need_to_be_rasterized_.pop_back(); 667
668 // Create raster task for this tile if necessary.
669 if (mts.raster_task.is_null())
670 mts.raster_task = CreateRasterTask(tile);
671
672 // Finally append raster task and image decode dependencies for tile.
673 task_schedule.AppendWithDependencies(
674 mts.raster_task, &decode_task_schedule);
675 pending_tasks++;
626 } 676 }
627 677
628 // Put the saved tiles back into the queue. The order is reversed 678 // Schedule running of tasks in |task_schedule|. This replaces any
629 // to preserve original ordering. 679 // previously scheduled tasks and effectively cancels any tasks
630 tiles_that_need_to_be_rasterized_.insert( 680 // not present in |task_schedule|.
631 tiles_that_need_to_be_rasterized_.end(), 681 raster_worker_pool_->ScheduleTasks(&task_schedule);
632 tiles_with_image_decoding_tasks.rbegin(),
633 tiles_with_image_decoding_tasks.rend());
634 682
635 if (did_initialize_visible_tile_) { 683 if (did_initialize_visible_tile_) {
636 did_initialize_visible_tile_ = false; 684 did_initialize_visible_tile_ = false;
637 client_->DidInitializeVisibleTile(); 685 client_->DidInitializeVisibleTile();
638 } 686 }
639 } 687 }
640 688
641 bool TileManager::DispatchImageDecodeTasksForTile(Tile* tile) { 689 RasterWorkerPool::Task TileManager::CreateImageDecodeTask(
642 TRACE_EVENT0("cc", "TileManager::DispatchImageDecodeTasksForTile"); 690 Tile* tile, skia::LazyPixelRef* pixel_ref) {
643 ManagedTileState& mts = tile->managed_state(); 691 TRACE_EVENT0("cc", "TileManager::CreateImageDecodeTask");
644 bool pending_decode_tasks = false;
645 692
646 for (PicturePileImpl::PixelRefIterator iter(tile->content_rect(), 693 return RasterWorkerPool::Task(
647 tile->contents_scale(),
648 tile->picture_pile());
649 iter; ++iter) {
650 skia::LazyPixelRef* pixel_ref = *iter;
651 uint32_t id = pixel_ref->getGenerationID();
652
653 // Check if image has already been decoded.
654 if (mts.decoded_pixel_refs.find(id) != mts.decoded_pixel_refs.end())
655 continue;
656
657 // Check if decode task is already pending.
658 if (pending_decode_tasks_.find(id) != pending_decode_tasks_.end()) {
659 pending_decode_tasks = true;
660 continue;
661 }
662
663 // TODO(qinmin): passing correct image size to PrepareToDecode().
664 if (pixel_ref->PrepareToDecode(skia::LazyPixelRef::PrepareParams())) {
665 rendering_stats_instrumentation_->IncrementDeferredImageCacheHitCount();
666 mts.decoded_pixel_refs.insert(id);
667 continue;
668 }
669
670 if (pending_tasks_ >= max_pending_tasks_)
671 break;
672
673 DispatchOneImageDecodeTask(tile, pixel_ref);
674 pending_decode_tasks = true;
675 }
676
677 return pending_decode_tasks;
678 }
679
680 void TileManager::DispatchOneImageDecodeTask(
681 scoped_refptr<Tile> tile, skia::LazyPixelRef* pixel_ref) {
682 TRACE_EVENT0("cc", "TileManager::DispatchOneImageDecodeTask");
683 uint32_t pixel_ref_id = pixel_ref->getGenerationID();
684 DCHECK(pending_decode_tasks_.end() ==
685 pending_decode_tasks_.find(pixel_ref_id));
686 pending_decode_tasks_.insert(pixel_ref_id);
687
688 raster_worker_pool_->PostTaskAndReply(
689 base::Bind(&TileManager::RunImageDecodeTask, 694 base::Bind(&TileManager::RunImageDecodeTask,
690 pixel_ref, 695 pixel_ref,
691 tile->layer_id(), 696 tile->layer_id(),
692 rendering_stats_instrumentation_), 697 rendering_stats_instrumentation_),
693 base::Bind(&TileManager::OnImageDecodeTaskCompleted, 698 base::Bind(&TileManager::OnImageDecodeTaskCompleted,
694 base::Unretained(this), 699 base::Unretained(this),
695 tile, 700 make_scoped_refptr(tile),
696 pixel_ref_id)); 701 pixel_ref->getGenerationID()));
697 pending_tasks_++;
698 } 702 }
699 703
700 void TileManager::OnImageDecodeTaskCompleted( 704 void TileManager::OnImageDecodeTaskCompleted(scoped_refptr<Tile> tile,
701 scoped_refptr<Tile> tile, uint32_t pixel_ref_id) { 705 uint32_t pixel_ref_id,
706 bool was_cancelled) {
702 TRACE_EVENT0("cc", "TileManager::OnImageDecodeTaskCompleted"); 707 TRACE_EVENT0("cc", "TileManager::OnImageDecodeTaskCompleted");
703 ManagedTileState& mts = tile->managed_state(); 708 DCHECK(pending_decode_tasks_.find(pixel_ref_id) !=
704 mts.decoded_pixel_refs.insert(pixel_ref_id); 709 pending_decode_tasks_.end());
705 pending_decode_tasks_.erase(pixel_ref_id); 710 pending_decode_tasks_.erase(pixel_ref_id);
706 pending_tasks_--;
707 } 711 }
708 712
709 scoped_ptr<ResourcePool::Resource> TileManager::PrepareTileForRaster( 713 TileManager::RasterTaskMetadata TileManager::GetRasterTaskMetadata(
710 Tile* tile) { 714 const Tile& tile) const {
711 scoped_ptr<ResourcePool::Resource> resource = resource_pool_->AcquireResource( 715 RasterTaskMetadata metadata;
712 tile->tile_size_.size(), 716 const ManagedTileState& mts = tile.managed_state();
713 tile->drawing_info().resource_format_); 717 metadata.is_tile_in_pending_tree_now_bin =
718 mts.tree_bin[PENDING_TREE] == NOW_BIN;
719 metadata.tile_resolution = mts.resolution;
720 metadata.layer_id = tile.layer_id();
721 metadata.tile_id = &tile;
722 metadata.source_frame_number = tile.source_frame_number();
723 return metadata;
724 }
725
726 RasterWorkerPool::Task TileManager::CreateRasterTask(Tile* tile) {
727 TRACE_EVENT0("cc", "TileManager::CreateRasterTask");
728
729 scoped_ptr<ResourcePool::Resource> resource =
730 resource_pool_->AcquireResource(
731 tile->tile_size_.size(),
732 tile->drawing_info().resource_format_);
714 resource_pool_->resource_provider()->AcquirePixelBuffer(resource->id()); 733 resource_pool_->resource_provider()->AcquirePixelBuffer(resource->id());
715 734
735 DCHECK_EQ(CAN_USE_MEMORY, tile->drawing_info().memory_state_);
716 tile->drawing_info().memory_state_ = USING_UNRELEASABLE_MEMORY; 736 tile->drawing_info().memory_state_ = USING_UNRELEASABLE_MEMORY;
717 737
718 return resource.Pass();
719 }
720
721 void TileManager::DispatchOneRasterTask(scoped_refptr<Tile> tile) {
722 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask");
723 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile);
724 ResourceProvider::ResourceId resource_id = resource->id();
725 PicturePileImpl::Analysis* analysis = new PicturePileImpl::Analysis; 738 PicturePileImpl::Analysis* analysis = new PicturePileImpl::Analysis;
726 739
727 // MapPixelBuffer() returns NULL if context was lost at the time 740 // MapPixelBuffer() returns NULL if context was lost at the time
728 // AcquirePixelBuffer() was called. For simplicity we still post 741 // AcquirePixelBuffer() was called. For simplicity we still create
729 // a raster task that is essentially a noop in these situations. 742 // a raster task that is essentially a noop in these situations.
730 uint8* buffer = resource_pool_->resource_provider()->MapPixelBuffer( 743 uint8* buffer = resource_pool_->resource_provider()->MapPixelBuffer(
731 resource_id); 744 resource->id());
732 745
733 // skia requires that our buffer be 4-byte aligned 746 return RasterWorkerPool::PictureTask(
734 CHECK(!(reinterpret_cast<intptr_t>(buffer) & 3));
735
736 raster_worker_pool_->PostRasterTaskAndReply(
737 tile->picture_pile(), 747 tile->picture_pile(),
738 base::Bind(&TileManager::RunAnalyzeAndRasterTask, 748 base::Bind(&TileManager::RunAnalyzeAndRasterTask,
739 base::Bind(&TileManager::RunAnalyzeTask, 749 base::Bind(&TileManager::RunAnalyzeTask,
740 analysis, 750 analysis,
741 tile->content_rect(), 751 tile->content_rect(),
742 tile->contents_scale(), 752 tile->contents_scale(),
743 use_color_estimator_, 753 use_color_estimator_,
744 GetRasterTaskMetadata(*tile), 754 GetRasterTaskMetadata(*tile),
745 rendering_stats_instrumentation_), 755 rendering_stats_instrumentation_),
746 base::Bind(&TileManager::RunRasterTask, 756 base::Bind(&TileManager::RunRasterTask,
747 buffer, 757 buffer,
748 analysis, 758 analysis,
749 tile->content_rect(), 759 tile->content_rect(),
750 tile->contents_scale(), 760 tile->contents_scale(),
751 GetRasterTaskMetadata(*tile), 761 GetRasterTaskMetadata(*tile),
752 rendering_stats_instrumentation_)), 762 rendering_stats_instrumentation_)),
753 base::Bind(&TileManager::OnRasterTaskCompleted, 763 base::Bind(&TileManager::OnRasterTaskCompleted,
754 base::Unretained(this), 764 base::Unretained(this),
755 tile, 765 make_scoped_refptr(tile),
756 base::Passed(&resource), 766 base::Passed(&resource),
757 base::Owned(analysis), 767 base::Owned(analysis)));
758 manage_tiles_call_count_));
759 pending_tasks_++;
760 }
761
762 TileManager::RasterTaskMetadata TileManager::GetRasterTaskMetadata(
763 const Tile& tile) const {
764 RasterTaskMetadata metadata;
765 const ManagedTileState& mts = tile.managed_state();
766 metadata.is_tile_in_pending_tree_now_bin =
767 mts.tree_bin[PENDING_TREE] == NOW_BIN;
768 metadata.tile_resolution = mts.resolution;
769 metadata.layer_id = tile.layer_id();
770 metadata.tile_id = &tile;
771 metadata.source_frame_number = tile.source_frame_number();
772 return metadata;
773 } 768 }
774 769
775 void TileManager::OnRasterTaskCompleted( 770 void TileManager::OnRasterTaskCompleted(
776 scoped_refptr<Tile> tile, 771 scoped_refptr<Tile> tile,
777 scoped_ptr<ResourcePool::Resource> resource, 772 scoped_ptr<ResourcePool::Resource> resource,
778 PicturePileImpl::Analysis* analysis, 773 PicturePileImpl::Analysis* analysis,
779 int manage_tiles_call_count_when_dispatched) { 774 bool was_cancelled) {
780 TRACE_EVENT0("cc", "TileManager::OnRasterTaskCompleted"); 775 TRACE_EVENT0("cc", "TileManager::OnRasterTaskCompleted");
781 776
782 pending_tasks_--; 777 ManagedTileState& mts = tile->managed_state();
778 DCHECK(!mts.raster_task.is_null());
779 mts.raster_task.Reset();
780
781 // Tile resources can't be freed until upload has completed.
782 DCHECK_EQ(USING_UNRELEASABLE_MEMORY, tile->drawing_info().memory_state_);
783 783
784 // Release raster resources. 784 // Release raster resources.
785 resource_pool_->resource_provider()->UnmapPixelBuffer(resource->id()); 785 resource_pool_->resource_provider()->UnmapPixelBuffer(resource->id());
786 786
787 tile->drawing_info().memory_state_ = USING_RELEASABLE_MEMORY; 787 if (was_cancelled) {
788 tile->drawing_info().memory_state_ = CAN_USE_MEMORY;
789 resource_pool_->resource_provider()->ReleasePixelBuffer(resource->id());
790 resource_pool_->ReleaseResource(resource.Pass());
791 return;
792 }
788 793
789 ManagedTileState& managed_tile_state = tile->managed_state(); 794 mts.picture_pile_analysis = *analysis;
790 managed_tile_state.picture_pile_analysis = *analysis; 795 mts.picture_pile_analyzed = true;
791 managed_tile_state.picture_pile_analyzed = true;
792 796
793 if (analysis->is_solid_color) { 797 if (analysis->is_solid_color) {
794 tile->drawing_info().set_solid_color(analysis->solid_color); 798 tile->drawing_info().set_solid_color(analysis->solid_color);
795 resource_pool_->resource_provider()->ReleasePixelBuffer(resource->id()); 799 resource_pool_->resource_provider()->ReleasePixelBuffer(resource->id());
796 resource_pool_->ReleaseResource(resource.Pass()); 800 resource_pool_->ReleaseResource(resource.Pass());
797 DidFinishTileInitialization(tile); 801 DidFinishTileInitialization(tile);
798 return; 802 return;
799 } 803 }
800 804
801 // Tile can be freed after the completion of the raster task. Call 805 resource_pool_->resource_provider()->BeginSetPixels(resource->id());
802 // AssignGpuMemoryToTiles() to re-assign gpu memory to highest priority 806 has_performed_uploads_since_last_flush_ = true;
803 // tiles if ManageTiles() was called since task was dispatched. The result
804 // of this could be that this tile is no longer allowed to use gpu
805 // memory and in that case we need to abort initialization and free all
806 // associated resources before calling DispatchMoreTasks().
807 if (manage_tiles_call_count_when_dispatched != manage_tiles_call_count_)
808 AssignGpuMemoryToTiles();
809 807
810 // Finish resource initialization we're still using memory. 808 tile->drawing_info().resource_ = resource.Pass();
811 if (tile->drawing_info().memory_state_ == USING_RELEASABLE_MEMORY) {
812 // Tile resources can't be freed until upload has completed.
813 tile->drawing_info().memory_state_ = USING_UNRELEASABLE_MEMORY;
814 809
815 resource_pool_->resource_provider()->BeginSetPixels(resource->id()); 810 bytes_pending_upload_ += tile->bytes_consumed_if_allocated();
816 has_performed_uploads_since_last_flush_ = true; 811 tiles_with_pending_upload_.push(tile);
817
818 tile->drawing_info().resource_ = resource.Pass();
819
820 bytes_pending_upload_ += tile->bytes_consumed_if_allocated();
821 tiles_with_pending_upload_.push(tile);
822 } else {
823 resource_pool_->resource_provider()->ReleasePixelBuffer(resource->id());
824 resource_pool_->ReleaseResource(resource.Pass());
825 }
826 } 812 }
827 813
828 void TileManager::DidFinishTileInitialization(Tile* tile) { 814 void TileManager::DidFinishTileInitialization(Tile* tile) {
829 if (tile->priority(ACTIVE_TREE).distance_to_visible_in_pixels == 0) 815 if (tile->priority(ACTIVE_TREE).distance_to_visible_in_pixels == 0)
830 did_initialize_visible_tile_ = true; 816 did_initialize_visible_tile_ = true;
831 } 817 }
832 818
833 void TileManager::DidTileTreeBinChange(Tile* tile, 819 void TileManager::DidTileTreeBinChange(Tile* tile,
834 TileManagerBin new_tree_bin, 820 TileManagerBin new_tree_bin,
835 WhichTree tree) { 821 WhichTree tree) {
836 ManagedTileState& mts = tile->managed_state(); 822 ManagedTileState& mts = tile->managed_state();
837 mts.tree_bin[tree] = new_tree_bin; 823 mts.tree_bin[tree] = new_tree_bin;
838 } 824 }
839 825
840 // static 826 // static
827 void TileManager::RunImageDecodeTask(
828 skia::LazyPixelRef* pixel_ref,
829 int layer_id,
830 RenderingStatsInstrumentation* stats_instrumentation) {
831 TRACE_EVENT0("cc", "TileManager::RunImageDecodeTask");
832 devtools_instrumentation::ScopedImageDecodeTask image_decode_task(layer_id);
833 base::TimeTicks start_time = stats_instrumentation->StartRecording();
834 pixel_ref->Decode();
835 base::TimeDelta duration = stats_instrumentation->EndRecording(start_time);
836 stats_instrumentation->AddDeferredImageDecode(duration);
837 }
838
839 // static
841 void TileManager::RunAnalyzeAndRasterTask( 840 void TileManager::RunAnalyzeAndRasterTask(
842 const RasterWorkerPool::RasterCallback& analyze_task, 841 const RasterWorkerPool::PictureTask::Callback& analyze_task,
843 const RasterWorkerPool::RasterCallback& raster_task, 842 const RasterWorkerPool::PictureTask::Callback& raster_task,
844 PicturePileImpl* picture_pile) { 843 PicturePileImpl* picture_pile) {
845 analyze_task.Run(picture_pile); 844 analyze_task.Run(picture_pile);
846 raster_task.Run(picture_pile); 845 raster_task.Run(picture_pile);
847 } 846 }
848 847
849 // static 848 // static
850 void TileManager::RunAnalyzeTask( 849 void TileManager::RunAnalyzeTask(
851 PicturePileImpl::Analysis* analysis, 850 PicturePileImpl::Analysis* analysis,
852 gfx::Rect rect, 851 gfx::Rect rect,
853 float contents_scale, 852 float contents_scale,
(...skipping 76 matching lines...) Expand 10 before | Expand all | Expand 10 after
930 "Renderer4.PictureRasterTimeUS", 929 "Renderer4.PictureRasterTimeUS",
931 raster_stats.total_rasterize_time.InMicroseconds(), 930 raster_stats.total_rasterize_time.InMicroseconds(),
932 0, 931 0,
933 100000, 932 100000,
934 100); 933 100);
935 } else { 934 } else {
936 picture_pile->Raster(&canvas, rect, contents_scale, NULL); 935 picture_pile->Raster(&canvas, rect, contents_scale, NULL);
937 } 936 }
938 } 937 }
939 938
940 // static
941 void TileManager::RunImageDecodeTask(
942 skia::LazyPixelRef* pixel_ref,
943 int layer_id,
944 RenderingStatsInstrumentation* stats_instrumentation) {
945 TRACE_EVENT0("cc", "TileManager::RunImageDecodeTask");
946 devtools_instrumentation::ScopedImageDecodeTask image_decode_task(layer_id);
947 base::TimeTicks start_time = stats_instrumentation->StartRecording();
948 pixel_ref->Decode();
949 base::TimeDelta duration = stats_instrumentation->EndRecording(start_time);
950 stats_instrumentation->AddDeferredImageDecode(duration);
951 }
952
953 } // namespace cc 939 } // namespace cc
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698