// 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_TILE_MANAGER_H_
#define CC_RESOURCES_TILE_MANAGER_H_

#include <deque>
#include <queue>
#include <set>
#include <utility>
#include <vector>

#include "base/containers/hash_tables.h"
#include "base/memory/scoped_ptr.h"
#include "base/values.h"
#include "cc/base/ref_counted_managed.h"
#include "cc/base/unique_notifier.h"
#include "cc/resources/eviction_tile_priority_queue.h"
#include "cc/resources/memory_history.h"
#include "cc/resources/raster_source.h"
#include "cc/resources/raster_tile_priority_queue.h"
#include "cc/resources/resource_pool.h"
#include "cc/resources/tile.h"
#include "cc/resources/tile_draw_info.h"
#include "cc/resources/tile_task_runner.h"

namespace base {
namespace debug {
class ConvertableToTraceFormat;
class TracedValue;
}
}

namespace cc {
class PictureLayerImpl;
class Rasterizer;
class ResourceProvider;

class CC_EXPORT TileManagerClient {
 public:
  // Returns the set of layers that the tile manager should consider for raster.
  // TODO(vmpstr): Change the way we determine if we are ready to activate, so
  // that this can be removed.
  virtual const std::vector<PictureLayerImpl*>& GetPictureLayers() const = 0;

  // Called when all tiles marked as required for activation are ready to draw.
  virtual void NotifyReadyToActivate() = 0;

  // Called when all tiles marked as required for draw are ready to draw.
  virtual void NotifyReadyToDraw() = 0;

  // Called when the visible representation of a tile might have changed. Some
  // examples are:
  // - Tile version initialized.
  // - Tile resources freed.
  // - Tile marked for on-demand raster.
  virtual void NotifyTileStateChanged(const Tile* tile) = 0;

  // Given an empty raster tile priority queue, this will build a priority queue
  // that will return tiles in order in which they should be rasterized.
  // Note if the queue was previous built, Reset must be called on it.
  virtual void BuildRasterQueue(RasterTilePriorityQueue* queue,
                                TreePriority tree_priority,
                                RasterTilePriorityQueue::Type type) = 0;

  // Given an empty eviction tile priority queue, this will build a priority
  // queue that will return tiles in order in which they should be evicted.
  // Note if the queue was previous built, Reset must be called on it.
  virtual void BuildEvictionQueue(EvictionTilePriorityQueue* queue,
                                  TreePriority tree_priority) = 0;

 protected:
  virtual ~TileManagerClient() {}
};

struct RasterTaskCompletionStats {
  RasterTaskCompletionStats();

