// Copyright 2013 The Flutter 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 FLUTTER_FLOW_RASTER_CACHE_H_
#define FLUTTER_FLOW_RASTER_CACHE_H_

#include <memory>
#include <unordered_map>

#include "flutter/display_list/dl_canvas.h"
#include "flutter/flow/raster_cache_key.h"
#include "flutter/flow/raster_cache_util.h"
#include "flutter/fml/macros.h"
#include "flutter/fml/memory/weak_ptr.h"
#include "flutter/fml/trace_event.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkRect.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkSize.h"

class GrDirectContext;
class SkColorSpace;

namespace flutter {

enum class RasterCacheLayerStrategy { kLayer, kLayerChildren };

class RasterCacheResult {
 public:
  RasterCacheResult(sk_sp<DlImage> image,
                    const SkRect& logical_rect,
                    const char* type,
                    sk_sp<const DlRTree> rtree = nullptr);

  virtual ~RasterCacheResult() = default;

  virtual void draw(DlCanvas& canvas,
                    const DlPaint* paint,
                    bool preserve_rtree) const;

  virtual SkISize image_dimensions() const {
    return image_ ? image_->dimensions() : SkISize::Make(0, 0);
  };

  virtual int64_t image_bytes() const {
    return image_ ? image_->GetApproximateByteSize() : 0;
  };

 private:
  sk_sp<DlImage> image_;
  SkRect logical_rect_;
  fml::tracing::TraceFlow flow_;
  sk_sp<const DlRTree> rtree_;
};

class Layer;
class RasterCacheItem;
struct PrerollContext;
struct PaintContext;

struct RasterCacheMetrics {
  /**
   * The number of cache entries with images evicted in this frame.
   */
  size_t eviction_count = 0;

  /**
   * The size of all of the images evicted in this frame.
   */
  size_t eviction_bytes = 0;

  /**
   * The number of cache entries with images used in this frame.
   */
  size_t in_use_count = 0;

  /**
   * The size of all of the images used in this frame.
   */
  size_t in_use_bytes = 0;

  /**
   * The total cache entries that had images during this frame.
   */
  size_t total_count() const { return in_use_count; }

  /**
   * The size of all of the cached images during this frame.
   */
  size_t total_bytes() const { return in_use_bytes; }
};

/**
 * RasterCache is used to cache rasterized layers or display lists to improve
 * performance.
 *
 * Life cycle of RasterCache methods:
 * - Preroll stage
 *   - LayerTree::Preroll - for each Layer in the tree:
 *     - RasterCacheItem::PrerollSetup
 *         At the start of each layer's preroll, add cache items to
 *         `PrerollContext::raster_cached_entries`.
 *     - RasterCacheItem::PrerollFinalize
 *         At the end of each layer's preroll, may mark cache entries as
 *         encountered by the current frame.
 * - Paint stage
 *   - RasterCache::EvictUnusedCacheEntries
 *       Evict cached images that are no longer used.
 *   - LayerTree::TryToPrepareRasterCache
 *       Create cache image for each cache entry if it does not exist.
 *   - LayerTree::Paint - for each layer in the tree:
 *       If layers or display lists are cached as cached images, the method
 *       `RasterCache::Draw` will be used to draw those cache images.
 *   - RasterCache::EndFrame:
 *       Computes used counts and memory then reports cache metrics.
 */
class RasterCache {
 public:
  struct Context {
    GrDirectContext* gr_context;
    const SkColorSpace* dst_color_space;
    const SkMatrix& matrix;
    const SkRect& logical_rect;
    const char* flow_type;
  };
  struct CacheInfo {
    const size_t accesses_since_visible;
    const bool has_image;
  };

  std::unique_ptr<RasterCacheResult> Rasterize(
      const RasterCache::Context& context,
      sk_sp<const DlRTree> rtree,
      const std::function<void(DlCanvas*)>& draw_function,
      const std::function<void(DlCanvas*, const SkRect& rect)>&
          draw_checkerboard) const;

  explicit RasterCache(
      size_t access_threshold = 3,
      size_t picture_and_display_list_cache_limit_per_frame =
          RasterCacheUtil::kDefaultPictureAndDisplayListCacheLimitPerFrame);

  virtual ~RasterCache() = default;

  // Draws this item if it should be rendered from the cache and returns
  // true iff it was successfully drawn. Typically this should only fail
  // if the item was disabled due to conditions discovered during |Preroll|
  // or if the attempt to populate the entry failed due to bounds overflow
  // conditions.
  // If |preserve_rtree| is true, the raster cache will preserve the original
  // RTree of cached content by blitting individual rectangles from the cached
  // image to the canvas according to the original layer R-Tree (if present).
  // This is to ensure that the target surface R-Tree will not be clobbered with
  // one large blit as it can affect platform view overlays and hit testing.
  bool Draw(const RasterCacheKeyID& id,
            DlCanvas& canvas,
            const DlPaint* paint,
            bool preserve_rtree = false) const;

