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

#include "cc/raster/playback_image_provider.h"

#include "cc/paint/paint_image_builder.h"
#include "cc/test/skia_common.h"
#include "cc/test/stub_decode_cache.h"
#include "testing/gtest/include/gtest/gtest.h"
#include "third_party/skia/include/gpu/GrContext.h"
#include "third_party/skia/include/gpu/gl/GrGLInterface.h"

namespace cc {
namespace {

sk_sp<SkImage> CreateRasterImage() {
  SkBitmap bitmap;
  bitmap.allocN32Pixels(10, 10);
  return SkImage::MakeFromBitmap(bitmap);
}

DecodedDrawImage CreateDecode() {
  return DecodedDrawImage(CreateRasterImage(), SkSize::MakeEmpty(),
                          SkSize::Make(1.0f, 1.0f), kMedium_SkFilterQuality,
                          true);
}

class MockDecodeCache : public StubDecodeCache {
 public:
  MockDecodeCache() = default;
  ~MockDecodeCache() override { EXPECT_EQ(refed_image_count_, 0); }

  DecodedDrawImage GetDecodedImageForDraw(
      const DrawImage& draw_image) override {
    last_image_ = draw_image;
    images_decoded_++;
    refed_image_count_++;
    return CreateDecode();
  }

  void DrawWithImageFinished(
      const DrawImage& draw_image,
      const DecodedDrawImage& decoded_draw_image) override {
    refed_image_count_--;
    EXPECT_GE(refed_image_count_, 0);
  }

  bool UseCacheForDrawImage(const DrawImage& image) const override {
    return use_cache_for_draw_image_;
  }

  void set_use_cache_for_draw_image(bool use) {
    use_cache_for_draw_image_ = use;
  }
  int refed_image_count() const { return refed_image_count_; }
  int images_decoded() const { return images_decoded_; }
  const DrawImage& last_image() { return last_image_; }

 private:
  int refed_image_count_ = 0;
  int images_decoded_ = 0;
  bool use_cache_for_draw_image_ = true;
  DrawImage last_image_;
};

TEST(PlaybackImageProviderTest, SkipsAllImages) {
  MockDecodeCache cache;
  PlaybackImageProvider provider(&cache, base::nullopt);

  SkIRect rect = SkIRect::MakeWH(10, 10);
  SkMatrix matrix = SkMatrix::I();

  EXPECT_FALSE(provider.GetDecodedDrawImage(DrawImage(
      PaintImageBuilder::WithDefault()
          .set_id(PaintImage::GetNextId())
          .set_image(CreateRasterImage(), PaintImage::GetNextContentId())
          .TakePaintImage(),
      rect, kMedium_SkFilterQuality, matrix)));
  EXPECT_EQ(cache.images_decoded(), 0);

  EXPECT_FALSE(provider.GetDecodedDrawImage(
      CreateDiscardableDrawImage(gfx::Size(10, 10), nullptr, SkRect::Make(rect),
                                 kMedium_SkFilterQuality, matrix)));
  EXPECT_EQ(cache.images_decoded(), 0);
}

TEST(PlaybackImageProviderTest, SkipsSomeImages) {
  MockDecodeCache cache;
  PaintImage skip_image = CreateDiscardablePaintImage(gfx::Size(10, 10));

  base::Optional<PlaybackImageProvider::Settings> settings;
  settings.emplace();
  settings->images_to_skip = {skip_image.stable_id()};

  PlaybackImageProvider provider(&cache, std::move(settings));

  SkIRect rect = SkIRect::MakeWH(10, 10);
  SkMatrix matrix = SkMatrix::I();
  EXPECT_FALSE(provider.GetDecodedDrawImage(
      DrawImage(skip_image, rect, kMedium_SkFilterQuality, matrix)));
  EXPECT_EQ(cache.images_decoded(), 0);
}

TEST(PlaybackImageProviderTest, RefAndUnrefDecode) {
  MockDecodeCache cache;

  base::Optional<PlaybackImageProvider::Settings> settings;
  settings.emplace();
  PlaybackImageProvider provider(&cache, std::move(settings));

  {
    SkRect rect = SkRect::MakeWH(10, 10);
    SkMatrix matrix = SkMatrix::I();
    auto decode = provider.GetDecodedDrawImage(CreateDiscardableDrawImage(
        gfx::Size(10, 10), nullptr, rect, kMedium_SkFilterQuality, matrix));
    EXPECT_TRUE(decode);
    EXPECT_EQ(cache.refed_image_count(), 1);
  }

  // Destroying the decode unrefs the image from the cache.
  EXPECT_EQ(cache.refed_image_count(), 0);
}

TEST(PlaybackImageProviderTest, SwapsGivenFrames) {
  MockDecodeCache cache;
  std::vector<FrameMetadata> frames = {
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(2)),
      FrameMetadata(true, base::TimeDelta::FromMilliseconds(3))};
  PaintImage image = CreateAnimatedImage(gfx::Size(10, 10), frames);

  base::flat_map<PaintImage::Id, size_t> image_to_frame;
  image_to_frame[image.stable_id()] = 1u;
  base::Optional<PlaybackImageProvider::Settings> settings;
  settings.emplace();
  settings->image_to_current_frame_index = image_to_frame;

  PlaybackImageProvider provider(&cache, std::move(settings));

  SkIRect rect = SkIRect::MakeWH(10, 10);
  SkMatrix matrix = SkMatrix::I();
  DrawImage draw_image(image, rect, kMedium_SkFilterQuality, matrix);
  provider.GetDecodedDrawImage(draw_image);
  ASSERT_TRUE(cache.last_image().paint_image());
  ASSERT_EQ(cache.last_image().paint_image(), image);
  ASSERT_EQ(cache.last_image().frame_index(), 1u);
}

TEST(PlaybackImageProviderTest, BitmapImages) {
  MockDecodeCache cache;

  base::Optional<PlaybackImageProvider::Settings> settings;
  settings.emplace();
  PlaybackImageProvider provider(&cache, std::move(settings));

  {
    SkIRect rect = SkIRect::MakeWH(10, 10);
    SkMatrix matrix = SkMatrix::I();
    auto draw_image = DrawImage(CreateBitmapImage(gfx::Size(10, 10)), rect,
                                kMedium_SkFilterQuality, matrix);
    auto decode = provider.GetDecodedDrawImage(draw_image);
    EXPECT_TRUE(decode);
    EXPECT_EQ(cache.refed_image_count(), 1);
  }

  // Destroying the decode unrefs the image from the cache.
  EXPECT_EQ(cache.refed_image_count(), 0);
}

TEST(PlaybackImageProviderTest, IgnoresImagesNotSupportedByCache) {
  MockDecodeCache cache;
  cache.set_use_cache_for_draw_image(false);
  base::Optional<PlaybackImageProvider::Settings> settings;
  settings.emplace();
  PlaybackImageProvider provider(&cache, std::move(settings));
  {
    SkIRect rect = SkIRect::MakeWH(10, 10);
    SkMatrix matrix = SkMatrix::I();
    auto draw_image = DrawImage(CreateBitmapImage(gfx::Size(10, 10)), rect,
                                kMedium_SkFilterQuality, matrix);
    auto decode = provider.GetDecodedDrawImage(draw_image);
    EXPECT_TRUE(decode);
    EXPECT_EQ(cache.refed_image_count(), 0);
  }

  EXPECT_EQ(cache.refed_image_count(), 0);
}

}  // namespace
}  // namespace cc
