1 // Copyright 2013 The Chromium Authors. All rights reserved. 2 // Use of this source code is governed by a BSD-style license that can be 3 // found in the LICENSE file. 4 5 #include "cc/resources/prioritized_tile_set.h" 6 7 #include <algorithm> 8 9 #include "cc/resources/managed_tile_state.h" 10 #include "cc/resources/tile.h" 11 12 namespace cc { 13 14 class BinComparator { 15 public: 16 bool operator()(const Tile* a, 17 const Tile* b) const { 18 const ManagedTileState& ams = a->managed_state(); 19 const ManagedTileState& bms = b->managed_state(); 20 21 if (ams.priority_bin != bms.priority_bin) 22 return ams.priority_bin < bms.priority_bin; 23 24 if (ams.required_for_activation != bms.required_for_activation) 25 return ams.required_for_activation; 26 27 if (ams.resolution != bms.resolution) 28 return ams.resolution < bms.resolution; 29 30 if (ams.distance_to_visible != bms.distance_to_visible) 31 return ams.distance_to_visible < bms.distance_to_visible; 32 33 gfx::Rect a_rect = a->content_rect(); 34 gfx::Rect b_rect = b->content_rect(); 35 if (a_rect.y() != b_rect.y()) 36 return a_rect.y() < b_rect.y(); 37 return a_rect.x() < b_rect.x(); 38 } 39 }; 40 41 namespace { 42 43 typedef std::vector<Tile*> TileVector; 44 45 void SortBinTiles(ManagedTileBin bin, TileVector* tiles) { 46 switch (bin) { 47 case NOW_AND_READY_TO_DRAW_BIN: 48 case NEVER_BIN: 49 break; 50 case NOW_BIN: 51 case SOON_BIN: 52 case EVENTUALLY_AND_ACTIVE_BIN: 53 case EVENTUALLY_BIN: 54 case AT_LAST_AND_ACTIVE_BIN: 55 case AT_LAST_BIN: 56 std::sort(tiles->begin(), tiles->end(), BinComparator()); 57 break; 58 default: 59 NOTREACHED(); 60 } 61 } 62 63 } // namespace 64 65 PrioritizedTileSet::PrioritizedTileSet() { 66 for (int bin = 0; bin < NUM_BINS; ++bin) 67 bin_sorted_[bin] = true; 68 } 69 70 PrioritizedTileSet::~PrioritizedTileSet() {} 71 72 void PrioritizedTileSet::InsertTile(Tile* tile, ManagedTileBin bin) { 73 tiles_[bin].push_back(tile); 74 bin_sorted_[bin] = false; 75 } 76 77 void PrioritizedTileSet::Clear() { 78 for (int bin = 0; bin < NUM_BINS; ++bin) { 79 tiles_[bin].clear(); 80 bin_sorted_[bin] = true; 81 } 82 } 83 84 void PrioritizedTileSet::SortBinIfNeeded(ManagedTileBin bin) { 85 if (!bin_sorted_[bin]) { 86 SortBinTiles(bin, &tiles_[bin]); 87 bin_sorted_[bin] = true; 88 } 89 } 90 91 PrioritizedTileSet::Iterator::Iterator( 92 PrioritizedTileSet* tile_set, bool use_priority_ordering) 93 : tile_set_(tile_set), 94 current_bin_(NOW_AND_READY_TO_DRAW_BIN), 95 use_priority_ordering_(use_priority_ordering) { 96 if (use_priority_ordering_) 97 tile_set_->SortBinIfNeeded(current_bin_); 98 iterator_ = tile_set->tiles_[current_bin_].begin(); 99 if (iterator_ == tile_set_->tiles_[current_bin_].end()) 100 AdvanceList(); 101 } 102 103 PrioritizedTileSet::Iterator::~Iterator() {} 104 105 void PrioritizedTileSet::Iterator::DisablePriorityOrdering() { 106 use_priority_ordering_ = false; 107 } 108 109 PrioritizedTileSet::Iterator& 110 PrioritizedTileSet::Iterator::operator++() { 111 // We can't increment past the end of the tiles. 112 DCHECK(iterator_ != tile_set_->tiles_[current_bin_].end()); 113 114 ++iterator_; 115 if (iterator_ == tile_set_->tiles_[current_bin_].end()) 116 AdvanceList(); 117 return *this; 118 } 119 120 Tile* PrioritizedTileSet::Iterator::operator*() { 121 DCHECK(iterator_ != tile_set_->tiles_[current_bin_].end()); 122 return *iterator_; 123 } 124 125 void PrioritizedTileSet::Iterator::AdvanceList() { 126 DCHECK(iterator_ == tile_set_->tiles_[current_bin_].end()); 127 128 while (current_bin_ != NEVER_BIN) { 129 current_bin_ = static_cast<ManagedTileBin>(current_bin_ + 1); 130 131 if (use_priority_ordering_) 132 tile_set_->SortBinIfNeeded(current_bin_); 133 134 iterator_ = tile_set_->tiles_[current_bin_].begin(); 135 if (iterator_ != tile_set_->tiles_[current_bin_].end()) 136 break; 137 } 138 } 139 140 } // namespace cc 141