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
23namespace base {
24namespace debug {
25class TracedValue;
26}
27}
28
29namespace cc {
30
31class PictureLayerTiling;
32class PicturePileImpl;
33
34class 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
58class 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