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 3 // found in the LICENSE file. 4 5 #ifndef CC_RESOURCES_PICTURE_LAYER_TILING_H_ 6 #define CC_RESOURCES_PICTURE_LAYER_TILING_H_ 7 8 #include <set> 9 #include <utility> 10 #include <vector> 11 12 #include "base/basictypes.h" 13 #include "base/containers/hash_tables.h" 14 #include "base/memory/scoped_ptr.h" 15 #include "cc/base/cc_export.h" 16 #include "cc/base/region.h" 17 #include "cc/base/tiling_data.h" 18 #include "cc/resources/tile.h" 19 #include "cc/resources/tile_priority.h" 20 #include "ui/gfx/rect.h" 21 22 namespace cc { 23 24 class PictureLayerTiling; 25 26 class CC_EXPORT PictureLayerTilingClient { 27 public: 28 // Create a tile at the given content_rect (in the contents scale of the 29 // tiling) This might return null if the client cannot create such a tile. 30 virtual scoped_refptr<Tile> CreateTile( 31 PictureLayerTiling* tiling, 32 const gfx::Rect& content_rect) = 0; 33 virtual void UpdatePile(Tile* tile) = 0; 34 virtual gfx::Size CalculateTileSize( 35 const gfx::Size& content_bounds) const = 0; 36 virtual const Region* GetInvalidation() = 0; 37 virtual const PictureLayerTiling* GetTwinTiling( 38 const PictureLayerTiling* tiling) const = 0; 39 virtual PictureLayerTiling* GetRecycledTwinTiling( 40 const PictureLayerTiling* tiling) = 0; 41 virtual size_t GetMaxTilesForInterestArea() const = 0; 42 virtual float GetSkewportTargetTimeInSeconds() const = 0; 43 virtual int GetSkewportExtrapolationLimitInContentPixels() const = 0; 44 45 protected: 46 virtual ~PictureLayerTilingClient() {} 47 }; 48 49 class CC_EXPORT PictureLayerTiling { 50 public: 51 class CC_EXPORT TilingRasterTileIterator { 52 public: 53 TilingRasterTileIterator(); 54 TilingRasterTileIterator(PictureLayerTiling* tiling, WhichTree tree); 55 ~TilingRasterTileIterator(); 56 57 operator bool() const { return !!current_tile_; } 58 Tile* operator*() { return current_tile_; } 59 TilePriority::PriorityBin get_type() const { return type_; } 60 61 TilingRasterTileIterator& operator++(); 62 63 gfx::Rect TileBounds() const { 64 DCHECK(*this); 65 if (type_ == TilePriority::NOW) { 66 return tiling_->tiling_data_.TileBounds(visible_iterator_.index_x(), 67 visible_iterator_.index_y()); 68 } 69 return tiling_->tiling_data_.TileBounds(spiral_iterator_.index_x(), 70 spiral_iterator_.index_y()); 71 } 72 73 private: 74 void AdvancePhase(); 75 bool TileNeedsRaster(Tile* tile) const { 76 RasterMode mode = tile->DetermineRasterModeForTree(tree_); 77 return tile->NeedsRasterForMode(mode); 78 } 79 80 PictureLayerTiling* tiling_; 81 82 TilePriority::PriorityBin type_; 83 gfx::Rect visible_rect_in_content_space_; 84 gfx::Rect skewport_in_content_space_; 85 gfx::Rect eventually_rect_in_content_space_; 86 gfx::Rect soon_border_rect_in_content_space_; 87 WhichTree tree_; 88 89 Tile* current_tile_; 90 TilingData::Iterator visible_iterator_; 91 TilingData::SpiralDifferenceIterator spiral_iterator_; 92 bool skewport_processed_; 93 }; 94 95 class CC_EXPORT TilingEvictionTileIterator { 96 public: 97 TilingEvictionTileIterator(); 98 TilingEvictionTileIterator(PictureLayerTiling* tiling, 99 TreePriority tree_priority); 100 ~TilingEvictionTileIterator(); 101 102 operator bool(); 103 Tile* operator*(); 104 TilingEvictionTileIterator& operator++(); 105 TilePriority::PriorityBin get_type() { 106 DCHECK(*this); 107 const TilePriority& priority = 108 (*tile_iterator_)->priority_for_tree_priority(tree_priority_); 109 return priority.priority_bin; 110 } 111 112 private: 113 void Initialize(); 114 bool IsValid() const { return is_valid_; } 115 116 bool is_valid_; 117 PictureLayerTiling* tiling_; 118 TreePriority tree_priority_; 119 std::vector<Tile*>::iterator tile_iterator_; 120 }; 121 122 ~PictureLayerTiling(); 123 124 // Create a tiling with no tiles. CreateTiles must be called to add some. 125 static scoped_ptr<PictureLayerTiling> Create( 126 float contents_scale, 127 const gfx::Size& layer_bounds, 128 PictureLayerTilingClient* client); 129 gfx::Size layer_bounds() const { return layer_bounds_; } 130 void SetLayerBounds(const gfx::Size& layer_bounds); 131 void Invalidate(const Region& layer_region); 132 void RemoveTilesInRegion(const Region& layer_region); 133 void CreateMissingTilesInLiveTilesRect(); 134 135 void SetClient(PictureLayerTilingClient* client); 136 void set_resolution(TileResolution resolution) { resolution_ = resolution; } 137 TileResolution resolution() const { return resolution_; } 138 139 gfx::Rect TilingRect() const; 140 gfx::Rect live_tiles_rect() const { return live_tiles_rect_; } 141 gfx::Size tile_size() const { return tiling_data_.max_texture_size(); } 142 float contents_scale() const { return contents_scale_; } 143 144 Tile* TileAt(int i, int j) const { 145 TileMap::const_iterator iter = tiles_.find(TileMapKey(i, j)); 146 return (iter == tiles_.end()) ? NULL : iter->second.get(); 147 } 148 149 void CreateAllTilesForTesting() { 150 SetLiveTilesRect(tiling_data_.tiling_rect()); 151 } 152 153 std::vector<Tile*> AllTilesForTesting() const { 154 std::vector<Tile*> all_tiles; 155 for (TileMap::const_iterator it = tiles_.begin(); 156 it != tiles_.end(); ++it) 157 all_tiles.push_back(it->second.get()); 158 return all_tiles; 159 } 160 161 const gfx::Rect& GetCurrentVisibleRectForTesting() const { 162 return current_visible_rect_in_content_space_; 163 } 164 165 // Iterate over all tiles to fill content_rect. Even if tiles are invalid 166 // (i.e. no valid resource) this tiling should still iterate over them. 167 // The union of all geometry_rect calls for each element iterated over should 168 // exactly equal content_rect and no two geometry_rects should intersect. 169 class CC_EXPORT CoverageIterator { 170 public: 171 CoverageIterator(); 172 CoverageIterator(const PictureLayerTiling* tiling, 173 float dest_scale, 174 const gfx::Rect& rect); 175 ~CoverageIterator(); 176 177 // Visible rect (no borders), always in the space of content_rect, 178 // regardless of the contents scale of the tiling. 179 gfx::Rect geometry_rect() const; 180 // Texture rect (in texels) for geometry_rect 181 gfx::RectF texture_rect() const; 182 gfx::Size texture_size() const; 183 184 // Full rect (including borders) of the current tile, always in the space 185 // of content_rect, regardless of the contents scale of the tiling. 186 gfx::Rect full_tile_geometry_rect() const; 187 188 Tile* operator->() const { return current_tile_; } 189 Tile* operator*() const { return current_tile_; } 190 191 CoverageIterator& operator++(); 192 operator bool() const { return tile_j_ <= bottom_; } 193 194 int i() const { return tile_i_; } 195 int j() const { return tile_j_; } 196 197 private: 198 const PictureLayerTiling* tiling_; 199 gfx::Rect dest_rect_; 200 float dest_to_content_scale_; 201 202 Tile* current_tile_; 203 gfx::Rect current_geometry_rect_; 204 int tile_i_; 205 int tile_j_; 206 int left_; 207 int top_; 208 int right_; 209 int bottom_; 210 211 friend class PictureLayerTiling; 212 }; 213 214 void Reset(); 215 216 void UpdateTilePriorities(WhichTree tree, 217 const gfx::Rect& visible_layer_rect, 218 float layer_contents_scale, 219 double current_frame_time_in_seconds); 220 221 // Copies the src_tree priority into the dst_tree priority for all tiles. 222 // The src_tree priority is reset to the lowest priority possible. This 223 // also updates the pile on each tile to be the current client's pile. 224 void DidBecomeActive(); 225 226 // Resets the active priority for all tiles in a tiling, when an active 227 // tiling is becoming recycled. This may include some tiles which are 228 // not in the the pending tiling (due to invalidations). This must 229 // be called before DidBecomeActive, as it resets the active priority 230 // while DidBecomeActive promotes pending priority on a similar set of tiles. 231 void DidBecomeRecycled(); 232 233 void UpdateTilesToCurrentPile(); 234 235 bool NeedsUpdateForFrameAtTime(double frame_time_in_seconds) { 236 return frame_time_in_seconds != last_impl_frame_time_in_seconds_; 237 } 238 239 void GetAllTilesForTracing(std::set<const Tile*>* tiles) const; 240 scoped_ptr<base::Value> AsValue() const; 241 size_t GPUMemoryUsageInBytes() const; 242 243 struct RectExpansionCache { 244 RectExpansionCache(); 245 246 gfx::Rect previous_start; 247 gfx::Rect previous_bounds; 248 gfx::Rect previous_result; 249 int64 previous_target; 250 }; 251 252 static 253 gfx::Rect ExpandRectEquallyToAreaBoundedBy( 254 const gfx::Rect& starting_rect, 255 int64 target_area, 256 const gfx::Rect& bounding_rect, 257 RectExpansionCache* cache); 258 259 bool has_ever_been_updated() const { 260 return last_impl_frame_time_in_seconds_ != 0.0; 261 } 262 263 protected: 264 friend class CoverageIterator; 265 friend class TilingRasterTileIterator; 266 friend class TilingEvictionTileIterator; 267 268 typedef std::pair<int, int> TileMapKey; 269 typedef base::hash_map<TileMapKey, scoped_refptr<Tile> > TileMap; 270 271 PictureLayerTiling(float contents_scale, 272 const gfx::Size& layer_bounds, 273 PictureLayerTilingClient* client); 274 void SetLiveTilesRect(const gfx::Rect& live_tiles_rect); 275 Tile* CreateTile(int i, int j, const PictureLayerTiling* twin_tiling); 276 void RemoveTileAt(int i, int j); 277 278 // Computes a skewport. The calculation extrapolates the last visible 279 // rect and the current visible rect to expand the skewport to where it 280 // would be in |skewport_target_time| seconds. Note that the skewport 281 // is guaranteed to contain the current visible rect. 282 gfx::Rect ComputeSkewport(double current_frame_time_in_seconds, 283 const gfx::Rect& visible_rect_in_content_space) 284 const; 285 286 void UpdateEvictionCacheIfNeeded(TreePriority tree_priority); 287 void DoInvalidate(const Region& layer_region, bool recreate_tiles); 288 289 // Given properties. 290 float contents_scale_; 291 gfx::Size layer_bounds_; 292 TileResolution resolution_; 293 PictureLayerTilingClient* client_; 294 295 // Internal data. 296 TilingData tiling_data_; 297 TileMap tiles_; // It is not legal to have a NULL tile in the tiles_ map. 298 gfx::Rect live_tiles_rect_; 299 300 // State saved for computing velocities based upon finite differences. 301 double last_impl_frame_time_in_seconds_; 302 gfx::Rect last_visible_rect_in_content_space_; 303 304 gfx::Rect current_visible_rect_in_content_space_; 305 gfx::Rect current_skewport_; 306 gfx::Rect current_eventually_rect_; 307 gfx::Rect current_soon_border_rect_; 308 309 std::vector<Tile*> eviction_tiles_cache_; 310 bool eviction_tiles_cache_valid_; 311 TreePriority eviction_cache_tree_priority_; 312 313 private: 314 DISALLOW_ASSIGN(PictureLayerTiling); 315 316 RectExpansionCache expansion_cache_; 317 }; 318 319 } // namespace cc 320 321 #endif // CC_RESOURCES_PICTURE_LAYER_TILING_H_ 322