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