// 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
  };

  static_assert(NamedTaskSet::ALL == (kNumberOfTaskSets - 1),
                "NamedTaskSet::ALL should be equal to 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(),
                                          resource_pool_->default_format());
    }
  }

  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(RasterTilePriorityQueue* raster_priority_queue,
                              size_t scheduled_raser_task_limit,
                              TileVector* tiles_that_need_to_be_rasterized);

  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_;

  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_
