// 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/display_list/display_list_attributes_testing.h"
#include "flutter/display_list/display_list_blend_mode.h"
#include "flutter/display_list/display_list_builder.h"
#include "flutter/display_list/display_list_color.h"
#include "flutter/display_list/display_list_color_filter.h"
#include "flutter/display_list/display_list_comparable.h"
#include "flutter/display_list/display_list_image_filter.h"
#include "flutter/display_list/display_list_sampling_options.h"
#include "flutter/display_list/display_list_tile_mode.h"
#include "flutter/display_list/types.h"
#include "gtest/gtest.h"

namespace flutter {
namespace testing {

TEST(DisplayListImageFilter, BuilderSetGet) {
  DlBlurImageFilter filter(5.0, 5.0, DlTileMode::kDecal);
  DisplayListBuilder builder;

  ASSERT_EQ(builder.getImageFilter(), nullptr);

  builder.setImageFilter(&filter);
  ASSERT_NE(builder.getImageFilter(), nullptr);
  ASSERT_TRUE(
      Equals(builder.getImageFilter(), static_cast<DlImageFilter*>(&filter)));

  builder.setImageFilter(nullptr);
  ASSERT_EQ(builder.getImageFilter(), nullptr);
}

TEST(DisplayListImageFilter, FromSkiaNullFilter) {
  std::shared_ptr<DlImageFilter> filter = DlImageFilter::From(nullptr);

  ASSERT_EQ(filter, nullptr);
  ASSERT_EQ(filter.get(), nullptr);
}

TEST(DisplayListImageFilter, FromSkiaBlurImageFilter) {
  sk_sp<SkImageFilter> sk_image_filter =
      SkImageFilters::Blur(5.0, 5.0, SkTileMode::kRepeat, nullptr);
  std::shared_ptr<DlImageFilter> filter = DlImageFilter::From(sk_image_filter);

  ASSERT_EQ(filter->type(), DlImageFilterType::kUnknown);

  // We cannot recapture the blur parameters from an SkBlurImageFilter
  ASSERT_EQ(filter->asBlur(), nullptr);
  ASSERT_EQ(filter->asDilate(), nullptr);
  ASSERT_EQ(filter->asErode(), nullptr);
  ASSERT_EQ(filter->asMatrix(), nullptr);
  ASSERT_EQ(filter->asCompose(), nullptr);
  ASSERT_EQ(filter->asColorFilter(), nullptr);
}

TEST(DisplayListImageFilter, FromSkiaDilateImageFilter) {
  sk_sp<SkImageFilter> sk_image_filter =
      SkImageFilters::Dilate(5.0, 5.0, nullptr);
  std::shared_ptr<DlImageFilter> filter = DlImageFilter::From(sk_image_filter);

  ASSERT_EQ(filter->type(), DlImageFilterType::kUnknown);

  // We cannot recapture the dilate parameters from an SkDilateImageFilter
  ASSERT_EQ(filter->asBlur(), nullptr);
  ASSERT_EQ(filter->asDilate(), nullptr);
  ASSERT_EQ(filter->asErode(), nullptr);
  ASSERT_EQ(filter->asMatrix(), nullptr);
  ASSERT_EQ(filter->asCompose(), nullptr);
  ASSERT_EQ(filter->asColorFilter(), nullptr);
}

TEST(DisplayListImageFilter, FromSkiaErodeImageFilter) {
  sk_sp<SkImageFilter> sk_image_filter =
      SkImageFilters::Erode(5.0, 5.0, nullptr);
  std::shared_ptr<DlImageFilter> filter = DlImageFilter::From(sk_image_filter);

  ASSERT_EQ(filter->type(), DlImageFilterType::kUnknown);

  // We cannot recapture the erode parameters from an SkErodeImageFilter
  ASSERT_EQ(filter->asBlur(), nullptr);
  ASSERT_EQ(filter->asDilate(), nullptr);
  ASSERT_EQ(filter->asErode(), nullptr);
  ASSERT_EQ(filter->asMatrix(), nullptr);
  ASSERT_EQ(filter->asCompose(), nullptr);
  ASSERT_EQ(filter->asColorFilter(), nullptr);
}

TEST(DisplayListImageFilter, FromSkiaMatrixImageFilter) {
  sk_sp<SkImageFilter> sk_image_filter = SkImageFilters::MatrixTransform(
      SkMatrix::RotateDeg(45), ToSk(DlImageSampling::kLinear), nullptr);
  std::shared_ptr<DlImageFilter> filter = DlImageFilter::From(sk_image_filter);

  ASSERT_EQ(filter->type(), DlImageFilterType::kUnknown);

  // We cannot recapture the blur parameters from an SkMatrixImageFilter
  ASSERT_EQ(filter->asBlur(), nullptr);
  ASSERT_EQ(filter->asDilate(), nullptr);
  ASSERT_EQ(filter->asErode(), nullptr);
  ASSERT_EQ(filter->asMatrix(), nullptr);
  ASSERT_EQ(filter->asCompose(), nullptr);
  ASSERT_EQ(filter->asColorFilter(), nullptr);
}

TEST(DisplayListImageFilter, FromSkiaComposeImageFilter) {
  sk_sp<SkImageFilter> sk_blur_filter =
      SkImageFilters::Blur(5.0, 5.0, SkTileMode::kRepeat, nullptr);
  sk_sp<SkImageFilter> sk_matrix_filter = SkImageFilters::MatrixTransform(
      SkMatrix::RotateDeg(45), ToSk(DlImageSampling::kLinear), nullptr);
  sk_sp<SkImageFilter> sk_image_filter =
      SkImageFilters::Compose(sk_blur_filter, sk_matrix_filter);
  std::shared_ptr<DlImageFilter> filter = DlImageFilter::From(sk_image_filter);

  ASSERT_EQ(filter->type(), DlImageFilterType::kUnknown);

  // We cannot recapture the blur parameters from an SkComposeImageFilter
  ASSERT_EQ(filter->asBlur(), nullptr);
  ASSERT_EQ(filter->asDilate(), nullptr);
  ASSERT_EQ(filter->asErode(), nullptr);
  ASSERT_EQ(filter->asMatrix(), nullptr);
  ASSERT_EQ(filter->asCompose(), nullptr);
  ASSERT_EQ(filter->asColorFilter(), nullptr);
}

TEST(DisplayListImageFilter, FromSkiaColorFilterImageFilter) {
  sk_sp<SkColorFilter> sk_color_filter =
      SkColorFilters::Blend(SK_ColorRED, SkBlendMode::kSrcIn);
  sk_sp<SkImageFilter> sk_image_filter =
      SkImageFilters::ColorFilter(sk_color_filter, nullptr);
  std::shared_ptr<DlImageFilter> filter = DlImageFilter::From(sk_image_filter);
  DlBlendColorFilter dl_color_filter(DlColor::kRed(), DlBlendMode::kSrcIn);
  DlColorFilterImageFilter dl_image_filter(dl_color_filter.shared());

  ASSERT_EQ(filter->type(), DlImageFilterType::kColorFilter);

  ASSERT_TRUE(*filter->asColorFilter() == dl_image_filter);
  ASSERT_EQ(*filter.get(), dl_image_filter);
  ASSERT_EQ(*filter->asColorFilter()->color_filter(), dl_color_filter);

  ASSERT_EQ(filter->asBlur(), nullptr);
  ASSERT_EQ(filter->asDilate(), nullptr);
  ASSERT_EQ(filter->asErode(), nullptr);
  ASSERT_EQ(filter->asMatrix(), nullptr);
  ASSERT_EQ(filter->asCompose(), nullptr);
  ASSERT_NE(filter->asColorFilter(), nullptr);
}

// SkRect::contains treats the rect as a half-open interval which is
// appropriate for so many operations. Unfortunately, we are using
// it here to test containment of the corners of a transformed quad
// so the corners of the quad that are measured against the right
// and bottom edges are contained even if they are on the right or
// bottom edge. This method does the "all sides inclusive" version
// of SkRect::contains.
static bool containsInclusive(const SkRect rect, const SkPoint p) {
  // Test with a slight offset of 1E-9 to "forgive" IEEE bit-rounding
  // Ending up with bounds that are off by 1E-9 (these numbers are all
  // being tested in device space with this method) will be off by a
  // negligible amount of a pixel that wouldn't contribute to changing
  // the color of a pixel.
  return (p.fX >= rect.fLeft - 1E-9 &&   //
          p.fX <= rect.fRight + 1E-9 &&  //
          p.fY >= rect.fTop - 1E-9 &&    //
          p.fY <= rect.fBottom + 1E-9);
}

static bool containsInclusive(const SkRect rect, const SkPoint quad[4]) {
  return (containsInclusive(rect, quad[0]) &&  //
          containsInclusive(rect, quad[1]) &&  //
          containsInclusive(rect, quad[2]) &&  //
          containsInclusive(rect, quad[3]));
}

static bool containsInclusive(const SkIRect rect, const SkPoint quad[4]) {
  return containsInclusive(SkRect::Make(rect), quad);
}

static bool containsInclusive(const SkIRect rect, const SkRect bounds) {
  return (bounds.fLeft >= rect.fLeft - 1E-9 &&
          bounds.fTop >= rect.fTop - 1E-9 &&
          bounds.fRight <= rect.fRight + 1E-9 &&
          bounds.fBottom <= rect.fBottom + 1E-9);
}

// Used to verify that the expected output bounds and revers engineered
// "input bounds for output bounds" rectangles are included in the rectangle
// returned from the various bounds computation methods under the specified
// matrix.
static void TestBoundsWithMatrix(const DlImageFilter& filter,
                                 const SkMatrix& matrix,
                                 const SkRect& sourceBounds,
                                 const SkPoint expectedLocalOutputQuad[4]) {
  SkRect deviceInputBounds = matrix.mapRect(sourceBounds);
  SkPoint expectedDeviceOutputQuad[4];
  matrix.mapPoints(expectedDeviceOutputQuad, expectedLocalOutputQuad, 4);

  SkIRect deviceFilterIBounds;
  ASSERT_EQ(filter.map_device_bounds(deviceInputBounds.roundOut(), matrix,
                                     deviceFilterIBounds),
            &deviceFilterIBounds);
  ASSERT_TRUE(containsInclusive(deviceFilterIBounds, expectedDeviceOutputQuad));

  SkIRect reverseInputIBounds;
  ASSERT_EQ(filter.get_input_device_bounds(deviceFilterIBounds, matrix,
                                           reverseInputIBounds),
            &reverseInputIBounds);
  ASSERT_TRUE(containsInclusive(reverseInputIBounds, deviceInputBounds));
}

static void TestInvalidBounds(const DlImageFilter& filter,
                              const SkMatrix& matrix,
                              const SkRect& localInputBounds) {
  SkIRect deviceInputBounds = matrix.mapRect(localInputBounds).roundOut();

  SkRect localFilterBounds;
  ASSERT_EQ(filter.map_local_bounds(localInputBounds, localFilterBounds),
            nullptr);
  ASSERT_EQ(localFilterBounds, localInputBounds);

  SkIRect deviceFilterIBounds;
  ASSERT_EQ(
      filter.map_device_bounds(deviceInputBounds, matrix, deviceFilterIBounds),
      nullptr);
  ASSERT_EQ(deviceFilterIBounds, deviceInputBounds);

  SkIRect reverseInputIBounds;
  ASSERT_EQ(filter.get_input_device_bounds(deviceInputBounds, matrix,
                                           reverseInputIBounds),
            nullptr);
  ASSERT_EQ(reverseInputIBounds, deviceInputBounds);
}

// localInputBounds is a sample bounds for testing as input to the filter.
// localExpectOutputBounds is the theoretical output bounds for applying
// the filter to the localInputBounds.
// localExpectInputBounds is the theoretical input bounds required for the
// filter to cover the localExpectOutputBounds
// If either of the expected bounds are nullptr then the bounds methods will
// be assumed to be unable to perform their computations for the given
// image filter and will be returning null.
static void TestBounds(const DlImageFilter& filter,
                       const SkRect& sourceBounds,
                       const SkPoint expectedLocalOutputQuad[4]) {
  SkRect localFilterBounds;
  ASSERT_EQ(filter.map_local_bounds(sourceBounds, localFilterBounds),
            &localFilterBounds);
  ASSERT_TRUE(containsInclusive(localFilterBounds, expectedLocalOutputQuad));

  for (int scale = 1; scale <= 4; scale++) {
    for (int skew = 0; skew < 8; skew++) {
      for (int degrees = 0; degrees <= 360; degrees += 15) {
        SkMatrix matrix;
        matrix.setScale(scale, scale);
        matrix.postSkew(skew / 8.0, skew / 8.0);
        matrix.postRotate(degrees);
        ASSERT_TRUE(matrix.invert(nullptr));
        TestBoundsWithMatrix(filter, matrix, sourceBounds,
                             expectedLocalOutputQuad);
        matrix.setPerspX(0.001);
        matrix.setPerspY(0.001);
        ASSERT_TRUE(matrix.invert(nullptr));
        TestBoundsWithMatrix(filter, matrix, sourceBounds,
                             expectedLocalOutputQuad);
      }
    }
  }
}

static void TestBounds(const DlImageFilter& filter,
                       const SkRect& sourceBounds,
                       const SkRect& expectedLocalOutputBounds) {
  SkPoint expectedLocalOutputQuad[4];
  expectedLocalOutputBounds.toQuad(expectedLocalOutputQuad);
  TestBounds(filter, sourceBounds, expectedLocalOutputQuad);
}

TEST(DisplayListImageFilter, BlurConstructor) {
  DlBlurImageFilter filter(5.0, 6.0, DlTileMode::kMirror);
}

TEST(DisplayListImageFilter, BlurShared) {
  DlBlurImageFilter filter(5.0, 6.0, DlTileMode::kMirror);

  ASSERT_NE(filter.shared().get(), &filter);
  ASSERT_EQ(*filter.shared(), filter);
}

TEST(DisplayListImageFilter, BlurAsBlur) {
  DlBlurImageFilter filter(5.0, 6.0, DlTileMode::kMirror);

  ASSERT_NE(filter.asBlur(), nullptr);
  ASSERT_EQ(filter.asBlur(), &filter);
}

TEST(DisplayListImageFilter, BlurContents) {
  DlBlurImageFilter filter(5.0, 6.0, DlTileMode::kMirror);

  ASSERT_EQ(filter.sigma_x(), 5.0);
  ASSERT_EQ(filter.sigma_y(), 6.0);
  ASSERT_EQ(filter.tile_mode(), DlTileMode::kMirror);
}

TEST(DisplayListImageFilter, BlurEquals) {
  DlBlurImageFilter filter1(5.0, 6.0, DlTileMode::kMirror);
  DlBlurImageFilter filter2(5.0, 6.0, DlTileMode::kMirror);

  TestEquals(filter1, filter2);
}

TEST(DisplayListImageFilter, BlurNotEquals) {
  DlBlurImageFilter filter1(5.0, 6.0, DlTileMode::kMirror);
  DlBlurImageFilter filter2(7.0, 6.0, DlTileMode::kMirror);
  DlBlurImageFilter filter3(5.0, 8.0, DlTileMode::kMirror);
  DlBlurImageFilter filter4(5.0, 6.0, DlTileMode::kRepeat);

  TestNotEquals(filter1, filter2, "Sigma X differs");
  TestNotEquals(filter1, filter3, "Sigma Y differs");
  TestNotEquals(filter1, filter4, "Tile Mode differs");
}

TEST(DisplayListImageFilter, BlurBounds) {
  DlBlurImageFilter filter = DlBlurImageFilter(5, 10, DlTileMode::kDecal);
  SkRect inputBounds = SkRect::MakeLTRB(20, 20, 80, 80);
  SkRect expectOutputBounds = inputBounds.makeOutset(15, 30);
  // SkRect expectInputBounds = expectOutputBounds.makeOutset(15, 30);
  TestBounds(filter, inputBounds, expectOutputBounds);
}

TEST(DisplayListImageFilter, DilateConstructor) {
  DlDilateImageFilter filter(5.0, 6.0);
}

TEST(DisplayListImageFilter, DilateShared) {
  DlDilateImageFilter filter(5.0, 6.0);

  ASSERT_NE(filter.shared().get(), &filter);
  ASSERT_EQ(*filter.shared(), filter);
}

TEST(DisplayListImageFilter, DilateAsDilate) {
  DlDilateImageFilter filter(5.0, 6.0);

  ASSERT_NE(filter.asDilate(), nullptr);
  ASSERT_EQ(filter.asDilate(), &filter);
}

TEST(DisplayListImageFilter, DilateContents) {
  DlDilateImageFilter filter(5.0, 6.0);

  ASSERT_EQ(filter.radius_x(), 5.0);
  ASSERT_EQ(filter.radius_y(), 6.0);
}

TEST(DisplayListImageFilter, DilateEquals) {
  DlDilateImageFilter filter1(5.0, 6.0);
  DlDilateImageFilter filter2(5.0, 6.0);

  TestEquals(filter1, filter2);
}

TEST(DisplayListImageFilter, DilateNotEquals) {
  DlDilateImageFilter filter1(5.0, 6.0);
  DlDilateImageFilter filter2(7.0, 6.0);
  DlDilateImageFilter filter3(5.0, 8.0);

  TestNotEquals(filter1, filter2, "Radius X differs");
  TestNotEquals(filter1, filter3, "Radius Y differs");
}

TEST(DisplayListImageFilter, DilateBounds) {
  DlDilateImageFilter filter = DlDilateImageFilter(5, 10);
  SkRect inputBounds = SkRect::MakeLTRB(20, 20, 80, 80);
  SkRect expectOutputBounds = inputBounds.makeOutset(5, 10);
  TestBounds(filter, inputBounds, expectOutputBounds);
}

TEST(DisplayListImageFilter, ErodeConstructor) {
  DlErodeImageFilter filter(5.0, 6.0);
}

TEST(DisplayListImageFilter, ErodeShared) {
  DlErodeImageFilter filter(5.0, 6.0);

  ASSERT_NE(filter.shared().get(), &filter);
  ASSERT_EQ(*filter.shared(), filter);
}

TEST(DisplayListImageFilter, ErodeAsErode) {
  DlErodeImageFilter filter(5.0, 6.0);

  ASSERT_NE(filter.asErode(), nullptr);
  ASSERT_EQ(filter.asErode(), &filter);
}

TEST(DisplayListImageFilter, ErodeContents) {
  DlErodeImageFilter filter(5.0, 6.0);

  ASSERT_EQ(filter.radius_x(), 5.0);
  ASSERT_EQ(filter.radius_y(), 6.0);
}

TEST(DisplayListImageFilter, ErodeEquals) {
  DlErodeImageFilter filter1(5.0, 6.0);
  DlErodeImageFilter filter2(5.0, 6.0);

  TestEquals(filter1, filter2);
}

TEST(DisplayListImageFilter, ErodeNotEquals) {
  DlErodeImageFilter filter1(5.0, 6.0);
  DlErodeImageFilter filter2(7.0, 6.0);
  DlErodeImageFilter filter3(5.0, 8.0);

  TestNotEquals(filter1, filter2, "Radius X differs");
  TestNotEquals(filter1, filter3, "Radius Y differs");
}

TEST(DisplayListImageFilter, ErodeBounds) {
  DlErodeImageFilter filter = DlErodeImageFilter(5, 10);
  SkRect inputBounds = SkRect::MakeLTRB(20, 20, 80, 80);
  SkRect expectOutputBounds = inputBounds.makeInset(5, 10);
  TestBounds(filter, inputBounds, expectOutputBounds);
}

TEST(DisplayListImageFilter, MatrixConstructor) {
  DlMatrixImageFilter filter(SkMatrix::MakeAll(2.0, 0.0, 10,  //
                                               0.5, 3.0, 15,  //
                                               0.0, 0.0, 1),
                             DlImageSampling::kLinear);
}

TEST(DisplayListImageFilter, MatrixShared) {
  DlMatrixImageFilter filter(SkMatrix::MakeAll(2.0, 0.0, 10,  //
                                               0.5, 3.0, 15,  //
                                               0.0, 0.0, 1),
                             DlImageSampling::kLinear);

  ASSERT_NE(filter.shared().get(), &filter);
  ASSERT_EQ(*filter.shared(), filter);
}

TEST(DisplayListImageFilter, MatrixAsMatrix) {
  DlMatrixImageFilter filter(SkMatrix::MakeAll(2.0, 0.0, 10,  //
                                               0.5, 3.0, 15,  //
                                               0.0, 0.0, 1),
                             DlImageSampling::kLinear);

  ASSERT_NE(filter.asMatrix(), nullptr);
  ASSERT_EQ(filter.asMatrix(), &filter);
}

TEST(DisplayListImageFilter, MatrixContents) {
  SkMatrix matrix = SkMatrix::MakeAll(2.0, 0.0, 10,  //
                                      0.5, 3.0, 15,  //
                                      0.0, 0.0, 1);
  DlMatrixImageFilter filter(matrix, DlImageSampling::kLinear);

  ASSERT_EQ(filter.matrix(), matrix);
  ASSERT_EQ(filter.sampling(), DlImageSampling::kLinear);
}

TEST(DisplayListImageFilter, MatrixEquals) {
  SkMatrix matrix = SkMatrix::MakeAll(2.0, 0.0, 10,  //
                                      0.5, 3.0, 15,  //
                                      0.0, 0.0, 1);
  DlMatrixImageFilter filter1(matrix, DlImageSampling::kLinear);
  DlMatrixImageFilter filter2(matrix, DlImageSampling::kLinear);

  TestEquals(filter1, filter2);
}

TEST(DisplayListImageFilter, MatrixNotEquals) {
  SkMatrix matrix1 = SkMatrix::MakeAll(2.0, 0.0, 10,  //
                                       0.5, 3.0, 15,  //
                                       0.0, 0.0, 1);
  SkMatrix matrix2 = SkMatrix::MakeAll(5.0, 0.0, 10,  //
                                       0.5, 3.0, 15,  //
                                       0.0, 0.0, 1);
  DlMatrixImageFilter filter1(matrix1, DlImageSampling::kLinear);
  DlMatrixImageFilter filter2(matrix2, DlImageSampling::kLinear);
  DlMatrixImageFilter filter3(matrix1, DlImageSampling::kNearestNeighbor);

  TestNotEquals(filter1, filter2, "Matrix differs");
  TestNotEquals(filter1, filter3, "Sampling differs");
}

TEST(DisplayListImageFilter, MatrixBounds) {
  SkMatrix matrix = SkMatrix::MakeAll(2.0, 0.0, 10,  //
                                      0.5, 3.0, 7,   //
                                      0.0, 0.0, 1);
  SkMatrix inverse;
  ASSERT_TRUE(matrix.invert(&inverse));
  DlMatrixImageFilter filter(matrix, DlImageSampling::kLinear);
  SkRect inputBounds = SkRect::MakeLTRB(20, 20, 80, 80);
  SkPoint expectedOutputQuad[4] = {
      {50, 77},    // (20,20) => (20*2 + 10, 20/2 + 20*3 + 7) == (50, 77)
      {50, 257},   // (20,80) => (20*2 + 10, 20/2 + 80*3 + 7) == (50, 257)
      {170, 287},  // (80,80) => (80*2 + 10, 80/2 + 80*3 + 7) == (170, 287)
      {170, 107},  // (80,20) => (80*2 + 10, 80/2 + 20*3 + 7) == (170, 107)
  };
  TestBounds(filter, inputBounds, expectedOutputQuad);
}

TEST(DisplayListImageFilter, ComposeConstructor) {
  DlMatrixImageFilter outer(SkMatrix::MakeAll(2.0, 0.0, 10,  //
                                              0.5, 3.0, 15,  //
                                              0.0, 0.0, 1),
                            DlImageSampling::kLinear);
  DlBlurImageFilter inner(5.0, 6.0, DlTileMode::kMirror);
  DlComposeImageFilter filter(outer, inner);
}

TEST(DisplayListImageFilter, ComposeShared) {
  DlMatrixImageFilter outer(SkMatrix::MakeAll(2.0, 0.0, 10,  //
                                              0.5, 3.0, 15,  //
                                              0.0, 0.0, 1),
                            DlImageSampling::kLinear);
  DlBlurImageFilter inner(5.0, 6.0, DlTileMode::kMirror);
  DlComposeImageFilter filter(outer, inner);

  ASSERT_NE(filter.shared().get(), &filter);
  ASSERT_EQ(*filter.shared(), filter);
}

TEST(DisplayListImageFilter, ComposeAsCompose) {
  DlMatrixImageFilter outer(SkMatrix::MakeAll(2.0, 0.0, 10,  //
                                              0.5, 3.0, 15,  //
                                              0.0, 0.0, 1),
                            DlImageSampling::kLinear);
  DlBlurImageFilter inner(5.0, 6.0, DlTileMode::kMirror);
  DlComposeImageFilter filter(outer, inner);

  ASSERT_NE(filter.asCompose(), nullptr);
  ASSERT_EQ(filter.asCompose(), &filter);
}

TEST(DisplayListImageFilter, ComposeContents) {
  DlMatrixImageFilter outer(SkMatrix::MakeAll(2.0, 0.0, 10,  //
                                              0.5, 3.0, 15,  //
                                              0.0, 0.0, 1),
                            DlImageSampling::kLinear);
  DlBlurImageFilter inner(5.0, 6.0, DlTileMode::kMirror);
  DlComposeImageFilter filter(outer, inner);

  ASSERT_EQ(*filter.outer().get(), outer);
  ASSERT_EQ(*filter.inner().get(), inner);
}

TEST(DisplayListImageFilter, ComposeEquals) {
  DlMatrixImageFilter outer1(SkMatrix::MakeAll(2.0, 0.0, 10,  //
                                               0.5, 3.0, 15,  //
                                               0.0, 0.0, 1),
                             DlImageSampling::kLinear);
  DlBlurImageFilter inner1(5.0, 6.0, DlTileMode::kMirror);
  DlComposeImageFilter filter1(outer1, inner1);

  DlMatrixImageFilter outer2(SkMatrix::MakeAll(2.0, 0.0, 10,  //
                                               0.5, 3.0, 15,  //
                                               0.0, 0.0, 1),
                             DlImageSampling::kLinear);
  DlBlurImageFilter inner2(5.0, 6.0, DlTileMode::kMirror);
  DlComposeImageFilter filter2(outer1, inner1);

  TestEquals(filter1, filter2);
}

TEST(DisplayListImageFilter, ComposeNotEquals) {
  DlMatrixImageFilter outer1(SkMatrix::MakeAll(2.0, 0.0, 10,  //
                                               0.5, 3.0, 15,  //
                                               0.0, 0.0, 1),
                             DlImageSampling::kLinear);
  DlBlurImageFilter inner1(5.0, 6.0, DlTileMode::kMirror);

  DlMatrixImageFilter outer2(SkMatrix::MakeAll(5.0, 0.0, 10,  //
                                               0.5, 3.0, 15,  //
                                               0.0, 0.0, 1),
                             DlImageSampling::kLinear);
  DlBlurImageFilter inner2(7.0, 6.0, DlTileMode::kMirror);

  DlComposeImageFilter filter1(outer1, inner1);
  DlComposeImageFilter filter2(outer2, inner1);
  DlComposeImageFilter filter3(outer1, inner2);

  TestNotEquals(filter1, filter2, "Outer differs");
  TestNotEquals(filter1, filter3, "Inner differs");
}

TEST(DisplayListImageFilter, ComposeBounds) {
  DlDilateImageFilter outer = DlDilateImageFilter(5, 10);
  DlBlurImageFilter inner = DlBlurImageFilter(12, 5, DlTileMode::kDecal);
  DlComposeImageFilter filter = DlComposeImageFilter(outer, inner);
  SkRect inputBounds = SkRect::MakeLTRB(20, 20, 80, 80);
  SkRect expectOutputBounds = inputBounds.makeOutset(36, 15).makeOutset(5, 10);
  TestBounds(filter, inputBounds, expectOutputBounds);
}

static void TestUnboundedBounds(DlImageFilter& filter,
                                const SkRect& sourceBounds,
                                const SkRect& expectedOutputBounds,
                                const SkRect& expectedInputBounds) {
  SkRect bounds;
  EXPECT_EQ(filter.map_local_bounds(sourceBounds, bounds), nullptr);
  EXPECT_EQ(bounds, expectedOutputBounds);

  SkIRect ibounds;
  EXPECT_EQ(
      filter.map_device_bounds(sourceBounds.roundOut(), SkMatrix::I(), ibounds),
      nullptr);
  EXPECT_EQ(ibounds, expectedOutputBounds.roundOut());

  EXPECT_EQ(filter.get_input_device_bounds(sourceBounds.roundOut(),
                                           SkMatrix::I(), ibounds),
            nullptr);
  EXPECT_EQ(ibounds, expectedInputBounds.roundOut());
}

TEST(DisplayListImageFilter, ComposeBoundsWithUnboundedInner) {
  auto inputBounds = SkRect::MakeLTRB(20, 20, 80, 80);
  auto expectedBounds = SkRect::MakeLTRB(5, 2, 95, 98);

  DlBlendColorFilter color_filter(DlColor::kRed(), DlBlendMode::kSrcOver);
  auto outer = DlBlurImageFilter(5.0, 6.0, DlTileMode::kRepeat);
  auto inner = DlColorFilterImageFilter(color_filter.shared());
  auto composed = DlComposeImageFilter(outer.shared(), inner.shared());

  TestUnboundedBounds(composed, inputBounds, expectedBounds, expectedBounds);
}

TEST(DisplayListImageFilter, ComposeBoundsWithUnboundedOuter) {
  auto inputBounds = SkRect::MakeLTRB(20, 20, 80, 80);
  auto expectedBounds = SkRect::MakeLTRB(5, 2, 95, 98);

  DlBlendColorFilter color_filter(DlColor::kRed(), DlBlendMode::kSrcOver);
  auto outer = DlColorFilterImageFilter(color_filter.shared());
  auto inner = DlBlurImageFilter(5.0, 6.0, DlTileMode::kRepeat);
  auto composed = DlComposeImageFilter(outer.shared(), inner.shared());

  TestUnboundedBounds(composed, inputBounds, expectedBounds, expectedBounds);
}

TEST(DisplayListImageFilter, ComposeBoundsWithUnboundedInnerAndOuter) {
  auto inputBounds = SkRect::MakeLTRB(20, 20, 80, 80);
  auto expectedBounds = inputBounds;

  DlBlendColorFilter color_filter1(DlColor::kRed(), DlBlendMode::kSrcOver);
  DlBlendColorFilter color_filter2(DlColor::kBlue(), DlBlendMode::kSrcOver);
  auto outer = DlColorFilterImageFilter(color_filter1.shared());
  auto inner = DlColorFilterImageFilter(color_filter2.shared());
  auto composed = DlComposeImageFilter(outer.shared(), inner.shared());

  TestUnboundedBounds(composed, inputBounds, expectedBounds, expectedBounds);
}

// See https://github.com/flutter/flutter/issues/108433
TEST(DisplayListImageFilter, Issue_108433) {
  auto inputBounds = SkIRect::MakeLTRB(20, 20, 80, 80);

  auto sk_filter = SkColorFilters::Blend(SK_ColorRED, SkBlendMode::kSrcOver);
  auto sk_outer = SkImageFilters::Blur(5.0, 6.0, SkTileMode::kRepeat, nullptr);
  auto sk_inner = SkImageFilters::ColorFilter(sk_filter, nullptr);
  auto sk_compose = SkImageFilters::Compose(sk_outer, sk_inner);

  DlBlendColorFilter dl_color_filter(DlColor::kRed(), DlBlendMode::kSrcOver);
  auto dl_outer = DlBlurImageFilter(5.0, 6.0, DlTileMode::kRepeat);
  auto dl_inner = DlColorFilterImageFilter(dl_color_filter.shared());
  auto dl_compose = DlComposeImageFilter(dl_outer, dl_inner);

  auto sk_bounds = sk_compose->filterBounds(
      inputBounds, SkMatrix::I(),
      SkImageFilter::MapDirection::kForward_MapDirection);

  SkIRect dl_bounds;
  EXPECT_EQ(dl_compose.map_device_bounds(inputBounds, SkMatrix::I(), dl_bounds),
            nullptr);
  ASSERT_EQ(dl_bounds, sk_bounds);
}

TEST(DisplayListImageFilter, ColorFilterConstructor) {
  DlBlendColorFilter dl_color_filter(DlColor::kRed(), DlBlendMode::kLighten);
  DlColorFilterImageFilter filter(dl_color_filter);
}

TEST(DisplayListImageFilter, ColorFilterShared) {
  DlBlendColorFilter dl_color_filter(DlColor::kRed(), DlBlendMode::kLighten);
  DlColorFilterImageFilter filter(dl_color_filter);

  ASSERT_EQ(*filter.shared(), filter);
}

TEST(DisplayListImageFilter, ColorFilterAsColorFilter) {
  DlBlendColorFilter dl_color_filter(DlColor::kRed(), DlBlendMode::kLighten);
  DlColorFilterImageFilter filter(dl_color_filter);

  ASSERT_NE(filter.asColorFilter(), nullptr);
  ASSERT_EQ(filter.asColorFilter(), &filter);
}

TEST(DisplayListImageFilter, ColorFilterContents) {
  DlBlendColorFilter dl_color_filter(DlColor::kRed(), DlBlendMode::kLighten);
  DlColorFilterImageFilter filter(dl_color_filter);

  ASSERT_EQ(*filter.color_filter().get(), dl_color_filter);
}

TEST(DisplayListImageFilter, ColorFilterEquals) {
  DlBlendColorFilter dl_color_filter1(DlColor::kRed(), DlBlendMode::kLighten);
  DlColorFilterImageFilter filter1(dl_color_filter1);

  DlBlendColorFilter dl_color_filter2(DlColor::kRed(), DlBlendMode::kLighten);
  DlColorFilterImageFilter filter2(dl_color_filter2);

  TestEquals(filter1, filter2);
}

TEST(DisplayListImageFilter, ColorFilterNotEquals) {
  DlBlendColorFilter dl_color_filter1(DlColor::kRed(), DlBlendMode::kLighten);
  DlColorFilterImageFilter filter1(dl_color_filter1);

  DlBlendColorFilter dl_color_filter2(DlColor::kBlue(), DlBlendMode::kLighten);
  DlColorFilterImageFilter filter2(dl_color_filter2);

  DlBlendColorFilter dl_color_filter3(DlColor::kRed(), DlBlendMode::kDarken);
  DlColorFilterImageFilter filter3(dl_color_filter3);

  TestNotEquals(filter1, filter2, "Color differs");
  TestNotEquals(filter1, filter3, "Blend Mode differs");
}

TEST(DisplayListImageFilter, ColorFilterBounds) {
  DlBlendColorFilter dl_color_filter(DlColor::kRed(), DlBlendMode::kSrcIn);
  DlColorFilterImageFilter filter(dl_color_filter);
  SkRect inputBounds = SkRect::MakeLTRB(20, 20, 80, 80);
  TestBounds(filter, inputBounds, inputBounds);
}

TEST(DisplayListImageFilter, ColorFilterModifiesTransparencyBounds) {
  DlBlendColorFilter dl_color_filter(DlColor::kRed(), DlBlendMode::kSrcOver);
  DlColorFilterImageFilter filter(dl_color_filter);
  SkRect inputBounds = SkRect::MakeLTRB(20, 20, 80, 80);
  TestInvalidBounds(filter, SkMatrix::I(), inputBounds);
}

TEST(DisplayListImageFilter, UnknownConstructor) {
  DlUnknownImageFilter filter(
      SkImageFilters::Blur(5.0, 6.0, SkTileMode::kRepeat, nullptr));
}

TEST(DisplayListImageFilter, UnknownShared) {
  DlUnknownImageFilter filter(
      SkImageFilters::Blur(5.0, 6.0, SkTileMode::kRepeat, nullptr));

  ASSERT_NE(filter.shared().get(), &filter);
  ASSERT_EQ(*filter.shared(), filter);
}

TEST(DisplayListImageFilter, UnknownContents) {
  sk_sp<SkImageFilter> sk_filter =
      SkImageFilters::Blur(5.0, 6.0, SkTileMode::kRepeat, nullptr);
  DlUnknownImageFilter filter(sk_filter);

  ASSERT_EQ(filter.skia_object(), sk_filter);
  ASSERT_EQ(filter.skia_object().get(), sk_filter.get());
}

TEST(DisplayListImageFilter, LocalImageFilterBounds) {
  auto filter_matrix = SkMatrix::MakeAll(2.0, 0.0, 10,  //
                                         0.5, 3.0, 15,  //
                                         0.0, 0.0, 1);
  std::vector<sk_sp<SkImageFilter>> sk_filters{
      SkImageFilters::Blur(5.0, 6.0, SkTileMode::kRepeat, nullptr),
      SkImageFilters::ColorFilter(
          SkColorFilters::Blend(SK_ColorRED, SkBlendMode::kSrcOver), nullptr),
      SkImageFilters::Dilate(5.0, 10.0, nullptr),
      SkImageFilters::MatrixTransform(filter_matrix,
                                      ToSk(DlImageSampling::kLinear), nullptr),
      SkImageFilters::Compose(
          SkImageFilters::Blur(5.0, 6.0, SkTileMode::kRepeat, nullptr),
          SkImageFilters::ColorFilter(
              SkColorFilters::Blend(SK_ColorRED, SkBlendMode::kSrcOver),
              nullptr))};

  DlBlendColorFilter dl_color_filter(DlColor::kRed(), DlBlendMode::kSrcOver);
  std::vector<std::shared_ptr<DlImageFilter>> dl_filters{
      std::make_shared<DlBlurImageFilter>(5.0, 6.0, DlTileMode::kRepeat),
      std::make_shared<DlColorFilterImageFilter>(dl_color_filter.shared()),
      std::make_shared<DlDilateImageFilter>(5, 10),
      std::make_shared<DlMatrixImageFilter>(filter_matrix,
                                            DlImageSampling::kLinear),
      std::make_shared<DlComposeImageFilter>(
          std::make_shared<DlBlurImageFilter>(5.0, 6.0, DlTileMode::kRepeat),
          std::make_shared<DlColorFilterImageFilter>(
              dl_color_filter.shared()))};

  auto persp = SkMatrix::I();
  persp.setPerspY(0.001);
  std::vector<SkMatrix> matrices = {
      SkMatrix::Translate(10.0, 10.0),
      SkMatrix::Scale(2.0, 2.0).preTranslate(10.0, 10.0),
      SkMatrix::RotateDeg(45).preTranslate(5.0, 5.0), persp};
  std::vector<SkMatrix> bounds_matrices{SkMatrix::Translate(5.0, 10.0),
                                        SkMatrix::Scale(2.0, 2.0)};

  for (unsigned i = 0; i < sk_filters.size(); i++) {
    for (unsigned j = 0; j < matrices.size(); j++) {
      for (unsigned k = 0; k < bounds_matrices.size(); k++) {
        auto& m = matrices[j];
        auto& bounds_matrix = bounds_matrices[k];
        auto sk_local_filter = sk_filters[i]->makeWithLocalMatrix(m);
        auto dl_local_filter = dl_filters[i]->makeWithLocalMatrix(m);
        if (!sk_local_filter || !dl_local_filter) {
          ASSERT_TRUE(!sk_local_filter);
          ASSERT_TRUE(!dl_local_filter);
          continue;
        }
        {
          auto inputBounds = SkIRect::MakeLTRB(20, 20, 80, 80);
          SkIRect sk_rect, dl_rect;
          sk_rect = sk_local_filter->filterBounds(
              inputBounds, bounds_matrix,
              SkImageFilter::MapDirection::kForward_MapDirection);
          dl_local_filter->map_device_bounds(inputBounds, bounds_matrix,
                                             dl_rect);
          ASSERT_EQ(sk_rect, dl_rect);
        }
        {
          // Test for: Know the outset bounds to get the inset bounds
          // Skia have some bounds calculate error of DilateFilter and
          // MatrixFilter
          // Skia issue: https://bugs.chromium.org/p/skia/issues/detail?id=13444
          // flutter issue: https://github.com/flutter/flutter/issues/108693
          if (i == 2 || i == 3) {
            continue;
          }
          auto outsetBounds = SkIRect::MakeLTRB(20, 20, 80, 80);
          SkIRect sk_rect, dl_rect;
          sk_rect = sk_local_filter->filterBounds(
              outsetBounds, bounds_matrix,
              SkImageFilter::MapDirection::kReverse_MapDirection);
          dl_local_filter->get_input_device_bounds(outsetBounds, bounds_matrix,
                                                   dl_rect);
          ASSERT_EQ(sk_rect, dl_rect);
        }
      }
    }
  }
}

TEST(DisplayListImageFilter, UnknownEquals) {
  sk_sp<SkImageFilter> sk_filter =
      SkImageFilters::Blur(5.0, 6.0, SkTileMode::kRepeat, nullptr);

  DlUnknownImageFilter filter1(sk_filter);
  DlUnknownImageFilter filter2(sk_filter);

  TestEquals(filter1, filter2);
}

TEST(DisplayListImageFilter, UnknownNotEquals) {
  DlUnknownImageFilter filter1(
      SkImageFilters::Blur(5.0, 6.0, SkTileMode::kRepeat, nullptr));
  DlUnknownImageFilter filter2(
      SkImageFilters::Blur(5.0, 6.0, SkTileMode::kRepeat, nullptr));

  // Even though the filter is the same, it is a different instance
  // and we cannot currently tell them apart because the Skia
  // ImageFilter objects do not implement ==
  TestNotEquals(filter1, filter2, "SkImageFilter instance differs");
}

}  // namespace testing
}  // namespace flutter
