| OLD | NEW |
| 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 117 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 128 ResourceProvider* resource_provider, | 128 ResourceProvider* resource_provider, |
| 129 scoped_ptr<RasterWorkerPool> raster_worker_pool, | 129 scoped_ptr<RasterWorkerPool> raster_worker_pool, |
| 130 size_t num_raster_threads, | 130 size_t num_raster_threads, |
| 131 bool use_color_estimator, | 131 bool use_color_estimator, |
| 132 RenderingStatsInstrumentation* rendering_stats_instrumentation, | 132 RenderingStatsInstrumentation* rendering_stats_instrumentation, |
| 133 bool use_map_image) | 133 bool use_map_image) |
| 134 : client_(client), | 134 : client_(client), |
| 135 resource_pool_(ResourcePool::Create(resource_provider)), | 135 resource_pool_(ResourcePool::Create(resource_provider)), |
| 136 raster_worker_pool_(raster_worker_pool.Pass()), | 136 raster_worker_pool_(raster_worker_pool.Pass()), |
| 137 manage_tiles_pending_(false), | 137 manage_tiles_pending_(false), |
| 138 manage_tiles_call_count_(0), | |
| 139 bytes_pending_upload_(0), | 138 bytes_pending_upload_(0), |
| 140 has_performed_uploads_since_last_flush_(false), | 139 has_performed_uploads_since_last_flush_(false), |
| 141 ever_exceeded_memory_budget_(false), | 140 ever_exceeded_memory_budget_(false), |
| 142 rendering_stats_instrumentation_(rendering_stats_instrumentation), | 141 rendering_stats_instrumentation_(rendering_stats_instrumentation), |
| 143 use_color_estimator_(use_color_estimator), | 142 use_color_estimator_(use_color_estimator), |
| 144 did_initialize_visible_tile_(false), | 143 did_initialize_visible_tile_(false), |
| 145 pending_tasks_(0), | |
| 146 max_pending_tasks_(kMaxNumPendingTasksPerThread * num_raster_threads) { | 144 max_pending_tasks_(kMaxNumPendingTasksPerThread * num_raster_threads) { |
| 147 raster_worker_pool_->SetClient(this); | 145 raster_worker_pool_->SetClient(this); |
| 148 } | 146 } |
| 149 | 147 |
| 150 TileManager::~TileManager() { | 148 TileManager::~TileManager() { |
| 151 // Reset global state and manage. This should cause | 149 // Reset global state and manage. This should cause |
| 152 // our memory usage to drop to zero. | 150 // our memory usage to drop to zero. |
| 153 global_state_ = GlobalStateThatImpactsTilePriority(); | 151 global_state_ = GlobalStateThatImpactsTilePriority(); |
| 154 AssignGpuMemoryToTiles(); | 152 AssignGpuMemoryToTiles(); |
| 155 // This should finish all pending tasks and release any uninitialized | 153 // This should finish all pending tasks and release any uninitialized |
| (...skipping 146 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 302 TRACE_EVENT0("cc", "TileManager::SortTiles"); | 300 TRACE_EVENT0("cc", "TileManager::SortTiles"); |
| 303 | 301 |
| 304 // Sort by bin, resolution and time until needed. | 302 // Sort by bin, resolution and time until needed. |
| 305 std::sort(tiles_.begin(), tiles_.end(), BinComparator()); | 303 std::sort(tiles_.begin(), tiles_.end(), BinComparator()); |
| 306 } | 304 } |
| 307 | 305 |
| 308 void TileManager::ManageTiles() { | 306 void TileManager::ManageTiles() { |
| 309 TRACE_EVENT0("cc", "TileManager::ManageTiles"); | 307 TRACE_EVENT0("cc", "TileManager::ManageTiles"); |
| 310 | 308 |
| 311 manage_tiles_pending_ = false; | 309 manage_tiles_pending_ = false; |
| 312 ++manage_tiles_call_count_; | |
| 313 | 310 |
| 314 AssignBinsToTiles(); | 311 AssignBinsToTiles(); |
| 315 SortTiles(); | 312 SortTiles(); |
| 316 AssignGpuMemoryToTiles(); | 313 AssignGpuMemoryToTiles(); |
| 317 | 314 |
| 318 TRACE_EVENT_INSTANT1( | 315 TRACE_EVENT_INSTANT1( |
| 319 "cc", "DidManage", TRACE_EVENT_SCOPE_THREAD, | 316 "cc", "DidManage", TRACE_EVENT_SCOPE_THREAD, |
| 320 "state", TracedValue::FromValue(BasicStateAsValue().release())); | 317 "state", TracedValue::FromValue(BasicStateAsValue().release())); |
| 321 | 318 |
| 322 // Finally, kick the rasterizer. | 319 // Finally, schedule rasterizer tasks. |
| 323 DispatchMoreTasks(); | 320 ScheduleTasks(); |
| 324 } | 321 } |
| 325 | 322 |
| 326 void TileManager::CheckForCompletedTileUploads() { | 323 void TileManager::CheckForCompletedTileUploads() { |
| 327 while (!tiles_with_pending_upload_.empty()) { | 324 while (!tiles_with_pending_upload_.empty()) { |
| 328 Tile* tile = tiles_with_pending_upload_.front(); | 325 Tile* tile = tiles_with_pending_upload_.front(); |
| 329 DCHECK(tile->tile_version().resource_); | 326 DCHECK(tile->tile_version().resource_); |
| 330 | 327 |
| 331 // Set pixel tasks complete in the order they are posted. | 328 // Set pixel tasks complete in the order they are posted. |
| 332 if (!resource_pool_->resource_provider()->DidSetPixelsComplete( | 329 if (!resource_pool_->resource_provider()->DidSetPixelsComplete( |
| 333 tile->tile_version().resource_->id())) { | 330 tile->tile_version().resource_->id())) { |
| 334 break; | 331 break; |
| 335 } | 332 } |
| 336 | 333 |
| 337 // It's now safe to release the pixel buffer. | 334 // It's now safe to release the pixel buffer. |
| 338 resource_pool_->resource_provider()->ReleasePixelBuffer( | 335 resource_pool_->resource_provider()->ReleasePixelBuffer( |
| 339 tile->tile_version().resource_->id()); | 336 tile->tile_version().resource_->id()); |
| 340 | 337 |
| 341 bytes_pending_upload_ -= tile->bytes_consumed_if_allocated(); | 338 bytes_pending_upload_ -= tile->bytes_consumed_if_allocated(); |
| 342 bool was_forced = tile->tile_version().forced_upload_; | 339 bool was_forced = tile->tile_version().forced_upload_; |
| 343 // Reset forced_upload_ since we now got the upload completed notification. | 340 // Reset forced_upload_ since we now got the upload completed notification. |
| 344 tile->tile_version().forced_upload_ = false; | 341 tile->tile_version().forced_upload_ = false; |
| 345 tile->tile_version().memory_state_ = USING_RELEASABLE_MEMORY; | 342 tile->tile_version().memory_state_ = USING_RELEASABLE_MEMORY; |
| 346 if (!was_forced) | 343 if (!was_forced) |
| 347 DidFinishTileInitialization(tile); | 344 DidFinishTileInitialization(tile); |
| 348 | 345 |
| 349 tiles_with_pending_upload_.pop(); | 346 tiles_with_pending_upload_.pop(); |
| 350 } | 347 } |
| 351 | 348 |
| 352 DispatchMoreTasks(); | 349 ScheduleTasks(); |
| 353 } | 350 } |
| 354 | 351 |
| 355 void TileManager::AbortPendingTileUploads() { | 352 void TileManager::AbortPendingTileUploads() { |
| 356 while (!tiles_with_pending_upload_.empty()) { | 353 while (!tiles_with_pending_upload_.empty()) { |
| 357 Tile* tile = tiles_with_pending_upload_.front(); | 354 Tile* tile = tiles_with_pending_upload_.front(); |
| 358 DCHECK(tile->tile_version().resource_); | 355 DCHECK(tile->tile_version().resource_); |
| 359 | 356 |
| 360 resource_pool_->resource_provider()->AbortSetPixels( | 357 resource_pool_->resource_provider()->AbortSetPixels( |
| 361 tile->tile_version().resource_->id()); | 358 tile->tile_version().resource_->id()); |
| 362 resource_pool_->resource_provider()->ReleasePixelBuffer( | 359 resource_pool_->resource_provider()->ReleasePixelBuffer( |
| (...skipping 99 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 462 tiles_that_need_to_be_initialized_for_activation_.insert(tile); | 459 tiles_that_need_to_be_initialized_for_activation_.insert(tile); |
| 463 } | 460 } |
| 464 | 461 |
| 465 void TileManager::DidFinishDispatchingWorkerPoolCompletionCallbacks() { | 462 void TileManager::DidFinishDispatchingWorkerPoolCompletionCallbacks() { |
| 466 // If a flush is needed, do it now before starting to dispatch more tasks. | 463 // If a flush is needed, do it now before starting to dispatch more tasks. |
| 467 if (has_performed_uploads_since_last_flush_) { | 464 if (has_performed_uploads_since_last_flush_) { |
| 468 resource_pool_->resource_provider()->ShallowFlushIfSupported(); | 465 resource_pool_->resource_provider()->ShallowFlushIfSupported(); |
| 469 has_performed_uploads_since_last_flush_ = false; | 466 has_performed_uploads_since_last_flush_ = false; |
| 470 } | 467 } |
| 471 | 468 |
| 472 DispatchMoreTasks(); | 469 ScheduleTasks(); |
| 473 } | 470 } |
| 474 | 471 |
| 475 void TileManager::AssignGpuMemoryToTiles() { | 472 void TileManager::AssignGpuMemoryToTiles() { |
| 476 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); | 473 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); |
| 477 size_t unreleasable_bytes = 0; | 474 size_t unreleasable_bytes = 0; |
| 478 | 475 |
| 479 // Now give memory out to the tiles until we're out, and build | 476 // Now give memory out to the tiles until we're out, and build |
| 480 // the needs-to-be-rasterized queue. | 477 // the needs-to-be-rasterized queue. |
| 481 tiles_that_need_to_be_rasterized_.clear(); | 478 tiles_that_need_to_be_rasterized_.clear(); |
| 482 tiles_that_need_to_be_initialized_for_activation_.clear(); | 479 tiles_that_need_to_be_initialized_for_activation_.clear(); |
| 483 | 480 |
| 484 // By clearing the tiles_that_need_to_be_rasterized_ vector list | 481 // By clearing the tiles_that_need_to_be_rasterized_ vector list |
| 485 // above we move all tiles currently waiting for raster to idle state. | 482 // above we move all tiles currently waiting for raster to idle state. |
| 486 // Some memory cannot be released. We figure out how much in this | 483 // Some memory cannot be released. We figure out how much in this |
| 487 // loop as well. | 484 // loop. |
| 488 for (TileVector::const_iterator it = tiles_.begin(); | 485 for (TileVector::const_iterator it = tiles_.begin(); |
| 489 it != tiles_.end(); | 486 it != tiles_.end(); |
| 490 ++it) { | 487 ++it) { |
| 491 const Tile* tile = *it; | 488 const Tile* tile = *it; |
| 492 if (tile->tile_version().memory_state_ == USING_UNRELEASABLE_MEMORY) | 489 if (tile->tile_version().memory_state_ == USING_UNRELEASABLE_MEMORY) |
| 493 unreleasable_bytes += tile->bytes_consumed_if_allocated(); | 490 unreleasable_bytes += tile->bytes_consumed_if_allocated(); |
| 494 } | 491 } |
| 495 | 492 |
| 496 // Global state's memory limit can decrease, causing | 493 // Global state's memory limit can decrease, causing |
| 497 // it to be less than unreleasable_bytes | 494 // it to be less than unreleasable_bytes |
| 498 size_t bytes_allocatable = | 495 size_t bytes_allocatable = |
| 499 global_state_.memory_limit_in_bytes > unreleasable_bytes ? | 496 global_state_.memory_limit_in_bytes > unreleasable_bytes ? |
| 500 global_state_.memory_limit_in_bytes - unreleasable_bytes : | 497 global_state_.memory_limit_in_bytes - unreleasable_bytes : |
| 501 0; | 498 0; |
| 502 size_t bytes_that_exceeded_memory_budget_in_now_bin = 0; | 499 size_t bytes_that_exceeded_memory_budget_in_now_bin = 0; |
| 503 size_t bytes_left = bytes_allocatable; | 500 size_t bytes_left = bytes_allocatable; |
| 504 size_t bytes_oom_in_now_bin_on_pending_tree = 0; | 501 size_t bytes_oom_in_now_bin_on_pending_tree = 0; |
| 505 TileVector tiles_requiring_memory_but_oomed; | 502 TileVector tiles_requiring_memory_but_oomed; |
| 503 bool higher_priority_tile_oomed = false; |
| 506 for (TileVector::iterator it = tiles_.begin(); | 504 for (TileVector::iterator it = tiles_.begin(); |
| 507 it != tiles_.end(); | 505 it != tiles_.end(); |
| 508 ++it) { | 506 ++it) { |
| 509 Tile* tile = *it; | 507 Tile* tile = *it; |
| 510 ManagedTileState& mts = tile->managed_state(); | 508 ManagedTileState& mts = tile->managed_state(); |
| 511 ManagedTileState::TileVersion& tile_version = tile->tile_version(); | 509 ManagedTileState::TileVersion& tile_version = tile->tile_version(); |
| 512 | 510 |
| 513 // If this tile doesn't need a resource, then nothing to do. | 511 // If this tile doesn't need a resource, then nothing to do. |
| 514 if (!tile_version.requires_resource()) | 512 if (!tile_version.requires_resource()) |
| 515 continue; | 513 continue; |
| 516 | 514 |
| 517 // If the memory is unreleasable, then we do not need to do anything. | 515 size_t tile_bytes = tile->bytes_consumed_if_allocated(); |
| 518 if (tile_version.memory_state_ == USING_UNRELEASABLE_MEMORY) { | 516 // Memory is already reserved for tile with unreleasable memory |
| 519 if (tile->required_for_activation()) { | 517 // so adding it to |tiles_that_need_to_be_rasterized_| doesn't |
| 520 AddRequiredTileForActivation(tile); | 518 // affect bytes_allocatable. |
| 521 // If after rasterizing, this tile has become required or the client has | 519 if (tile_version.memory_state_ == USING_UNRELEASABLE_MEMORY) |
| 522 // changed its mind about forcing tiles, do that now. | 520 tile_bytes = 0; |
| 523 if (!tile->tile_version().forced_upload_ && | 521 |
| 524 client_->ShouldForceTileUploadsRequiredForActivationToComplete()) { | 522 // If the tile is not needed, free it up. |
| 525 ForceTileUploadToComplete(tile); | 523 if (mts.is_in_never_bin_on_both_trees()) { |
| 526 } | 524 if (tile_version.memory_state_ != USING_UNRELEASABLE_MEMORY) { |
| 525 FreeResourcesForTile(tile); |
| 526 tile_version.memory_state_ = NOT_ALLOWED_TO_USE_MEMORY; |
| 527 } | 527 } |
| 528 continue; | 528 continue; |
| 529 } | 529 } |
| 530 | 530 |
| 531 size_t tile_bytes = tile->bytes_consumed_if_allocated(); | |
| 532 // If the tile is not needed, free it up. | |
| 533 if (mts.is_in_never_bin_on_both_trees()) { | |
| 534 FreeResourcesForTile(tile); | |
| 535 tile_version.memory_state_ = NOT_ALLOWED_TO_USE_MEMORY; | |
| 536 continue; | |
| 537 } | |
| 538 // Tile is OOM. | 531 // Tile is OOM. |
| 539 if (tile_bytes > bytes_left) { | 532 if (tile_bytes > bytes_left) { |
| 540 FreeResourcesForTile(tile); | |
| 541 tile->tile_version().set_rasterize_on_demand(); | 533 tile->tile_version().set_rasterize_on_demand(); |
| 542 if (mts.tree_bin[PENDING_TREE] == NOW_BIN) { | 534 if (mts.tree_bin[PENDING_TREE] == NOW_BIN) { |
| 543 tiles_requiring_memory_but_oomed.push_back(tile); | 535 tiles_requiring_memory_but_oomed.push_back(tile); |
| 544 bytes_oom_in_now_bin_on_pending_tree += tile_bytes; | 536 bytes_oom_in_now_bin_on_pending_tree += tile_bytes; |
| 545 } | 537 } |
| 538 FreeResourcesForTile(tile); |
| 539 higher_priority_tile_oomed = true; |
| 546 continue; | 540 continue; |
| 547 } | 541 } |
| 542 |
| 548 tile_version.set_use_resource(); | 543 tile_version.set_use_resource(); |
| 549 bytes_left -= tile_bytes; | 544 bytes_left -= tile_bytes; |
| 550 if (!tile_version.resource_ && | 545 |
| 551 tile_version.memory_state_ == CAN_USE_MEMORY) { | 546 // Tile shouldn't be rasterized if we've failed to assign |
| 547 // gpu memory to a higher priority tile. This is important for |
| 548 // two reasons: |
| 549 // 1. Tile size should not impact raster priority. |
| 550 // 2. Tile with unreleasable memory could otherwise incorrectly |
| 551 // be added as it's not affected by |bytes_allocatable|. |
| 552 if (higher_priority_tile_oomed) |
| 553 continue; |
| 554 |
| 555 if (!tile_version.resource_) |
| 552 tiles_that_need_to_be_rasterized_.push_back(tile); | 556 tiles_that_need_to_be_rasterized_.push_back(tile); |
| 553 } | 557 |
| 554 if (!tile_version.resource_ && tile->required_for_activation()) | 558 if (!tile_version.resource_ && tile->required_for_activation()) |
| 555 AddRequiredTileForActivation(tile); | 559 AddRequiredTileForActivation(tile); |
| 560 |
| 561 if (tile_version.memory_state_ == USING_UNRELEASABLE_MEMORY && |
| 562 tile->required_for_activation()) { |
| 563 // If after rasterizing, this tile has become required or the client has |
| 564 // changed its mind about forcing tiles, do that now. |
| 565 if (!tile->tile_version().forced_upload_ && |
| 566 client_->ShouldForceTileUploadsRequiredForActivationToComplete()) { |
| 567 ForceTileUploadToComplete(tile); |
| 568 } |
| 569 } |
| 556 } | 570 } |
| 557 | 571 |
| 558 // In OOM situation, we iterate tiles_, remove the memory for active tree | 572 // In OOM situation, we iterate tiles_, remove the memory for active tree |
| 559 // and not the now bin. And give them to bytes_oom_in_now_bin_on_pending_tree | 573 // and not the now bin. And give them to bytes_oom_in_now_bin_on_pending_tree |
| 560 if (!tiles_requiring_memory_but_oomed.empty()) { | 574 if (!tiles_requiring_memory_but_oomed.empty()) { |
| 561 size_t bytes_freed = 0; | 575 size_t bytes_freed = 0; |
| 562 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 576 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
| 563 Tile* tile = *it; | 577 Tile* tile = *it; |
| 564 ManagedTileState& mts = tile->managed_state(); | 578 ManagedTileState& mts = tile->managed_state(); |
| 565 ManagedTileState::TileVersion& tile_version = tile->tile_version(); | 579 ManagedTileState::TileVersion& tile_version = tile->tile_version(); |
| (...skipping 38 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 604 "budget", global_state_.memory_limit_in_bytes, | 618 "budget", global_state_.memory_limit_in_bytes, |
| 605 "over", bytes_that_exceeded_memory_budget_in_now_bin); | 619 "over", bytes_that_exceeded_memory_budget_in_now_bin); |
| 606 } | 620 } |
| 607 memory_stats_from_last_assign_.total_budget_in_bytes = | 621 memory_stats_from_last_assign_.total_budget_in_bytes = |
| 608 global_state_.memory_limit_in_bytes; | 622 global_state_.memory_limit_in_bytes; |
| 609 memory_stats_from_last_assign_.bytes_allocated = | 623 memory_stats_from_last_assign_.bytes_allocated = |
| 610 bytes_allocatable - bytes_left; | 624 bytes_allocatable - bytes_left; |
| 611 memory_stats_from_last_assign_.bytes_unreleasable = unreleasable_bytes; | 625 memory_stats_from_last_assign_.bytes_unreleasable = unreleasable_bytes; |
| 612 memory_stats_from_last_assign_.bytes_over = | 626 memory_stats_from_last_assign_.bytes_over = |
| 613 bytes_that_exceeded_memory_budget_in_now_bin; | 627 bytes_that_exceeded_memory_budget_in_now_bin; |
| 614 | |
| 615 // Reverse two tiles_that_need_* vectors such that pop_back gets | |
| 616 // the highest priority tile. | |
| 617 std::reverse( | |
| 618 tiles_that_need_to_be_rasterized_.begin(), | |
| 619 tiles_that_need_to_be_rasterized_.end()); | |
| 620 } | 628 } |
| 621 | 629 |
| 622 void TileManager::FreeResourcesForTile(Tile* tile) { | 630 void TileManager::FreeResourcesForTile(Tile* tile) { |
| 623 DCHECK(tile->tile_version().memory_state_ != USING_UNRELEASABLE_MEMORY); | 631 DCHECK_NE(USING_UNRELEASABLE_MEMORY, tile->tile_version().memory_state_); |
| 624 if (tile->tile_version().resource_) { | 632 if (tile->tile_version().resource_) { |
| 625 resource_pool_->ReleaseResource( | 633 resource_pool_->ReleaseResource( |
| 626 tile->tile_version().resource_.Pass()); | 634 tile->tile_version().resource_.Pass()); |
| 627 } | 635 } |
| 628 tile->tile_version().memory_state_ = NOT_ALLOWED_TO_USE_MEMORY; | 636 tile->tile_version().memory_state_ = NOT_ALLOWED_TO_USE_MEMORY; |
| 629 } | 637 } |
| 630 | 638 |
| 631 bool TileManager::CanDispatchRasterTask(Tile* tile) const { | 639 void TileManager::ScheduleTasks() { |
| 632 if (pending_tasks_ >= max_pending_tasks_) | 640 TRACE_EVENT0("cc", "TileManager::ScheduleTasks"); |
| 633 return false; | 641 RasterWorkerPool::Task::Queue tasks; |
| 634 size_t new_bytes_pending = bytes_pending_upload_; | |
| 635 new_bytes_pending += tile->bytes_consumed_if_allocated(); | |
| 636 return new_bytes_pending <= kMaxPendingUploadBytes && | |
| 637 tiles_with_pending_upload_.size() < kMaxPendingUploads; | |
| 638 } | |
| 639 | 642 |
| 640 void TileManager::DispatchMoreTasks() { | 643 size_t bytes_pending_upload = bytes_pending_upload_; |
| 641 TileVector tiles_with_image_decoding_tasks; | 644 unsigned pending_tasks = 0; |
| 642 | 645 |
| 643 // Process all tiles in the need_to_be_rasterized queue: | 646 // Build a new task queue containing all task currently needed. Tasks |
| 644 // 1. Dispatch image decode tasks. | 647 // are added in order of priority, highest priority task first. |
| 645 // 2. If the image decode isn't done, save the tile for later processing. | 648 for (TileVector::iterator it = tiles_that_need_to_be_rasterized_.begin(); |
| 646 // 3. Attempt to dispatch a raster task, or break out of the loop. | 649 it != tiles_that_need_to_be_rasterized_.end(); |
| 647 while (!tiles_that_need_to_be_rasterized_.empty()) { | 650 ++it) { |
| 648 Tile* tile = tiles_that_need_to_be_rasterized_.back(); | 651 Tile* tile = *it; |
| 652 ManagedTileState& mts = tile->managed_state(); |
| 649 | 653 |
| 650 DCHECK(tile->tile_version().requires_resource()); | 654 // Skip tile if determined to not require resource. |
| 655 if (!tile->tile_version().requires_resource()) |
| 656 continue; |
| 651 | 657 |
| 652 if (DispatchImageDecodeTasksForTile(tile)) { | 658 // Skip tile if already rasterized. |
| 653 tiles_with_image_decoding_tasks.push_back(tile); | 659 if (tile->tile_version().resource_) |
| 654 } else if (!CanDispatchRasterTask(tile)) { | 660 continue; |
| 655 break; | 661 |
| 656 } else { | 662 // TODO(reveman): Remove throttling based on max pending tasks. |
| 657 DispatchOneRasterTask(tile); | 663 if (pending_tasks >= max_pending_tasks_) |
| 658 } | 664 break; |
| 659 tiles_that_need_to_be_rasterized_.pop_back(); | 665 |
| 666 // TODO(reveman): Remove throttling based on max pending uploads. |
| 667 if (tiles_with_pending_upload_.size() >= kMaxPendingUploads) |
| 668 break; |
| 669 |
| 670 // TODO(reveman): Throttle based on shared memory usage rather |
| 671 // than bytes pending upload. |
| 672 size_t new_bytes_pending = bytes_pending_upload; |
| 673 new_bytes_pending += tile->bytes_consumed_if_allocated(); |
| 674 if (new_bytes_pending > kMaxPendingUploadBytes) |
| 675 break; |
| 676 bytes_pending_upload = new_bytes_pending; |
| 677 |
| 678 // Create raster task for this tile if necessary. |
| 679 if (mts.raster_task.is_null()) |
| 680 mts.raster_task = CreateRasterTask(tile); |
| 681 |
| 682 // Finally append raster task. |
| 683 tasks.Append(mts.raster_task); |
| 684 pending_tasks++; |
| 660 } | 685 } |
| 661 | 686 |
| 662 // Put the saved tiles back into the queue. The order is reversed | 687 if (!tasks.empty()) { |
| 663 // to preserve original ordering. | 688 RasterWorkerPool::Task root(&tasks); |
| 664 tiles_that_need_to_be_rasterized_.insert( | 689 |
| 665 tiles_that_need_to_be_rasterized_.end(), | 690 // Schedule running of tasks in |task_schedule|. This replaces any |
| 666 tiles_with_image_decoding_tasks.rbegin(), | 691 // previously scheduled tasks and effectively cancels any tasks |
| 667 tiles_with_image_decoding_tasks.rend()); | 692 // not present in |task_schedule|. |
| 693 raster_worker_pool_->ScheduleTasks(&root); |
| 694 } else { |
| 695 raster_worker_pool_->ScheduleTasks(NULL); |
| 696 } |
| 668 | 697 |
| 669 if (did_initialize_visible_tile_) { | 698 if (did_initialize_visible_tile_) { |
| 670 did_initialize_visible_tile_ = false; | 699 did_initialize_visible_tile_ = false; |
| 671 client_->DidInitializeVisibleTile(); | 700 client_->DidInitializeVisibleTile(); |
| 672 } | 701 } |
| 673 } | 702 } |
| 674 | 703 |
| 675 bool TileManager::DispatchImageDecodeTasksForTile(Tile* tile) { | 704 RasterWorkerPool::Task TileManager::CreateImageDecodeTask( |
| 676 TRACE_EVENT0("cc", "TileManager::DispatchImageDecodeTasksForTile"); | 705 Tile* tile, skia::LazyPixelRef* pixel_ref) { |
| 677 ManagedTileState& mts = tile->managed_state(); | 706 TRACE_EVENT0("cc", "TileManager::CreateImageDecodeTask"); |
| 678 bool pending_decode_tasks = false; | |
| 679 | 707 |
| 708 return RasterWorkerPool::Task( |
| 709 base::Bind(&TileManager::RunImageDecodeTask, |
| 710 pixel_ref, |
| 711 tile->layer_id(), |
| 712 rendering_stats_instrumentation_), |
| 713 base::Bind(&TileManager::OnImageDecodeTaskCompleted, |
| 714 base::Unretained(this), |
| 715 make_scoped_refptr(tile), |
| 716 pixel_ref->getGenerationID())); |
| 717 } |
| 718 |
| 719 void TileManager::OnImageDecodeTaskCompleted(scoped_refptr<Tile> tile, |
| 720 uint32_t pixel_ref_id, |
| 721 bool was_cancelled) { |
| 722 TRACE_EVENT0("cc", "TileManager::OnImageDecodeTaskCompleted"); |
| 723 DCHECK(pending_decode_tasks_.find(pixel_ref_id) != |
| 724 pending_decode_tasks_.end()); |
| 725 pending_decode_tasks_.erase(pixel_ref_id); |
| 726 } |
| 727 |
| 728 TileManager::RasterTaskMetadata TileManager::GetRasterTaskMetadata( |
| 729 const Tile& tile) const { |
| 730 RasterTaskMetadata metadata; |
| 731 const ManagedTileState& mts = tile.managed_state(); |
| 732 metadata.is_tile_in_pending_tree_now_bin = |
| 733 mts.tree_bin[PENDING_TREE] == NOW_BIN; |
| 734 metadata.tile_resolution = mts.resolution; |
| 735 metadata.layer_id = tile.layer_id(); |
| 736 metadata.tile_id = &tile; |
| 737 metadata.source_frame_number = tile.source_frame_number(); |
| 738 return metadata; |
| 739 } |
| 740 |
| 741 RasterWorkerPool::Task TileManager::CreateRasterTask(Tile* tile) { |
| 742 TRACE_EVENT0("cc", "TileManager::CreateRasterTask"); |
| 743 |
| 744 scoped_ptr<ResourcePool::Resource> resource = |
| 745 resource_pool_->AcquireResource( |
| 746 tile->tile_size_.size(), |
| 747 tile->tile_version().resource_format_); |
| 748 resource_pool_->resource_provider()->AcquirePixelBuffer(resource->id()); |
| 749 |
| 750 DCHECK_EQ(CAN_USE_MEMORY, tile->tile_version().memory_state_); |
| 751 tile->tile_version().memory_state_ = USING_UNRELEASABLE_MEMORY; |
| 752 |
| 753 PicturePileImpl::Analysis* analysis = new PicturePileImpl::Analysis; |
| 754 |
| 755 // MapPixelBuffer() returns NULL if context was lost at the time |
| 756 // AcquirePixelBuffer() was called. For simplicity we still create |
| 757 // a raster task that is essentially a noop in these situations. |
| 758 uint8* buffer = resource_pool_->resource_provider()->MapPixelBuffer( |
| 759 resource->id()); |
| 760 |
| 761 // Create image decode schedule that his tile depends on. |
| 762 RasterWorkerPool::Task::Queue decode_tasks; |
| 680 for (PicturePileImpl::PixelRefIterator iter(tile->content_rect(), | 763 for (PicturePileImpl::PixelRefIterator iter(tile->content_rect(), |
| 681 tile->contents_scale(), | 764 tile->contents_scale(), |
| 682 tile->picture_pile()); | 765 tile->picture_pile()); |
| 683 iter; ++iter) { | 766 iter; ++iter) { |
| 684 skia::LazyPixelRef* pixel_ref = *iter; | 767 skia::LazyPixelRef* pixel_ref = *iter; |
| 685 uint32_t id = pixel_ref->getGenerationID(); | 768 uint32_t id = pixel_ref->getGenerationID(); |
| 686 | 769 |
| 687 // Check if image has already been decoded. | 770 // Append existing image decode task if available. |
| 688 if (mts.decoded_pixel_refs.find(id) != mts.decoded_pixel_refs.end()) | 771 PixelRefMap::iterator decode_task_it = pending_decode_tasks_.find(id); |
| 689 continue; | 772 if (decode_task_it != pending_decode_tasks_.end()) { |
| 690 | 773 decode_tasks.Append(decode_task_it->second); |
| 691 // Check if decode task is already pending. | |
| 692 if (pending_decode_tasks_.find(id) != pending_decode_tasks_.end()) { | |
| 693 pending_decode_tasks = true; | |
| 694 continue; | 774 continue; |
| 695 } | 775 } |
| 696 | 776 |
| 697 // TODO(qinmin): passing correct image size to PrepareToDecode(). | 777 // TODO(qinmin): passing correct image size to PrepareToDecode(). |
| 698 if (pixel_ref->PrepareToDecode(skia::LazyPixelRef::PrepareParams())) { | 778 if (pixel_ref->PrepareToDecode(skia::LazyPixelRef::PrepareParams())) { |
| 699 rendering_stats_instrumentation_->IncrementDeferredImageCacheHitCount(); | 779 rendering_stats_instrumentation_->IncrementDeferredImageCacheHitCount(); |
| 700 mts.decoded_pixel_refs.insert(id); | |
| 701 continue; | 780 continue; |
| 702 } | 781 } |
| 703 | 782 |
| 704 if (pending_tasks_ >= max_pending_tasks_) | 783 // Create and append new image decode task for this pixel ref. |
| 705 break; | 784 RasterWorkerPool::Task decode_task = CreateImageDecodeTask( |
| 706 | 785 tile, pixel_ref); |
| 707 DispatchOneImageDecodeTask(tile, pixel_ref); | 786 decode_tasks.Append(decode_task); |
| 708 pending_decode_tasks = true; | 787 pending_decode_tasks_[id] = decode_task; |
| 709 } | 788 } |
| 710 | 789 |
| 711 return pending_decode_tasks; | 790 return RasterWorkerPool::PictureTask( |
| 712 } | |
| 713 | |
| 714 void TileManager::DispatchOneImageDecodeTask( | |
| 715 scoped_refptr<Tile> tile, skia::LazyPixelRef* pixel_ref) { | |
| 716 TRACE_EVENT0("cc", "TileManager::DispatchOneImageDecodeTask"); | |
| 717 uint32_t pixel_ref_id = pixel_ref->getGenerationID(); | |
| 718 DCHECK(pending_decode_tasks_.end() == | |
| 719 pending_decode_tasks_.find(pixel_ref_id)); | |
| 720 pending_decode_tasks_.insert(pixel_ref_id); | |
| 721 | |
| 722 raster_worker_pool_->PostTaskAndReply( | |
| 723 base::Bind(&TileManager::RunImageDecodeTask, | |
| 724 pixel_ref, | |
| 725 tile->layer_id(), | |
| 726 rendering_stats_instrumentation_), | |
| 727 base::Bind(&TileManager::OnImageDecodeTaskCompleted, | |
| 728 base::Unretained(this), | |
| 729 tile, | |
| 730 pixel_ref_id)); | |
| 731 pending_tasks_++; | |
| 732 } | |
| 733 | |
| 734 void TileManager::OnImageDecodeTaskCompleted( | |
| 735 scoped_refptr<Tile> tile, uint32_t pixel_ref_id) { | |
| 736 TRACE_EVENT0("cc", "TileManager::OnImageDecodeTaskCompleted"); | |
| 737 ManagedTileState& mts = tile->managed_state(); | |
| 738 mts.decoded_pixel_refs.insert(pixel_ref_id); | |
| 739 pending_decode_tasks_.erase(pixel_ref_id); | |
| 740 pending_tasks_--; | |
| 741 } | |
| 742 | |
| 743 scoped_ptr<ResourcePool::Resource> TileManager::PrepareTileForRaster( | |
| 744 Tile* tile) { | |
| 745 scoped_ptr<ResourcePool::Resource> resource = resource_pool_->AcquireResource( | |
| 746 tile->tile_size_.size(), | |
| 747 tile->tile_version().resource_format_); | |
| 748 resource_pool_->resource_provider()->AcquirePixelBuffer(resource->id()); | |
| 749 | |
| 750 tile->tile_version().memory_state_ = USING_UNRELEASABLE_MEMORY; | |
| 751 | |
| 752 return resource.Pass(); | |
| 753 } | |
| 754 | |
| 755 void TileManager::DispatchOneRasterTask(scoped_refptr<Tile> tile) { | |
| 756 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask"); | |
| 757 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); | |
| 758 ResourceProvider::ResourceId resource_id = resource->id(); | |
| 759 PicturePileImpl::Analysis* analysis = new PicturePileImpl::Analysis; | |
| 760 | |
| 761 // MapPixelBuffer() returns NULL if context was lost at the time | |
| 762 // AcquirePixelBuffer() was called. For simplicity we still post | |
| 763 // a raster task that is essentially a noop in these situations. | |
| 764 uint8* buffer = resource_pool_->resource_provider()->MapPixelBuffer( | |
| 765 resource_id); | |
| 766 | |
| 767 // skia requires that our buffer be 4-byte aligned | |
| 768 CHECK(!(reinterpret_cast<intptr_t>(buffer) & 3)); | |
| 769 | |
| 770 raster_worker_pool_->PostRasterTaskAndReply( | |
| 771 tile->picture_pile(), | 791 tile->picture_pile(), |
| 772 base::Bind(&TileManager::RunAnalyzeAndRasterTask, | 792 base::Bind(&TileManager::RunAnalyzeAndRasterTask, |
| 773 base::Bind(&TileManager::RunAnalyzeTask, | 793 base::Bind(&TileManager::RunAnalyzeTask, |
| 774 analysis, | 794 analysis, |
| 775 tile->content_rect(), | 795 tile->content_rect(), |
| 776 tile->contents_scale(), | 796 tile->contents_scale(), |
| 777 use_color_estimator_, | 797 use_color_estimator_, |
| 778 GetRasterTaskMetadata(*tile), | 798 GetRasterTaskMetadata(*tile), |
| 779 rendering_stats_instrumentation_), | 799 rendering_stats_instrumentation_), |
| 780 base::Bind(&TileManager::RunRasterTask, | 800 base::Bind(&TileManager::RunRasterTask, |
| 781 buffer, | 801 buffer, |
| 782 analysis, | 802 analysis, |
| 783 tile->content_rect(), | 803 tile->content_rect(), |
| 784 tile->contents_scale(), | 804 tile->contents_scale(), |
| 785 GetRasterTaskMetadata(*tile), | 805 GetRasterTaskMetadata(*tile), |
| 786 rendering_stats_instrumentation_)), | 806 rendering_stats_instrumentation_)), |
| 787 base::Bind(&TileManager::OnRasterTaskCompleted, | 807 base::Bind(&TileManager::OnRasterTaskCompleted, |
| 788 base::Unretained(this), | 808 base::Unretained(this), |
| 789 tile, | 809 make_scoped_refptr(tile), |
| 790 base::Passed(&resource), | 810 base::Passed(&resource), |
| 791 base::Owned(analysis), | 811 base::Owned(analysis)), |
| 792 manage_tiles_call_count_)); | 812 &decode_tasks); |
| 793 pending_tasks_++; | |
| 794 } | |
| 795 | |
| 796 TileManager::RasterTaskMetadata TileManager::GetRasterTaskMetadata( | |
| 797 const Tile& tile) const { | |
| 798 RasterTaskMetadata metadata; | |
| 799 const ManagedTileState& mts = tile.managed_state(); | |
| 800 metadata.is_tile_in_pending_tree_now_bin = | |
| 801 mts.tree_bin[PENDING_TREE] == NOW_BIN; | |
| 802 metadata.tile_resolution = mts.resolution; | |
| 803 metadata.layer_id = tile.layer_id(); | |
| 804 metadata.tile_id = &tile; | |
| 805 metadata.source_frame_number = tile.source_frame_number(); | |
| 806 return metadata; | |
| 807 } | 813 } |
| 808 | 814 |
| 809 void TileManager::OnRasterTaskCompleted( | 815 void TileManager::OnRasterTaskCompleted( |
| 810 scoped_refptr<Tile> tile, | 816 scoped_refptr<Tile> tile, |
| 811 scoped_ptr<ResourcePool::Resource> resource, | 817 scoped_ptr<ResourcePool::Resource> resource, |
| 812 PicturePileImpl::Analysis* analysis, | 818 PicturePileImpl::Analysis* analysis, |
| 813 int manage_tiles_call_count_when_dispatched) { | 819 bool was_cancelled) { |
| 814 TRACE_EVENT0("cc", "TileManager::OnRasterTaskCompleted"); | 820 TRACE_EVENT0("cc", "TileManager::OnRasterTaskCompleted"); |
| 815 | 821 |
| 816 pending_tasks_--; | 822 ManagedTileState& mts = tile->managed_state(); |
| 823 DCHECK(!mts.raster_task.is_null()); |
| 824 mts.raster_task.Reset(); |
| 825 |
| 826 // Tile resources can't be freed until upload has completed. |
| 827 DCHECK_EQ(USING_UNRELEASABLE_MEMORY, tile->tile_version().memory_state_); |
| 817 | 828 |
| 818 // Release raster resources. | 829 // Release raster resources. |
| 819 resource_pool_->resource_provider()->UnmapPixelBuffer(resource->id()); | 830 resource_pool_->resource_provider()->UnmapPixelBuffer(resource->id()); |
| 820 | 831 |
| 821 tile->tile_version().memory_state_ = USING_RELEASABLE_MEMORY; | 832 if (was_cancelled) { |
| 833 tile->tile_version().memory_state_ = CAN_USE_MEMORY; |
| 834 resource_pool_->resource_provider()->ReleasePixelBuffer(resource->id()); |
| 835 resource_pool_->ReleaseResource(resource.Pass()); |
| 836 return; |
| 837 } |
| 822 | 838 |
| 823 ManagedTileState& managed_tile_state = tile->managed_state(); | 839 mts.picture_pile_analysis = *analysis; |
| 824 managed_tile_state.picture_pile_analysis = *analysis; | 840 mts.picture_pile_analyzed = true; |
| 825 managed_tile_state.picture_pile_analyzed = true; | |
| 826 | 841 |
| 827 if (analysis->is_solid_color) { | 842 if (analysis->is_solid_color) { |
| 828 tile->tile_version().set_solid_color(analysis->solid_color); | 843 tile->tile_version().set_solid_color(analysis->solid_color); |
| 829 resource_pool_->resource_provider()->ReleasePixelBuffer(resource->id()); | 844 resource_pool_->resource_provider()->ReleasePixelBuffer(resource->id()); |
| 830 resource_pool_->ReleaseResource(resource.Pass()); | 845 resource_pool_->ReleaseResource(resource.Pass()); |
| 831 DidFinishTileInitialization(tile); | 846 DidFinishTileInitialization(tile); |
| 832 return; | 847 return; |
| 833 } | 848 } |
| 834 | 849 |
| 835 // Tile can be freed after the completion of the raster task. Call | 850 resource_pool_->resource_provider()->BeginSetPixels(resource->id()); |
| 836 // AssignGpuMemoryToTiles() to re-assign gpu memory to highest priority | 851 has_performed_uploads_since_last_flush_ = true; |
| 837 // tiles if ManageTiles() was called since task was dispatched. The result | |
| 838 // of this could be that this tile is no longer allowed to use gpu | |
| 839 // memory and in that case we need to abort initialization and free all | |
| 840 // associated resources before calling DispatchMoreTasks(). | |
| 841 if (manage_tiles_call_count_when_dispatched != manage_tiles_call_count_) | |
| 842 AssignGpuMemoryToTiles(); | |
| 843 | 852 |
| 844 // Finish resource initialization we're still using memory. | 853 tile->tile_version().resource_ = resource.Pass(); |
| 845 if (tile->tile_version().memory_state_ == USING_RELEASABLE_MEMORY) { | |
| 846 // Tile resources can't be freed until upload has completed. | |
| 847 tile->tile_version().memory_state_ = USING_UNRELEASABLE_MEMORY; | |
| 848 | 854 |
| 849 resource_pool_->resource_provider()->BeginSetPixels(resource->id()); | 855 bytes_pending_upload_ += tile->bytes_consumed_if_allocated(); |
| 850 has_performed_uploads_since_last_flush_ = true; | 856 tiles_with_pending_upload_.push(tile); |
| 851 | 857 |
| 852 tile->tile_version().resource_ = resource.Pass(); | 858 if (tile->required_for_activation() && |
| 853 | 859 client_->ShouldForceTileUploadsRequiredForActivationToComplete()) |
| 854 bytes_pending_upload_ += tile->bytes_consumed_if_allocated(); | 860 ForceTileUploadToComplete(tile); |
| 855 tiles_with_pending_upload_.push(tile); | |
| 856 | |
| 857 if (tile->required_for_activation() && | |
| 858 client_->ShouldForceTileUploadsRequiredForActivationToComplete()) | |
| 859 ForceTileUploadToComplete(tile); | |
| 860 } else { | |
| 861 resource_pool_->resource_provider()->ReleasePixelBuffer(resource->id()); | |
| 862 resource_pool_->ReleaseResource(resource.Pass()); | |
| 863 } | |
| 864 } | 861 } |
| 865 | 862 |
| 866 void TileManager::DidFinishTileInitialization(Tile* tile) { | 863 void TileManager::DidFinishTileInitialization(Tile* tile) { |
| 867 if (tile->priority(ACTIVE_TREE).distance_to_visible_in_pixels == 0) | 864 if (tile->priority(ACTIVE_TREE).distance_to_visible_in_pixels == 0) |
| 868 did_initialize_visible_tile_ = true; | 865 did_initialize_visible_tile_ = true; |
| 869 if (tile->required_for_activation()) { | 866 if (tile->required_for_activation()) { |
| 870 // It's possible that a tile required for activation is not in this list | 867 // It's possible that a tile required for activation is not in this list |
| 871 // if it was marked as being required after being dispatched for | 868 // if it was marked as being required after being dispatched for |
| 872 // rasterization but before AssignGPUMemory was called again. | 869 // rasterization but before AssignGPUMemory was called again. |
| 873 tiles_that_need_to_be_initialized_for_activation_.erase(tile); | 870 tiles_that_need_to_be_initialized_for_activation_.erase(tile); |
| 874 } | 871 } |
| 875 } | 872 } |
| 876 | 873 |
| 877 void TileManager::DidTileTreeBinChange(Tile* tile, | 874 void TileManager::DidTileTreeBinChange(Tile* tile, |
| 878 TileManagerBin new_tree_bin, | 875 TileManagerBin new_tree_bin, |
| 879 WhichTree tree) { | 876 WhichTree tree) { |
| 880 ManagedTileState& mts = tile->managed_state(); | 877 ManagedTileState& mts = tile->managed_state(); |
| 881 mts.tree_bin[tree] = new_tree_bin; | 878 mts.tree_bin[tree] = new_tree_bin; |
| 882 } | 879 } |
| 883 | 880 |
| 884 // static | 881 // static |
| 882 void TileManager::RunImageDecodeTask( |
| 883 skia::LazyPixelRef* pixel_ref, |
| 884 int layer_id, |
| 885 RenderingStatsInstrumentation* stats_instrumentation) { |
| 886 TRACE_EVENT0("cc", "TileManager::RunImageDecodeTask"); |
| 887 devtools_instrumentation::ScopedLayerTask image_decode_task( |
| 888 devtools_instrumentation::kImageDecodeTask, layer_id); |
| 889 base::TimeTicks start_time = stats_instrumentation->StartRecording(); |
| 890 pixel_ref->Decode(); |
| 891 base::TimeDelta duration = stats_instrumentation->EndRecording(start_time); |
| 892 stats_instrumentation->AddDeferredImageDecode(duration); |
| 893 } |
| 894 |
| 895 // static |
| 885 void TileManager::RunAnalyzeAndRasterTask( | 896 void TileManager::RunAnalyzeAndRasterTask( |
| 886 const RasterWorkerPool::RasterCallback& analyze_task, | 897 const RasterWorkerPool::PictureTask::Callback& analyze_task, |
| 887 const RasterWorkerPool::RasterCallback& raster_task, | 898 const RasterWorkerPool::PictureTask::Callback& raster_task, |
| 888 PicturePileImpl* picture_pile) { | 899 PicturePileImpl* picture_pile) { |
| 889 analyze_task.Run(picture_pile); | 900 analyze_task.Run(picture_pile); |
| 890 raster_task.Run(picture_pile); | 901 raster_task.Run(picture_pile); |
| 891 } | 902 } |
| 892 | 903 |
| 893 // static | 904 // static |
| 894 void TileManager::RunAnalyzeTask( | 905 void TileManager::RunAnalyzeTask( |
| 895 PicturePileImpl::Analysis* analysis, | 906 PicturePileImpl::Analysis* analysis, |
| 896 gfx::Rect rect, | 907 gfx::Rect rect, |
| 897 float contents_scale, | 908 float contents_scale, |
| (...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 973 "Renderer4.PictureRasterTimeUS", | 984 "Renderer4.PictureRasterTimeUS", |
| 974 raster_stats.total_rasterize_time.InMicroseconds(), | 985 raster_stats.total_rasterize_time.InMicroseconds(), |
| 975 0, | 986 0, |
| 976 100000, | 987 100000, |
| 977 100); | 988 100); |
| 978 } else { | 989 } else { |
| 979 picture_pile->RasterToBitmap(&canvas, rect, contents_scale, NULL); | 990 picture_pile->RasterToBitmap(&canvas, rect, contents_scale, NULL); |
| 980 } | 991 } |
| 981 } | 992 } |
| 982 | 993 |
| 983 // static | |
| 984 void TileManager::RunImageDecodeTask( | |
| 985 skia::LazyPixelRef* pixel_ref, | |
| 986 int layer_id, | |
| 987 RenderingStatsInstrumentation* stats_instrumentation) { | |
| 988 TRACE_EVENT0("cc", "TileManager::RunImageDecodeTask"); | |
| 989 devtools_instrumentation::ScopedLayerTask image_decode_task( | |
| 990 devtools_instrumentation::kImageDecodeTask, layer_id); | |
| 991 base::TimeTicks start_time = stats_instrumentation->StartRecording(); | |
| 992 pixel_ref->Decode(); | |
| 993 base::TimeDelta duration = stats_instrumentation->EndRecording(start_time); | |
| 994 stats_instrumentation->AddDeferredImageDecode(duration); | |
| 995 } | |
| 996 | |
| 997 } // namespace cc | 994 } // namespace cc |
| OLD | NEW |