// 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.

#include "flutter/flow/raster_cache.h"

#include <vector>

#include "flutter/flow/layers/layer.h"
#include "flutter/flow/paint_utils.h"
#include "flutter/fml/logging.h"
#include "flutter/fml/trace_event.h"
#include "third_party/skia/include/core/SkCanvas.h"
#include "third_party/skia/include/core/SkImage.h"
#include "third_party/skia/include/core/SkPicture.h"
#include "third_party/skia/include/core/SkSurface.h"

namespace flow {

RasterCacheResult::RasterCacheResult() {}

RasterCacheResult::RasterCacheResult(const RasterCacheResult& other) = default;

RasterCacheResult::~RasterCacheResult() = default;

RasterCacheResult::RasterCacheResult(sk_sp<SkImage> image,
                                     const SkRect& logical_rect)
    : image_(std::move(image)), logical_rect_(logical_rect) {}

void RasterCacheResult::draw(SkCanvas& canvas, const SkPaint* paint) const {
  SkAutoCanvasRestore auto_restore(&canvas, true);
  SkIRect bounds =
      RasterCache::GetDeviceBounds(logical_rect_, canvas.getTotalMatrix());
  FML_DCHECK(bounds.size() == image_->dimensions());
  canvas.resetMatrix();
  canvas.drawImage(image_, bounds.fLeft, bounds.fTop, paint);
}

RasterCache::RasterCache(size_t access_threshold,
                         size_t picture_cache_limit_per_frame)
    : access_threshold_(access_threshold),
      picture_cache_limit_per_frame_(picture_cache_limit_per_frame),
      checkerboard_images_(false),
      weak_factory_(this) {}

RasterCache::~RasterCache() = default;

static bool CanRasterizePicture(SkPicture* picture) {
  if (picture == nullptr) {
    return false;
  }

  const SkRect cull_rect = picture->cullRect();

  if (cull_rect.isEmpty()) {
    // No point in ever rasterizing an empty picture.
    return false;
  }

  if (!cull_rect.isFinite()) {
    // Cannot attempt to rasterize into an infinitely large surface.
    return false;
  }

  return true;
}

static bool IsPictureWorthRasterizing(SkPicture* picture,
                                      bool will_change,
                                      bool is_complex) {
  if (will_change) {
    // If the picture is going to change in the future, there is no point in
    // doing to extra work to rasterize.
    return false;
  }

  if (!CanRasterizePicture(picture)) {
    // No point in deciding whether the picture is worth rasterizing if it
    // cannot be rasterized at all.
    return false;
  }

  if (is_complex) {
    // The caller seems to have extra information about the picture and thinks
    // the picture is always worth rasterizing.
    return true;
  }

  // TODO(abarth): We should find a better heuristic here that lets us avoid
  // wasting memory on trivial layers that are easy to re-rasterize every frame.
  return picture->approximateOpCount() > 5;
}

static RasterCacheResult Rasterize(
    GrContext* context,
    const SkMatrix& ctm,
    SkColorSpace* dst_color_space,
    bool checkerboard,
    const SkRect& logical_rect,
    std::function<void(SkCanvas*)> draw_function) {
  TRACE_EVENT0("flutter", "RasterCachePopulate");
  SkIRect cache_rect = RasterCache::GetDeviceBounds(logical_rect, ctm);

  const SkImageInfo image_info = SkImageInfo::MakeN32Premul(
      cache_rect.width(), cache_rect.height(), sk_ref_sp(dst_color_space));

  sk_sp<SkSurface> surface =
      context
          ? SkSurface::MakeRenderTarget(context, SkBudgeted::kYes, image_info)
          : SkSurface::MakeRaster(image_info);

  if (!surface) {
    return {};
  }

  SkCanvas* canvas = surface->getCanvas();
  canvas->clear(SK_ColorTRANSPARENT);
  canvas->translate(-cache_rect.left(), -cache_rect.top());
  canvas->concat(ctm);
  draw_function(canvas);

  if (checkerboard) {
    DrawCheckerboard(canvas, logical_rect);
  }

  return {surface->makeImageSnapshot(), logical_rect};
}

RasterCacheResult RasterizePicture(SkPicture* picture,
                                   GrContext* context,
                                   const SkMatrix& ctm,
                                   SkColorSpace* dst_color_space,
                                   bool checkerboard) {
  return Rasterize(context, ctm, dst_color_space, checkerboard,
                   picture->cullRect(),
                   [=](SkCanvas* canvas) { canvas->drawPicture(picture); });
}

static inline size_t ClampSize(size_t value, size_t min, size_t max) {
  if (value > max) {
    return max;
  }

  if (value < min) {
    return min;
  }

  return value;
}

void RasterCache::Prepare(PrerollContext* context,
                          Layer* layer,
                          const SkMatrix& ctm) {
  LayerRasterCacheKey cache_key(layer, ctm);
  Entry& entry = layer_cache_[cache_key];
  entry.access_count = ClampSize(entry.access_count + 1, 0, access_threshold_);
  entry.used_this_frame = true;
  if (!entry.image.is_valid()) {
    entry.image = Rasterize(context->gr_context, ctm, context->dst_color_space,
                            checkerboard_images_, layer->paint_bounds(),
                            [layer, context](SkCanvas* canvas) {
                              SkISize canvas_size = canvas->getBaseLayerSize();
                              SkNWayCanvas internal_nodes_canvas(
                                  canvas_size.width(), canvas_size.height());
                              internal_nodes_canvas.addCanvas(canvas);
                              Layer::PaintContext paintContext = {
                                  (SkCanvas*)&internal_nodes_canvas,
                                  canvas,
                                  nullptr,
                                  context->frame_time,
                                  context->engine_time,
                                  context->texture_registry,
                                  context->raster_cache,
                                  context->checkerboard_offscreen_layers};
                              if (layer->needs_painting()) {
                                layer->Paint(paintContext);
                              }
                            });
  }
}

bool RasterCache::Prepare(GrContext* context,
                          SkPicture* picture,
                          const SkMatrix& transformation_matrix,
                          SkColorSpace* dst_color_space,
                          bool is_complex,
                          bool will_change) {
  if (picture_cached_this_frame_ >= picture_cache_limit_per_frame_) {
    return false;
  }
  if (!IsPictureWorthRasterizing(picture, will_change, is_complex)) {
    // We only deal with pictures that are worthy of rasterization.
    return false;
  }

  // Decompose the matrix (once) for all subsequent operations. We want to make
  // sure to avoid volumetric distortions while accounting for scaling.
  const MatrixDecomposition matrix(transformation_matrix);

  if (!matrix.IsValid()) {
    // The matrix was singular. No point in going further.
    return false;
  }

  PictureRasterCacheKey cache_key(picture->uniqueID(), transformation_matrix);

  Entry& entry = picture_cache_[cache_key];
  entry.access_count = ClampSize(entry.access_count + 1, 0, access_threshold_);
  entry.used_this_frame = true;

  if (entry.access_count < access_threshold_ || access_threshold_ == 0) {
    // Frame threshold has not yet been reached.
    return false;
  }

  if (!entry.image.is_valid()) {
    entry.image = RasterizePicture(picture, context, transformation_matrix,
                                   dst_color_space, checkerboard_images_);
  }
  picture_cached_this_frame_++;
  return true;
}

RasterCacheResult RasterCache::Get(const SkPicture& picture,
                                   const SkMatrix& ctm) const {
  PictureRasterCacheKey cache_key(picture.uniqueID(), ctm);
  auto it = picture_cache_.find(cache_key);
  return it == picture_cache_.end() ? RasterCacheResult() : it->second.image;
}

RasterCacheResult RasterCache::Get(Layer* layer, const SkMatrix& ctm) const {
  LayerRasterCacheKey cache_key(layer, ctm);
  auto it = layer_cache_.find(cache_key);
  return it == layer_cache_.end() ? RasterCacheResult() : it->second.image;
}

void RasterCache::SweepAfterFrame() {
  using PictureCache = PictureRasterCacheKey::Map<Entry>;
  using LayerCache = LayerRasterCacheKey::Map<Entry>;
  SweepOneCacheAfterFrame<PictureCache, PictureCache::iterator>(picture_cache_);
  SweepOneCacheAfterFrame<LayerCache, LayerCache::iterator>(layer_cache_);
  picture_cached_this_frame_ = 0;
  TraceStatsToTimeline();
}

void RasterCache::Clear() {
  picture_cache_.clear();
  layer_cache_.clear();
}

void RasterCache::SetCheckboardCacheImages(bool checkerboard) {
  if (checkerboard_images_ == checkerboard) {
    return;
  }

  checkerboard_images_ = checkerboard;

  // Clear all existing entries so previously rasterized items (with or without
  // a checkerboard) will be refreshed in subsequent passes.
  Clear();
}

void RasterCache::TraceStatsToTimeline() const {
#if FLUTTER_RUNTIME_MODE != FLUTTER_RUNTIME_MODE_RELEASE

  size_t layer_cache_count = 0;
  size_t layer_cache_bytes = 0;
  size_t picture_cache_count = 0;
  size_t picture_cache_bytes = 0;

  for (const auto& item : layer_cache_) {
    const auto dimensions = item.second.image.image_dimensions();
    layer_cache_count++;
    layer_cache_bytes += dimensions.width() * dimensions.height() * 4;
  }

  for (const auto& item : picture_cache_) {
    const auto dimensions = item.second.image.image_dimensions();
    picture_cache_count++;
    picture_cache_bytes += dimensions.width() * dimensions.height() * 4;
  }

  FML_TRACE_COUNTER("flutter", "RasterCache",
                    reinterpret_cast<int64_t>(this),             //
                    "LayerCount", layer_cache_count,             //
                    "LayerMBytes", layer_cache_bytes * 1e-6,     //
                    "PictureCount", picture_cache_count,         //
                    "PictureMBytes", picture_cache_bytes * 1e-6  //
  );

#endif  // FLUTTER_RUNTIME_MODE != FLUTTER_RUNTIME_MODE_RELEASE
}

}  // namespace flow
