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()); |
| 174 state->SetBoolean("is_picture_pile_analyzed", picture_pile_analyzed); |
| 175 state->SetBoolean("is_cheap_to_raster", picture_pile_analysis.is_cheap_to_rast
er); |
| 176 state->SetBoolean("is_transparent", picture_pile_analysis.is_transparent); |
| 177 state->SetBoolean("is_solid_color", picture_pile_analysis.is_solid_color); |
173 return state.PassAs<base::Value>(); | 178 return state.PassAs<base::Value>(); |
174 } | 179 } |
175 | 180 |
176 TileManager::TileManager( | 181 TileManager::TileManager( |
177 TileManagerClient* client, | 182 TileManagerClient* client, |
178 ResourceProvider* resource_provider, | 183 ResourceProvider* resource_provider, |
179 size_t num_raster_threads, | 184 size_t num_raster_threads, |
180 bool use_cheapness_estimator) | 185 bool use_cheapness_estimator, |
| 186 bool use_color_estimator, |
| 187 bool prediction_benchmarking) |
181 : client_(client), | 188 : client_(client), |
182 resource_pool_(ResourcePool::Create(resource_provider)), | 189 resource_pool_(ResourcePool::Create(resource_provider)), |
183 raster_worker_pool_(RasterWorkerPool::Create(this, num_raster_threads)), | 190 raster_worker_pool_(RasterWorkerPool::Create(this, num_raster_threads)), |
184 manage_tiles_pending_(false), | 191 manage_tiles_pending_(false), |
185 manage_tiles_call_count_(0), | 192 manage_tiles_call_count_(0), |
186 bytes_pending_upload_(0), | 193 bytes_pending_upload_(0), |
187 has_performed_uploads_since_last_flush_(false), | 194 has_performed_uploads_since_last_flush_(false), |
188 ever_exceeded_memory_budget_(false), | 195 ever_exceeded_memory_budget_(false), |
189 record_rendering_stats_(false), | 196 record_rendering_stats_(false), |
190 use_cheapness_estimator_(use_cheapness_estimator), | 197 use_cheapness_estimator_(use_cheapness_estimator), |
| 198 use_color_estimator_(use_color_estimator), |
191 allow_cheap_tasks_(true), | 199 allow_cheap_tasks_(true), |
192 did_schedule_cheap_tasks_(false) { | 200 did_schedule_cheap_tasks_(false), |
| 201 prediction_benchmarking_(prediction_benchmarking) { |
193 for (int i = 0; i < NUM_STATES; ++i) { | 202 for (int i = 0; i < NUM_STATES; ++i) { |
194 for (int j = 0; j < NUM_TREES; ++j) { | 203 for (int j = 0; j < NUM_TREES; ++j) { |
195 for (int k = 0; k < NUM_BINS; ++k) | 204 for (int k = 0; k < NUM_BINS; ++k) |
196 raster_state_count_[i][j][k] = 0; | 205 raster_state_count_[i][j][k] = 0; |
197 } | 206 } |
198 } | 207 } |
199 } | 208 } |
200 | 209 |
201 TileManager::~TileManager() { | 210 TileManager::~TileManager() { |
202 // Reset global state and manage. This should cause | 211 // Reset global state and manage. This should cause |
(...skipping 161 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
364 DidTileTreeBinChange(tile, | 373 DidTileTreeBinChange(tile, |
365 bin_map[BinFromTilePriority(tile->priority(ACTIVE_TREE))], | 374 bin_map[BinFromTilePriority(tile->priority(ACTIVE_TREE))], |
366 ACTIVE_TREE); | 375 ACTIVE_TREE); |
367 DidTileTreeBinChange(tile, | 376 DidTileTreeBinChange(tile, |
368 bin_map[BinFromTilePriority(tile->priority(PENDING_TREE))], | 377 bin_map[BinFromTilePriority(tile->priority(PENDING_TREE))], |
369 PENDING_TREE); | 378 PENDING_TREE); |
370 | 379 |
371 for (int i = 0; i < NUM_BIN_PRIORITIES; ++i) | 380 for (int i = 0; i < NUM_BIN_PRIORITIES; ++i) |
372 mts.bin[i] = bin_map[mts.bin[i]]; | 381 mts.bin[i] = bin_map[mts.bin[i]]; |
373 | 382 |
374 if (tile->priority(ACTIVE_TREE).is_live || | 383 if (!tile->managed_state().resource && |
375 tile->priority(PENDING_TREE).is_live || | 384 !tile->managed_state().resource_is_being_initialized && |
376 tile->managed_state().resource || | 385 !tile->priority(ACTIVE_TREE).is_live && |
377 tile->managed_state().resource_is_being_initialized) { | 386 !tile->priority(PENDING_TREE).is_live) |
378 live_or_allocated_tiles_.push_back(tile); | 387 continue; |
379 } | 388 |
| 389 live_or_allocated_tiles_.push_back(tile); |
380 } | 390 } |
381 TRACE_COUNTER_ID1("cc", "LiveOrAllocatedTileCount", this, | 391 TRACE_COUNTER_ID1("cc", "LiveOrAllocatedTileCount", this, |
382 live_or_allocated_tiles_.size()); | 392 live_or_allocated_tiles_.size()); |
383 | 393 |
384 SortTiles(); | 394 SortTiles(); |
385 | 395 |
386 // Assign gpu memory and determine what tiles need to be rasterized. | 396 // Assign gpu memory and determine what tiles need to be rasterized. |
387 AssignGpuMemoryToTiles(); | 397 AssignGpuMemoryToTiles(); |
388 | 398 |
389 TRACE_EVENT_INSTANT1("cc", "DidManage", "state", | 399 TRACE_EVENT_INSTANT1("cc", "DidManage", "state", |
(...skipping 62 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
452 void TileManager::GetMemoryStats( | 462 void TileManager::GetMemoryStats( |
453 size_t* memoryRequiredBytes, | 463 size_t* memoryRequiredBytes, |
454 size_t* memoryNiceToHaveBytes, | 464 size_t* memoryNiceToHaveBytes, |
455 size_t* memoryUsedBytes) const { | 465 size_t* memoryUsedBytes) const { |
456 *memoryRequiredBytes = 0; | 466 *memoryRequiredBytes = 0; |
457 *memoryNiceToHaveBytes = 0; | 467 *memoryNiceToHaveBytes = 0; |
458 *memoryUsedBytes = 0; | 468 *memoryUsedBytes = 0; |
459 for (size_t i = 0; i < live_or_allocated_tiles_.size(); i++) { | 469 for (size_t i = 0; i < live_or_allocated_tiles_.size(); i++) { |
460 const Tile* tile = live_or_allocated_tiles_[i]; | 470 const Tile* tile = live_or_allocated_tiles_[i]; |
461 const ManagedTileState& mts = tile->managed_state(); | 471 const ManagedTileState& mts = tile->managed_state(); |
| 472 if (tile->is_transparent() || tile->is_solid_color()) |
| 473 continue; |
| 474 |
462 size_t tile_bytes = tile->bytes_consumed_if_allocated(); | 475 size_t tile_bytes = tile->bytes_consumed_if_allocated(); |
463 if (mts.gpu_memmgr_stats_bin == NOW_BIN) | 476 if (mts.gpu_memmgr_stats_bin == NOW_BIN) |
464 *memoryRequiredBytes += tile_bytes; | 477 *memoryRequiredBytes += tile_bytes; |
465 if (mts.gpu_memmgr_stats_bin != NEVER_BIN) | 478 if (mts.gpu_memmgr_stats_bin != NEVER_BIN) |
466 *memoryNiceToHaveBytes += tile_bytes; | 479 *memoryNiceToHaveBytes += tile_bytes; |
467 if (mts.can_use_gpu_memory) | 480 if (mts.can_use_gpu_memory) |
468 *memoryUsedBytes += tile_bytes; | 481 *memoryUsedBytes += tile_bytes; |
469 } | 482 } |
470 } | 483 } |
471 | 484 |
(...skipping 100 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
572 // By clearing the tiles_that_need_to_be_rasterized_ vector and | 585 // By clearing the tiles_that_need_to_be_rasterized_ vector and |
573 // tiles_with_image_decoding_tasks_ list above we move all tiles | 586 // tiles_with_image_decoding_tasks_ list above we move all tiles |
574 // currently waiting for raster to idle state. | 587 // currently waiting for raster to idle state. |
575 // Call DidTileRasterStateChange() for each of these tiles to | 588 // Call DidTileRasterStateChange() for each of these tiles to |
576 // have this state change take effect. | 589 // have this state change take effect. |
577 // Some memory cannot be released. We figure out how much in this | 590 // Some memory cannot be released. We figure out how much in this |
578 // loop as well. | 591 // loop as well. |
579 for (TileVector::iterator it = live_or_allocated_tiles_.begin(); | 592 for (TileVector::iterator it = live_or_allocated_tiles_.begin(); |
580 it != live_or_allocated_tiles_.end(); ++it) { | 593 it != live_or_allocated_tiles_.end(); ++it) { |
581 Tile* tile = *it; | 594 Tile* tile = *it; |
582 if (!tile->managed_state().can_be_freed) | 595 if (tile->is_solid_color() || tile->is_transparent()) |
| 596 continue; |
| 597 |
| 598 ManagedTileState& managed_tile_state = tile->managed_state(); |
| 599 if (!managed_tile_state.can_be_freed) |
583 unreleasable_bytes += tile->bytes_consumed_if_allocated(); | 600 unreleasable_bytes += tile->bytes_consumed_if_allocated(); |
584 if (tile->managed_state().raster_state == WAITING_FOR_RASTER_STATE) | 601 if (managed_tile_state.raster_state == WAITING_FOR_RASTER_STATE) |
585 DidTileRasterStateChange(tile, IDLE_STATE); | 602 DidTileRasterStateChange(tile, IDLE_STATE); |
586 } | 603 } |
587 | 604 |
588 size_t bytes_allocatable = global_state_.memory_limit_in_bytes - unreleasable_
bytes; | 605 size_t bytes_allocatable = global_state_.memory_limit_in_bytes - unreleasable_
bytes; |
589 size_t bytes_that_exceeded_memory_budget_in_now_bin = 0; | 606 size_t bytes_that_exceeded_memory_budget_in_now_bin = 0; |
590 size_t bytes_left = bytes_allocatable; | 607 size_t bytes_left = bytes_allocatable; |
591 for (TileVector::iterator it = live_or_allocated_tiles_.begin(); it != live_or
_allocated_tiles_.end(); ++it) { | 608 for (TileVector::iterator it = live_or_allocated_tiles_.begin(); it != live_or
_allocated_tiles_.end(); ++it) { |
592 Tile* tile = *it; | 609 Tile* tile = *it; |
| 610 if (tile->is_solid_color() || tile->is_transparent()) |
| 611 continue; |
| 612 |
| 613 ManagedTileState& managed_tile_state = tile->managed_state(); |
593 size_t tile_bytes = tile->bytes_consumed_if_allocated(); | 614 size_t tile_bytes = tile->bytes_consumed_if_allocated(); |
594 ManagedTileState& managed_tile_state = tile->managed_state(); | |
595 if (!managed_tile_state.can_be_freed) | 615 if (!managed_tile_state.can_be_freed) |
596 continue; | 616 continue; |
597 if (managed_tile_state.bin[HIGH_PRIORITY_BIN] == NEVER_BIN && | 617 if (managed_tile_state.bin[HIGH_PRIORITY_BIN] == NEVER_BIN && |
598 managed_tile_state.bin[LOW_PRIORITY_BIN] == NEVER_BIN) { | 618 managed_tile_state.bin[LOW_PRIORITY_BIN] == NEVER_BIN) { |
599 managed_tile_state.can_use_gpu_memory = false; | 619 managed_tile_state.can_use_gpu_memory = false; |
600 FreeResourcesForTile(tile); | 620 FreeResourcesForTile(tile); |
601 continue; | 621 continue; |
602 } | 622 } |
603 if (tile_bytes > bytes_left) { | 623 if (tile_bytes > bytes_left) { |
604 managed_tile_state.can_use_gpu_memory = false; | 624 managed_tile_state.can_use_gpu_memory = false; |
(...skipping 49 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
654 return new_bytes_pending <= kMaxPendingUploadBytes && | 674 return new_bytes_pending <= kMaxPendingUploadBytes && |
655 tiles_with_pending_upload_.size() < kMaxPendingUploads; | 675 tiles_with_pending_upload_.size() < kMaxPendingUploads; |
656 } | 676 } |
657 | 677 |
658 void TileManager::DispatchMoreTasks() { | 678 void TileManager::DispatchMoreTasks() { |
659 if (did_schedule_cheap_tasks_) | 679 if (did_schedule_cheap_tasks_) |
660 allow_cheap_tasks_ = false; | 680 allow_cheap_tasks_ = false; |
661 | 681 |
662 // Because tiles in the image decoding list have higher priorities, we | 682 // 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 | 683 // need to process those tiles first before we start to handle the tiles |
664 // in the need_to_be_rasterized queue. | 684 // in the need_to_be_rasterized queue. Note that solid/transparent tiles |
| 685 // will not be put into the decoding list. |
665 for(TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); | 686 for(TileList::iterator it = tiles_with_image_decoding_tasks_.begin(); |
666 it != tiles_with_image_decoding_tasks_.end(); ) { | 687 it != tiles_with_image_decoding_tasks_.end(); ) { |
| 688 ManagedTileState& managed_tile_state = (*it)->managed_state(); |
667 DispatchImageDecodeTasksForTile(*it); | 689 DispatchImageDecodeTasksForTile(*it); |
668 ManagedTileState& managed_state = (*it)->managed_state(); | 690 if (managed_tile_state.pending_pixel_refs.empty()) { |
669 if (managed_state.pending_pixel_refs.empty()) { | |
670 if (!CanDispatchRasterTask(*it)) | 691 if (!CanDispatchRasterTask(*it)) |
671 return; | 692 return; |
672 DispatchOneRasterTask(*it); | 693 DispatchOneRasterTask(*it); |
673 tiles_with_image_decoding_tasks_.erase(it++); | 694 tiles_with_image_decoding_tasks_.erase(it++); |
674 } else { | 695 } else { |
675 ++it; | 696 ++it; |
676 } | 697 } |
677 } | 698 } |
678 | 699 |
679 // Process all tiles in the need_to_be_rasterized queue. If a tile has | 700 // Process all tiles in the need_to_be_rasterized queue. If a tile is |
680 // image decoding tasks, put it to the back of the image decoding list. | 701 // solid/transparent, then we are done (we don't need to rasterize |
| 702 // the tile). If a tile has image decoding tasks, put it to the back |
| 703 // of the image decoding list. |
681 while (!tiles_that_need_to_be_rasterized_.empty()) { | 704 while (!tiles_that_need_to_be_rasterized_.empty()) { |
682 Tile* tile = tiles_that_need_to_be_rasterized_.back(); | 705 Tile* tile = tiles_that_need_to_be_rasterized_.back(); |
| 706 ManagedTileState& managed_tile_state = tile->managed_state(); |
| 707 |
| 708 AnalyzeTile(tile); |
| 709 if (tile->is_solid_color() || tile->is_transparent()) { |
| 710 DidTileRasterStateChange(tile, IDLE_STATE); |
| 711 tiles_that_need_to_be_rasterized_.pop_back(); |
| 712 continue; |
| 713 } |
| 714 |
683 DispatchImageDecodeTasksForTile(tile); | 715 DispatchImageDecodeTasksForTile(tile); |
684 ManagedTileState& managed_state = tile->managed_state(); | 716 if (!managed_tile_state.pending_pixel_refs.empty()) { |
685 if (!managed_state.pending_pixel_refs.empty()) { | |
686 tiles_with_image_decoding_tasks_.push_back(tile); | 717 tiles_with_image_decoding_tasks_.push_back(tile); |
687 } else { | 718 } else { |
688 if (!CanDispatchRasterTask(tile)) | 719 if (!CanDispatchRasterTask(tile)) |
689 return; | 720 return; |
690 DispatchOneRasterTask(tile); | 721 DispatchOneRasterTask(tile); |
691 } | 722 } |
692 tiles_that_need_to_be_rasterized_.pop_back(); | 723 tiles_that_need_to_be_rasterized_.pop_back(); |
693 } | 724 } |
694 } | 725 } |
695 | 726 |
| 727 void TileManager::AnalyzeTile(Tile* tile) { |
| 728 ManagedTileState& managed_tile_state = tile->managed_state(); |
| 729 if ((use_cheapness_estimator_ || use_color_estimator_) && |
| 730 !managed_tile_state.picture_pile_analyzed) { |
| 731 tile->picture_pile()->AnalyzeInRect( |
| 732 tile->content_rect(), |
| 733 tile->contents_scale(), |
| 734 &managed_tile_state.picture_pile_analysis); |
| 735 managed_tile_state.picture_pile_analysis.is_cheap_to_raster &= |
| 736 use_cheapness_estimator_; |
| 737 managed_tile_state.picture_pile_analysis.is_solid_color &= |
| 738 use_color_estimator_; |
| 739 managed_tile_state.picture_pile_analysis.is_transparent &= |
| 740 use_color_estimator_; |
| 741 managed_tile_state.picture_pile_analyzed = true; |
| 742 } |
| 743 } |
| 744 |
696 void TileManager::GatherPixelRefsForTile(Tile* tile) { | 745 void TileManager::GatherPixelRefsForTile(Tile* tile) { |
697 TRACE_EVENT0("cc", "TileManager::GatherPixelRefsForTile"); | 746 TRACE_EVENT0("cc", "TileManager::GatherPixelRefsForTile"); |
698 ManagedTileState& managed_state = tile->managed_state(); | 747 ManagedTileState& managed_tile_state = tile->managed_state(); |
699 if (managed_state.need_to_gather_pixel_refs) { | 748 if (managed_tile_state.need_to_gather_pixel_refs) { |
700 base::TimeTicks gather_begin_time; | 749 base::TimeTicks gather_begin_time; |
701 if (record_rendering_stats_) | 750 if (record_rendering_stats_) |
702 gather_begin_time = base::TimeTicks::HighResNow(); | 751 gather_begin_time = base::TimeTicks::HighResNow(); |
703 tile->picture_pile()->GatherPixelRefs( | 752 tile->picture_pile()->GatherPixelRefs( |
704 tile->content_rect_, | 753 tile->content_rect_, |
705 tile->contents_scale_, | 754 tile->contents_scale_, |
706 managed_state.pending_pixel_refs); | 755 managed_tile_state.pending_pixel_refs); |
707 managed_state.need_to_gather_pixel_refs = false; | 756 managed_tile_state.need_to_gather_pixel_refs = false; |
708 if (record_rendering_stats_) { | 757 if (record_rendering_stats_) { |
709 rendering_stats_.totalImageGatheringCount++; | 758 rendering_stats_.totalImageGatheringCount++; |
710 rendering_stats_.totalImageGatheringTime += | 759 rendering_stats_.totalImageGatheringTime += |
711 base::TimeTicks::HighResNow() - gather_begin_time; | 760 base::TimeTicks::HighResNow() - gather_begin_time; |
712 } | 761 } |
713 } | 762 } |
714 } | 763 } |
715 | 764 |
716 void TileManager::DispatchImageDecodeTasksForTile(Tile* tile) { | 765 void TileManager::DispatchImageDecodeTasksForTile(Tile* tile) { |
717 GatherPixelRefsForTile(tile); | 766 GatherPixelRefsForTile(tile); |
(...skipping 69 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
787 return resource.Pass(); | 836 return resource.Pass(); |
788 } | 837 } |
789 | 838 |
790 void TileManager::DispatchOneRasterTask(scoped_refptr<Tile> tile) { | 839 void TileManager::DispatchOneRasterTask(scoped_refptr<Tile> tile) { |
791 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask"); | 840 TRACE_EVENT0("cc", "TileManager::DispatchOneRasterTask"); |
792 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); | 841 scoped_ptr<ResourcePool::Resource> resource = PrepareTileForRaster(tile); |
793 ResourceProvider::ResourceId resource_id = resource->id(); | 842 ResourceProvider::ResourceId resource_id = resource->id(); |
794 uint8* buffer = | 843 uint8* buffer = |
795 resource_pool_->resource_provider()->MapPixelBuffer(resource_id); | 844 resource_pool_->resource_provider()->MapPixelBuffer(resource_id); |
796 | 845 |
797 bool is_cheap = use_cheapness_estimator_ && allow_cheap_tasks_ && | 846 ManagedTileState& managed_tile_state = tile->managed_state(); |
798 tile->picture_pile()->IsCheapInRect(tile->content_rect_, | 847 bool is_cheap_to_raster = |
799 tile->contents_scale()); | 848 managed_tile_state.picture_pile_analysis.is_cheap_to_raster; |
800 raster_worker_pool_->PostRasterTaskAndReply( | 849 raster_worker_pool_->PostRasterTaskAndReply( |
801 tile->picture_pile(), | 850 tile->picture_pile(), |
802 is_cheap, | 851 allow_cheap_tasks_ && is_cheap_to_raster, |
803 base::Bind(&TileManager::RunRasterTask, | 852 base::Bind(&TileManager::RunRasterTask, |
804 buffer, | 853 buffer, |
805 tile->content_rect(), | 854 tile->content_rect(), |
806 tile->contents_scale(), | 855 tile->contents_scale(), |
807 GetRasterTaskMetadata(*tile)), | 856 GetRasterTaskMetadata(*tile)), |
808 base::Bind(&TileManager::OnRasterTaskCompleted, | 857 base::Bind(&TileManager::OnRasterTaskCompleted, |
809 base::Unretained(this), | 858 base::Unretained(this), |
810 tile, | 859 tile, |
811 base::Passed(&resource), | 860 base::Passed(&resource), |
812 manage_tiles_call_count_)); | 861 manage_tiles_call_count_)); |
813 did_schedule_cheap_tasks_ |= is_cheap; | 862 did_schedule_cheap_tasks_ |= (allow_cheap_tasks_ && is_cheap_to_raster); |
814 } | 863 } |
815 | 864 |
816 TileManager::RasterTaskMetadata TileManager::GetRasterTaskMetadata( | 865 TileManager::RasterTaskMetadata TileManager::GetRasterTaskMetadata( |
817 const Tile& tile) const { | 866 const Tile& tile) const { |
818 RasterTaskMetadata metadata; | 867 RasterTaskMetadata metadata; |
819 const ManagedTileState& mts = tile.managed_state(); | 868 const ManagedTileState& mts = tile.managed_state(); |
820 metadata.use_cheapness_estimator = use_cheapness_estimator_; | 869 metadata.prediction_benchmarking = prediction_benchmarking_; |
821 metadata.is_tile_in_pending_tree_now_bin = | 870 metadata.is_tile_in_pending_tree_now_bin = |
822 mts.tree_bin[PENDING_TREE] == NOW_BIN; | 871 mts.tree_bin[PENDING_TREE] == NOW_BIN; |
823 metadata.tile_resolution = mts.resolution; | 872 metadata.tile_resolution = mts.resolution; |
824 metadata.layer_id = tile.layer_id(); | 873 metadata.layer_id = tile.layer_id(); |
825 return metadata; | 874 return metadata; |
826 } | 875 } |
827 | 876 |
828 void TileManager::OnRasterTaskCompleted( | 877 void TileManager::OnRasterTaskCompleted( |
829 scoped_refptr<Tile> tile, | 878 scoped_refptr<Tile> tile, |
830 scoped_ptr<ResourcePool::Resource> resource, | 879 scoped_ptr<ResourcePool::Resource> resource, |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
951 stats->totalRasterizeTime += duration; | 1000 stats->totalRasterizeTime += duration; |
952 if (metadata.is_tile_in_pending_tree_now_bin) | 1001 if (metadata.is_tile_in_pending_tree_now_bin) |
953 stats->totalRasterizeTimeForNowBinsOnPendingTree += duration; | 1002 stats->totalRasterizeTimeForNowBinsOnPendingTree += duration; |
954 | 1003 |
955 UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.PictureRasterTimeMS", | 1004 UMA_HISTOGRAM_CUSTOM_COUNTS("Renderer4.PictureRasterTimeMS", |
956 duration.InMilliseconds(), | 1005 duration.InMilliseconds(), |
957 0, | 1006 0, |
958 10, | 1007 10, |
959 10); | 1008 10); |
960 | 1009 |
961 if (metadata.use_cheapness_estimator) { | 1010 if (metadata.prediction_benchmarking) { |
962 bool is_predicted_cheap = | 1011 PicturePileImpl::Analysis analysis; |
963 picture_pile->IsCheapInRect(rect, contents_scale); | 1012 picture_pile->AnalyzeInRect(rect, contents_scale, &analysis); |
| 1013 bool is_predicted_cheap = analysis.is_cheap_to_raster; |
964 bool is_actually_cheap = duration.InMillisecondsF() <= 1.0f; | 1014 bool is_actually_cheap = duration.InMillisecondsF() <= 1.0f; |
965 RecordCheapnessPredictorResults(is_predicted_cheap, is_actually_cheap); | 1015 RecordCheapnessPredictorResults(is_predicted_cheap, is_actually_cheap); |
| 1016 |
| 1017 DCHECK_EQ(bitmap.rowBytes(), |
| 1018 bitmap.width() * bitmap.bytesPerPixel()); |
| 1019 |
| 1020 RecordSolidColorPredictorResults( |
| 1021 reinterpret_cast<SkColor*>(bitmap.getPixels()), |
| 1022 bitmap.getSize() / bitmap.bytesPerPixel(), |
| 1023 analysis.is_solid_color, |
| 1024 analysis.solid_color, |
| 1025 analysis.is_transparent); |
966 } | 1026 } |
967 } | 1027 } |
968 } | 1028 } |
969 | 1029 |
970 // static | 1030 // static |
971 void TileManager::RecordCheapnessPredictorResults(bool is_predicted_cheap, | 1031 void TileManager::RecordCheapnessPredictorResults(bool is_predicted_cheap, |
972 bool is_actually_cheap) { | 1032 bool is_actually_cheap) { |
973 if (is_predicted_cheap && !is_actually_cheap) | 1033 if (is_predicted_cheap && !is_actually_cheap) |
974 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorBadlyWrong", true); | 1034 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorBadlyWrong", true); |
975 else if (!is_predicted_cheap && is_actually_cheap) | 1035 else if (!is_predicted_cheap && is_actually_cheap) |
976 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorSafelyWrong", true); | 1036 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorSafelyWrong", true); |
977 | 1037 |
978 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorAccuracy", | 1038 UMA_HISTOGRAM_BOOLEAN("Renderer4.CheapPredictorAccuracy", |
979 is_predicted_cheap == is_actually_cheap); | 1039 is_predicted_cheap == is_actually_cheap); |
980 } | 1040 } |
981 | 1041 |
982 // static | 1042 // static |
| 1043 void TileManager::RecordSolidColorPredictorResults( |
| 1044 const SkColor* actual_colors, |
| 1045 size_t color_count, |
| 1046 bool is_predicted_solid, |
| 1047 SkColor predicted_color, |
| 1048 bool is_predicted_transparent) { |
| 1049 DCHECK_GT(color_count, 0u); |
| 1050 |
| 1051 bool is_actually_solid = true; |
| 1052 bool is_transparent = true; |
| 1053 |
| 1054 SkColor actual_color = *actual_colors; |
| 1055 for (unsigned int i = 0; i < color_count; ++i) { |
| 1056 SkColor current_color = actual_colors[i]; |
| 1057 if (current_color != actual_color || |
| 1058 SkColorGetA(current_color) != 255) |
| 1059 is_actually_solid = false; |
| 1060 |
| 1061 if (SkColorGetA(current_color) != 0) |
| 1062 is_transparent = false; |
| 1063 |
| 1064 if(!is_actually_solid && !is_transparent) |
| 1065 break; |
| 1066 } |
| 1067 |
| 1068 if (is_predicted_solid && !is_actually_solid) |
| 1069 UMA_HISTOGRAM_BOOLEAN("Renderer4.ColorPredictor.WrongActualNotSolid", true); |
| 1070 else if (is_predicted_solid && |
| 1071 is_actually_solid && |
| 1072 predicted_color != actual_color) |
| 1073 UMA_HISTOGRAM_BOOLEAN("Renderer4.ColorPredictor.WrongColor", true); |
| 1074 else if (!is_predicted_solid && is_actually_solid) |
| 1075 UMA_HISTOGRAM_BOOLEAN("Renderer4.ColorPredictor.WrongActualSolid", true); |
| 1076 |
| 1077 bool correct_guess = (is_predicted_solid && is_actually_solid && |
| 1078 predicted_color == actual_color) || |
| 1079 (!is_predicted_solid && !is_actually_solid); |
| 1080 UMA_HISTOGRAM_BOOLEAN("Renderer4.ColorPredictor.Accuracy", correct_guess); |
| 1081 |
| 1082 if (correct_guess) |
| 1083 UMA_HISTOGRAM_BOOLEAN("Renderer4.ColorPredictor.IsCorrectSolid", |
| 1084 is_predicted_solid); |
| 1085 |
| 1086 if (is_predicted_transparent) |
| 1087 UMA_HISTOGRAM_BOOLEAN( |
| 1088 "Renderer4.ColorPredictor.PredictedTransparentIsActually", |
| 1089 is_transparent); |
| 1090 UMA_HISTOGRAM_BOOLEAN("Renderer4.ColorPredictor.IsActuallyTransparent", |
| 1091 is_transparent); |
| 1092 } |
| 1093 |
| 1094 // static |
983 void TileManager::RunImageDecodeTask(skia::LazyPixelRef* pixel_ref, | 1095 void TileManager::RunImageDecodeTask(skia::LazyPixelRef* pixel_ref, |
984 RenderingStats* stats) { | 1096 RenderingStats* stats) { |
985 TRACE_EVENT0("cc", "TileManager::RunImageDecodeTask"); | 1097 TRACE_EVENT0("cc", "TileManager::RunImageDecodeTask"); |
986 base::TimeTicks decode_begin_time; | 1098 base::TimeTicks decode_begin_time; |
987 if (stats) | 1099 if (stats) |
988 decode_begin_time = base::TimeTicks::HighResNow(); | 1100 decode_begin_time = base::TimeTicks::HighResNow(); |
989 pixel_ref->Decode(); | 1101 pixel_ref->Decode(); |
990 if (stats) { | 1102 if (stats) { |
991 stats->totalDeferredImageDecodeCount++; | 1103 stats->totalDeferredImageDecodeCount++; |
992 stats->totalDeferredImageDecodeTime += | 1104 stats->totalDeferredImageDecodeTime += |
993 base::TimeTicks::HighResNow() - decode_begin_time; | 1105 base::TimeTicks::HighResNow() - decode_begin_time; |
994 } | 1106 } |
995 } | 1107 } |
996 | 1108 |
997 } // namespace cc | 1109 } // namespace cc |
OLD | NEW |