Chromium Code Reviews| 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 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 113 TileManagerClient* client, | 113 TileManagerClient* client, |
| 114 ResourceProvider* resource_provider, | 114 ResourceProvider* resource_provider, |
| 115 size_t num_raster_threads, | 115 size_t num_raster_threads, |
| 116 bool use_color_estimator, | 116 bool use_color_estimator, |
| 117 bool prediction_benchmarking, | 117 bool prediction_benchmarking, |
| 118 RenderingStatsInstrumentation* rendering_stats_instrumentation) | 118 RenderingStatsInstrumentation* rendering_stats_instrumentation) |
| 119 : client_(client), | 119 : client_(client), |
| 120 resource_pool_(ResourcePool::Create(resource_provider)), | 120 resource_pool_(ResourcePool::Create(resource_provider)), |
| 121 raster_worker_pool_(RasterWorkerPool::Create(this, num_raster_threads)), | 121 raster_worker_pool_(RasterWorkerPool::Create(this, num_raster_threads)), |
| 122 manage_tiles_pending_(false), | 122 manage_tiles_pending_(false), |
| 123 manage_tiles_call_count_(0), | |
| 124 bytes_pending_upload_(0), | 123 bytes_pending_upload_(0), |
| 125 has_performed_uploads_since_last_flush_(false), | 124 has_performed_uploads_since_last_flush_(false), |
| 126 ever_exceeded_memory_budget_(false), | 125 ever_exceeded_memory_budget_(false), |
| 127 rendering_stats_instrumentation_(rendering_stats_instrumentation), | 126 rendering_stats_instrumentation_(rendering_stats_instrumentation), |
| 128 use_color_estimator_(use_color_estimator), | 127 use_color_estimator_(use_color_estimator), |
| 129 prediction_benchmarking_(prediction_benchmarking), | 128 prediction_benchmarking_(prediction_benchmarking), |
| 130 did_initialize_visible_tile_(false), | 129 did_initialize_visible_tile_(false), |
| 131 pending_tasks_(0), | |
| 132 max_pending_tasks_(kMaxNumPendingTasksPerThread * num_raster_threads) { | 130 max_pending_tasks_(kMaxNumPendingTasksPerThread * num_raster_threads) { |
| 133 } | 131 } |
| 134 | 132 |
| 135 TileManager::~TileManager() { | 133 TileManager::~TileManager() { |
| 136 // Reset global state and manage. This should cause | 134 // Reset global state and manage. This should cause |
| 137 // our memory usage to drop to zero. | 135 // our memory usage to drop to zero. |
| 138 global_state_ = GlobalStateThatImpactsTilePriority(); | 136 global_state_ = GlobalStateThatImpactsTilePriority(); |
| 139 AssignGpuMemoryToTiles(); | 137 AssignGpuMemoryToTiles(); |
| 140 // This should finish all pending tasks and release any uninitialized | 138 // This should finish all pending tasks and release any uninitialized |
| 141 // resources. | 139 // resources. |
| (...skipping 141 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 283 | 281 |
| 284 // Sort by bin, resolution and time until needed. | 282 // Sort by bin, resolution and time until needed. |
| 285 std::sort(tiles_.begin(), tiles_.end(), BinComparator()); | 283 std::sort(tiles_.begin(), tiles_.end(), BinComparator()); |
| 286 } | 284 } |
| 287 | 285 |
| 288 void TileManager::ManageTiles() { | 286 void TileManager::ManageTiles() { |
| 289 TRACE_EVENT0("cc", "TileManager::ManageTiles"); | 287 TRACE_EVENT0("cc", "TileManager::ManageTiles"); |
| 290 TRACE_COUNTER_ID1("cc", "TileCount", this, tiles_.size()); | 288 TRACE_COUNTER_ID1("cc", "TileCount", this, tiles_.size()); |
| 291 | 289 |
| 292 manage_tiles_pending_ = false; | 290 manage_tiles_pending_ = false; |
| 293 ++manage_tiles_call_count_; | |
| 294 | 291 |
| 295 AssignBinsToTiles(); | 292 AssignBinsToTiles(); |
| 296 SortTiles(); | 293 SortTiles(); |
| 297 AssignGpuMemoryToTiles(); | 294 AssignGpuMemoryToTiles(); |
| 298 | 295 |
| 299 TRACE_EVENT_INSTANT1("cc", "DidManage", TRACE_EVENT_SCOPE_THREAD, | 296 TRACE_EVENT_INSTANT1("cc", "DidManage", TRACE_EVENT_SCOPE_THREAD, |
| 300 "state", ValueToString(BasicStateAsValue())); | 297 "state", ValueToString(BasicStateAsValue())); |
| 301 | 298 |
| 302 // Finally, kick the rasterizer. | 299 // Finally, schedule rasterizer tasks. |
| 303 DispatchMoreTasks(); | 300 ScheduleTasks(); |
| 304 } | 301 } |
| 305 | 302 |
| 306 void TileManager::CheckForCompletedTileUploads() { | 303 void TileManager::CheckForCompletedTileUploads() { |
| 307 while (!tiles_with_pending_upload_.empty()) { | 304 while (!tiles_with_pending_upload_.empty()) { |
| 308 Tile* tile = tiles_with_pending_upload_.front(); | 305 Tile* tile = tiles_with_pending_upload_.front(); |
| 309 DCHECK(tile->drawing_info().resource_); | 306 DCHECK(tile->drawing_info().resource_); |
| 310 | 307 |
| 311 // Set pixel tasks complete in the order they are posted. | 308 // Set pixel tasks complete in the order they are posted. |
| 312 if (!resource_pool_->resource_provider()->DidSetPixelsComplete( | 309 if (!resource_pool_->resource_provider()->DidSetPixelsComplete( |
| 313 tile->drawing_info().resource_->id())) { | 310 tile->drawing_info().resource_->id())) { |
| 314 break; | 311 break; |
| 315 } | 312 } |
| 316 | 313 |
| 317 // It's now safe to release the pixel buffer. | 314 // It's now safe to release the pixel buffer. |
| 318 resource_pool_->resource_provider()->ReleasePixelBuffer( | 315 resource_pool_->resource_provider()->ReleasePixelBuffer( |
| 319 tile->drawing_info().resource_->id()); | 316 tile->drawing_info().resource_->id()); |
| 320 | 317 |
| 321 bytes_pending_upload_ -= tile->bytes_consumed_if_allocated(); | 318 bytes_pending_upload_ -= tile->bytes_consumed_if_allocated(); |
| 322 // Reset forced_upload_ since we now got the upload completed notification. | 319 // Reset forced_upload_ since we now got the upload completed notification. |
| 323 tile->drawing_info().forced_upload_ = false; | 320 tile->drawing_info().forced_upload_ = false; |
| 324 tile->drawing_info().memory_state_ = USING_RELEASABLE_MEMORY; | 321 tile->drawing_info().memory_state_ = USING_RELEASABLE_MEMORY; |
| 325 DidFinishTileInitialization(tile); | 322 DidFinishTileInitialization(tile); |
| 326 | 323 |
| 327 tiles_with_pending_upload_.pop(); | 324 tiles_with_pending_upload_.pop(); |
| 328 } | 325 } |
| 329 | 326 |
| 330 DispatchMoreTasks(); | 327 ScheduleTasks(); |
| 331 } | 328 } |
| 332 | 329 |
| 333 void TileManager::AbortPendingTileUploads() { | 330 void TileManager::AbortPendingTileUploads() { |
| 334 while (!tiles_with_pending_upload_.empty()) { | 331 while (!tiles_with_pending_upload_.empty()) { |
| 335 Tile* tile = tiles_with_pending_upload_.front(); | 332 Tile* tile = tiles_with_pending_upload_.front(); |
| 336 DCHECK(tile->drawing_info().resource_); | 333 DCHECK(tile->drawing_info().resource_); |
| 337 | 334 |
| 338 resource_pool_->resource_provider()->AbortSetPixels( | 335 resource_pool_->resource_provider()->AbortSetPixels( |
| 339 tile->drawing_info().resource_->id()); | 336 tile->drawing_info().resource_->id()); |
| 340 resource_pool_->resource_provider()->ReleasePixelBuffer( | 337 resource_pool_->resource_provider()->ReleasePixelBuffer( |
| (...skipping 90 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 431 return requirements.PassAs<base::Value>(); | 428 return requirements.PassAs<base::Value>(); |
| 432 } | 429 } |
| 433 | 430 |
| 434 void TileManager::DidFinishDispatchingWorkerPoolCompletionCallbacks() { | 431 void TileManager::DidFinishDispatchingWorkerPoolCompletionCallbacks() { |
| 435 // If a flush is needed, do it now before starting to dispatch more tasks. | 432 // If a flush is needed, do it now before starting to dispatch more tasks. |
| 436 if (has_performed_uploads_since_last_flush_) { | 433 if (has_performed_uploads_since_last_flush_) { |
| 437 resource_pool_->resource_provider()->ShallowFlushIfSupported(); | 434 resource_pool_->resource_provider()->ShallowFlushIfSupported(); |
| 438 has_performed_uploads_since_last_flush_ = false; | 435 has_performed_uploads_since_last_flush_ = false; |
| 439 } | 436 } |
| 440 | 437 |
| 441 DispatchMoreTasks(); | 438 ScheduleTasks(); |
| 442 } | 439 } |
| 443 | 440 |
| 444 void TileManager::AssignGpuMemoryToTiles() { | 441 void TileManager::AssignGpuMemoryToTiles() { |
| 445 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); | 442 TRACE_EVENT0("cc", "TileManager::AssignGpuMemoryToTiles"); |
| 446 size_t unreleasable_bytes = 0; | 443 size_t unreleasable_bytes = 0; |
| 447 | 444 |
| 448 // Now give memory out to the tiles until we're out, and build | 445 // Now give memory out to the tiles until we're out, and build |
| 449 // the needs-to-be-rasterized queue. | 446 // the needs-to-be-rasterized queue. |
| 450 tiles_that_need_to_be_rasterized_.clear(); | 447 tiles_that_need_to_be_rasterized_.clear(); |
| 451 | 448 |
| 452 // By clearing the tiles_that_need_to_be_rasterized_ vector list | 449 // By clearing the tiles_that_need_to_be_rasterized_ vector list |
| 453 // above we move all tiles currently waiting for raster to idle state. | 450 // above we move all tiles currently waiting for raster to idle state. |
| 454 // Some memory cannot be released. We figure out how much in this | 451 // Some memory cannot be released. We figure out how much in this |
| 455 // loop as well. | 452 // loop. |
| 456 for (TileVector::const_iterator it = tiles_.begin(); | 453 for (TileVector::const_iterator it = tiles_.begin(); |
| 457 it != tiles_.end(); | 454 it != tiles_.end(); |
| 458 ++it) { | 455 ++it) { |
| 459 const Tile* tile = *it; | 456 const Tile* tile = *it; |
| 460 if (tile->drawing_info().memory_state_ == USING_UNRELEASABLE_MEMORY) | 457 if (tile->drawing_info().memory_state_ == USING_UNRELEASABLE_MEMORY) |
| 461 unreleasable_bytes += tile->bytes_consumed_if_allocated(); | 458 unreleasable_bytes += tile->bytes_consumed_if_allocated(); |
| 462 } | 459 } |
| 463 | 460 |
| 464 // Global state's memory limit can decrease, causing | 461 // Global state's memory limit can decrease, causing |
| 465 // it to be less than unreleasable_bytes | 462 // it to be less than unreleasable_bytes |
| 466 size_t bytes_allocatable = | 463 size_t bytes_allocatable = |
| 467 global_state_.memory_limit_in_bytes > unreleasable_bytes ? | 464 global_state_.memory_limit_in_bytes > unreleasable_bytes ? |
| 468 global_state_.memory_limit_in_bytes - unreleasable_bytes : | 465 global_state_.memory_limit_in_bytes - unreleasable_bytes : |
| 469 0; | 466 0; |
| 470 size_t bytes_that_exceeded_memory_budget_in_now_bin = 0; | 467 size_t bytes_that_exceeded_memory_budget_in_now_bin = 0; |
| 471 size_t bytes_left = bytes_allocatable; | 468 size_t bytes_left = bytes_allocatable; |
| 472 size_t bytes_oom_in_now_bin_on_pending_tree = 0; | 469 size_t bytes_oom_in_now_bin_on_pending_tree = 0; |
| 473 TileVector tiles_requiring_memory_but_oomed; | 470 TileVector tiles_requiring_memory_but_oomed; |
| 471 bool higher_priority_tile_oomed = false; | |
| 474 for (TileVector::iterator it = tiles_.begin(); | 472 for (TileVector::iterator it = tiles_.begin(); |
| 475 it != tiles_.end(); | 473 it != tiles_.end(); |
| 476 ++it) { | 474 ++it) { |
| 477 Tile* tile = *it; | 475 Tile* tile = *it; |
| 478 ManagedTileState& mts = tile->managed_state(); | 476 ManagedTileState& mts = tile->managed_state(); |
| 479 ManagedTileState::DrawingInfo& drawing_info = tile->drawing_info(); | 477 ManagedTileState::DrawingInfo& drawing_info = tile->drawing_info(); |
| 480 | 478 |
| 481 // If this tile doesn't need a resource, or if the memory | 479 // If this tile doesn't need a resource, then we do not need |
| 482 // is unreleasable, then we do not need to do anything. | 480 // to do anything. |
| 483 if (!drawing_info.requires_resource() || | 481 if (!drawing_info.requires_resource()) |
| 484 drawing_info.memory_state_ == USING_UNRELEASABLE_MEMORY) { | |
| 485 continue; | 482 continue; |
| 486 } | |
| 487 | 483 |
| 488 size_t tile_bytes = tile->bytes_consumed_if_allocated(); | 484 size_t tile_bytes = tile->bytes_consumed_if_allocated(); |
| 485 // Memory is already reserved for tile with unreleasable memory | |
| 486 // so adding it to |tiles_that_need_to_be_rasterized_| doesn't | |
| 487 // affect bytes_allocatable. | |
| 488 if (drawing_info.memory_state_ == USING_UNRELEASABLE_MEMORY) | |
| 489 tile_bytes = 0; | |
| 490 | |
| 489 // If the tile is not needed, free it up. | 491 // If the tile is not needed, free it up. |
| 490 if (mts.is_in_never_bin_on_both_trees()) { | 492 if (mts.is_in_never_bin_on_both_trees()) { |
| 491 FreeResourcesForTile(tile); | 493 if (drawing_info.memory_state_ != USING_UNRELEASABLE_MEMORY) { |
| 492 drawing_info.memory_state_ = NOT_ALLOWED_TO_USE_MEMORY; | 494 FreeResourcesForTile(tile); |
| 495 drawing_info.memory_state_ = NOT_ALLOWED_TO_USE_MEMORY; | |
| 496 } | |
| 493 continue; | 497 continue; |
| 494 } | 498 } |
| 495 // Tile is OOM. | 499 // Tile is OOM. |
| 496 if (tile_bytes > bytes_left) { | 500 if (tile_bytes > bytes_left) { |
| 497 FreeResourcesForTile(tile); | |
| 498 tile->drawing_info().set_rasterize_on_demand(); | 501 tile->drawing_info().set_rasterize_on_demand(); |
| 499 if (mts.tree_bin[PENDING_TREE] == NOW_BIN) { | 502 if (mts.tree_bin[PENDING_TREE] == NOW_BIN) { |
| 500 tiles_requiring_memory_but_oomed.push_back(tile); | 503 tiles_requiring_memory_but_oomed.push_back(tile); |
| 501 bytes_oom_in_now_bin_on_pending_tree += tile_bytes; | 504 bytes_oom_in_now_bin_on_pending_tree += tile_bytes; |
| 502 } | 505 } |
| 506 FreeResourcesForTile(tile); | |
| 507 higher_priority_tile_oomed = true; | |
| 503 continue; | 508 continue; |
| 504 } | 509 } |
| 505 drawing_info.set_use_resource(); | 510 drawing_info.set_use_resource(); |
| 506 bytes_left -= tile_bytes; | 511 bytes_left -= tile_bytes; |
| 507 if (!drawing_info.resource_ && | 512 // Tile shouldn't be rasterized if we've failed to assign |
|
vmpstr
2013/05/06 18:05:51
If a large tile is OOM, followed by a smaller tile
reveman
2013/05/06 21:36:27
Yes, being assigned memory is not the same as bein
| |
| 508 drawing_info.memory_state_ == CAN_USE_MEMORY) { | 513 // gpu memory to a higher priority tile. This is important for |
| 514 // two reasons: | |
| 515 // 1. Tile size should not impact raster priority. | |
| 516 // 2. Tile with unreleasable memory could otherwise incorrectly | |
| 517 // be added as it's not affected by |bytes_allocatable|. | |
| 518 if (!drawing_info.resource_ && !higher_priority_tile_oomed) | |
| 509 tiles_that_need_to_be_rasterized_.push_back(tile); | 519 tiles_that_need_to_be_rasterized_.push_back(tile); |
| 510 } | |
| 511 } | 520 } |
| 512 | 521 |
| 513 // In OOM situation, we iterate tiles_, remove the memory for active tree | 522 // In OOM situation, we iterate tiles_, remove the memory for active tree |
| 514 // and not the now bin. And give them to bytes_oom_in_now_bin_on_pending_tree | 523 // and not the now bin. And give them to bytes_oom_in_now_bin_on_pending_tree |
| 515 if (!tiles_requiring_memory_but_oomed.empty()) { | 524 if (!tiles_requiring_memory_but_oomed.empty()) { |
| 516 size_t bytes_freed = 0; | 525 size_t bytes_freed = 0; |
| 517 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { | 526 for (TileVector::iterator it = tiles_.begin(); it != tiles_.end(); ++it) { |
| 518 Tile* tile = *it; | 527 Tile* tile = *it; |
| 519 ManagedTileState& mts = tile->managed_state(); | 528 ManagedTileState& mts = tile->managed_state(); |
| 520 ManagedTileState::DrawingInfo& drawing_info = tile->drawing_info(); | 529 ManagedTileState::DrawingInfo& drawing_info = tile->drawing_info(); |
| (...skipping 35 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 556 "budget", global_state_.memory_limit_in_bytes, | 565 "budget", global_state_.memory_limit_in_bytes, |
| 557 "over", bytes_that_exceeded_memory_budget_in_now_bin); | 566 "over", bytes_that_exceeded_memory_budget_in_now_bin); |
| 558 } | 567 } |
| 559 memory_stats_from_last_assign_.total_budget_in_bytes = | 568 memory_stats_from_last_assign_.total_budget_in_bytes = |
| 560 global_state_.memory_limit_in_bytes; | 569 global_state_.memory_limit_in_bytes; |
| 561 memory_stats_from_last_assign_.bytes_allocated = | 570 memory_stats_from_last_assign_.bytes_allocated = |
| 562 bytes_allocatable - bytes_left; | 571 bytes_allocatable - bytes_left; |
| 563 memory_stats_from_last_assign_.bytes_unreleasable = unreleasable_bytes; | 572 memory_stats_from_last_assign_.bytes_unreleasable = unreleasable_bytes; |
| 564 memory_stats_from_last_assign_.bytes_over = | 573 memory_stats_from_last_assign_.bytes_over = |
| 565 bytes_that_exceeded_memory_budget_in_now_bin; | 574 bytes_that_exceeded_memory_budget_in_now_bin; |
| 566 | |
| 567 // Reverse two tiles_that_need_* vectors such that pop_back gets | |
| 568 // the highest priority tile. | |
| 569 std::reverse( | |
| 570 tiles_that_need_to_be_rasterized_.begin(), | |
| 571 tiles_that_need_to_be_rasterized_.end()); | |
| 572 } | 575 } |
| 573 | 576 |
| 574 void TileManager::FreeResourcesForTile(Tile* tile) { | 577 void TileManager::FreeResourcesForTile(Tile* tile) { |
| 575 DCHECK(tile->drawing_info().memory_state_ != USING_UNRELEASABLE_MEMORY); | 578 DCHECK_NE(USING_UNRELEASABLE_MEMORY, tile->drawing_info().memory_state_); |
|
vmpstr
2013/05/06 18:05:51
nit: I kinda prefer the constant to be the second
reveman
2013/05/06 21:36:27
DCHECK_NE is used in both ways throughout chromium
| |
| 576 if (tile->drawing_info().resource_) { | 579 if (tile->drawing_info().resource_) { |
| 577 resource_pool_->ReleaseResource( | 580 resource_pool_->ReleaseResource( |
| 578 tile->drawing_info().resource_.Pass()); | 581 tile->drawing_info().resource_.Pass()); |
| 579 } | 582 } |
| 580 tile->drawing_info().memory_state_ = NOT_ALLOWED_TO_USE_MEMORY; | 583 tile->drawing_info().memory_state_ = NOT_ALLOWED_TO_USE_MEMORY; |
| 581 } | 584 } |
| 582 | 585 |
| 583 bool TileManager::CanDispatchRasterTask(Tile* tile) const { | 586 void TileManager::ScheduleTasks() { |
| 584 if (pending_tasks_ >= max_pending_tasks_) | 587 TRACE_EVENT0("cc", "TileManager::ScheduleTasks"); |
| 585 return false; | 588 RasterWorkerPool::Task::Queue task_queue; |
| 586 size_t new_bytes_pending = bytes_pending_upload_; | |
| 587 new_bytes_pending += tile->bytes_consumed_if_allocated(); | |
| 588 return new_bytes_pending <= kMaxPendingUploadBytes && | |
| 589 tiles_with_pending_upload_.size() < kMaxPendingUploads; | |
| 590 } | |
| 591 | 589 |
| 592 void TileManager::DispatchMoreTasks() { | 590 size_t bytes_pending_upload = bytes_pending_upload_; |
| 593 TileVector tiles_with_image_decoding_tasks; | 591 ManagedTileState::PixelRefSet decode_tasks; |
| 594 | 592 |
| 593 // Build a new task queue containing all task currently needed. Tasks | |
| 594 // are added to queue in order of priority, highest priority task first. | |
| 595 // | |
| 595 // Process all tiles in the need_to_be_rasterized queue: | 596 // Process all tiles in the need_to_be_rasterized queue: |
| 596 // 1. Dispatch image decode tasks. | 597 // 1. Queue image decode tasks for tile. |
| 597 // 2. If the image decode isn't done, save the tile for later processing. | 598 // 2. If the image decode is pending, skip tile for later processing. |
| 598 // 3. Attempt to dispatch a raster task, or break out of the loop. | 599 // 3. Attempt to queue a raster task, or break out of the loop. |
| 599 while (!tiles_that_need_to_be_rasterized_.empty()) { | 600 for (TileVector::iterator it = tiles_that_need_to_be_rasterized_.begin(); |
| 600 Tile* tile = tiles_that_need_to_be_rasterized_.back(); | 601 it != tiles_that_need_to_be_rasterized_.end(); |
| 602 ++it) { | |
| 603 Tile* tile = *it; | |
| 601 | 604 |
| 602 DCHECK(tile->drawing_info().requires_resource()); | 605 // Skip tile if determined to not require resource. |
| 606 if (!tile->drawing_info().requires_resource()) | |
| 607 continue; | |
| 603 | 608 |
| 604 if (DispatchImageDecodeTasksForTile(tile)) { | 609 // Skip tile if already rasterized. |
| 605 tiles_with_image_decoding_tasks.push_back(tile); | 610 if (tile->drawing_info().resource_) |
| 606 } else if (!CanDispatchRasterTask(tile)) { | 611 continue; |
| 612 | |
| 613 bool pending_decode_tasks = false; | |
| 614 ManagedTileState& mts = tile->managed_state(); | |
| 615 | |
| 616 for (PicturePileImpl::PixelRefIterator iter(tile->content_rect(), | |
|
vmpstr
2013/05/06 18:05:51
Is it possible to refactor this loop into a separa
reveman
2013/05/06 21:36:27
Done.
| |
| 617 tile->contents_scale(), | |
| 618 tile->picture_pile()); | |
| 619 iter; ++iter) { | |
| 620 skia::LazyPixelRef* pixel_ref = *iter; | |
| 621 uint32_t id = pixel_ref->getGenerationID(); | |
| 622 | |
| 623 // Check if image has already been decoded for this tile. | |
| 624 if (mts.decoded_pixel_refs.find(id) != mts.decoded_pixel_refs.end()) | |
| 625 continue; | |
| 626 | |
| 627 // TODO(qinmin): passing correct image size to PrepareToDecode(). | |
| 628 if (pixel_ref->PrepareToDecode(skia::LazyPixelRef::PrepareParams())) { | |
| 629 rendering_stats_instrumentation_->IncrementDeferredImageCacheHitCount(); | |
| 630 mts.decoded_pixel_refs.insert(id); | |
| 631 continue; | |
| 632 } | |
| 633 | |
| 634 pending_decode_tasks = true; | |
| 635 | |
| 636 // TODO(reveman): Remove max pending tasks throttling. | |
| 637 if (task_queue.size() >= max_pending_tasks_) | |
| 607 break; | 638 break; |
| 608 } else { | 639 |
| 609 DispatchOneRasterTask(tile); | 640 // Check if already added to |task_queue|. There should only be |
| 641 // one task per pixel ref. | |
| 642 if (decode_tasks.find(id) != decode_tasks.end()) | |
| 643 continue; | |
| 644 decode_tasks.insert(id); | |
| 645 | |
| 646 // Queue existing task if available. | |
| 647 PixelRefMap::iterator decode_task_it = pending_decode_tasks_.find(id); | |
| 648 if (decode_task_it != pending_decode_tasks_.end()) { | |
| 649 task_queue.Append(decode_task_it->second); | |
| 650 continue; | |
| 651 } | |
| 652 | |
| 653 // Create and queue new image decode task for this pixel ref. | |
| 654 RasterWorkerPool::Task decode_task = CreateImageDecodeTask( | |
| 655 tile, pixel_ref); | |
| 656 task_queue.Append(decode_task); | |
| 657 pending_decode_tasks_[id] = decode_task; | |
| 610 } | 658 } |
| 611 tiles_that_need_to_be_rasterized_.pop_back(); | 659 |
| 660 // Skip tile if image decode is pending. | |
| 661 if (pending_decode_tasks) | |
| 662 continue; | |
| 663 | |
| 664 // TODO(reveman): Remove throttling based on max pending tasks. | |
| 665 if (task_queue.size() >= max_pending_tasks_) | |
| 666 break; | |
| 667 | |
| 668 // TODO(reveman): Remove throttling based on max pending uploads. | |
| 669 if (tiles_with_pending_upload_.size() >= kMaxPendingUploads) | |
| 670 break; | |
| 671 | |
| 672 // TODO(reveman): Throttle based on shared memory usage rather | |
| 673 // than bytes pending upload. | |
| 674 size_t new_bytes_pending = bytes_pending_upload; | |
| 675 new_bytes_pending += tile->bytes_consumed_if_allocated(); | |
| 676 if (new_bytes_pending > kMaxPendingUploadBytes) | |
| 677 break; | |
| 678 bytes_pending_upload = new_bytes_pending; | |
| 679 | |
| 680 // Create raster task for this tile if necessary. | |
| 681 if (mts.raster_task.is_null()) | |
| 682 mts.raster_task = CreateRasterTask(tile); | |
| 683 | |
| 684 // Finally queue raster task for tile. | |
| 685 task_queue.Append(mts.raster_task); | |
| 612 } | 686 } |
| 613 | 687 |
| 614 // Put the saved tiles back into the queue. The order is reversed | 688 // Schedule running of tasks in |task_queue|. This replaces any |
| 615 // to preserve original ordering. | 689 // previously scheduled tasks and effectively cancels any tasks |
|
vmpstr
2013/05/06 18:05:51
How do we cancel an upload? (or ensure upload cont
reveman
2013/05/06 21:36:27
We can't cancel an upload at the moment but that's
| |
| 616 tiles_that_need_to_be_rasterized_.insert( | 690 // not present in |task_queue|. |
| 617 tiles_that_need_to_be_rasterized_.end(), | 691 raster_worker_pool_->ScheduleTasks(&task_queue); |
| 618 tiles_with_image_decoding_tasks.rbegin(), | |
| 619 tiles_with_image_decoding_tasks.rend()); | |
| 620 | 692 |
| 621 if (did_initialize_visible_tile_) { | 693 if (did_initialize_visible_tile_) { |
| 622 did_initialize_visible_tile_ = false; | 694 did_initialize_visible_tile_ = false; |
| 623 client_->DidInitializeVisibleTile(); | 695 client_->DidInitializeVisibleTile(); |
| 624 } | 696 } |
| 625 } | 697 } |
| 626 | 698 |
| 627 bool TileManager::DispatchImageDecodeTasksForTile(Tile* tile) { | 699 RasterWorkerPool::Task TileManager::CreateImageDecodeTask( |
|
vmpstr
2013/05/06 18:05:51
I guess my earlier comment is asking to just renam
reveman
2013/05/06 21:36:27
Done.
| |
| 628 TRACE_EVENT0("cc", "TileManager::DispatchImageDecodeTasksForTile"); | 700 Tile* tile, skia::LazyPixelRef* pixel_ref) { |
| 629 ManagedTileState& mts = tile->managed_state(); | 701 TRACE_EVENT0("cc", "TileManager::CreateImageDecodeTask"); |
| 630 bool pending_decode_tasks = false; | |
| 631 | 702 |
| 632 for (PicturePileImpl::PixelRefIterator iter(tile->content_rect(), | 703 return RasterWorkerPool::Task( |
| 633 tile->contents_scale(), | |
| 634 tile->picture_pile()); | |
| 635 iter; ++iter) { | |
| 636 skia::LazyPixelRef* pixel_ref = *iter; | |
| 637 uint32_t id = pixel_ref->getGenerationID(); | |
| 638 | |
| 639 // Check if image has already been decoded. | |
| 640 if (mts.decoded_pixel_refs.find(id) != mts.decoded_pixel_refs.end()) | |
| 641 continue; | |
| 642 | |
| 643 // Check if decode task is already pending. | |
| 644 if (pending_decode_tasks_.find(id) != pending_decode_tasks_.end()) { | |
| 645 pending_decode_tasks = true; | |
| 646 continue; | |
| 647 } | |
| 648 | |
| 649 // TODO(qinmin): passing correct image size to PrepareToDecode(). | |
| 650 if (pixel_ref->PrepareToDecode(skia::LazyPixelRef::PrepareParams())) { | |
| 651 rendering_stats_instrumentation_->IncrementDeferredImageCacheHitCount(); | |
| 652 mts.decoded_pixel_refs.insert(id); | |
| 653 continue; | |
| 654 } | |
| 655 | |
| 656 if (pending_tasks_ >= max_pending_tasks_) | |
| 657 break; | |
| 658 | |
| 659 DispatchOneImageDecodeTask(tile, pixel_ref); | |
| 660 pending_decode_tasks = true; | |
| 661 } | |
| 662 | |
| 663 return pending_decode_tasks; | |
| 664 } | |
| 665 | |
| 666 void TileManager::DispatchOneImageDecodeTask( | |
| 667 scoped_refptr<Tile> tile, skia::LazyPixelRef* pixel_ref) { | |
| 668 TRACE_EVENT0("cc", "TileManager::DispatchOneImageDecodeTask"); | |
| 669 uint32_t pixel_ref_id = pixel_ref->getGenerationID(); | |
| 670 DCHECK(pending_decode_tasks_.end() == | |
| 671 pending_decode_tasks_.find(pixel_ref_id)); | |
| 672 pending_decode_tasks_.insert(pixel_ref_id); | |
| 673 | |
| 674 raster_worker_pool_->PostTaskAndReply( | |
| 675 base::Bind(&TileManager::RunImageDecodeTask, | 704 base::Bind(&TileManager::RunImageDecodeTask, |
| 676 pixel_ref, | 705 pixel_ref, |
| 677 rendering_stats_instrumentation_), | 706 rendering_stats_instrumentation_), |
| 678 base::Bind(&TileManager::OnImageDecodeTaskCompleted, | 707 base::Bind(&TileManager::OnImageDecodeTaskCompleted, |
| 679 base::Unretained(this), | 708 base::Unretained(this), |
| 680 tile, | 709 make_scoped_refptr(tile), |
| 681 pixel_ref_id)); | 710 pixel_ref->getGenerationID())); |
| 682 pending_tasks_++; | |
| 683 } | 711 } |
| 684 | 712 |
| 685 void TileManager::OnImageDecodeTaskCompleted( | 713 void TileManager::OnImageDecodeTaskCompleted(scoped_refptr<Tile> tile, |
| 686 scoped_refptr<Tile> tile, uint32_t pixel_ref_id) { | 714 uint32_t pixel_ref_id, |
| 715 bool was_cancelled) { | |
| 687 TRACE_EVENT0("cc", "TileManager::OnImageDecodeTaskCompleted"); | 716 TRACE_EVENT0("cc", "TileManager::OnImageDecodeTaskCompleted"); |
| 717 DCHECK(pending_decode_tasks_.find(pixel_ref_id) != | |
| 718 pending_decode_tasks_.end()); | |
| 719 pending_decode_tasks_.erase(pixel_ref_id); | |
| 720 if (was_cancelled) | |
| 721 return; | |
| 688 ManagedTileState& mts = tile->managed_state(); | 722 ManagedTileState& mts = tile->managed_state(); |
| 723 // Note: |decoded_pixel_refs| might already contain |pixel_ref_id| as | |
| 724 // the PrepareToDecode() check in ScheduleTasks() could have added it. | |
| 689 mts.decoded_pixel_refs.insert(pixel_ref_id); | 725 mts.decoded_pixel_refs.insert(pixel_ref_id); |
| 690 pending_decode_tasks_.erase(pixel_ref_id); | |
| 691 pending_tasks_--; | |
| 692 } | 726 } |
| 693 | 727 |
| 694 scoped_ptr<ResourcePool::Resource> TileManager::PrepareTileForRaster( | 728 RasterWorkerPool::Task TileManager::CreateRasterTask(Tile* tile) { |
| 695 Tile* tile) { | 729 TRACE_EVENT0("cc", "TileManager::CreateRasterTask"); |
| 696 scoped_ptr<ResourcePool::Resource> resource = resource_pool_->AcquireResource( | 730 |
| 697 tile->tile_size_.size(), | 731 scoped_ptr<ResourcePool::Resource> resource = |
| 698 tile->drawing_info().resource_format_); | 732 resource_pool_->AcquireResource( |
| 733 tile->tile_size_.size(), | |
| 734 tile->drawing_info().resource_format_); | |
| 699 resource_pool_->resource_provider()->AcquirePixelBuffer(resource->id()); | 735 resource_pool_->resource_provider()->AcquirePixelBuffer(resource->id()); |
| 700 | 736 |
| 737 DCHECK_EQ(CAN_USE_MEMORY, tile->drawing_info().memory_state_); | |
| 701 tile->drawing_info().memory_state_ = USING_UNRELEASABLE_MEMORY; | 738 tile->drawing_info().memory_state_ = USING_UNRELEASABLE_MEMORY; |
| 702 | 739 |
| 703 return resource.Pass(); | |
| 704 } | |
| 705 | |
| 706 void TileManager::DispatchOneRasterTask(scoped_refptr<Tile> tile) { | |
| 707 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask"); | |
| 708 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); | |
| 709 ResourceProvider::ResourceId resource_id = resource->id(); | |
| 710 PicturePileImpl::Analysis* analysis = new PicturePileImpl::Analysis; | 740 PicturePileImpl::Analysis* analysis = new PicturePileImpl::Analysis; |
| 711 | 741 |
| 712 // MapPixelBuffer() returns NULL if context was lost at the time | 742 // MapPixelBuffer() returns NULL if context was lost at the time |
| 713 // AcquirePixelBuffer() was called. For simplicity we still post | 743 // AcquirePixelBuffer() was called. For simplicity we still post |
| 714 // a raster task that is essentially a noop in these situations. | 744 // a raster task that is essentially a noop in these situations. |
| 715 uint8* buffer = resource_pool_->resource_provider()->MapPixelBuffer( | 745 uint8* buffer = resource_pool_->resource_provider()->MapPixelBuffer( |
| 716 resource_id); | 746 resource->id()); |
| 717 | 747 |
| 718 // skia requires that our buffer be 4-byte aligned | 748 // skia requires that our buffer be 4-byte aligned |
| 719 CHECK(!(reinterpret_cast<intptr_t>(buffer) & 3)); | 749 CHECK(!(reinterpret_cast<intptr_t>(buffer) & 3)); |
|
vmpstr
2013/05/06 18:05:51
I would vote that this moves into MapPixelBuffer,
reveman
2013/05/06 21:36:27
I agree. Moving it RP and closer to the source as
| |
| 720 | 750 |
| 721 raster_worker_pool_->PostRasterTaskAndReply( | 751 return RasterWorkerPool::PictureTask( |
| 722 tile->picture_pile(), | 752 tile->picture_pile(), |
| 723 base::Bind(&TileManager::RunAnalyzeAndRasterTask, | 753 base::Bind(&TileManager::RunAnalyzeAndRasterTask, |
| 724 base::Bind(&TileManager::RunAnalyzeTask, | 754 base::Bind(&TileManager::RunAnalyzeTask, |
| 725 analysis, | 755 analysis, |
| 726 tile->content_rect(), | 756 tile->content_rect(), |
| 727 tile->contents_scale(), | 757 tile->contents_scale(), |
| 728 use_color_estimator_, | 758 use_color_estimator_, |
| 729 GetRasterTaskMetadata(*tile), | 759 GetRasterTaskMetadata(*tile), |
| 730 rendering_stats_instrumentation_), | 760 rendering_stats_instrumentation_), |
| 731 base::Bind(&TileManager::RunRasterTask, | 761 base::Bind(&TileManager::RunRasterTask, |
| 732 buffer, | 762 buffer, |
| 733 analysis, | 763 analysis, |
| 734 tile->content_rect(), | 764 tile->content_rect(), |
| 735 tile->contents_scale(), | 765 tile->contents_scale(), |
| 736 GetRasterTaskMetadata(*tile), | 766 GetRasterTaskMetadata(*tile), |
| 737 rendering_stats_instrumentation_)), | 767 rendering_stats_instrumentation_)), |
| 738 base::Bind(&TileManager::OnRasterTaskCompleted, | 768 base::Bind(&TileManager::OnRasterTaskCompleted, |
| 739 base::Unretained(this), | 769 base::Unretained(this), |
| 740 tile, | 770 make_scoped_refptr(tile), |
| 741 base::Passed(&resource), | 771 base::Passed(&resource), |
| 742 base::Owned(analysis), | 772 base::Owned(analysis))); |
| 743 manage_tiles_call_count_)); | |
| 744 pending_tasks_++; | |
| 745 } | 773 } |
| 746 | 774 |
| 747 TileManager::RasterTaskMetadata TileManager::GetRasterTaskMetadata( | 775 TileManager::RasterTaskMetadata TileManager::GetRasterTaskMetadata( |
| 748 const Tile& tile) const { | 776 const Tile& tile) const { |
| 749 RasterTaskMetadata metadata; | 777 RasterTaskMetadata metadata; |
| 750 const ManagedTileState& mts = tile.managed_state(); | 778 const ManagedTileState& mts = tile.managed_state(); |
| 751 metadata.prediction_benchmarking = prediction_benchmarking_; | 779 metadata.prediction_benchmarking = prediction_benchmarking_; |
| 752 metadata.is_tile_in_pending_tree_now_bin = | 780 metadata.is_tile_in_pending_tree_now_bin = |
| 753 mts.tree_bin[PENDING_TREE] == NOW_BIN; | 781 mts.tree_bin[PENDING_TREE] == NOW_BIN; |
| 754 metadata.tile_resolution = mts.resolution; | 782 metadata.tile_resolution = mts.resolution; |
| 755 metadata.layer_id = tile.layer_id(); | 783 metadata.layer_id = tile.layer_id(); |
| 756 return metadata; | 784 return metadata; |
| 757 } | 785 } |
| 758 | 786 |
| 759 void TileManager::OnRasterTaskCompleted( | 787 void TileManager::OnRasterTaskCompleted( |
| 760 scoped_refptr<Tile> tile, | 788 scoped_refptr<Tile> tile, |
| 761 scoped_ptr<ResourcePool::Resource> resource, | 789 scoped_ptr<ResourcePool::Resource> resource, |
| 762 PicturePileImpl::Analysis* analysis, | 790 PicturePileImpl::Analysis* analysis, |
| 763 int manage_tiles_call_count_when_dispatched) { | 791 bool was_cancelled) { |
| 764 TRACE_EVENT0("cc", "TileManager::OnRasterTaskCompleted"); | 792 TRACE_EVENT0("cc", "TileManager::OnRasterTaskCompleted"); |
| 765 | 793 |
| 766 pending_tasks_--; | 794 ManagedTileState& mts = tile->managed_state(); |
| 795 DCHECK(!mts.raster_task.is_null()); | |
| 796 mts.raster_task.Reset(); | |
| 797 | |
| 798 // Tile resources can't be freed until upload has completed. | |
| 799 DCHECK_EQ(USING_UNRELEASABLE_MEMORY, tile->drawing_info().memory_state_); | |
| 767 | 800 |
| 768 // Release raster resources. | 801 // Release raster resources. |
| 769 resource_pool_->resource_provider()->UnmapPixelBuffer(resource->id()); | 802 resource_pool_->resource_provider()->UnmapPixelBuffer(resource->id()); |
| 770 | 803 |
| 771 tile->drawing_info().memory_state_ = USING_RELEASABLE_MEMORY; | 804 if (was_cancelled) { |
| 805 tile->drawing_info().memory_state_ = CAN_USE_MEMORY; | |
|
vmpstr
2013/05/06 18:05:51
Why can use memory? I would think that if it was c
reveman
2013/05/06 21:36:27
The tile will always be allowed to use memory at t
| |
| 806 resource_pool_->resource_provider()->ReleasePixelBuffer(resource->id()); | |
| 807 resource_pool_->ReleaseResource(resource.Pass()); | |
| 808 return; | |
| 809 } | |
| 772 | 810 |
| 773 ManagedTileState& managed_tile_state = tile->managed_state(); | 811 mts.picture_pile_analysis = *analysis; |
| 774 managed_tile_state.picture_pile_analysis = *analysis; | 812 mts.picture_pile_analyzed = true; |
| 775 managed_tile_state.picture_pile_analyzed = true; | |
| 776 | 813 |
| 777 if (analysis->is_solid_color) { | 814 if (analysis->is_solid_color) { |
| 778 tile->drawing_info().set_solid_color(analysis->solid_color); | 815 tile->drawing_info().set_solid_color(analysis->solid_color); |
| 779 resource_pool_->resource_provider()->ReleasePixelBuffer(resource->id()); | 816 resource_pool_->resource_provider()->ReleasePixelBuffer(resource->id()); |
| 780 resource_pool_->ReleaseResource(resource.Pass()); | 817 resource_pool_->ReleaseResource(resource.Pass()); |
| 781 DidFinishTileInitialization(tile); | 818 DidFinishTileInitialization(tile); |
| 782 return; | 819 return; |
| 783 } | 820 } |
| 784 | 821 |
| 785 // Tile can be freed after the completion of the raster task. Call | 822 resource_pool_->resource_provider()->BeginSetPixels(resource->id()); |
| 786 // AssignGpuMemoryToTiles() to re-assign gpu memory to highest priority | 823 has_performed_uploads_since_last_flush_ = true; |
| 787 // tiles if ManageTiles() was called since task was dispatched. The result | |
| 788 // of this could be that this tile is no longer allowed to use gpu | |
| 789 // memory and in that case we need to abort initialization and free all | |
| 790 // associated resources before calling DispatchMoreTasks(). | |
| 791 if (manage_tiles_call_count_when_dispatched != manage_tiles_call_count_) | |
| 792 AssignGpuMemoryToTiles(); | |
| 793 | 824 |
| 794 // Finish resource initialization we're still using memory. | 825 tile->drawing_info().resource_ = resource.Pass(); |
| 795 if (tile->drawing_info().memory_state_ == USING_RELEASABLE_MEMORY) { | |
| 796 // Tile resources can't be freed until upload has completed. | |
| 797 tile->drawing_info().memory_state_ = USING_UNRELEASABLE_MEMORY; | |
| 798 | 826 |
| 799 resource_pool_->resource_provider()->BeginSetPixels(resource->id()); | 827 bytes_pending_upload_ += tile->bytes_consumed_if_allocated(); |
| 800 has_performed_uploads_since_last_flush_ = true; | 828 tiles_with_pending_upload_.push(tile); |
| 801 | |
| 802 tile->drawing_info().resource_ = resource.Pass(); | |
| 803 | |
| 804 bytes_pending_upload_ += tile->bytes_consumed_if_allocated(); | |
| 805 tiles_with_pending_upload_.push(tile); | |
| 806 } else { | |
| 807 resource_pool_->resource_provider()->ReleasePixelBuffer(resource->id()); | |
| 808 resource_pool_->ReleaseResource(resource.Pass()); | |
| 809 } | |
| 810 } | 829 } |
| 811 | 830 |
| 812 void TileManager::DidFinishTileInitialization(Tile* tile) { | 831 void TileManager::DidFinishTileInitialization(Tile* tile) { |
| 813 if (tile->priority(ACTIVE_TREE).distance_to_visible_in_pixels == 0) | 832 if (tile->priority(ACTIVE_TREE).distance_to_visible_in_pixels == 0) |
| 814 did_initialize_visible_tile_ = true; | 833 did_initialize_visible_tile_ = true; |
| 815 } | 834 } |
| 816 | 835 |
| 817 void TileManager::DidTileTreeBinChange(Tile* tile, | 836 void TileManager::DidTileTreeBinChange(Tile* tile, |
| 818 TileManagerBin new_tree_bin, | 837 TileManagerBin new_tree_bin, |
| 819 WhichTree tree) { | 838 WhichTree tree) { |
| 820 ManagedTileState& mts = tile->managed_state(); | 839 ManagedTileState& mts = tile->managed_state(); |
| 821 mts.tree_bin[tree] = new_tree_bin; | 840 mts.tree_bin[tree] = new_tree_bin; |
| 822 } | 841 } |
| 823 | 842 |
| 824 // static | 843 // static |
| 844 void TileManager::RunImageDecodeTask( | |
| 845 skia::LazyPixelRef* pixel_ref, | |
| 846 RenderingStatsInstrumentation* stats_instrumentation) { | |
| 847 TRACE_EVENT0("cc", "TileManager::RunImageDecodeTask"); | |
| 848 base::TimeTicks start_time = stats_instrumentation->StartRecording(); | |
| 849 pixel_ref->Decode(); | |
| 850 base::TimeDelta duration = stats_instrumentation->EndRecording(start_time); | |
| 851 stats_instrumentation->AddDeferredImageDecode(duration); | |
| 852 } | |
| 853 | |
| 854 // static | |
| 825 void TileManager::RunAnalyzeAndRasterTask( | 855 void TileManager::RunAnalyzeAndRasterTask( |
| 826 const RasterWorkerPool::RasterCallback& analyze_task, | 856 const RasterWorkerPool::PictureTask::Callback& analyze_task, |
| 827 const RasterWorkerPool::RasterCallback& raster_task, | 857 const RasterWorkerPool::PictureTask::Callback& raster_task, |
| 828 PicturePileImpl* picture_pile) { | 858 PicturePileImpl* picture_pile) { |
| 829 analyze_task.Run(picture_pile); | 859 analyze_task.Run(picture_pile); |
| 830 raster_task.Run(picture_pile); | 860 raster_task.Run(picture_pile); |
| 831 } | 861 } |
| 832 | 862 |
| 833 // static | 863 // static |
| 834 void TileManager::RunAnalyzeTask( | 864 void TileManager::RunAnalyzeTask( |
| 835 PicturePileImpl::Analysis* analysis, | 865 PicturePileImpl::Analysis* analysis, |
| 836 gfx::Rect rect, | 866 gfx::Rect rect, |
| 837 float contents_scale, | 867 float contents_scale, |
| (...skipping 81 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 919 raster_stats.total_rasterize_time.InMicroseconds(), | 949 raster_stats.total_rasterize_time.InMicroseconds(), |
| 920 0, | 950 0, |
| 921 100000, | 951 100000, |
| 922 100); | 952 100); |
| 923 } else { | 953 } else { |
| 924 picture_pile->Raster(&canvas, rect, contents_scale, NULL); | 954 picture_pile->Raster(&canvas, rect, contents_scale, NULL); |
| 925 } | 955 } |
| 926 } | 956 } |
| 927 | 957 |
| 928 // static | 958 // static |
| 929 void TileManager::RunImageDecodeTask( | |
| 930 skia::LazyPixelRef* pixel_ref, | |
| 931 RenderingStatsInstrumentation* stats_instrumentation) { | |
| 932 TRACE_EVENT0("cc", "TileManager::RunImageDecodeTask"); | |
| 933 base::TimeTicks start_time = stats_instrumentation->StartRecording(); | |
| 934 pixel_ref->Decode(); | |
| 935 base::TimeDelta duration = stats_instrumentation->EndRecording(start_time); | |
| 936 stats_instrumentation->AddDeferredImageDecode(duration); | |
| 937 } | |
| 938 | |
| 939 // static | |
| 940 void TileManager::RecordSolidColorPredictorResults( | 959 void TileManager::RecordSolidColorPredictorResults( |
| 941 const SkPMColor* actual_colors, | 960 const SkPMColor* actual_colors, |
| 942 size_t color_count, | 961 size_t color_count, |
| 943 bool is_predicted_solid, | 962 bool is_predicted_solid, |
| 944 SkPMColor predicted_color) { | 963 SkPMColor predicted_color) { |
| 945 DCHECK_GT(color_count, 0u); | 964 DCHECK_GT(color_count, 0u); |
| 946 | 965 |
| 947 bool is_actually_solid = true; | 966 bool is_actually_solid = true; |
| 948 | 967 |
| 949 SkPMColor actual_color = *actual_colors; | 968 SkPMColor actual_color = *actual_colors; |
| (...skipping 14 matching lines...) Expand all Loading... | |
| 964 is_predicted_solid && predicted_color != actual_color); | 983 is_predicted_solid && predicted_color != actual_color); |
| 965 HISTOGRAM_BOOLEAN("Renderer4.ColorPredictor.Accuracy", | 984 HISTOGRAM_BOOLEAN("Renderer4.ColorPredictor.Accuracy", |
| 966 is_predicted_solid == is_actually_solid && | 985 is_predicted_solid == is_actually_solid && |
| 967 (!is_predicted_solid || predicted_color == actual_color)); | 986 (!is_predicted_solid || predicted_color == actual_color)); |
| 968 HISTOGRAM_BOOLEAN("Renderer4.ColorPredictor.IsCorrectSolid", | 987 HISTOGRAM_BOOLEAN("Renderer4.ColorPredictor.IsCorrectSolid", |
| 969 is_predicted_solid == is_actually_solid && | 988 is_predicted_solid == is_actually_solid && |
| 970 (is_predicted_solid && predicted_color == actual_color)); | 989 (is_predicted_solid && predicted_color == actual_color)); |
| 971 } | 990 } |
| 972 | 991 |
| 973 } // namespace cc | 992 } // namespace cc |
| OLD | NEW |