// 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.h"
#include "flutter/display_list/display_list_builder.h"
#include "flutter/display_list/display_list_complexity.h"
#include "flutter/display_list/display_list_complexity_gl.h"
#include "flutter/display_list/display_list_complexity_metal.h"
#include "flutter/display_list/display_list_sampling_options.h"
#include "flutter/display_list/display_list_test_utils.h"
#include "flutter/testing/testing.h"
#include "third_party/skia/include/core/SkColor.h"

namespace flutter {
namespace testing {

namespace {

std::vector<DisplayListComplexityCalculator*> Calculators() {
  return {DisplayListMetalComplexityCalculator::GetInstance(),
          DisplayListGLComplexityCalculator::GetInstance(),
          DisplayListNaiveComplexityCalculator::GetInstance()};
}

std::vector<DisplayListComplexityCalculator*> AccumulatorCalculators() {
  return {DisplayListMetalComplexityCalculator::GetInstance(),
          DisplayListGLComplexityCalculator::GetInstance()};
}

std::vector<SkPoint> GetTestPoints() {
  std::vector<SkPoint> points;
  points.push_back(SkPoint::Make(0, 0));
  points.push_back(SkPoint::Make(10, 0));
  points.push_back(SkPoint::Make(10, 10));
  points.push_back(SkPoint::Make(20, 10));
  points.push_back(SkPoint::Make(20, 20));

  return points;
}

}  // namespace

TEST(DisplayListComplexity, EmptyDisplayList) {
  auto display_list = GetSampleDisplayList(0);

  auto calculators = Calculators();
  for (auto calculator : calculators) {
    ASSERT_EQ(calculator->Compute(display_list.get()), 0u);
  }
}

TEST(DisplayListComplexity, DisplayListCeiling) {
  auto display_list = GetSampleDisplayList();

  auto calculators = AccumulatorCalculators();
  for (auto calculator : calculators) {
    calculator->SetComplexityCeiling(10u);
    ASSERT_EQ(calculator->Compute(display_list.get()), 10u);
    calculator->SetComplexityCeiling(std::numeric_limits<unsigned int>::max());
  }
}

TEST(DisplayListComplexity, NestedDisplayList) {
  auto display_list = GetSampleNestedDisplayList();

  auto calculators = Calculators();
  for (auto calculator : calculators) {
    // There's only one draw call in the "outer" DisplayList, which calls
    // drawDisplayList with the "inner" DisplayList. To ensure we are
    // recursing correctly into the inner DisplayList, check that we aren't
    // returning 0 (if the function is a no-op) or 1 (as the op_count is 1)
    ASSERT_GT(calculator->Compute(display_list.get()), 1u);
  }
}

TEST(DisplayListComplexity, AntiAliasing) {
  DisplayListBuilder builder_no_aa;
  builder_no_aa.drawLine(SkPoint::Make(0, 0), SkPoint::Make(100, 100));
  auto display_list_no_aa = builder_no_aa.Build();

  DisplayListBuilder builder_aa;
  builder_aa.setAntiAlias(true);
  builder_aa.drawLine(SkPoint::Make(0, 0), SkPoint::Make(100, 100));
  auto display_list_aa = builder_aa.Build();

  auto calculators = AccumulatorCalculators();
  for (auto calculator : calculators) {
    ASSERT_NE(calculator->Compute(display_list_no_aa.get()),
              calculator->Compute(display_list_aa.get()));
  }
}

TEST(DisplayListComplexity, StrokeWidth) {
  DisplayListBuilder builder_stroke_0;
  builder_stroke_0.setStrokeWidth(0.0f);
  builder_stroke_0.drawLine(SkPoint::Make(0, 0), SkPoint::Make(100, 100));
  auto display_list_stroke_0 = builder_stroke_0.Build();

  DisplayListBuilder builder_stroke_1;
  builder_stroke_1.setStrokeWidth(1.0f);
  builder_stroke_1.drawLine(SkPoint::Make(0, 0), SkPoint::Make(100, 100));
  auto display_list_stroke_1 = builder_stroke_1.Build();

  auto calculators = AccumulatorCalculators();
  for (auto calculator : calculators) {
    ASSERT_NE(calculator->Compute(display_list_stroke_0.get()),
              calculator->Compute(display_list_stroke_1.get()));
  }
}

TEST(DisplayListComplexity, Style) {
  DisplayListBuilder builder_filled;
  builder_filled.setStyle(DlDrawStyle::kFill);
  builder_filled.drawRect(SkRect::MakeXYWH(10, 10, 80, 80));
  auto display_list_filled = builder_filled.Build();

  DisplayListBuilder builder_stroked;
  builder_stroked.setStyle(DlDrawStyle::kStroke);
  builder_stroked.drawRect(SkRect::MakeXYWH(10, 10, 80, 80));
  auto display_list_stroked = builder_stroked.Build();

  auto calculators = AccumulatorCalculators();
  for (auto calculator : calculators) {
    ASSERT_NE(calculator->Compute(display_list_filled.get()),
              calculator->Compute(display_list_stroked.get()));
  }
}

TEST(DisplayListComplexity, SaveLayers) {
  DisplayListBuilder builder;
  builder.saveLayer(nullptr, true);
  auto display_list = builder.Build();

  auto calculators = AccumulatorCalculators();
  for (auto calculator : calculators) {
    ASSERT_NE(calculator->Compute(display_list.get()), 0u);
  }
}

TEST(DisplayListComplexity, DrawPath) {
  DisplayListBuilder builder_line;
  SkPath line_path;
  line_path.moveTo(SkPoint::Make(0, 0));
  line_path.lineTo(SkPoint::Make(10, 10));
  line_path.close();
  builder_line.drawPath(line_path);
  auto display_list_line = builder_line.Build();

  DisplayListBuilder builder_quad;
  SkPath quad_path;
  quad_path.moveTo(SkPoint::Make(0, 0));
  quad_path.quadTo(SkPoint::Make(10, 10), SkPoint::Make(10, 20));
  quad_path.close();
  builder_quad.drawPath(quad_path);
  auto display_list_quad = builder_quad.Build();

  DisplayListBuilder builder_conic;
  SkPath conic_path;
  conic_path.moveTo(SkPoint::Make(0, 0));
  conic_path.conicTo(SkPoint::Make(10, 10), SkPoint::Make(10, 20), 1.5f);
  conic_path.close();
  builder_conic.drawPath(conic_path);
  auto display_list_conic = builder_conic.Build();

  DisplayListBuilder builder_cubic;
  SkPath cubic_path;
  cubic_path.moveTo(SkPoint::Make(0, 0));
  cubic_path.cubicTo(SkPoint::Make(10, 10), SkPoint::Make(10, 20),
                     SkPoint::Make(20, 20));
  builder_cubic.drawPath(cubic_path);
  auto display_list_cubic = builder_cubic.Build();

  auto calculators = AccumulatorCalculators();
  for (auto calculator : calculators) {
    ASSERT_NE(calculator->Compute(display_list_line.get()), 0u);
    ASSERT_NE(calculator->Compute(display_list_quad.get()), 0u);
    ASSERT_NE(calculator->Compute(display_list_conic.get()), 0u);
    ASSERT_NE(calculator->Compute(display_list_cubic.get()), 0u);
  }
}

TEST(DisplayListComplexity, DrawShadow) {
  DisplayListBuilder builder_line;
  SkPath line_path;
  line_path.moveTo(SkPoint::Make(0, 0));
  line_path.lineTo(SkPoint::Make(10, 10));
  line_path.close();
  builder_line.drawShadow(line_path, SK_ColorRED, 10.0f, false, 1.0f);
  auto display_list_line = builder_line.Build();

  DisplayListBuilder builder_quad;
  SkPath quad_path;
  quad_path.moveTo(SkPoint::Make(0, 0));
  quad_path.quadTo(SkPoint::Make(10, 10), SkPoint::Make(10, 20));
  quad_path.close();
  builder_quad.drawShadow(quad_path, SK_ColorRED, 10.0f, false, 1.0f);
  auto display_list_quad = builder_quad.Build();

  DisplayListBuilder builder_conic;
  SkPath conic_path;
  conic_path.moveTo(SkPoint::Make(0, 0));
  conic_path.conicTo(SkPoint::Make(10, 10), SkPoint::Make(10, 20), 1.5f);
  conic_path.close();
  builder_conic.drawShadow(conic_path, SK_ColorRED, 10.0f, false, 1.0f);
  auto display_list_conic = builder_conic.Build();

  DisplayListBuilder builder_cubic;
  SkPath cubic_path;
  cubic_path.moveTo(SkPoint::Make(0, 0));
  cubic_path.cubicTo(SkPoint::Make(10, 10), SkPoint::Make(10, 20),
                     SkPoint::Make(20, 20));
  builder_cubic.drawShadow(cubic_path, SK_ColorRED, 10.0f, false, 1.0f);
  auto display_list_cubic = builder_cubic.Build();

  auto calculators = AccumulatorCalculators();
  for (auto calculator : calculators) {
    ASSERT_NE(calculator->Compute(display_list_line.get()), 0u);
    ASSERT_NE(calculator->Compute(display_list_quad.get()), 0u);
    ASSERT_NE(calculator->Compute(display_list_conic.get()), 0u);
    ASSERT_NE(calculator->Compute(display_list_cubic.get()), 0u);
  }
}

TEST(DisplayListComplexity, DrawOval) {
  DisplayListBuilder builder;
  builder.drawOval(SkRect::MakeXYWH(10, 10, 100, 80));
  auto display_list = builder.Build();

  auto calculators = AccumulatorCalculators();
  for (auto calculator : calculators) {
    ASSERT_NE(calculator->Compute(display_list.get()), 0u);
  }
}

TEST(DisplayListComplexity, DrawCircle) {
  DisplayListBuilder builder;
  builder.drawCircle(SkPoint::Make(50, 50), 10.0f);
  auto display_list = builder.Build();

  auto calculators = AccumulatorCalculators();
  for (auto calculator : calculators) {
    ASSERT_NE(calculator->Compute(display_list.get()), 0u);
  }
}

TEST(DisplayListComplexity, DrawRRect) {
  DisplayListBuilder builder;
  builder.drawRRect(
      SkRRect::MakeRectXY(SkRect::MakeXYWH(10, 10, 80, 80), 2.0f, 3.0f));
  auto display_list = builder.Build();

  auto calculators = AccumulatorCalculators();
  for (auto calculator : calculators) {
    ASSERT_NE(calculator->Compute(display_list.get()), 0u);
  }
}

TEST(DisplayListComplexity, DrawDRRect) {
  DisplayListBuilder builder;
  SkRRect outer =
      SkRRect::MakeRectXY(SkRect::MakeXYWH(10, 10, 80, 80), 2.0f, 3.0f);
  SkRRect inner =
      SkRRect::MakeRectXY(SkRect::MakeXYWH(15, 15, 70, 70), 1.5f, 1.5f);
  builder.drawDRRect(outer, inner);
  auto display_list = builder.Build();

  auto calculators = AccumulatorCalculators();
  for (auto calculator : calculators) {
    ASSERT_NE(calculator->Compute(display_list.get()), 0u);
  }
}

TEST(DisplayListComplexity, DrawArc) {
  DisplayListBuilder builder;
  builder.drawArc(SkRect::MakeXYWH(10, 10, 100, 80), 0.0f, 10.0f, true);
  auto display_list = builder.Build();

  auto calculators = AccumulatorCalculators();
  for (auto calculator : calculators) {
    ASSERT_NE(calculator->Compute(display_list.get()), 0u);
  }
}

TEST(DisplayListComplexity, DrawVertices) {
  auto points = GetTestPoints();
  auto vertices = DlVertices::Make(DlVertexMode::kTriangles, points.size(),
                                   points.data(), nullptr, nullptr);
  DisplayListBuilder builder;
  builder.drawVertices(vertices, DlBlendMode::kSrc);
  auto display_list = builder.Build();

  auto calculators = AccumulatorCalculators();
  for (auto calculator : calculators) {
    ASSERT_NE(calculator->Compute(display_list.get()), 0u);
  }
}

TEST(DisplayListComplexity, DrawTextBlob) {
  auto text_blob = SkTextBlob::MakeFromString(
      "The quick brown fox jumps over the lazy dog.", SkFont());

  DisplayListBuilder builder;
  builder.drawTextBlob(text_blob, 0.0f, 0.0f);
  auto display_list = builder.Build();

  DisplayListBuilder builder_multiple;
  builder_multiple.drawTextBlob(text_blob, 0.0f, 0.0f);
  builder_multiple.drawTextBlob(text_blob, 0.0f, 0.0f);
  auto display_list_multiple = builder_multiple.Build();

  auto calculators = AccumulatorCalculators();
  for (auto calculator : calculators) {
    ASSERT_NE(calculator->Compute(display_list.get()), 0u);
    ASSERT_GT(calculator->Compute(display_list_multiple.get()),
              calculator->Compute(display_list.get()));
  }
}

TEST(DisplayListComplexity, DrawPoints) {
  auto points = GetTestPoints();
  DisplayListBuilder builder_lines;
  builder_lines.drawPoints(SkCanvas::kLines_PointMode, points.size(),
                           points.data());
  auto display_list_lines = builder_lines.Build();

  DisplayListBuilder builder_points;
  builder_points.drawPoints(SkCanvas::kPoints_PointMode, points.size(),
                            points.data());
  auto display_list_points = builder_points.Build();

  DisplayListBuilder builder_polygon;
  builder_polygon.drawPoints(SkCanvas::kPolygon_PointMode, points.size(),
                             points.data());
  auto display_list_polygon = builder_polygon.Build();

  auto calculators = AccumulatorCalculators();
  for (auto calculator : calculators) {
    ASSERT_NE(calculator->Compute(display_list_lines.get()), 0u);
    ASSERT_NE(calculator->Compute(display_list_points.get()), 0u);
    ASSERT_NE(calculator->Compute(display_list_polygon.get()), 0u);
  }
}

TEST(DisplayListComplexity, DrawImage) {
  SkImageInfo info =
      SkImageInfo::Make(50, 50, SkColorType::kRGBA_8888_SkColorType,
                        SkAlphaType::kPremul_SkAlphaType);
  SkBitmap bitmap;
  bitmap.allocPixels(info, 0);
  auto image = SkImage::MakeFromBitmap(bitmap);

  DisplayListBuilder builder;
  builder.drawImage(DlImage::Make(image), SkPoint::Make(0, 0),
                    DlImageSampling::kNearestNeighbor, false);
  auto display_list = builder.Build();

  auto calculators = AccumulatorCalculators();
  for (auto calculator : calculators) {
    ASSERT_NE(calculator->Compute(display_list.get()), 0u);
  }
}

TEST(DisplayListComplexity, DrawImageNine) {
  SkImageInfo info =
      SkImageInfo::Make(50, 50, SkColorType::kRGBA_8888_SkColorType,
                        SkAlphaType::kPremul_SkAlphaType);
  SkBitmap bitmap;
  bitmap.allocPixels(info, 0);
  auto image = SkImage::MakeFromBitmap(bitmap);

  SkIRect center = SkIRect::MakeXYWH(5, 5, 20, 20);
  SkRect dest = SkRect::MakeXYWH(0, 0, 50, 50);

  DisplayListBuilder builder;
  builder.drawImageNine(DlImage::Make(image), center, dest,
                        DlFilterMode::kNearest, true);
  auto display_list = builder.Build();

  auto calculators = AccumulatorCalculators();
  for (auto calculator : calculators) {
    ASSERT_NE(calculator->Compute(display_list.get()), 0u);
  }
}

TEST(DisplayListComplexity, DrawImageRect) {
  SkImageInfo info =
      SkImageInfo::Make(50, 50, SkColorType::kRGBA_8888_SkColorType,
                        SkAlphaType::kPremul_SkAlphaType);
  SkBitmap bitmap;
  bitmap.allocPixels(info, 0);
  auto image = SkImage::MakeFromBitmap(bitmap);

  SkRect src = SkRect::MakeXYWH(0, 0, 50, 50);
  SkRect dest = SkRect::MakeXYWH(0, 0, 50, 50);

  DisplayListBuilder builder;
  builder.drawImageRect(DlImage::Make(image), src, dest,
                        DlImageSampling::kNearestNeighbor, true);
  auto display_list = builder.Build();

  auto calculators = AccumulatorCalculators();
  for (auto calculator : calculators) {
    ASSERT_NE(calculator->Compute(display_list.get()), 0u);
  }
}

TEST(DisplayListComplexity, DrawAtlas) {
  SkImageInfo info =
      SkImageInfo::Make(50, 50, SkColorType::kRGBA_8888_SkColorType,
                        SkAlphaType::kPremul_SkAlphaType);
  SkBitmap bitmap;
  bitmap.allocPixels(info, 0);
  auto image = SkImage::MakeFromBitmap(bitmap);

  std::vector<SkRect> rects;
  std::vector<SkRSXform> xforms;
  for (int i = 0; i < 10; i++) {
    rects.push_back(SkRect::MakeXYWH(0, 0, 10, 10));
    xforms.push_back(SkRSXform::Make(0, 0, 0, 0));
  }

  DisplayListBuilder builder;
  builder.drawAtlas(DlImage::Make(image), xforms.data(), rects.data(), nullptr,
                    10, DlBlendMode::kSrc, DlImageSampling::kNearestNeighbor,
                    nullptr, true);
  auto display_list = builder.Build();

  auto calculators = AccumulatorCalculators();
  for (auto calculator : calculators) {
    ASSERT_NE(calculator->Compute(display_list.get()), 0u);
  }
}

}  // namespace testing
}  // namespace flutter
