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
22namespace cc {
23
24class PictureLayerTiling;
25
26class 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
49class 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