Home | History | Annotate | Download | only in resources
      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