• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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:
~PictureLayerTilingClient()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_; }
get_type()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();
TileNeedsRaster(Tile * tile)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);
layer_bounds()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);
set_resolution(TileResolution resolution)150   void set_resolution(TileResolution resolution) { resolution_ = resolution; }
resolution()151   TileResolution resolution() const { return resolution_; }
152 
tiling_size()153   gfx::Size tiling_size() const { return tiling_data_.tiling_size(); }
live_tiles_rect()154   gfx::Rect live_tiles_rect() const { return live_tiles_rect_; }
tile_size()155   gfx::Size tile_size() const { return tiling_data_.max_texture_size(); }
contents_scale()156   float contents_scale() const { return contents_scale_; }
157 
TileAt(int i,int j)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 
CreateAllTilesForTesting()163   void CreateAllTilesForTesting() {
164     SetLiveTilesRect(gfx::Rect(tiling_data_.tiling_size()));
165   }
166 
TilingDataForTesting()167   const TilingData& TilingDataForTesting() const { return tiling_data_; }
168 
AllTilesForTesting()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 
AllRefTilesForTesting()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 
GetCurrentVisibleRectForTesting()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 
i()217     int i() const { return tile_i_; }
j()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 
NeedsUpdateForFrameAtTimeAndViewport(double frame_time_in_seconds,const gfx::Rect & viewport_in_layer_space)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 
has_ever_been_updated()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