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 "ui/gfx/rect.h"
     21 
     22 namespace cc {
     23 
     24 class PictureLayerTiling;
     25 
     26 class 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 
     49 class 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