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/tile_manager.h" | 5 #include "cc/tile_manager.h" |
| 6 | 6 |
| 7 #include <algorithm> | 7 #include <algorithm> |
| 8 | 8 |
| 9 #include "base/bind.h" | 9 #include "base/bind.h" |
| 10 #include "base/debug/trace_event.h" | 10 #include "base/debug/trace_event.h" |
| (...skipping 127 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 138 ManagedTileState::ManagedTileState() | 138 ManagedTileState::ManagedTileState() |
| 139 : can_use_gpu_memory(false), | 139 : can_use_gpu_memory(false), |
| 140 can_be_freed(true), | 140 can_be_freed(true), |
| 141 resource_is_being_initialized(false), | 141 resource_is_being_initialized(false), |
| 142 contents_swizzled(false), | 142 contents_swizzled(false), |
| 143 need_to_gather_pixel_refs(true), | 143 need_to_gather_pixel_refs(true), |
| 144 gpu_memmgr_stats_bin(NEVER_BIN), | 144 gpu_memmgr_stats_bin(NEVER_BIN), |
| 145 raster_state(IDLE_STATE), | 145 raster_state(IDLE_STATE), |
| 146 resolution(NON_IDEAL_RESOLUTION), | 146 resolution(NON_IDEAL_RESOLUTION), |
| 147 time_to_needed_in_seconds(std::numeric_limits<float>::infinity()), | 147 time_to_needed_in_seconds(std::numeric_limits<float>::infinity()), |
| 148 distance_to_visible_in_pixels(std::numeric_limits<float>::infinity()) { | 148 distance_to_visible_in_pixels(std::numeric_limits<float>::infinity()), |
| 149 picture_pile_analyzed(false) { | |
| 149 for (int i = 0; i < NUM_TREES; ++i) { | 150 for (int i = 0; i < NUM_TREES; ++i) { |
| 150 tree_bin[i] = NEVER_BIN; | 151 tree_bin[i] = NEVER_BIN; |
| 151 bin[i] = NEVER_BIN; | 152 bin[i] = NEVER_BIN; |
| 152 } | 153 } |
| 153 } | 154 } |
| 154 | 155 |
| 155 ManagedTileState::~ManagedTileState() { | 156 ManagedTileState::~ManagedTileState() { |
| 156 DCHECK(!resource); | 157 DCHECK(!resource); |
| 157 DCHECK(!resource_is_being_initialized); | 158 DCHECK(!resource_is_being_initialized); |
| 158 } | 159 } |
| 159 | 160 |
| 160 scoped_ptr<base::Value> ManagedTileState::AsValue() const { | 161 scoped_ptr<base::Value> ManagedTileState::AsValue() const { |
| 161 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); | 162 scoped_ptr<base::DictionaryValue> state(new base::DictionaryValue()); |
| 162 state->SetBoolean("can_use_gpu_memory", can_use_gpu_memory); | 163 state->SetBoolean("can_use_gpu_memory", can_use_gpu_memory); |
| 163 state->SetBoolean("can_be_freed", can_be_freed); | 164 state->SetBoolean("can_be_freed", can_be_freed); |
| 164 state->SetBoolean("has_resource", resource.get() != 0); | 165 state->SetBoolean("has_resource", resource.get() != 0); |
| 165 state->SetBoolean("resource_is_being_initialized", resource_is_being_initializ ed); | 166 state->SetBoolean("resource_is_being_initialized", resource_is_being_initializ ed); |
| 166 state->Set("raster_state", TileRasterStateAsValue(raster_state).release()); | 167 state->Set("raster_state", TileRasterStateAsValue(raster_state).release()); |
| 167 state->Set("bin.0", TileManagerBinAsValue(bin[ACTIVE_TREE]).release()); | 168 state->Set("bin.0", TileManagerBinAsValue(bin[ACTIVE_TREE]).release()); |
| 168 state->Set("bin.1", TileManagerBinAsValue(bin[PENDING_TREE]).release()); | 169 state->Set("bin.1", TileManagerBinAsValue(bin[PENDING_TREE]).release()); |
| 169 state->Set("gpu_memmgr_stats_bin", TileManagerBinAsValue(bin[ACTIVE_TREE]).rel ease()); | 170 state->Set("gpu_memmgr_stats_bin", TileManagerBinAsValue(bin[ACTIVE_TREE]).rel ease()); |
| 170 state->Set("resolution", TileResolutionAsValue(resolution).release()); | 171 state->Set("resolution", TileResolutionAsValue(resolution).release()); |
| 171 state->Set("time_to_needed_in_seconds", MathUtil::asValueSafely(time_to_needed _in_seconds).release()); | 172 state->Set("time_to_needed_in_seconds", MathUtil::asValueSafely(time_to_needed _in_seconds).release()); |
| 172 state->Set("distance_to_visible_in_pixels", MathUtil::asValueSafely(distance_t o_visible_in_pixels).release()); | 173 state->Set("distance_to_visible_in_pixels", MathUtil::asValueSafely(distance_t o_visible_in_pixels).release()); |
|
Sami
2013/03/05 20:18:31
Please also record the analysis result here.
| |
| 173 return state.PassAs<base::Value>(); | 174 return state.PassAs<base::Value>(); |
| 174 } | 175 } |
| 175 | 176 |
| 176 TileManager::TileManager( | 177 TileManager::TileManager( |
| 177 TileManagerClient* client, | 178 TileManagerClient* client, |
| 178 ResourceProvider* resource_provider, | 179 ResourceProvider* resource_provider, |
| 179 size_t num_raster_threads, | 180 size_t num_raster_threads, |
| 180 bool use_cheapness_estimator) | 181 bool use_cheapness_estimator, |
| 182 bool use_color_estimator, | |
| 183 bool prediction_benchmarking) | |
| 181 : client_(client), | 184 : client_(client), |
| 182 resource_pool_(ResourcePool::Create(resource_provider)), | 185 resource_pool_(ResourcePool::Create(resource_provider)), |
| 183 raster_worker_pool_(RasterWorkerPool::Create(this, num_raster_threads)), | 186 raster_worker_pool_(RasterWorkerPool::Create(this, num_raster_threads)), |
| 184 manage_tiles_pending_(false), | 187 manage_tiles_pending_(false), |
| 185 manage_tiles_call_count_(0), | 188 manage_tiles_call_count_(0), |
| 186 bytes_pending_upload_(0), | 189 bytes_pending_upload_(0), |
| 187 has_performed_uploads_since_last_flush_(false), | 190 has_performed_uploads_since_last_flush_(false), |
| 188 ever_exceeded_memory_budget_(false), | 191 ever_exceeded_memory_budget_(false), |
| 189 record_rendering_stats_(false), | 192 record_rendering_stats_(false), |
| 190 use_cheapness_estimator_(use_cheapness_estimator), | 193 use_cheapness_estimator_(use_cheapness_estimator), |
| 194 use_color_estimator_(use_color_estimator), | |
| 191 allow_cheap_tasks_(true), | 195 allow_cheap_tasks_(true), |
| 192 did_schedule_cheap_tasks_(false) { | 196 did_schedule_cheap_tasks_(false), |
| 197 prediction_benchmarking_(prediction_benchmarking) { | |
| 193 for (int i = 0; i < NUM_STATES; ++i) { | 198 for (int i = 0; i < NUM_STATES; ++i) { |
| 194 for (int j = 0; j < NUM_TREES; ++j) { | 199 for (int j = 0; j < NUM_TREES; ++j) { |
| 195 for (int k = 0; k < NUM_BINS; ++k) | 200 for (int k = 0; k < NUM_BINS; ++k) |
| 196 raster_state_count_[i][j][k] = 0; | 201 raster_state_count_[i][j][k] = 0; |
| 197 } | 202 } |
| 198 } | 203 } |
| 199 } | 204 } |
| 200 | 205 |
| 201 TileManager::~TileManager() { | 206 TileManager::~TileManager() { |
| 202 // Reset global state and manage. This should cause | 207 // Reset global state and manage. This should cause |
| (...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 364 DidTileTreeBinChange(tile, | 369 DidTileTreeBinChange(tile, |
| 365 bin_map[BinFromTilePriority(tile->priority(ACTIVE_TREE))], | 370 bin_map[BinFromTilePriority(tile->priority(ACTIVE_TREE))], |
| 366 ACTIVE_TREE); | 371 ACTIVE_TREE); |
| 367 DidTileTreeBinChange(tile, | 372 DidTileTreeBinChange(tile, |
| 368 bin_map[BinFromTilePriority(tile->priority(PENDING_TREE))], | 373 bin_map[BinFromTilePriority(tile->priority(PENDING_TREE))], |
| 369 PENDING_TREE); | 374 PENDING_TREE); |
| 370 | 375 |
| 371 for (int i = 0; i < NUM_BIN_PRIORITIES; ++i) | 376 for (int i = 0; i < NUM_BIN_PRIORITIES; ++i) |
| 372 mts.bin[i] = bin_map[mts.bin[i]]; | 377 mts.bin[i] = bin_map[mts.bin[i]]; |
| 373 | 378 |
| 374 if (tile->priority(ACTIVE_TREE).is_live || | 379 if (!tile->managed_state().resource && |
| 375 tile->priority(PENDING_TREE).is_live || | 380 !tile->managed_state().resource_is_being_initialized && |
| 376 tile->managed_state().resource || | 381 !tile->priority(ACTIVE_TREE).is_live && |
| 377 tile->managed_state().resource_is_being_initialized) { | 382 !tile->priority(PENDING_TREE).is_live) |
| 378 live_or_allocated_tiles_.push_back(tile); | 383 continue; |
| 379 } | 384 |
| 385 live_or_allocated_tiles_.push_back(tile); | |
| 380 } | 386 } |
| 381 TRACE_COUNTER_ID1("cc", "LiveOrAllocatedTileCount", this, | 387 TRACE_COUNTER_ID1("cc", "LiveOrAllocatedTileCount", this, |
| 382 live_or_allocated_tiles_.size()); | 388 live_or_allocated_tiles_.size()); |
| 383 | 389 |
| 384 SortTiles(); | 390 SortTiles(); |
| 385 | 391 |
| 386 // Assign gpu memory and determine what tiles need to be rasterized. | 392 // Assign gpu memory and determine what tiles need to be rasterized. |
| 387 AssignGpuMemoryToTiles(); | 393 AssignGpuMemoryToTiles(); |
| 388 | 394 |
| 389 TRACE_EVENT_INSTANT1("cc", "DidManage", "state", | 395 TRACE_EVENT_INSTANT1("cc", "DidManage", "state", |
| (...skipping 59 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 449 did_schedule_cheap_tasks_ = false; | 455 did_schedule_cheap_tasks_ = false; |
| 450 } | 456 } |
| 451 | 457 |
| 452 void TileManager::GetMemoryStats( | 458 void TileManager::GetMemoryStats( |
| 453 size_t* memoryRequiredBytes, | 459 size_t* memoryRequiredBytes, |
| 454 size_t* memoryNiceToHaveBytes, | 460 size_t* memoryNiceToHaveBytes, |
| 455 size_t* memoryUsedBytes) const { | 461 size_t* memoryUsedBytes) const { |
| 456 *memoryRequiredBytes = 0; | 462 *memoryRequiredBytes = 0; |
| 457 *memoryNiceToHaveBytes = 0; | 463 *memoryNiceToHaveBytes = 0; |
| 458 *memoryUsedBytes = 0; | 464 *memoryUsedBytes = 0; |
| 459 for (size_t i = 0; i < live_or_allocated_tiles_.size(); i++) { | 465 for (size_t i = 0; i < live_or_allocated_tiles_.size(); i++) { |
|
Sami
2013/03/05 20:18:31
Do we need to skip solid/empty tiles here?
| |
| 460 const Tile* tile = live_or_allocated_tiles_[i]; | 466 const Tile* tile = live_or_allocated_tiles_[i]; |
| 461 const ManagedTileState& mts = tile->managed_state(); | 467 const ManagedTileState& mts = tile->managed_state(); |
| 462 size_t tile_bytes = tile->bytes_consumed_if_allocated(); | 468 size_t tile_bytes = tile->bytes_consumed_if_allocated(); |
| 463 if (mts.gpu_memmgr_stats_bin == NOW_BIN) | 469 if (mts.gpu_memmgr_stats_bin == NOW_BIN) |
| 464 *memoryRequiredBytes += tile_bytes; | 470 *memoryRequiredBytes += tile_bytes; |
| 465 if (mts.gpu_memmgr_stats_bin != NEVER_BIN) | 471 if (mts.gpu_memmgr_stats_bin != NEVER_BIN) |
| 466 *memoryNiceToHaveBytes += tile_bytes; | 472 *memoryNiceToHaveBytes += tile_bytes; |
| 467 if (mts.can_use_gpu_memory) | 473 if (mts.can_use_gpu_memory) |
| 468 *memoryUsedBytes += tile_bytes; | 474 *memoryUsedBytes += tile_bytes; |
| 469 } | 475 } |
| (...skipping 102 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 572 // By clearing the tiles_that_need_to_be_rasterized_ vector and | 578 // By clearing the tiles_that_need_to_be_rasterized_ vector and |
| 573 // tiles_with_image_decoding_tasks_ list above we move all tiles | 579 // tiles_with_image_decoding_tasks_ list above we move all tiles |
| 574 // currently waiting for raster to idle state. | 580 // currently waiting for raster to idle state. |
| 575 // Call DidTileRasterStateChange() for each of these tiles to | 581 // Call DidTileRasterStateChange() for each of these tiles to |
| 576 // have this state change take effect. | 582 // have this state change take effect. |
| 577 // Some memory cannot be released. We figure out how much in this | 583 // Some memory cannot be released. We figure out how much in this |
| 578 // loop as well. | 584 // loop as well. |
| 579 for (TileVector::iterator it = live_or_allocated_tiles_.begin(); | 585 for (TileVector::iterator it = live_or_allocated_tiles_.begin(); |
| 580 it != live_or_allocated_tiles_.end(); ++it) { | 586 it != live_or_allocated_tiles_.end(); ++it) { |
| 581 Tile* tile = *it; | 587 Tile* tile = *it; |
| 582 if (!tile->managed_state().can_be_freed) | 588 if (tile->is_solid_color() || tile->is_transparent()) |
| 589 continue; | |
| 590 | |
| 591 ManagedTileState& managed_state = tile->managed_state(); | |
| 592 if (!managed_state.can_be_freed) | |
| 583 unreleasable_bytes += tile->bytes_consumed_if_allocated(); | 593 unreleasable_bytes += tile->bytes_consumed_if_allocated(); |
| 584 if (tile->managed_state().raster_state == WAITING_FOR_RASTER_STATE) | 594 if (managed_state.raster_state == WAITING_FOR_RASTER_STATE) |
| 585 DidTileRasterStateChange(tile, IDLE_STATE); | 595 DidTileRasterStateChange(tile, IDLE_STATE); |
| 586 } | 596 } |
| 587 | 597 |
| 588 size_t bytes_allocatable = global_state_.memory_limit_in_bytes - unreleasable_ bytes; | 598 size_t bytes_allocatable = global_state_.memory_limit_in_bytes - unreleasable_ bytes; |
| 589 size_t bytes_that_exceeded_memory_budget_in_now_bin = 0; | 599 size_t bytes_that_exceeded_memory_budget_in_now_bin = 0; |
| 590 size_t bytes_left = bytes_allocatable; | 600 size_t bytes_left = bytes_allocatable; |
| 591 for (TileVector::iterator it = live_or_allocated_tiles_.begin(); it != live_or _allocated_tiles_.end(); ++it) { | 601 for (TileVector::iterator it = live_or_allocated_tiles_.begin(); it != live_or _allocated_tiles_.end(); ++it) { |
| 592 Tile* tile = *it; | 602 Tile* tile = *it; |
| 603 if (tile->is_solid_color() || tile->is_transparent()) | |
| 604 continue; | |
| 605 | |
| 606 ManagedTileState& managed_state = tile->managed_state(); | |
|
Sami
2013/03/05 20:18:31
The rest of the file calls this managed_tile_state
| |
| 593 size_t tile_bytes = tile->bytes_consumed_if_allocated(); | 607 size_t tile_bytes = tile->bytes_consumed_if_allocated(); |
| 594 ManagedTileState& managed_tile_state = tile->managed_state(); | 608 if (!managed_state.can_be_freed) |
| 595 if (!managed_tile_state.can_be_freed) | |
| 596 continue; | 609 continue; |
| 597 if (managed_tile_state.bin[HIGH_PRIORITY_BIN] == NEVER_BIN && | 610 if (managed_state.bin[HIGH_PRIORITY_BIN] == NEVER_BIN && |
| 598 managed_tile_state.bin[LOW_PRIORITY_BIN] == NEVER_BIN) { | 611 managed_state.bin[LOW_PRIORITY_BIN] == NEVER_BIN) { |
| 599 managed_tile_state.can_use_gpu_memory = false; | 612 managed_state.can_use_gpu_memory = false; |
| 600 FreeResourcesForTile(tile); | 613 FreeResourcesForTile(tile); |
| 601 continue; | 614 continue; |
| 602 } | 615 } |
| 603 if (tile_bytes > bytes_left) { | 616 if (tile_bytes > bytes_left) { |
| 604 managed_tile_state.can_use_gpu_memory = false; | 617 managed_state.can_use_gpu_memory = false; |
| 605 if (managed_tile_state.bin[HIGH_PRIORITY_BIN] == NOW_BIN || | 618 if (managed_state.bin[HIGH_PRIORITY_BIN] == NOW_BIN || |
| 606 managed_tile_state.bin[LOW_PRIORITY_BIN] == NOW_BIN) | 619 managed_state.bin[LOW_PRIORITY_BIN] == NOW_BIN) |
| 607 bytes_that_exceeded_memory_budget_in_now_bin += tile_bytes; | 620 bytes_that_exceeded_memory_budget_in_now_bin += tile_bytes; |
| 608 FreeResourcesForTile(tile); | 621 FreeResourcesForTile(tile); |
| 609 continue; | 622 continue; |
| 610 } | 623 } |
| 611 bytes_left -= tile_bytes; | 624 bytes_left -= tile_bytes; |
| 612 managed_tile_state.can_use_gpu_memory = true; | 625 managed_state.can_use_gpu_memory = true; |
| 613 if (!managed_tile_state.resource && | 626 if (!managed_state.resource && |
| 614 !managed_tile_state.resource_is_being_initialized) { | 627 !managed_state.resource_is_being_initialized) { |
| 615 tiles_that_need_to_be_rasterized_.push_back(tile); | 628 tiles_that_need_to_be_rasterized_.push_back(tile); |
| 616 DidTileRasterStateChange(tile, WAITING_FOR_RASTER_STATE); | 629 DidTileRasterStateChange(tile, WAITING_FOR_RASTER_STATE); |
| 617 } | 630 } |
| 618 } | 631 } |
| 619 | 632 |
| 620 ever_exceeded_memory_budget_ |= | 633 ever_exceeded_memory_budget_ |= |
| 621 bytes_that_exceeded_memory_budget_in_now_bin > 0; | 634 bytes_that_exceeded_memory_budget_in_now_bin > 0; |
| 622 if (ever_exceeded_memory_budget_) { | 635 if (ever_exceeded_memory_budget_) { |
| 623 TRACE_COUNTER_ID2("cc", "over_memory_budget", this, | 636 TRACE_COUNTER_ID2("cc", "over_memory_budget", this, |
| 624 "budget", global_state_.memory_limit_in_bytes, | 637 "budget", global_state_.memory_limit_in_bytes, |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 657 | 670 |
| 658 void TileManager::DispatchMoreTasks() { | 671 void TileManager::DispatchMoreTasks() { |
| 659 if (did_schedule_cheap_tasks_) | 672 if (did_schedule_cheap_tasks_) |
| 660 allow_cheap_tasks_ = false; | 673 allow_cheap_tasks_ = false; |
| 661 | 674 |
| 662 // Because tiles in the image decoding list have higher priorities, we | 675 // Because tiles in the image decoding list have higher priorities, we |
| 663 // need to process those tiles first before we start to handle the tiles | 676 // need to process those tiles first before we start to handle the tiles |
| 664 // in the need_to_be_rasterized queue. | 677 // in the need_to_be_rasterized queue. |
| 665 for(TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); | 678 for(TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); |
| 666 it != tiles_with_image_decoding_tasks_.end(); ) { | 679 it != tiles_with_image_decoding_tasks_.end(); ) { |
| 680 Tile* tile = *it; | |
|
Sami
2013/03/05 20:18:31
This looks unused.
| |
| 681 ManagedTileState& managed_state = (*it)->managed_state(); | |
|
Sami
2013/03/05 20:18:31
Is the idea that tiles with image decoding tasks a
| |
| 667 DispatchImageDecodeTasksForTile(*it); | 682 DispatchImageDecodeTasksForTile(*it); |
| 668 ManagedTileState& managed_state = (*it)->managed_state(); | |
| 669 if (managed_state.pending_pixel_refs.empty()) { | 683 if (managed_state.pending_pixel_refs.empty()) { |
| 670 if (!CanDispatchRasterTask(*it)) | 684 if (!CanDispatchRasterTask(*it)) |
| 671 return; | 685 return; |
| 672 DispatchOneRasterTask(*it); | 686 DispatchOneRasterTask(*it); |
| 673 tiles_with_image_decoding_tasks_.erase(it++); | 687 tiles_with_image_decoding_tasks_.erase(it++); |
| 674 } else { | 688 } else { |
| 675 ++it; | 689 ++it; |
| 676 } | 690 } |
| 677 } | 691 } |
| 678 | 692 |
| 679 // Process all tiles in the need_to_be_rasterized queue. If a tile has | 693 // Process all tiles in the need_to_be_rasterized queue. If a tile has |
| 680 // image decoding tasks, put it to the back of the image decoding list. | 694 // image decoding tasks, put it to the back of the image decoding list. |
| 681 while (!tiles_that_need_to_be_rasterized_.empty()) { | 695 while (!tiles_that_need_to_be_rasterized_.empty()) { |
| 682 Tile* tile = tiles_that_need_to_be_rasterized_.back(); | 696 Tile* tile = tiles_that_need_to_be_rasterized_.back(); |
| 697 ManagedTileState& managed_state = tile->managed_state(); | |
|
Sami
2013/03/05 20:18:31
This function is getting long -- mind the analysis
| |
| 698 | |
| 699 if ((use_cheapness_estimator_ || | |
| 700 use_color_estimator_) && | |
| 701 !managed_state.picture_pile_analyzed) { | |
| 702 tile->picture_pile()->AnalyzeInRect(tile->content_rect(), | |
| 703 tile->contents_scale(), | |
| 704 &managed_state.picture_pile_analysis); | |
| 705 managed_state.picture_pile_analysis.is_cheap_to_raster &= | |
| 706 use_cheapness_estimator_; | |
| 707 managed_state.picture_pile_analysis.is_solid_color &= | |
| 708 use_color_estimator_; | |
| 709 managed_state.picture_pile_analysis.is_transparent &= | |
| 710 use_color_estimator_; | |
| 711 managed_state.picture_pile_analyzed = true; | |
| 712 } | |
| 713 | |
| 714 if (managed_state.picture_pile_analysis.is_solid_color || | |
| 715 managed_state.picture_pile_analysis.is_transparent) { | |
| 716 DidTileRasterStateChange(tile, IDLE_STATE); | |
| 717 tiles_that_need_to_be_rasterized_.pop_back(); | |
| 718 continue; | |
| 719 } | |
| 720 | |
| 683 DispatchImageDecodeTasksForTile(tile); | 721 DispatchImageDecodeTasksForTile(tile); |
| 684 ManagedTileState& managed_state = tile->managed_state(); | |
| 685 if (!managed_state.pending_pixel_refs.empty()) { | 722 if (!managed_state.pending_pixel_refs.empty()) { |
| 686 tiles_with_image_decoding_tasks_.push_back(tile); | 723 tiles_with_image_decoding_tasks_.push_back(tile); |
| 687 } else { | 724 } else { |
| 688 if (!CanDispatchRasterTask(tile)) | 725 if (!CanDispatchRasterTask(tile)) |
| 689 return; | 726 return; |
| 690 DispatchOneRasterTask(tile); | 727 DispatchOneRasterTask(tile); |
| 691 } | 728 } |
| 692 tiles_that_need_to_be_rasterized_.pop_back(); | 729 tiles_that_need_to_be_rasterized_.pop_back(); |
| 693 } | 730 } |
| 694 } | 731 } |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 787 return resource.Pass(); | 824 return resource.Pass(); |
| 788 } | 825 } |
| 789 | 826 |
| 790 void TileManager::DispatchOneRasterTask(scoped_refptr<Tile> tile) { | 827 void TileManager::DispatchOneRasterTask(scoped_refptr<Tile> tile) { |
| 791 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask"); | 828 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask"); |
| 792 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); | 829 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); |
| 793 ResourceProvider::ResourceId resource_id = resource->id(); | 830 ResourceProvider::ResourceId resource_id = resource->id(); |
| 794 uint8* buffer = | 831 uint8* buffer = |
| 795 resource_pool_->resource_provider()->mapPixelBuffer(resource_id); | 832 resource_pool_->resource_provider()->mapPixelBuffer(resource_id); |
| 796 | 833 |
| 797 bool is_cheap = use_cheapness_estimator_ && allow_cheap_tasks_ && | 834 ManagedTileState& managed_state = tile->managed_state(); |
| 798 tile->picture_pile()->IsCheapInRect(tile->content_rect_, | 835 bool is_cheap_to_raster = |
| 799 tile->contents_scale()); | 836 managed_state.picture_pile_analysis.is_cheap_to_raster; |
|
Sami
2013/03/05 20:18:31
Nit: indent by 4.
| |
| 800 raster_worker_pool_->PostRasterTaskAndReply( | 837 raster_worker_pool_->PostRasterTaskAndReply( |
| 801 tile->picture_pile(), | 838 tile->picture_pile(), |
| 802 is_cheap, | 839 allow_cheap_tasks_ && is_cheap_to_raster, |
| 803 base::Bind(&TileManager::RunRasterTask, | 840 base::Bind(&TileManager::RunRasterTask, |
| 804 buffer, | 841 buffer, |
| 805 tile->content_rect(), | 842 tile->content_rect(), |
| 806 tile->contents_scale(), | 843 tile->contents_scale(), |
| 807 GetRasterTaskMetadata(*tile)), | 844 GetRasterTaskMetadata(*tile)), |
| 808 base::Bind(&TileManager::OnRasterTaskCompleted, | 845 base::Bind(&TileManager::OnRasterTaskCompleted, |
| 809 base::Unretained(this), | 846 base::Unretained(this), |
| 810 tile, | 847 tile, |
| 811 base::Passed(&resource), | 848 base::Passed(&resource), |
| 812 manage_tiles_call_count_)); | 849 manage_tiles_call_count_)); |
| 813 did_schedule_cheap_tasks_ |= is_cheap; | 850 did_schedule_cheap_tasks_ |= (allow_cheap_tasks_ && is_cheap_to_raster); |
| 814 } | 851 } |
| 815 | 852 |
| 816 TileManager::RasterTaskMetadata TileManager::GetRasterTaskMetadata( | 853 TileManager::RasterTaskMetadata TileManager::GetRasterTaskMetadata( |
| 817 const Tile& tile) const { | 854 const Tile& tile) const { |
| 818 RasterTaskMetadata metadata; | 855 RasterTaskMetadata metadata; |
| 819 const ManagedTileState& mts = tile.managed_state(); | 856 const ManagedTileState& mts = tile.managed_state(); |
| 820 metadata.use_cheapness_estimator = use_cheapness_estimator_; | 857 metadata.prediction_benchmarking = prediction_benchmarking_; |
| 821 metadata.is_tile_in_pending_tree_now_bin = | 858 metadata.is_tile_in_pending_tree_now_bin = |
| 822 mts.tree_bin[PENDING_TREE] == NOW_BIN; | 859 mts.tree_bin[PENDING_TREE] == NOW_BIN; |
| 823 metadata.tile_resolution = mts.resolution; | 860 metadata.tile_resolution = mts.resolution; |
| 824 metadata.layer_id = tile.layer_id(); | 861 metadata.layer_id = tile.layer_id(); |
| 825 return metadata; | 862 return metadata; |
| 826 } | 863 } |
| 827 | 864 |
| 828 void TileManager::OnRasterTaskCompleted( | 865 void TileManager::OnRasterTaskCompleted( |
| 829 scoped_refptr<Tile> tile, | 866 scoped_refptr<Tile> tile, |
| 830 scoped_ptr<ResourcePool::Resource> resource, | 867 scoped_ptr<ResourcePool::Resource> resource, |
| (...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... | |
| 951 stats->totalRasterizeTime += duration; | 988 stats->totalRasterizeTime += duration; |
| 952 if (metadata.is_tile_in_pending_tree_now_bin) | 989 if (metadata.is_tile_in_pending_tree_now_bin) |
| 953 stats->totalRasterizeTimeForNowBinsOnPendingTree += duration; | 990 stats->totalRasterizeTimeForNowBinsOnPendingTree += duration; |
| 954 | 991 |
| 955 UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.PictureRasterTimeMS", | 992 UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.PictureRasterTimeMS", |
| 956 duration.InMilliseconds(), | 993 duration.InMilliseconds(), |
| 957 0, | 994 0, |
| 958 10, | 995 10, |
| 959 10); | 996 10); |
| 960 | 997 |
| 961 if (metadata.use_cheapness_estimator) { | 998 if (metadata.prediction_benchmarking) { |
| 962 bool is_predicted_cheap = | 999 PicturePileImpl::Analysis analysis; |
| 963 picture_pile->IsCheapInRect(rect, contents_scale); | 1000 picture_pile->AnalyzeInRect(rect, contents_scale, &analysis); |
| 1001 bool is_predicted_cheap = analysis.is_cheap_to_raster; | |
| 964 bool is_actually_cheap = duration.InMillisecondsF() <= 1.0f; | 1002 bool is_actually_cheap = duration.InMillisecondsF() <= 1.0f; |
| 965 RecordCheapnessPredictorResults(is_predicted_cheap, is_actually_cheap); | 1003 RecordCheapnessPredictorResults(is_predicted_cheap, is_actually_cheap); |
| 1004 | |
| 1005 RecordSolidColorPredictorResults( | |
| 1006 reinterpret_cast<SkColor*>(bitmap.getPixels()), | |
| 1007 bitmap.getSize() / bitmap.bytesPerPixel(), | |
| 1008 analysis.is_solid_color, | |
| 1009 analysis.solid_color, | |
| 1010 analysis.is_transparent); | |
| 966 } | 1011 } |
| 967 } | 1012 } |
| 968 } | 1013 } |
| 969 | 1014 |
| 970 // static | 1015 // static |
| 971 void TileManager::RecordCheapnessPredictorResults(bool is_predicted_cheap, | 1016 void TileManager::RecordCheapnessPredictorResults(bool is_predicted_cheap, |
| 972 bool is_actually_cheap) { | 1017 bool is_actually_cheap) { |
| 973 if (is_predicted_cheap && !is_actually_cheap) | 1018 if (is_predicted_cheap && !is_actually_cheap) |
| 974 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorBadlyWrong", true); | 1019 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorBadlyWrong", true); |
| 975 else if (!is_predicted_cheap && is_actually_cheap) | 1020 else if (!is_predicted_cheap && is_actually_cheap) |
| 976 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorSafelyWrong", true); | 1021 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorSafelyWrong", true); |
| 977 | 1022 |
| 978 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorAccuracy", | 1023 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorAccuracy", |
| 979 is_predicted_cheap == is_actually_cheap); | 1024 is_predicted_cheap == is_actually_cheap); |
| 980 } | 1025 } |
| 981 | 1026 |
| 982 // static | 1027 // static |
| 1028 void TileManager::RecordSolidColorPredictorResults( | |
| 1029 const SkColor* actual_colors, | |
| 1030 size_t color_count, | |
| 1031 bool is_predicted_solid, | |
| 1032 SkColor predicted_color, | |
| 1033 bool is_predicted_transparent) { | |
| 1034 DCHECK_GT(color_count, 0); | |
| 1035 | |
| 1036 bool is_actually_solid = true; | |
| 1037 bool is_transparent = true; | |
| 1038 | |
| 1039 SkColor actual_color = *actual_colors; | |
| 1040 for (int i = 0; i < color_count; ++i) { | |
| 1041 SkColor current_color = actual_colors[i]; | |
| 1042 if (current_color != actual_color || | |
| 1043 SkColorGetA(current_color) != 255) | |
| 1044 is_actually_solid = false; | |
| 1045 | |
| 1046 if (SkColorGetA(current_color) != 0) | |
| 1047 is_transparent = false; | |
| 1048 } | |
|
Sami
2013/03/05 20:18:31
Add if (!is_actually_solid || !is_transparent) bre
| |
| 1049 | |
| 1050 if (is_predicted_solid && !is_actually_solid) | |
| 1051 UMA_HISTOGRAM_BOOLEAN("Renderer4.ColorPredictor.WrongActualNotSolid", true); | |
| 1052 else if (is_predicted_solid && | |
| 1053 is_actually_solid && | |
| 1054 predicted_color != actual_color) | |
| 1055 UMA_HISTOGRAM_BOOLEAN("Renderer4.ColorPredictor.WrongColor", true); | |
| 1056 else if (!is_predicted_solid && is_actually_solid) | |
| 1057 UMA_HISTOGRAM_BOOLEAN("Renderer4.ColorPredictor.WrongActualSolid", true); | |
| 1058 | |
| 1059 bool correct_guess = (is_predicted_solid && is_actually_solid && | |
| 1060 predicted_color == actual_color) || | |
| 1061 (!is_predicted_solid && !is_actually_solid); | |
| 1062 UMA_HISTOGRAM_BOOLEAN("Renderer4.ColorPredictor.Accuracy", correct_guess); | |
| 1063 | |
| 1064 if (correct_guess) | |
| 1065 UMA_HISTOGRAM_BOOLEAN("Renderer4.ColorPredictor.IsCorrectSolid", | |
| 1066 is_predicted_solid); | |
| 1067 | |
| 1068 if (is_predicted_transparent) | |
| 1069 UMA_HISTOGRAM_BOOLEAN( | |
| 1070 "Renderer4.ColorPredictor.PredictedTransparentIsActually", | |
| 1071 is_transparent); | |
| 1072 UMA_HISTOGRAM_BOOLEAN("Renderer4.ColorPredictor.IsActuallyTransparent", | |
| 1073 is_transparent); | |
| 1074 } | |
| 1075 | |
| 1076 // static | |
| 983 void TileManager::RunImageDecodeTask(skia::LazyPixelRef* pixel_ref, | 1077 void TileManager::RunImageDecodeTask(skia::LazyPixelRef* pixel_ref, |
| 984 RenderingStats* stats) { | 1078 RenderingStats* stats) { |
| 985 TRACE_EVENT0("cc", "TileManager::RunImageDecodeTask"); | 1079 TRACE_EVENT0("cc", "TileManager::RunImageDecodeTask"); |
| 986 base::TimeTicks decode_begin_time; | 1080 base::TimeTicks decode_begin_time; |
| 987 if (stats) | 1081 if (stats) |
| 988 decode_begin_time = base::TimeTicks::HighResNow(); | 1082 decode_begin_time = base::TimeTicks::HighResNow(); |
| 989 pixel_ref->Decode(); | 1083 pixel_ref->Decode(); |
| 990 if (stats) { | 1084 if (stats) { |
| 991 stats->totalDeferredImageDecodeCount++; | 1085 stats->totalDeferredImageDecodeCount++; |
| 992 stats->totalDeferredImageDecodeTime += | 1086 stats->totalDeferredImageDecodeTime += |
| 993 base::TimeTicks::HighResNow() - decode_begin_time; | 1087 base::TimeTicks::HighResNow() - decode_begin_time; |
| 994 } | 1088 } |
| 995 } | 1089 } |
| 996 | 1090 |
| 997 } // namespace cc | 1091 } // namespace cc |
| OLD | NEW |