  bool HasEntry(const RasterCacheKeyID& id, const SkMatrix&) const;

  void BeginFrame();

  void EvictUnusedCacheEntries();

  void EndFrame();

  void Clear();

  void SetCheckboardCacheImages(bool checkerboard);

  const RasterCacheMetrics& picture_metrics() const { return picture_metrics_; }
  const RasterCacheMetrics& layer_metrics() const { return layer_metrics_; }

  size_t GetCachedEntriesCount() const;

  /**
   * Return the number of map entries in the layer cache regardless of whether
   * the entries have been populated with an image.
   */
  size_t GetLayerCachedEntriesCount() const;

  /**
   * Return the number of map entries in the picture caches (SkPicture and
   * DisplayList) regardless of whether the entries have been populated with
   * an image.
   */
  size_t GetPictureCachedEntriesCount() const;

  /**
   * @brief Estimate how much memory is used by picture raster cache entries in
   * bytes, including cache entries in the SkPicture cache and the DisplayList
   * cache.
   *
   * Only SkImage's memory usage is counted as other objects are often much
   * smaller compared to SkImage. SkImageInfo::computeMinByteSize is used to
   * estimate the SkImage memory usage.
   */
  size_t EstimatePictureCacheByteSize() const;

  /**
   * @brief Estimate how much memory is used by layer raster cache entries in
   * bytes.
   *
   * Only SkImage's memory usage is counted as other objects are often much
   * smaller compared to SkImage. SkImageInfo::computeMinByteSize is used to
   * estimate the SkImage memory usage.
   */
  size_t EstimateLayerCacheByteSize() const;

  /**
   * @brief Return the number of frames that a picture must be prepared
   * before it will be cached. If the number is 0, then no picture will
   * ever be cached.
   *
   * If the number is one, then it must be prepared and drawn on 1 frame
   * and it will then be cached on the next frame if it is prepared.
   */
  size_t access_threshold() const { return access_threshold_; }

  bool GenerateNewCacheInThisFrame() const {
    // Disabling caching when access_threshold is zero is historic behavior.
    return access_threshold_ != 0 && display_list_cached_this_frame_ <
                                         display_list_cache_limit_per_frame_;
  }

  /**
   * @brief The entry whose RasterCacheKey is generated by RasterCacheKeyID
   * and matrix is marked as encountered by the current frame. The entry
   * will be created if it does not exist. Optionally the entry will be marked
   * as visible in the current frame if the caller determines that it
   * intersects the cull rect. The access_count of the entry will be
   * increased if it is visible, or if it was ever visible.
   * @return the number of times the entry has been hit since it was created.
   * For a new entry that will be 1 if it is visible, or zero if non-visible.
   */
  CacheInfo MarkSeen(const RasterCacheKeyID& id,
                     const SkMatrix& matrix,
                     bool visible) const;

  /**
   * Returns the access count (i.e. accesses_since_visible) for the given
   * entry in the cache, or -1 if no such entry exists.
   */
  int GetAccessCount(const RasterCacheKeyID& id, const SkMatrix& matrix) const;

  bool UpdateCacheEntry(const RasterCacheKeyID& id,
                        const Context& raster_cache_context,
                        const std::function<void(DlCanvas*)>& render_function,
                        sk_sp<const DlRTree> rtree = nullptr) const;

 private:
  struct Entry {
    bool encountered_this_frame = false;
    bool visible_this_frame = false;
    size_t accesses_since_visible = 0;
    std::unique_ptr<RasterCacheResult> image;
  };

  void UpdateMetrics();

  RasterCacheMetrics& GetMetricsForKind(RasterCacheKeyKind kind);

  const size_t access_threshold_;
  const size_t display_list_cache_limit_per_frame_;
  mutable size_t display_list_cached_this_frame_ = 0;
  RasterCacheMetrics layer_metrics_;
  RasterCacheMetrics picture_metrics_;
  mutable RasterCacheKey::Map<Entry> cache_;
  bool checkerboard_images_;

  void TraceStatsToTimeline() const;

  friend class RasterCacheItem;
  friend class LayerRasterCacheItem;

  FML_DISALLOW_COPY_AND_ASSIGN(RasterCache);
};

}  // namespace flutter

#endif  // FLUTTER_FLOW_RASTER_CACHE_H_