  size_t completed_count;
  size_t canceled_count;
};
scoped_refptr<base::debug::ConvertableToTraceFormat>
    RasterTaskCompletionStatsAsValue(const RasterTaskCompletionStats& stats);

// This class manages tiles, deciding which should get rasterized and which
// should no longer have any memory assigned to them. Tile objects are "owned"
// by layers; they automatically register with the manager when they are
// created, and unregister from the manager when they are deleted.
class CC_EXPORT TileManager : public TileTaskRunnerClient,
                              public RefCountedManager<Tile> {
 public:
  enum NamedTaskSet {
    REQUIRED_FOR_ACTIVATION,
    REQUIRED_FOR_DRAW,
    // PixelBufferTileTaskWorkerPool depends on ALL being last.
    ALL
    // Adding additional values requires increasing kNumberOfTaskSets in
    // rasterizer.h
  };

  COMPILE_ASSERT(NamedTaskSet::ALL == (kNumberOfTaskSets - 1),
                 NamedTaskSet_ALL_not_kNumberOfTaskSets_minus_1);

  static scoped_ptr<TileManager> Create(TileManagerClient* client,
                                        base::SequencedTaskRunner* task_runner,
                                        ResourcePool* resource_pool,
                                        TileTaskRunner* tile_task_runner,
                                        Rasterizer* rasterizer,
                                        size_t scheduled_raster_task_limit);
  ~TileManager() override;

  // Assigns tile memory and schedules work to prepare tiles for drawing.
  // - Runs client_->NotifyReadyToActivate() when all tiles required for
  // activation are prepared, or failed to prepare due to OOM.
  // - Runs client_->NotifyReadyToDraw() when all tiles required draw are
  // prepared, or failed to prepare due to OOM.
  void PrepareTiles(const GlobalStateThatImpactsTilePriority& state);

  void UpdateVisibleTiles(const GlobalStateThatImpactsTilePriority& state);

  scoped_refptr<Tile> CreateTile(RasterSource* raster_source,
                                 const gfx::Size& desired_texture_size,
                                 const gfx::Rect& content_rect,
                                 float contents_scale,
                                 int layer_id,
                                 int source_frame_number,
                                 int flags);

  scoped_refptr<base::debug::ConvertableToTraceFormat> BasicStateAsValue()
      const;
  void BasicStateAsValueInto(base::debug::TracedValue* dict) const;
  const MemoryHistory::Entry& memory_stats_from_last_assign() const {
    return memory_stats_from_last_assign_;
  }

  void InitializeTilesWithResourcesForTesting(const std::vector<Tile*>& tiles) {
    for (size_t i = 0; i < tiles.size(); ++i) {
      TileDrawInfo& draw_info = tiles[i]->draw_info();
      draw_info.resource_ =
          resource_pool_->AcquireResource(tiles[i]->desired_texture_size());
    }
  }

  void ReleaseTileResourcesForTesting(const std::vector<Tile*>& tiles) {
    for (size_t i = 0; i < tiles.size(); ++i) {
      Tile* tile = tiles[i];
      FreeResourcesForTile(tile);
    }
  }

  void SetGlobalStateForTesting(
      const GlobalStateThatImpactsTilePriority& state) {
    global_state_ = state;
  }

  void SetTileTaskRunnerForTesting(TileTaskRunner* tile_task_runner);

  void FreeResourcesAndCleanUpReleasedTilesForTesting() {
    FreeResourcesForReleasedTiles();
    CleanUpReleasedTiles();
  }

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

  void SetScheduledRasterTaskLimitForTesting(size_t limit) {
    scheduled_raster_task_limit_ = limit;
  }

 protected:
  TileManager(TileManagerClient* client,
              const scoped_refptr<base::SequencedTaskRunner>& task_runner,
              ResourcePool* resource_pool,
              TileTaskRunner* tile_task_runner,
              Rasterizer* rasterizer,
              size_t scheduled_raster_task_limit);

  void FreeResourcesForReleasedTiles();
  void CleanUpReleasedTiles();

  // Overriden from RefCountedManager<Tile>:
  friend class Tile;
  void Release(Tile* tile) override;

  // Overriden from TileTaskRunnerClient:
  void DidFinishRunningTileTasks(TaskSet task_set) override;
  TaskSetCollection TasksThatShouldBeForcedToComplete() const override;

  typedef std::vector<Tile*> TileVector;
  typedef std::set<Tile*> TileSet;

  // Virtual for test
  virtual void ScheduleTasks(
      const TileVector& tiles_that_need_to_be_rasterized);

  void AssignGpuMemoryToTiles(TileVector* tiles_that_need_to_be_rasterized,
                              size_t scheduled_raser_task_limit,
                              bool required_for_draw_only);

  void SynchronouslyRasterizeTiles(
      const GlobalStateThatImpactsTilePriority& state);

 private:
  class MemoryUsage {
   public:
    MemoryUsage();
    MemoryUsage(int64 memory_bytes, int resource_count);

    static MemoryUsage FromConfig(const gfx::Size& size, ResourceFormat format);
    static MemoryUsage FromTile(const Tile* tile);

    MemoryUsage& operator+=(const MemoryUsage& other);
    MemoryUsage& operator-=(const MemoryUsage& other);
    MemoryUsage operator-(const MemoryUsage& other);

    bool Exceeds(const MemoryUsage& limit) const;
    int64 memory_bytes() const { return memory_bytes_; }

   private:
    int64 memory_bytes_;
    int resource_count_;
  };

  void OnImageDecodeTaskCompleted(int layer_id,
                                  SkPixelRef* pixel_ref,
                                  bool was_canceled);
  void OnRasterTaskCompleted(Tile::Id tile,
                             scoped_ptr<ScopedResource> resource,
                             const RasterSource::SolidColorAnalysis& analysis,
                             bool was_canceled);
  void UpdateTileDrawInfo(Tile* tile,
                          scoped_ptr<ScopedResource> resource,
                          const RasterSource::SolidColorAnalysis& analysis);

  void FreeResourcesForTile(Tile* tile);
  void FreeResourcesForTileAndNotifyClientIfTileWasReadyToDraw(Tile* tile);
  scoped_refptr<ImageDecodeTask> CreateImageDecodeTask(Tile* tile,
                                                       SkPixelRef* pixel_ref);
  scoped_refptr<RasterTask> CreateRasterTask(Tile* tile);

  void RebuildEvictionQueueIfNeeded();
  bool FreeTileResourcesUntilUsageIsWithinLimit(const MemoryUsage& limit,
                                                MemoryUsage* usage);
  bool FreeTileResourcesWithLowerPriorityUntilUsageIsWithinLimit(
      const MemoryUsage& limit,
      const TilePriority& oother_priority,
      MemoryUsage* usage);
  bool TilePriorityViolatesMemoryPolicy(const TilePriority& priority);
  bool IsReadyToActivate() const;
  bool IsReadyToDraw() const;
  void NotifyReadyToActivate();
  void NotifyReadyToDraw();
  void CheckIfReadyToActivate();
  void CheckIfReadyToDraw();
  void CheckIfMoreTilesNeedToBePrepared();

  TileManagerClient* client_;
  scoped_refptr<base::SequencedTaskRunner> task_runner_;
  ResourcePool* resource_pool_;
  TileTaskRunner* tile_task_runner_;
  Rasterizer* rasterizer_;
  GlobalStateThatImpactsTilePriority global_state_;
  size_t scheduled_raster_task_limit_;

  typedef base::hash_map<Tile::Id, Tile*> TileMap;
  TileMap tiles_;

  bool all_tiles_that_need_to_be_rasterized_are_scheduled_;
  MemoryHistory::Entry memory_stats_from_last_assign_;

  bool did_check_for_completed_tasks_since_last_schedule_tasks_;
  bool did_oom_on_last_assign_;

  typedef base::hash_map<uint32_t, scoped_refptr<ImageDecodeTask>>
      PixelRefTaskMap;
  typedef base::hash_map<int, PixelRefTaskMap> LayerPixelRefTaskMap;
  LayerPixelRefTaskMap image_decode_tasks_;

  typedef base::hash_map<int, int> LayerCountMap;
  LayerCountMap used_layer_counts_;

  RasterTaskCompletionStats update_visible_tiles_stats_;

  std::vector<Tile*> released_tiles_;

  ResourceFormat resource_format_;

  // Queue used when scheduling raster tasks.
  TileTaskQueue raster_queue_;

  std::vector<scoped_refptr<RasterTask>> orphan_raster_tasks_;

  UniqueNotifier ready_to_activate_notifier_;
  UniqueNotifier ready_to_draw_notifier_;
  UniqueNotifier ready_to_activate_check_notifier_;
  UniqueNotifier ready_to_draw_check_notifier_;
  UniqueNotifier more_tiles_need_prepare_check_notifier_;

  RasterTilePriorityQueue raster_priority_queue_;
  EvictionTilePriorityQueue eviction_priority_queue_;
  bool eviction_priority_queue_is_up_to_date_;

  bool did_notify_ready_to_activate_;
  bool did_notify_ready_to_draw_;

  DISALLOW_COPY_AND_ASSIGN(TileManager);
};

}  // namespace cc

#endif  // CC_RESOURCES_TILE_MANAGER_H_
