// Copyright 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#ifndef CC_RESOURCES_PICTURE_LAYER_TILING_H_
#define CC_RESOURCES_PICTURE_LAYER_TILING_H_

#include <map>
#include <utility>
#include <vector>

#include "base/basictypes.h"
#include "base/containers/hash_tables.h"
#include "base/memory/scoped_ptr.h"
#include "cc/base/cc_export.h"
#include "cc/base/region.h"
#include "cc/base/tiling_data.h"
#include "cc/resources/tile.h"
#include "cc/resources/tile_priority.h"
#include "cc/trees/occlusion.h"
#include "ui/gfx/geometry/rect.h"

namespace base {
namespace trace_event {
class TracedValue;
}
}

namespace cc {

class PictureLayerTiling;
class RasterSource;

class CC_EXPORT PictureLayerTilingClient {
 public:
  // Create a tile at the given content_rect (in the contents scale of the
  // tiling) This might return null if the client cannot create such a tile.
  virtual scoped_refptr<Tile> CreateTile(float contents_scale,
                                         const gfx::Rect& content_rect) = 0;
  virtual gfx::Size CalculateTileSize(
    const gfx::Size& content_bounds) const = 0;
  // This invalidation region defines the area (if any, it can by null) that
  // tiles can not be shared between pending and active trees.
  virtual const Region* GetPendingInvalidation() = 0;
  virtual const PictureLayerTiling* GetPendingOrActiveTwinTiling(
      const PictureLayerTiling* tiling) const = 0;
  virtual PictureLayerTiling* GetRecycledTwinTiling(
      const PictureLayerTiling* tiling) = 0;
  virtual TilePriority::PriorityBin GetMaxTilePriorityBin() const = 0;
  virtual WhichTree GetTree() const = 0;
  virtual bool RequiresHighResToDraw() const = 0;

 protected:
  virtual ~PictureLayerTilingClient() {}
};

class CC_EXPORT PictureLayerTiling {
 public:
  static const int kBorderTexels = 1;

  ~PictureLayerTiling();

  static float CalculateSoonBorderDistance(
      const gfx::Rect& visible_rect_in_content_space,
      float content_to_screen_scale);

  // Create a tiling with no tiles. CreateTile() must be called to add some.
  static scoped_ptr<PictureLayerTiling> Create(
      float contents_scale,
      scoped_refptr<RasterSource> raster_source,
      PictureLayerTilingClient* client,
      size_t max_tiles_for_interest_area,
      float skewport_target_time_in_seconds,
      int skewport_extrapolation_limit_in_content_pixels);

  void SetRasterSourceAndResize(scoped_refptr<RasterSource> raster_source);
  void Invalidate(const Region& layer_invalidation);
  void SetRasterSourceOnTiles();
  void CreateMissingTilesInLiveTilesRect();

  void CloneTilesAndPropertiesFrom(const PictureLayerTiling& twin_tiling);

  void set_resolution(TileResolution resolution) { resolution_ = resolution; }
  TileResolution resolution() const { return resolution_; }
  void set_can_require_tiles_for_activation(bool can_require_tiles) {
    can_require_tiles_for_activation_ = can_require_tiles;
  }

  RasterSource* raster_source() const { return raster_source_.get(); }
  gfx::Size tiling_size() const { return tiling_data_.tiling_size(); }
  gfx::Rect live_tiles_rect() const { return live_tiles_rect_; }
  gfx::Size tile_size() const { return tiling_data_.max_texture_size(); }
  float contents_scale() const { return contents_scale_; }

  Tile* TileAt(int i, int j) const {
    TileMap::const_iterator iter = tiles_.find(TileMapKey(i, j));
    return (iter == tiles_.end()) ? NULL : iter->second.get();
  }

  void CreateAllTilesForTesting() {
    SetLiveTilesRect(gfx::Rect(tiling_data_.tiling_size()));
  }

  const TilingData& TilingDataForTesting() const { return tiling_data_; }

  std::vector<Tile*> AllTilesForTesting() const {
    std::vector<Tile*> all_tiles;
    for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it)
      all_tiles.push_back(it->second.get());
    return all_tiles;
  }

