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 "cc/trees/occlusion.h" 21 #include "ui/gfx/rect.h" 22 23 namespace base { 24 namespace debug { 25 class TracedValue; 26 } 27 } 28 29 namespace cc { 30 31 class PictureLayerTiling; 32 class PicturePileImpl; 33 34 class CC_EXPORT PictureLayerTilingClient { 35 public: 36 // Create a tile at the given content_rect (in the contents scale of the 37 // tiling) This might return null if the client cannot create such a tile. 38 virtual scoped_refptr<Tile> CreateTile( 39 PictureLayerTiling* tiling, 40 const gfx::Rect& content_rect) = 0; 41 virtual PicturePileImpl* GetPile() = 0; 42 virtual gfx::Size CalculateTileSize( 43 const gfx::Size& content_bounds) const = 0; 44 virtual const Region* GetInvalidation() = 0; 45 virtual const PictureLayerTiling* GetTwinTiling( 46 const PictureLayerTiling* tiling) const = 0; 47 virtual PictureLayerTiling* GetRecycledTwinTiling( 48 const PictureLayerTiling* tiling) = 0; 49 virtual size_t GetMaxTilesForInterestArea() const = 0; 50 virtual float GetSkewportTargetTimeInSeconds() const = 0; 51 virtual int GetSkewportExtrapolationLimitInContentPixels() const = 0; 52 virtual WhichTree GetTree() const = 0; 53 54 protected: 55 virtual ~PictureLayerTilingClient() {} 56 }; 57 58 class CC_EXPORT PictureLayerTiling { 59 public: 60 enum EvictionCategory { 61 EVENTUALLY, 62 EVENTUALLY_AND_REQUIRED_FOR_ACTIVATION, 63 SOON, 64 SOON_AND_REQUIRED_FOR_ACTIVATION, 65 NOW, 66 NOW_AND_REQUIRED_FOR_ACTIVATION 67 }; 68 69 class CC_EXPORT TilingRasterTileIterator { 70 public: 71 TilingRasterTileIterator(); 72 TilingRasterTileIterator(PictureLayerTiling* tiling, WhichTree tree); 73 ~TilingRasterTileIterator(); 74 75 operator bool() const { return !!current_tile_; } 76 const Tile* operator*() const { return current_tile_; } 77 Tile* operator*() { return current_tile_; } 78 TilePriority::PriorityBin get_type() const { 79 switch (phase_) { 80 case VISIBLE_RECT: 81 return TilePriority::NOW; 82 case SKEWPORT_RECT: 83 case SOON_BORDER_RECT: 84 return TilePriority::SOON; 85 case EVENTUALLY_RECT: 86 return TilePriority::EVENTUALLY; 87 } 88 NOTREACHED(); 89 return TilePriority::EVENTUALLY; 90 } 91 92 TilingRasterTileIterator& operator++(); 93 94 private: 95 enum Phase { 96 VISIBLE_RECT, 97 SKEWPORT_RECT, 98 SOON_BORDER_RECT, 99 EVENTUALLY_RECT 100 }; 101 102 void AdvancePhase(); 103 bool TileNeedsRaster(Tile* tile) const { 104 RasterMode mode = tile->DetermineRasterModeForTree(tree_); 105 return !tile->is_occluded(tree_) && tile->NeedsRasterForMode(mode); 106 } 107 108 PictureLayerTiling* tiling_; 109 110 Phase phase_; 111 WhichTree tree_; 112 113 Tile* current_tile_; 114 TilingData::Iterator visible_iterator_; 115 TilingData::SpiralDifferenceIterator spiral_iterator_; 116 }; 117 118 class CC_EXPORT TilingEvictionTileIterator { 119 public: 120 TilingEvictionTileIterator(); 121 TilingEvictionTileIterator(PictureLayerTiling* tiling, 122 TreePriority tree_priority, 123 EvictionCategory category); 124 ~TilingEvictionTileIterator(); 125 126 operator bool() const; 127 const Tile* operator*() const; 128 Tile* operator*(); 129 TilingEvictionTileIterator& operator++(); 130 131 private: 132 const std::vector<Tile*>* eviction_tiles_; 133 size_t current_eviction_tiles_index_; 134 }; 135 136 ~PictureLayerTiling(); 137 138 // Create a tiling with no tiles. CreateTiles must be called to add some. 139 static scoped_ptr<PictureLayerTiling> Create( 140 float contents_scale, 141 const gfx::Size& layer_bounds, 142 PictureLayerTilingClient* client); 143 gfx::Size layer_bounds() const { return layer_bounds_; } 144 void UpdateTilesToCurrentPile(const Region& layer_invalidation, 145 const gfx::Size& new_layer_bounds); 146 void CreateMissingTilesInLiveTilesRect(); 147 void RemoveTilesInRegion(const Region& layer_region); 148 149 void SetClient(PictureLayerTilingClient* client); 150 void set_resolution(TileResolution resolution) { resolution_ = resolution; } 151 TileResolution resolution() const { return resolution_; } 152 153 gfx::Size tiling_size() const { return tiling_data_.tiling_size(); } 154 gfx::Rect live_tiles_rect() const { return live_tiles_rect_; } 155 gfx::Size tile_size() const { return tiling_data_.max_texture_size(); } 156 float contents_scale() const { return contents_scale_; } 157 158 Tile* TileAt(int i, int j) const { 159 TileMap::const_iterator iter = tiles_.find(TileMapKey(i, j)); 160 return (iter == tiles_.end()) ? NULL : iter->second.get(); 161 } 162 163 void CreateAllTilesForTesting() { 164 SetLiveTilesRect(gfx::Rect(tiling_data_.tiling_size())); 165 } 166 167 const TilingData& TilingDataForTesting() const { return tiling_data_; } 168 169 std::vector<Tile*> AllTilesForTesting() const { 170 std::vector<Tile*> all_tiles; 171 for (TileMap::const_iterator it = tiles_.begin(); 172 it != tiles_.end(); ++it) 173 all_tiles.push_back(it->second.get()); 174 return all_tiles; 175 } 176 177 std::vector<scoped_refptr<Tile> > AllRefTilesForTesting() const { 178 std::vector<scoped_refptr<Tile> > all_tiles; 179 for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it) 180 all_tiles.push_back(it->second); 181 return all_tiles; 182 } 183 184 const gfx::Rect& GetCurrentVisibleRectForTesting() const { 185 return current_visible_rect_; 186 } 187 188 // Iterate over all tiles to fill content_rect. Even if tiles are invalid 189 // (i.e. no valid resource) this tiling should still iterate over them. 190 // The union of all geometry_rect calls for each element iterated over should 191 // exactly equal content_rect and no two geometry_rects should intersect. 192 class CC_EXPORT CoverageIterator { 193 public: 194 CoverageIterator(); 195 CoverageIterator(const PictureLayerTiling* tiling, 196 float dest_scale, 197 const gfx::Rect& rect); 198 ~CoverageIterator(); 199 200 // Visible rect (no borders), always in the space of content_rect, 201 // regardless of the contents scale of the tiling. 202 gfx::Rect geometry_rect() const; 203 // Texture rect (in texels) for geometry_rect 204 gfx::RectF texture_rect() const; 205 gfx::Size texture_size() const; 206 207 // Full rect (including borders) of the current tile, always in the space 208 // of content_rect, regardless of the contents scale of the tiling. 209 gfx::Rect full_tile_geometry_rect() const; 210 211 Tile* operator->() const { return current_tile_; } 212 Tile* operator*() const { return current_tile_; } 213 214 CoverageIterator& operator++(); 215 operator bool() const { return tile_j_ <= bottom_; } 216 217 int i() const { return tile_i_; } 218 int j() const { return tile_j_; } 219 220 private: 221 const PictureLayerTiling* tiling_; 222 gfx::Rect dest_rect_; 223 float dest_to_content_scale_; 224 225 Tile* current_tile_; 226 gfx::Rect current_geometry_rect_; 227 int tile_i_; 228 int tile_j_; 229 int left_; 230 int top_; 231 int right_; 232 int bottom_; 233 234 friend class PictureLayerTiling; 235 }; 236 237 void Reset(); 238 239 void UpdateTilePriorities(WhichTree tree, 240 const gfx::Rect& viewport_in_layer_space, 241 float ideal_contents_scale, 242 double current_frame_time_in_seconds, 243 const Occlusion& occlusion_in_layer_space); 244 245 // Copies the src_tree priority into the dst_tree priority for all tiles. 246 // The src_tree priority is reset to the lowest priority possible. This 247 // also updates the pile on each tile to be the current client's pile. 248 void DidBecomeActive(); 249 250 // Resets the active priority for all tiles in a tiling, when an active 251 // tiling is becoming recycled. This may include some tiles which are 252 // not in the the pending tiling (due to invalidations). This must 253 // be called before DidBecomeActive, as it resets the active priority 254 // while DidBecomeActive promotes pending priority on a similar set of tiles. 255 void DidBecomeRecycled(); 256 257 bool NeedsUpdateForFrameAtTimeAndViewport( 258 double frame_time_in_seconds, 259 const gfx::Rect& viewport_in_layer_space) { 260 return frame_time_in_seconds != last_impl_frame_time_in_seconds_ || 261 viewport_in_layer_space != last_viewport_in_layer_space_; 262 } 263 264 void GetAllTilesForTracing(std::set<const Tile*>* tiles) const; 265 void AsValueInto(base::debug::TracedValue* array) const; 266 size_t GPUMemoryUsageInBytes() const; 267 268 struct RectExpansionCache { 269 RectExpansionCache(); 270 271 gfx::Rect previous_start; 272 gfx::Rect previous_bounds; 273 gfx::Rect previous_result; 274 int64 previous_target; 275 }; 276 277 static 278 gfx::Rect ExpandRectEquallyToAreaBoundedBy( 279 const gfx::Rect& starting_rect, 280 int64 target_area, 281 const gfx::Rect& bounding_rect, 282 RectExpansionCache* cache); 283 284 bool has_ever_been_updated() const { 285 return last_impl_frame_time_in_seconds_ != 0.0; 286 } 287 288 protected: 289 friend class CoverageIterator; 290 friend class TilingRasterTileIterator; 291 friend class TilingEvictionTileIterator; 292 293 typedef std::pair<int, int> TileMapKey; 294 typedef base::hash_map<TileMapKey, scoped_refptr<Tile> > TileMap; 295 296 PictureLayerTiling(float contents_scale, 297 const gfx::Size& layer_bounds, 298 PictureLayerTilingClient* client); 299 void SetLiveTilesRect(const gfx::Rect& live_tiles_rect); 300 void VerifyLiveTilesRect(); 301 Tile* CreateTile(int i, int j, const PictureLayerTiling* twin_tiling); 302 // Returns true if the Tile existed and was removed from the tiling. 303 bool RemoveTileAt(int i, int j, PictureLayerTiling* recycled_twin); 304 305 // Computes a skewport. The calculation extrapolates the last visible 306 // rect and the current visible rect to expand the skewport to where it 307 // would be in |skewport_target_time| seconds. Note that the skewport 308 // is guaranteed to contain the current visible rect. 309 gfx::Rect ComputeSkewport(double current_frame_time_in_seconds, 310 const gfx::Rect& visible_rect_in_content_space) 311 const; 312 313 void UpdateEvictionCacheIfNeeded(TreePriority tree_priority); 314 const std::vector<Tile*>* GetEvictionTiles(TreePriority tree_priority, 315 EvictionCategory category); 316 317 void Invalidate(const Region& layer_region); 318 319 void DoInvalidate(const Region& layer_region, 320 bool recreate_invalidated_tiles); 321 322 // Given properties. 323 float contents_scale_; 324 gfx::Size layer_bounds_; 325 TileResolution resolution_; 326 PictureLayerTilingClient* client_; 327 328 // Internal data. 329 TilingData tiling_data_; 330 TileMap tiles_; // It is not legal to have a NULL tile in the tiles_ map. 331 gfx::Rect live_tiles_rect_; 332 333 // State saved for computing velocities based upon finite differences. 334 double last_impl_frame_time_in_seconds_; 335 gfx::Rect last_viewport_in_layer_space_; 336 gfx::Rect last_visible_rect_in_content_space_; 337 338 // Iteration rects in content space 339 gfx::Rect current_visible_rect_; 340 gfx::Rect current_skewport_rect_; 341 gfx::Rect current_soon_border_rect_; 342 gfx::Rect current_eventually_rect_; 343 344 bool has_visible_rect_tiles_; 345 bool has_skewport_rect_tiles_; 346 bool has_soon_border_rect_tiles_; 347 bool has_eventually_rect_tiles_; 348 349 // TODO(reveman): Remove this in favour of an array of eviction_tiles_ when we 350 // change all enums to have a consistent way of getting the count/last 351 // element. 352 std::vector<Tile*> eviction_tiles_now_; 353 std::vector<Tile*> eviction_tiles_now_and_required_for_activation_; 354 std::vector<Tile*> eviction_tiles_soon_; 355 std::vector<Tile*> eviction_tiles_soon_and_required_for_activation_; 356 std::vector<Tile*> eviction_tiles_eventually_; 357 std::vector<Tile*> eviction_tiles_eventually_and_required_for_activation_; 358 359 bool eviction_tiles_cache_valid_; 360 TreePriority eviction_cache_tree_priority_; 361 362 private: 363 DISALLOW_ASSIGN(PictureLayerTiling); 364 365 RectExpansionCache expansion_cache_; 366 }; 367 368 } // namespace cc 369 370 #endif // CC_RESOURCES_PICTURE_LAYER_TILING_H_ 371