  void UpdateAllTilePrioritiesForTesting() {
    for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it)
      UpdateTileAndTwinPriority(it->second.get());
  }

  std::vector<scoped_refptr<Tile>> AllRefTilesForTesting() const {
    std::vector<scoped_refptr<Tile>> all_tiles;
    for (TileMap::const_iterator it = tiles_.begin(); it != tiles_.end(); ++it)
      all_tiles.push_back(it->second);
    return all_tiles;
  }

  void SetAllTilesOccludedForTesting() {
    gfx::Rect viewport_in_layer_space =
        ScaleToEnclosingRect(current_visible_rect_, 1.0f / contents_scale_);
    current_occlusion_in_layer_space_ =
        Occlusion(gfx::Transform(),
                  SimpleEnclosedRegion(viewport_in_layer_space),
                  SimpleEnclosedRegion(viewport_in_layer_space));
  }

  const gfx::Rect& GetCurrentVisibleRectForTesting() const {
    return current_visible_rect_;
  }

  bool IsTileOccluded(const Tile* tile) const;
  bool IsTileRequiredForActivationIfVisible(const Tile* tile) const;
  bool IsTileRequiredForDrawIfVisible(const Tile* tile) const;

  void UpdateTileAndTwinPriority(Tile* tile) const;
  TilePriority ComputePriorityForTile(const Tile* tile) const;
  void UpdateRequiredStateForTile(Tile* tile, WhichTree tree) const;
  bool has_visible_rect_tiles() const { return has_visible_rect_tiles_; }
  bool has_skewport_rect_tiles() const { return has_skewport_rect_tiles_; }
  bool has_soon_border_rect_tiles() const {
    return has_soon_border_rect_tiles_;
  }
  bool has_eventually_rect_tiles() const { return has_eventually_rect_tiles_; }

  const gfx::Rect& current_visible_rect() const {
    return current_visible_rect_;
  }
  const gfx::Rect& current_skewport_rect() const {
    return current_skewport_rect_;
  }
  const gfx::Rect& current_soon_border_rect() const {
    return current_soon_border_rect_;
  }
  const gfx::Rect& current_eventually_rect() const {
    return current_eventually_rect_;
  }

  // Iterate over all tiles to fill content_rect.  Even if tiles are invalid
  // (i.e. no valid resource) this tiling should still iterate over them.
  // The union of all geometry_rect calls for each element iterated over should
  // exactly equal content_rect and no two geometry_rects should intersect.
  class CC_EXPORT CoverageIterator {
   public:
    CoverageIterator();
    CoverageIterator(const PictureLayerTiling* tiling,
        float dest_scale,
        const gfx::Rect& rect);
    ~CoverageIterator();

    // Visible rect (no borders), always in the space of content_rect,
    // regardless of the contents scale of the tiling.
    gfx::Rect geometry_rect() const;
    // Texture rect (in texels) for geometry_rect
    gfx::RectF texture_rect() const;

    Tile* operator->() const { return current_tile_; }
    Tile* operator*() const { return current_tile_; }

    CoverageIterator& operator++();
    operator bool() const { return tile_j_ <= bottom_; }

    int i() const { return tile_i_; }
    int j() const { return tile_j_; }

   private:
    const PictureLayerTiling* tiling_;
    gfx::Rect dest_rect_;
    float dest_to_content_scale_;

    Tile* current_tile_;
    gfx::Rect current_geometry_rect_;
    int tile_i_;
    int tile_j_;
    int left_;
    int top_;
    int right_;
    int bottom_;

    friend class PictureLayerTiling;
  };

  void Reset();

  bool ComputeTilePriorityRects(const gfx::Rect& viewport_in_layer_space,
                                float ideal_contents_scale,
                                double current_frame_time_in_seconds,
                                const Occlusion& occlusion_in_layer_space);

  void GetAllTilesAndPrioritiesForTracing(
      std::map<const Tile*, TilePriority>* tile_map) const;
  void AsValueInto(base::trace_event::TracedValue* array) const;
  size_t GPUMemoryUsageInBytes() const;

  struct RectExpansionCache {
    RectExpansionCache();

    gfx::Rect previous_start;
    gfx::Rect previous_bounds;
    gfx::Rect previous_result;
    int64 previous_target;
  };

  static
  gfx::Rect ExpandRectEquallyToAreaBoundedBy(
      const gfx::Rect& starting_rect,
      int64 target_area,
      const gfx::Rect& bounding_rect,
      RectExpansionCache* cache);

  bool has_ever_been_updated() const {
    return visible_rect_history_[0].frame_time_in_seconds != 0.0;
  }

 protected:
  friend class CoverageIterator;
  friend class TilingSetRasterQueueAll;
  friend class TilingSetRasterQueueRequired;
  friend class TilingSetEvictionQueue;

  typedef std::pair<int, int> TileMapKey;
  typedef base::hash_map<TileMapKey, scoped_refptr<Tile>> TileMap;

  struct FrameVisibleRect {
    gfx::Rect visible_rect_in_content_space;
    double frame_time_in_seconds = 0.0;
  };

  PictureLayerTiling(float contents_scale,
                     scoped_refptr<RasterSource> raster_source,
                     PictureLayerTilingClient* client,
                     size_t max_tiles_for_interest_area,
                     float skewport_target_time_in_seconds,
                     int skewport_extrapolation_limit_in_content_pixels);
  void SetLiveTilesRect(const gfx::Rect& live_tiles_rect);
  void VerifyLiveTilesRect(bool is_on_recycle_tree) const;
  Tile* CreateTile(int i,
                   int j,
                   const PictureLayerTiling* twin_tiling,
                   PictureLayerTiling* recycled_twin);
  // Returns true if the Tile existed and was removed from the tiling.
  bool RemoveTileAt(int i, int j, PictureLayerTiling* recycled_twin);

  // Computes a skewport. The calculation extrapolates the last visible
  // rect and the current visible rect to expand the skewport to where it
  // would be in |skewport_target_time| seconds. Note that the skewport
  // is guaranteed to contain the current visible rect.
  gfx::Rect ComputeSkewport(double current_frame_time_in_seconds,
                            const gfx::Rect& visible_rect_in_content_space)
      const;

  // Save the required data for computing tile priorities later.
  void UpdateTilePriorityRects(float content_to_screen_scale_,
                               const gfx::Rect& visible_rect_in_content_space,
                               const gfx::Rect& skewport,
                               const gfx::Rect& soon_border_rect,
                               const gfx::Rect& eventually_rect,
                               const Occlusion& occlusion_in_layer_space);

  void UpdateTilePriorityForTree(Tile* tile, WhichTree tree) const;
  bool NeedsUpdateForFrameAtTimeAndViewport(
      double frame_time_in_seconds,
      const gfx::Rect& viewport_in_layer_space) {
    return frame_time_in_seconds !=
               visible_rect_history_[0].frame_time_in_seconds ||
           viewport_in_layer_space != last_viewport_in_layer_space_;
  }
  void UpdateVisibleRectHistory(
      double frame_time_in_seconds,
      const gfx::Rect& visible_rect_in_content_space) {
    visible_rect_history_[1] = visible_rect_history_[0];
    visible_rect_history_[0].frame_time_in_seconds = frame_time_in_seconds;
    visible_rect_history_[0].visible_rect_in_content_space =
        visible_rect_in_content_space;
    // If we don't have a second history item, set it to the most recent one.
    if (visible_rect_history_[1].frame_time_in_seconds == 0.0)
      visible_rect_history_[1] = visible_rect_history_[0];
  }

  const size_t max_tiles_for_interest_area_;
  const float skewport_target_time_in_seconds_;
  const int skewport_extrapolation_limit_in_content_pixels_;

  // Given properties.
  const float contents_scale_;
  PictureLayerTilingClient* const client_;
  scoped_refptr<RasterSource> raster_source_;
  TileResolution resolution_;

  // Internal data.
  TilingData tiling_data_;
  TileMap tiles_;  // It is not legal to have a NULL tile in the tiles_ map.
  gfx::Rect live_tiles_rect_;

  gfx::Rect last_viewport_in_layer_space_;
  // State saved for computing velocities based upon finite differences.
  FrameVisibleRect visible_rect_history_[2];

  bool can_require_tiles_for_activation_;

  // Iteration rects in content space.
  gfx::Rect current_visible_rect_;
  gfx::Rect current_skewport_rect_;
  gfx::Rect current_soon_border_rect_;
  gfx::Rect current_eventually_rect_;
  // Other properties used for tile iteration and prioritization.
  float current_content_to_screen_scale_;
  Occlusion current_occlusion_in_layer_space_;

  bool has_visible_rect_tiles_;
  bool has_skewport_rect_tiles_;
  bool has_soon_border_rect_tiles_;
  bool has_eventually_rect_tiles_;

 private:
  DISALLOW_ASSIGN(PictureLayerTiling);

  RectExpansionCache expansion_cache_;
};

}  // namespace cc

#endif  // CC_RESOURCES_PICTURE_LAYER_TILING_H_
