// 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 <algorithm>
#include <cstring>
#include <memory>
#include <optional>
#include <utility>
#include <vector>

#include "flutter/display_list/testing/dl_test_snippets.h"
#include "fml/logging.h"
#include "gtest/gtest.h"
#include "impeller/core/formats.h"
#include "impeller/core/texture_descriptor.h"
#include "impeller/entity/contents/atlas_contents.h"
#include "impeller/entity/contents/clip_contents.h"
#include "impeller/entity/contents/conical_gradient_contents.h"
#include "impeller/entity/contents/content_context.h"
#include "impeller/entity/contents/contents.h"
#include "impeller/entity/contents/filters/color_filter_contents.h"
#include "impeller/entity/contents/filters/filter_contents.h"
#include "impeller/entity/contents/filters/gaussian_blur_filter_contents.h"
#include "impeller/entity/contents/filters/inputs/filter_input.h"
#include "impeller/entity/contents/linear_gradient_contents.h"
#include "impeller/entity/contents/radial_gradient_contents.h"
#include "impeller/entity/contents/runtime_effect_contents.h"
#include "impeller/entity/contents/solid_color_contents.h"
#include "impeller/entity/contents/solid_rrect_blur_contents.h"
#include "impeller/entity/contents/text_contents.h"
#include "impeller/entity/contents/texture_contents.h"
#include "impeller/entity/contents/tiled_texture_contents.h"
#include "impeller/entity/entity.h"
#include "impeller/entity/entity_pass.h"
#include "impeller/entity/entity_pass_delegate.h"
#include "impeller/entity/entity_playground.h"
#include "impeller/entity/geometry/geometry.h"
#include "impeller/entity/geometry/point_field_geometry.h"
#include "impeller/entity/geometry/stroke_path_geometry.h"
#include "impeller/entity/render_target_cache.h"
#include "impeller/geometry/color.h"
#include "impeller/geometry/geometry_asserts.h"
#include "impeller/geometry/path_builder.h"
#include "impeller/geometry/point.h"
#include "impeller/geometry/sigma.h"
#include "impeller/geometry/vector.h"
#include "impeller/playground/playground.h"
#include "impeller/playground/widgets.h"
#include "impeller/renderer/command.h"
#include "impeller/renderer/pipeline_descriptor.h"
#include "impeller/renderer/render_pass.h"
#include "impeller/renderer/render_target.h"
#include "impeller/renderer/testing/mocks.h"
#include "impeller/renderer/vertex_buffer_builder.h"
#include "impeller/typographer/backends/skia/text_frame_skia.h"
#include "impeller/typographer/backends/skia/typographer_context_skia.h"
#include "third_party/imgui/imgui.h"
#include "third_party/skia/include/core/SkTextBlob.h"

// TODO(zanderso): https://github.com/flutter/flutter/issues/127701
// NOLINTBEGIN(bugprone-unchecked-optional-access)

namespace impeller {
namespace testing {

using EntityTest = EntityPlayground;
INSTANTIATE_PLAYGROUND_SUITE(EntityTest);

TEST_P(EntityTest, CanCreateEntity) {
  Entity entity;
  ASSERT_TRUE(entity.GetTransform().IsIdentity());
}

class TestPassDelegate final : public EntityPassDelegate {
 public:
  explicit TestPassDelegate(bool collapse = false) : collapse_(collapse) {}

  // |EntityPassDelegate|
  ~TestPassDelegate() override = default;

  // |EntityPassDelgate|
  bool CanElide() override { return false; }

  // |EntityPassDelgate|
  bool CanCollapseIntoParentPass(EntityPass* entity_pass) override {
    return collapse_;
  }

  // |EntityPassDelgate|
  std::shared_ptr<Contents> CreateContentsForSubpassTarget(
      std::shared_ptr<Texture> target,
      const Matrix& transform) override {
    return nullptr;
  }

  // |EntityPassDelegate|
  std::shared_ptr<FilterContents> WithImageFilter(
      const FilterInput::Variant& input,
      const Matrix& effect_transform) const override {
    return nullptr;
  }

 private:
  const std::optional<Rect> coverage_;
  const bool collapse_;
};

auto CreatePassWithRectPath(Rect rect,
                            std::optional<Rect> bounds_hint,
                            bool collapse = false) {
  auto subpass = std::make_unique<EntityPass>();
  Entity entity;
  entity.SetContents(SolidColorContents::Make(
      PathBuilder{}.AddRect(rect).TakePath(), Color::Red()));
  subpass->AddEntity(std::move(entity));
  subpass->SetDelegate(std::make_unique<TestPassDelegate>(collapse));
  subpass->SetBoundsLimit(bounds_hint);
  return subpass;
}

TEST_P(EntityTest, EntityPassRespectsSubpassBoundsLimit) {
  EntityPass pass;

  auto subpass0 = CreatePassWithRectPath(Rect::MakeLTRB(0, 0, 100, 100),
                                         Rect::MakeLTRB(50, 50, 150, 150));
  auto subpass1 = CreatePassWithRectPath(Rect::MakeLTRB(500, 500, 1000, 1000),
                                         Rect::MakeLTRB(800, 800, 900, 900));

  auto subpass0_coverage =
      pass.GetSubpassCoverage(*subpass0.get(), std::nullopt);
  ASSERT_TRUE(subpass0_coverage.has_value());
  ASSERT_RECT_NEAR(subpass0_coverage.value(), Rect::MakeLTRB(50, 50, 100, 100));

  auto subpass1_coverage =
      pass.GetSubpassCoverage(*subpass1.get(), std::nullopt);
  ASSERT_TRUE(subpass1_coverage.has_value());
  ASSERT_RECT_NEAR(subpass1_coverage.value(),
                   Rect::MakeLTRB(800, 800, 900, 900));

  pass.AddSubpass(std::move(subpass0));
  pass.AddSubpass(std::move(subpass1));

  auto coverage = pass.GetElementsCoverage(std::nullopt);
  ASSERT_TRUE(coverage.has_value());
  ASSERT_RECT_NEAR(coverage.value(), Rect::MakeLTRB(50, 50, 900, 900));
}

TEST_P(EntityTest, EntityPassCanMergeSubpassIntoParent) {
  // Both a red and a blue box should appear if the pass merging has worked
  // correctly.

  EntityPass pass;
  auto subpass = CreatePassWithRectPath(Rect::MakeLTRB(0, 0, 100, 100),
                                        Rect::MakeLTRB(50, 50, 150, 150), true);
  pass.AddSubpass(std::move(subpass));

  Entity entity;
  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
  auto contents = std::make_unique<SolidColorContents>();
  contents->SetGeometry(Geometry::MakeRect(Rect::MakeLTRB(100, 100, 200, 200)));
  contents->SetColor(Color::Blue());
  entity.SetContents(std::move(contents));

  pass.AddEntity(std::move(entity));

  ASSERT_TRUE(OpenPlaygroundHere(pass));
}

TEST_P(EntityTest, EntityPassCoverageRespectsCoverageLimit) {
  // Rect is drawn entirely in negative area.
  auto pass = CreatePassWithRectPath(Rect::MakeLTRB(-200, -200, -100, -100),
                                     std::nullopt);

  // Without coverage limit.
  {
    auto pass_coverage = pass->GetElementsCoverage(std::nullopt);
    ASSERT_TRUE(pass_coverage.has_value());
    ASSERT_RECT_NEAR(pass_coverage.value(),
                     Rect::MakeLTRB(-200, -200, -100, -100));
  }

  // With limit that doesn't overlap.
  {
    auto pass_coverage =
        pass->GetElementsCoverage(Rect::MakeLTRB(0, 0, 100, 100));
    ASSERT_FALSE(pass_coverage.has_value());
  }

  // With limit that partially overlaps.
  {
    auto pass_coverage =
        pass->GetElementsCoverage(Rect::MakeLTRB(-150, -150, 0, 0));
    ASSERT_TRUE(pass_coverage.has_value());
    ASSERT_RECT_NEAR(pass_coverage.value(),
                     Rect::MakeLTRB(-150, -150, -100, -100));
  }
}

TEST_P(EntityTest, FilterCoverageRespectsCropRect) {
  auto image = CreateTextureForFixture("boston.jpg");
  auto filter = ColorFilterContents::MakeBlend(BlendMode::kSoftLight,
                                               FilterInput::Make({image}));

  // Without the crop rect (default behavior).
  {
    auto actual = filter->GetCoverage({});
    auto expected = Rect::MakeSize(image->GetSize());

    ASSERT_TRUE(actual.has_value());
    ASSERT_RECT_NEAR(actual.value(), expected);
  }

  // With the crop rect.
  {
    auto expected = Rect::MakeLTRB(50, 50, 100, 100);
    filter->SetCoverageHint(expected);
    auto actual = filter->GetCoverage({});

    ASSERT_TRUE(actual.has_value());
    ASSERT_RECT_NEAR(actual.value(), expected);
  }
}

TEST_P(EntityTest, CanDrawRect) {
  auto contents = std::make_shared<SolidColorContents>();
  contents->SetGeometry(Geometry::MakeRect(Rect::MakeXYWH(100, 100, 100, 100)));
  contents->SetColor(Color::Red());

  Entity entity;
  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
  entity.SetContents(contents);

  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
}

TEST_P(EntityTest, CanDrawRRect) {
  auto contents = std::make_shared<SolidColorContents>();
  auto path = PathBuilder{}
                  .SetConvexity(Convexity::kConvex)
                  .AddRoundedRect(Rect::MakeXYWH(100, 100, 100, 100), 10.0)
                  .TakePath();
  contents->SetGeometry(Geometry::MakeFillPath(path));
  contents->SetColor(Color::Red());

  Entity entity;
  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
  entity.SetContents(contents);

  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
}

TEST_P(EntityTest, GeometryBoundsAreTransformed) {
  auto geometry = Geometry::MakeRect(Rect::MakeXYWH(100, 100, 100, 100));
  auto transform = Matrix::MakeScale({2.0, 2.0, 2.0});

  ASSERT_RECT_NEAR(geometry->GetCoverage(transform).value(),
                   Rect::MakeXYWH(200, 200, 200, 200));
}

TEST_P(EntityTest, ThreeStrokesInOnePath) {
  Path path = PathBuilder{}
                  .MoveTo({100, 100})
                  .LineTo({100, 200})
                  .MoveTo({100, 300})
                  .LineTo({100, 400})
                  .MoveTo({100, 500})
                  .LineTo({100, 600})
                  .TakePath();

  Entity entity;
  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
  auto contents = std::make_unique<SolidColorContents>();
  contents->SetGeometry(Geometry::MakeStrokePath(path, 5.0));
  contents->SetColor(Color::Red());
  entity.SetContents(std::move(contents));
  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
}

TEST_P(EntityTest, StrokeWithTextureContents) {
  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
  Path path = PathBuilder{}
                  .MoveTo({100, 100})
                  .LineTo({100, 200})
                  .MoveTo({100, 300})
                  .LineTo({100, 400})
                  .MoveTo({100, 500})
                  .LineTo({100, 600})
                  .TakePath();

  Entity entity;
  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
  auto contents = std::make_unique<TiledTextureContents>();
  contents->SetGeometry(Geometry::MakeStrokePath(path, 100.0));
  contents->SetTexture(bridge);
  contents->SetTileModes(Entity::TileMode::kClamp, Entity::TileMode::kClamp);
  entity.SetContents(std::move(contents));
  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
}

TEST_P(EntityTest, TriangleInsideASquare) {
  auto callback = [&](ContentContext& context, RenderPass& pass) {
    Point offset(100, 100);

    static PlaygroundPoint point_a(Point(10, 10) + offset, 20, Color::White());
    Point a = DrawPlaygroundPoint(point_a);
    static PlaygroundPoint point_b(Point(210, 10) + offset, 20, Color::White());
    Point b = DrawPlaygroundPoint(point_b);
    static PlaygroundPoint point_c(Point(210, 210) + offset, 20,
                                   Color::White());
    Point c = DrawPlaygroundPoint(point_c);
    static PlaygroundPoint point_d(Point(10, 210) + offset, 20, Color::White());
    Point d = DrawPlaygroundPoint(point_d);
    static PlaygroundPoint point_e(Point(50, 50) + offset, 20, Color::White());
    Point e = DrawPlaygroundPoint(point_e);
    static PlaygroundPoint point_f(Point(100, 50) + offset, 20, Color::White());
    Point f = DrawPlaygroundPoint(point_f);
    static PlaygroundPoint point_g(Point(50, 150) + offset, 20, Color::White());
    Point g = DrawPlaygroundPoint(point_g);
    Path path = PathBuilder{}
                    .MoveTo(a)
                    .LineTo(b)
                    .LineTo(c)
                    .LineTo(d)
                    .Close()
                    .MoveTo(e)
                    .LineTo(f)
                    .LineTo(g)
                    .Close()
                    .TakePath();

    Entity entity;
    entity.SetTransform(Matrix::MakeScale(GetContentScale()));
    auto contents = std::make_unique<SolidColorContents>();
    contents->SetGeometry(Geometry::MakeStrokePath(path, 20.0));
    contents->SetColor(Color::Red());
    entity.SetContents(std::move(contents));

    return entity.Render(context, pass);
  };
  ASSERT_TRUE(OpenPlaygroundHere(callback));
}

TEST_P(EntityTest, StrokeCapAndJoinTest) {
  const Point padding(300, 250);
  const Point margin(140, 180);

  auto callback = [&](ContentContext& context, RenderPass& pass) {
    // Slightly above sqrt(2) by default, so that right angles are just below
    // the limit and acute angles are over the limit (causing them to get
    // beveled).
    static Scalar miter_limit = 1.41421357;
    static Scalar width = 30;

    ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
    {
      ImGui::SliderFloat("Miter limit", &miter_limit, 0, 30);
      ImGui::SliderFloat("Stroke width", &width, 0, 100);
      if (ImGui::Button("Reset")) {
        miter_limit = 1.41421357;
        width = 30;
      }
    }
    ImGui::End();

    auto world_matrix = Matrix::MakeScale(GetContentScale());
    auto render_path = [width = width, &context, &pass, &world_matrix](
                           const Path& path, Cap cap, Join join) {
      auto contents = std::make_unique<SolidColorContents>();
      contents->SetGeometry(
          Geometry::MakeStrokePath(path, width, miter_limit, cap, join));
      contents->SetColor(Color::Red());

      Entity entity;
      entity.SetTransform(world_matrix);
      entity.SetContents(std::move(contents));

      auto coverage = entity.GetCoverage();
      if (coverage.has_value()) {
        auto bounds_contents = std::make_unique<SolidColorContents>();
        bounds_contents->SetGeometry(Geometry::MakeFillPath(
            PathBuilder{}.AddRect(entity.GetCoverage().value()).TakePath()));
        bounds_contents->SetColor(Color::Green().WithAlpha(0.5));
        Entity bounds_entity;
        bounds_entity.SetContents(std::move(bounds_contents));
        bounds_entity.Render(context, pass);
      }

      entity.Render(context, pass);
    };

    const Point a_def(0, 0), b_def(0, 100), c_def(150, 0), d_def(150, -100),
        e_def(75, 75);
    const Scalar r = 30;
    // Cap::kButt demo.
    {
      Point off = Point(0, 0) * padding + margin;
      static PlaygroundPoint point_a(off + a_def, r, Color::Black());
      static PlaygroundPoint point_b(off + b_def, r, Color::White());
      auto [a, b] = DrawPlaygroundLine(point_a, point_b);
      static PlaygroundPoint point_c(off + c_def, r, Color::Black());
      static PlaygroundPoint point_d(off + d_def, r, Color::White());
      auto [c, d] = DrawPlaygroundLine(point_c, point_d);
      render_path(PathBuilder{}.AddCubicCurve(a, b, d, c).TakePath(),
                  Cap::kButt, Join::kBevel);
    }

    // Cap::kSquare demo.
    {
      Point off = Point(1, 0) * padding + margin;
      static PlaygroundPoint point_a(off + a_def, r, Color::Black());
      static PlaygroundPoint point_b(off + b_def, r, Color::White());
      auto [a, b] = DrawPlaygroundLine(point_a, point_b);
      static PlaygroundPoint point_c(off + c_def, r, Color::Black());
      static PlaygroundPoint point_d(off + d_def, r, Color::White());
      auto [c, d] = DrawPlaygroundLine(point_c, point_d);
      render_path(PathBuilder{}.AddCubicCurve(a, b, d, c).TakePath(),
                  Cap::kSquare, Join::kBevel);
    }

    // Cap::kRound demo.
    {
      Point off = Point(2, 0) * padding + margin;
      static PlaygroundPoint point_a(off + a_def, r, Color::Black());
      static PlaygroundPoint point_b(off + b_def, r, Color::White());
      auto [a, b] = DrawPlaygroundLine(point_a, point_b);
      static PlaygroundPoint point_c(off + c_def, r, Color::Black());
      static PlaygroundPoint point_d(off + d_def, r, Color::White());
      auto [c, d] = DrawPlaygroundLine(point_c, point_d);
      render_path(PathBuilder{}.AddCubicCurve(a, b, d, c).TakePath(),
                  Cap::kRound, Join::kBevel);
    }

    // Join::kBevel demo.
    {
      Point off = Point(0, 1) * padding + margin;
      static PlaygroundPoint point_a =
          PlaygroundPoint(off + a_def, r, Color::White());
      static PlaygroundPoint point_b =
          PlaygroundPoint(off + e_def, r, Color::White());
      static PlaygroundPoint point_c =
          PlaygroundPoint(off + c_def, r, Color::White());
      Point a = DrawPlaygroundPoint(point_a);
      Point b = DrawPlaygroundPoint(point_b);
      Point c = DrawPlaygroundPoint(point_c);
      render_path(
          PathBuilder{}.MoveTo(a).LineTo(b).LineTo(c).Close().TakePath(),
          Cap::kButt, Join::kBevel);
    }

    // Join::kMiter demo.
    {
      Point off = Point(1, 1) * padding + margin;
      static PlaygroundPoint point_a(off + a_def, r, Color::White());
      static PlaygroundPoint point_b(off + e_def, r, Color::White());
      static PlaygroundPoint point_c(off + c_def, r, Color::White());
      Point a = DrawPlaygroundPoint(point_a);
      Point b = DrawPlaygroundPoint(point_b);
      Point c = DrawPlaygroundPoint(point_c);
      render_path(
          PathBuilder{}.MoveTo(a).LineTo(b).LineTo(c).Close().TakePath(),
          Cap::kButt, Join::kMiter);
    }

    // Join::kRound demo.
    {
      Point off = Point(2, 1) * padding + margin;
      static PlaygroundPoint point_a(off + a_def, r, Color::White());
      static PlaygroundPoint point_b(off + e_def, r, Color::White());
      static PlaygroundPoint point_c(off + c_def, r, Color::White());
      Point a = DrawPlaygroundPoint(point_a);
      Point b = DrawPlaygroundPoint(point_b);
      Point c = DrawPlaygroundPoint(point_c);
      render_path(
          PathBuilder{}.MoveTo(a).LineTo(b).LineTo(c).Close().TakePath(),
          Cap::kButt, Join::kRound);
    }

    return true;
  };
  ASSERT_TRUE(OpenPlaygroundHere(callback));
}

TEST_P(EntityTest, CubicCurveTest) {
  // Compare with https://fiddle.skia.org/c/b3625f26122c9de7afe7794fcf25ead3
  Path path =
      PathBuilder{}
          .MoveTo({237.164, 125.003})
          .CubicCurveTo({236.709, 125.184}, {236.262, 125.358},
                        {235.81, 125.538})
          .CubicCurveTo({235.413, 125.68}, {234.994, 125.832},
                        {234.592, 125.977})
          .CubicCurveTo({234.592, 125.977}, {234.591, 125.977},
                        {234.59, 125.977})
          .CubicCurveTo({222.206, 130.435}, {207.708, 135.753},
                        {192.381, 141.429})
          .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160})
          .Close()
          .TakePath();
  Entity entity;
  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
  entity.SetContents(SolidColorContents::Make(path, Color::Red()));
  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
}

TEST_P(EntityTest, CanDrawCorrectlyWithRotatedTransform) {
  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
    const char* input_axis[] = {"X", "Y", "Z"};
    static int rotation_axis_index = 0;
    static float rotation = 0;
    ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
    ImGui::SliderFloat("Rotation", &rotation, -kPi, kPi);
    ImGui::Combo("Rotation Axis", &rotation_axis_index, input_axis,
                 sizeof(input_axis) / sizeof(char*));
    Matrix rotation_matrix;
    switch (rotation_axis_index) {
      case 0:
        rotation_matrix = Matrix::MakeRotationX(Radians(rotation));
        break;
      case 1:
        rotation_matrix = Matrix::MakeRotationY(Radians(rotation));
        break;
      case 2:
        rotation_matrix = Matrix::MakeRotationZ(Radians(rotation));
        break;
      default:
        rotation_matrix = Matrix{};
        break;
    }

    if (ImGui::Button("Reset")) {
      rotation = 0;
    }
    ImGui::End();
    Matrix current_transform =
        Matrix::MakeScale(GetContentScale())
            .MakeTranslation(
                Vector3(Point(pass.GetRenderTargetSize().width / 2.0,
                              pass.GetRenderTargetSize().height / 2.0)));
    Matrix result_transform = current_transform * rotation_matrix;
    Path path =
        PathBuilder{}.AddRect(Rect::MakeXYWH(-300, -400, 600, 800)).TakePath();

    Entity entity;
    entity.SetTransform(result_transform);
    entity.SetContents(SolidColorContents::Make(path, Color::Red()));
    return entity.Render(context, pass);
  };
  ASSERT_TRUE(OpenPlaygroundHere(callback));
}

TEST_P(EntityTest, CubicCurveAndOverlapTest) {
  // Compare with https://fiddle.skia.org/c/7a05a3e186c65a8dfb732f68020aae06
  Path path =
      PathBuilder{}
          .MoveTo({359.934, 96.6335})
          .CubicCurveTo({358.189, 96.7055}, {356.436, 96.7908},
                        {354.673, 96.8895})
          .CubicCurveTo({354.571, 96.8953}, {354.469, 96.9016},
                        {354.367, 96.9075})
          .CubicCurveTo({352.672, 97.0038}, {350.969, 97.113},
                        {349.259, 97.2355})
          .CubicCurveTo({349.048, 97.2506}, {348.836, 97.2678},
                        {348.625, 97.2834})
          .CubicCurveTo({347.019, 97.4014}, {345.407, 97.5299},
                        {343.789, 97.6722})
          .CubicCurveTo({343.428, 97.704}, {343.065, 97.7402},
                        {342.703, 97.7734})
          .CubicCurveTo({341.221, 97.9086}, {339.736, 98.0505},
                        {338.246, 98.207})
          .CubicCurveTo({337.702, 98.2642}, {337.156, 98.3292},
                        {336.612, 98.3894})
          .CubicCurveTo({335.284, 98.5356}, {333.956, 98.6837},
                        {332.623, 98.8476})
          .CubicCurveTo({332.495, 98.8635}, {332.366, 98.8818},
                        {332.237, 98.8982})
          .LineTo({332.237, 102.601})
          .LineTo({321.778, 102.601})
          .LineTo({321.778, 100.382})
          .CubicCurveTo({321.572, 100.413}, {321.367, 100.442},
                        {321.161, 100.476})
          .CubicCurveTo({319.22, 100.79}, {317.277, 101.123},
                        {315.332, 101.479})
          .CubicCurveTo({315.322, 101.481}, {315.311, 101.482},
                        {315.301, 101.484})
          .LineTo({310.017, 105.94})
          .LineTo({309.779, 105.427})
          .LineTo({314.403, 101.651})
          .CubicCurveTo({314.391, 101.653}, {314.379, 101.656},
                        {314.368, 101.658})
          .CubicCurveTo({312.528, 102.001}, {310.687, 102.366},
                        {308.846, 102.748})
          .CubicCurveTo({307.85, 102.955}, {306.855, 103.182}, {305.859, 103.4})
          .CubicCurveTo({305.048, 103.579}, {304.236, 103.75},
                        {303.425, 103.936})
          .LineTo({299.105, 107.578})
          .LineTo({298.867, 107.065})
          .LineTo({302.394, 104.185})
          .LineTo({302.412, 104.171})
          .CubicCurveTo({301.388, 104.409}, {300.366, 104.67},
                        {299.344, 104.921})
          .CubicCurveTo({298.618, 105.1}, {297.89, 105.269}, {297.165, 105.455})
          .CubicCurveTo({295.262, 105.94}, {293.36, 106.445},
                        {291.462, 106.979})
          .CubicCurveTo({291.132, 107.072}, {290.802, 107.163},
                        {290.471, 107.257})
          .CubicCurveTo({289.463, 107.544}, {288.455, 107.839},
                        {287.449, 108.139})
          .CubicCurveTo({286.476, 108.431}, {285.506, 108.73},
                        {284.536, 109.035})
          .CubicCurveTo({283.674, 109.304}, {282.812, 109.579},
                        {281.952, 109.859})
          .CubicCurveTo({281.177, 110.112}, {280.406, 110.377},
                        {279.633, 110.638})
          .CubicCurveTo({278.458, 111.037}, {277.256, 111.449},
                        {276.803, 111.607})
          .CubicCurveTo({276.76, 111.622}, {276.716, 111.637},
                        {276.672, 111.653})
          .CubicCurveTo({275.017, 112.239}, {273.365, 112.836},
                        {271.721, 113.463})
          .LineTo({271.717, 113.449})
          .CubicCurveTo({271.496, 113.496}, {271.238, 113.559},
                        {270.963, 113.628})
          .CubicCurveTo({270.893, 113.645}, {270.822, 113.663},
                        {270.748, 113.682})
          .CubicCurveTo({270.468, 113.755}, {270.169, 113.834},
                        {269.839, 113.926})
          .CubicCurveTo({269.789, 113.94}, {269.732, 113.957},
                        {269.681, 113.972})
          .CubicCurveTo({269.391, 114.053}, {269.081, 114.143},
                        {268.756, 114.239})
          .CubicCurveTo({268.628, 114.276}, {268.5, 114.314},
                        {268.367, 114.354})
          .CubicCurveTo({268.172, 114.412}, {267.959, 114.478},
                        {267.752, 114.54})
          .CubicCurveTo({263.349, 115.964}, {258.058, 117.695},
                        {253.564, 119.252})
          .CubicCurveTo({253.556, 119.255}, {253.547, 119.258},
                        {253.538, 119.261})
          .CubicCurveTo({251.844, 119.849}, {250.056, 120.474},
                        {248.189, 121.131})
          .CubicCurveTo({248, 121.197}, {247.812, 121.264}, {247.621, 121.331})
          .CubicCurveTo({247.079, 121.522}, {246.531, 121.715},
                        {245.975, 121.912})
          .CubicCurveTo({245.554, 122.06}, {245.126, 122.212},
                        {244.698, 122.364})
          .CubicCurveTo({244.071, 122.586}, {243.437, 122.811},
                        {242.794, 123.04})
          .CubicCurveTo({242.189, 123.255}, {241.58, 123.472},
                        {240.961, 123.693})
          .CubicCurveTo({240.659, 123.801}, {240.357, 123.909},
                        {240.052, 124.018})
          .CubicCurveTo({239.12, 124.351}, {238.18, 124.687}, {237.22, 125.032})
          .LineTo({237.164, 125.003})
          .CubicCurveTo({236.709, 125.184}, {236.262, 125.358},
                        {235.81, 125.538})
          .CubicCurveTo({235.413, 125.68}, {234.994, 125.832},
                        {234.592, 125.977})
          .CubicCurveTo({234.592, 125.977}, {234.591, 125.977},
                        {234.59, 125.977})
          .CubicCurveTo({222.206, 130.435}, {207.708, 135.753},
                        {192.381, 141.429})
          .CubicCurveTo({162.77, 151.336}, {122.17, 156.894}, {84.1123, 160})
          .LineTo({360, 160})
          .LineTo({360, 119.256})
          .LineTo({360, 106.332})
          .LineTo({360, 96.6307})
          .CubicCurveTo({359.978, 96.6317}, {359.956, 96.6326},
                        {359.934, 96.6335})
          .Close()
          .MoveTo({337.336, 124.143})
          .CubicCurveTo({337.274, 122.359}, {338.903, 121.511},
                        {338.903, 121.511})
          .CubicCurveTo({338.903, 121.511}, {338.96, 123.303},
                        {337.336, 124.143})
          .Close()
          .MoveTo({340.082, 121.849})
          .CubicCurveTo({340.074, 121.917}, {340.062, 121.992},
                        {340.046, 122.075})
          .CubicCurveTo({340.039, 122.109}, {340.031, 122.142},
                        {340.023, 122.177})
          .CubicCurveTo({340.005, 122.26}, {339.98, 122.346},
                        {339.952, 122.437})
          .CubicCurveTo({339.941, 122.473}, {339.931, 122.507},
                        {339.918, 122.544})
          .CubicCurveTo({339.873, 122.672}, {339.819, 122.804},
                        {339.75, 122.938})
          .CubicCurveTo({339.747, 122.944}, {339.743, 122.949},
                        {339.74, 122.955})
          .CubicCurveTo({339.674, 123.08}, {339.593, 123.205},
                        {339.501, 123.328})
          .CubicCurveTo({339.473, 123.366}, {339.441, 123.401},
                        {339.41, 123.438})
          .CubicCurveTo({339.332, 123.534}, {339.243, 123.625},
                        {339.145, 123.714})
          .CubicCurveTo({339.105, 123.75}, {339.068, 123.786},
                        {339.025, 123.821})
          .CubicCurveTo({338.881, 123.937}, {338.724, 124.048},
                        {338.539, 124.143})
          .CubicCurveTo({338.532, 123.959}, {338.554, 123.79},
                        {338.58, 123.626})
          .CubicCurveTo({338.58, 123.625}, {338.58, 123.625}, {338.58, 123.625})
          .CubicCurveTo({338.607, 123.455}, {338.65, 123.299},
                        {338.704, 123.151})
          .CubicCurveTo({338.708, 123.14}, {338.71, 123.127},
                        {338.714, 123.117})
          .CubicCurveTo({338.769, 122.971}, {338.833, 122.838},
                        {338.905, 122.712})
          .CubicCurveTo({338.911, 122.702}, {338.916, 122.69200000000001},
                        {338.922, 122.682})
          .CubicCurveTo({338.996, 122.557}, {339.072, 122.444},
                        {339.155, 122.34})
          .CubicCurveTo({339.161, 122.333}, {339.166, 122.326},
                        {339.172, 122.319})
          .CubicCurveTo({339.256, 122.215}, {339.339, 122.12},
                        {339.425, 122.037})
          .CubicCurveTo({339.428, 122.033}, {339.431, 122.03},
                        {339.435, 122.027})
          .CubicCurveTo({339.785, 121.687}, {340.106, 121.511},
                        {340.106, 121.511})
          .CubicCurveTo({340.106, 121.511}, {340.107, 121.645},
                        {340.082, 121.849})
          .Close()
          .MoveTo({340.678, 113.245})
          .CubicCurveTo({340.594, 113.488}, {340.356, 113.655},
                        {340.135, 113.775})
          .CubicCurveTo({339.817, 113.948}, {339.465, 114.059},
                        {339.115, 114.151})
          .CubicCurveTo({338.251, 114.379}, {337.34, 114.516},
                        {336.448, 114.516})
          .CubicCurveTo({335.761, 114.516}, {335.072, 114.527},
                        {334.384, 114.513})
          .CubicCurveTo({334.125, 114.508}, {333.862, 114.462},
                        {333.605, 114.424})
          .CubicCurveTo({332.865, 114.318}, {332.096, 114.184},
                        {331.41, 113.883})
          .CubicCurveTo({330.979, 113.695}, {330.442, 113.34},
                        {330.672, 112.813})
          .CubicCurveTo({331.135, 111.755}, {333.219, 112.946},
                        {334.526, 113.833})
          .CubicCurveTo({334.54, 113.816}, {334.554, 113.8}, {334.569, 113.784})
          .CubicCurveTo({333.38, 112.708}, {331.749, 110.985},
                        {332.76, 110.402})
          .CubicCurveTo({333.769, 109.82}, {334.713, 111.93},
                        {335.228, 113.395})
          .CubicCurveTo({334.915, 111.889}, {334.59, 109.636},
                        {335.661, 109.592})
          .CubicCurveTo({336.733, 109.636}, {336.408, 111.889},
                        {336.07, 113.389})
          .CubicCurveTo({336.609, 111.93}, {337.553, 109.82},
                        {338.563, 110.402})
          .CubicCurveTo({339.574, 110.984}, {337.942, 112.708},
                        {336.753, 113.784})
          .CubicCurveTo({336.768, 113.8}, {336.782, 113.816},
                        {336.796, 113.833})
          .CubicCurveTo({338.104, 112.946}, {340.187, 111.755},
                        {340.65, 112.813})
          .CubicCurveTo({340.71, 112.95}, {340.728, 113.102},
                        {340.678, 113.245})
          .Close()
          .MoveTo({346.357, 106.771})
          .CubicCurveTo({346.295, 104.987}, {347.924, 104.139},
                        {347.924, 104.139})
          .CubicCurveTo({347.924, 104.139}, {347.982, 105.931},
                        {346.357, 106.771})
          .Close()
          .MoveTo({347.56, 106.771})
          .CubicCurveTo({347.498, 104.987}, {349.127, 104.139},
                        {349.127, 104.139})
          .CubicCurveTo({349.127, 104.139}, {349.185, 105.931},
                        {347.56, 106.771})
          .Close()
          .TakePath();
  Entity entity;
  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
  entity.SetContents(SolidColorContents::Make(path, Color::Red()));
  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
}

TEST_P(EntityTest, SolidColorContentsStrokeSetStrokeCapsAndJoins) {
  {
    auto geometry = Geometry::MakeStrokePath(Path{});
    auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
    // Defaults.
    ASSERT_EQ(path_geometry->GetStrokeCap(), Cap::kButt);
    ASSERT_EQ(path_geometry->GetStrokeJoin(), Join::kMiter);
  }

  {
    auto geometry = Geometry::MakeStrokePath(Path{}, 1.0, 4.0, Cap::kSquare);
    auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
    ASSERT_EQ(path_geometry->GetStrokeCap(), Cap::kSquare);
  }

  {
    auto geometry = Geometry::MakeStrokePath(Path{}, 1.0, 4.0, Cap::kRound);
    auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
    ASSERT_EQ(path_geometry->GetStrokeCap(), Cap::kRound);
  }
}

TEST_P(EntityTest, SolidColorContentsStrokeSetMiterLimit) {
  {
    auto geometry = Geometry::MakeStrokePath(Path{});
    auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
    ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 4);
  }

  {
    auto geometry = Geometry::MakeStrokePath(Path{}, 1.0, /*miter_limit=*/8.0);
    auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
    ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 8);
  }

  {
    auto geometry = Geometry::MakeStrokePath(Path{}, 1.0, /*miter_limit=*/-1.0);
    auto path_geometry = static_cast<StrokePathGeometry*>(geometry.get());
    ASSERT_FLOAT_EQ(path_geometry->GetMiterLimit(), 4);
  }
}

TEST_P(EntityTest, BlendingModeOptions) {
  std::vector<const char*> blend_mode_names;
  std::vector<BlendMode> blend_mode_values;
  {
    // Force an exhausiveness check with a switch. When adding blend modes,
    // update this switch with a new name/value to make it selectable in the
    // test GUI.

    const BlendMode b{};
    static_assert(b == BlendMode::kClear);  // Ensure the first item in
                                            // the switch is the first
                                            // item in the enum.
    static_assert(Entity::kLastPipelineBlendMode == BlendMode::kModulate);
    switch (b) {
      case BlendMode::kClear:
        blend_mode_names.push_back("Clear");
        blend_mode_values.push_back(BlendMode::kClear);
      case BlendMode::kSource:
        blend_mode_names.push_back("Source");
        blend_mode_values.push_back(BlendMode::kSource);
      case BlendMode::kDestination:
        blend_mode_names.push_back("Destination");
        blend_mode_values.push_back(BlendMode::kDestination);
      case BlendMode::kSourceOver:
        blend_mode_names.push_back("SourceOver");
        blend_mode_values.push_back(BlendMode::kSourceOver);
      case BlendMode::kDestinationOver:
        blend_mode_names.push_back("DestinationOver");
        blend_mode_values.push_back(BlendMode::kDestinationOver);
      case BlendMode::kSourceIn:
        blend_mode_names.push_back("SourceIn");
        blend_mode_values.push_back(BlendMode::kSourceIn);
      case BlendMode::kDestinationIn:
        blend_mode_names.push_back("DestinationIn");
        blend_mode_values.push_back(BlendMode::kDestinationIn);
      case BlendMode::kSourceOut:
        blend_mode_names.push_back("SourceOut");
        blend_mode_values.push_back(BlendMode::kSourceOut);
      case BlendMode::kDestinationOut:
        blend_mode_names.push_back("DestinationOut");
        blend_mode_values.push_back(BlendMode::kDestinationOut);
      case BlendMode::kSourceATop:
        blend_mode_names.push_back("SourceATop");
        blend_mode_values.push_back(BlendMode::kSourceATop);
      case BlendMode::kDestinationATop:
        blend_mode_names.push_back("DestinationATop");
        blend_mode_values.push_back(BlendMode::kDestinationATop);
      case BlendMode::kXor:
        blend_mode_names.push_back("Xor");
        blend_mode_values.push_back(BlendMode::kXor);
      case BlendMode::kPlus:
        blend_mode_names.push_back("Plus");
        blend_mode_values.push_back(BlendMode::kPlus);
      case BlendMode::kModulate:
        blend_mode_names.push_back("Modulate");
        blend_mode_values.push_back(BlendMode::kModulate);
    };
  }

  auto callback = [&](ContentContext& context, RenderPass& pass) {
    auto world_matrix = Matrix::MakeScale(GetContentScale());
    auto draw_rect = [&context, &pass, &world_matrix](
                         Rect rect, Color color, BlendMode blend_mode) -> bool {
      using VS = SolidFillPipeline::VertexShader;

      VertexBufferBuilder<VS::PerVertexData> vtx_builder;
      {
        auto r = rect.GetLTRB();
        vtx_builder.AddVertices({
            {Point(r[0], r[1])},
            {Point(r[2], r[1])},
            {Point(r[2], r[3])},
            {Point(r[0], r[1])},
            {Point(r[2], r[3])},
            {Point(r[0], r[3])},
        });
      }

      pass.SetCommandLabel("Blended Rectangle");
      auto options = OptionsFromPass(pass);
      options.blend_mode = blend_mode;
      options.primitive_type = PrimitiveType::kTriangle;
      pass.SetPipeline(context.GetSolidFillPipeline(options));
      pass.SetVertexBuffer(
          vtx_builder.CreateVertexBuffer(context.GetTransientsBuffer()));

      VS::FrameInfo frame_info;
      frame_info.mvp = pass.GetOrthographicTransform() * world_matrix;
      frame_info.color = color.Premultiply();
      VS::BindFrameInfo(
          pass, context.GetTransientsBuffer().EmplaceUniform(frame_info));

      return pass.Draw().ok();
    };

    ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
    static Color color1(1, 0, 0, 0.5), color2(0, 1, 0, 0.5);
    ImGui::ColorEdit4("Color 1", reinterpret_cast<float*>(&color1));
    ImGui::ColorEdit4("Color 2", reinterpret_cast<float*>(&color2));
    static int current_blend_index = 3;
    ImGui::ListBox("Blending mode", &current_blend_index,
                   blend_mode_names.data(), blend_mode_names.size());
    ImGui::End();

    BlendMode selected_mode = blend_mode_values[current_blend_index];

    Point a, b, c, d;
    static PlaygroundPoint point_a(Point(400, 100), 20, Color::White());
    static PlaygroundPoint point_b(Point(200, 300), 20, Color::White());
    std::tie(a, b) = DrawPlaygroundLine(point_a, point_b);
    static PlaygroundPoint point_c(Point(470, 190), 20, Color::White());
    static PlaygroundPoint point_d(Point(270, 390), 20, Color::White());
    std::tie(c, d) = DrawPlaygroundLine(point_c, point_d);

    bool result = true;
    result = result &&
             draw_rect(Rect::MakeXYWH(0, 0, pass.GetRenderTargetSize().width,
                                      pass.GetRenderTargetSize().height),
                       Color(), BlendMode::kClear);
    result = result && draw_rect(Rect::MakeLTRB(a.x, a.y, b.x, b.y), color1,
                                 BlendMode::kSourceOver);
    result = result && draw_rect(Rect::MakeLTRB(c.x, c.y, d.x, d.y), color2,
                                 selected_mode);
    return result;
  };
  ASSERT_TRUE(OpenPlaygroundHere(callback));
}

TEST_P(EntityTest, BezierCircleScaled) {
  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
    static float scale = 20;

    ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
    ImGui::SliderFloat("Scale", &scale, 1, 100);
    ImGui::End();

    Entity entity;
    entity.SetTransform(Matrix::MakeScale(GetContentScale()));
    auto path = PathBuilder{}
                    .MoveTo({97.325, 34.818})
                    .CubicCurveTo({98.50862885295136, 34.81812293973836},
                                  {99.46822048142015, 33.85863261475589},
                                  {99.46822048142015, 32.67499810206613})
                    .CubicCurveTo({99.46822048142015, 31.491363589376355},
                                  {98.50862885295136, 30.53187326439389},
                                  {97.32499434685802, 30.531998226542708})
                    .CubicCurveTo({96.14153655073771, 30.532123170035373},
                                  {95.18222070648729, 31.491540299350355},
                                  {95.18222070648729, 32.67499810206613})
                    .CubicCurveTo({95.18222070648729, 33.85845590478189},
                                  {96.14153655073771, 34.81787303409686},
                                  {97.32499434685802, 34.81799797758954})
                    .Close()
                    .TakePath();
    entity.SetTransform(
        Matrix::MakeScale({scale, scale, 1.0}).Translate({-90, -20, 0}));
    entity.SetContents(SolidColorContents::Make(path, Color::Red()));
    return entity.Render(context, pass);
  };
  ASSERT_TRUE(OpenPlaygroundHere(callback));
}

TEST_P(EntityTest, Filters) {
  auto bridge = CreateTextureForFixture("bay_bridge.jpg");
  auto boston = CreateTextureForFixture("boston.jpg");
  auto kalimba = CreateTextureForFixture("kalimba.jpg");
  ASSERT_TRUE(bridge && boston && kalimba);

  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
    auto fi_bridge = FilterInput::Make(bridge);
    auto fi_boston = FilterInput::Make(boston);
    auto fi_kalimba = FilterInput::Make(kalimba);

    std::shared_ptr<FilterContents> blend0 = ColorFilterContents::MakeBlend(
        BlendMode::kModulate, {fi_kalimba, fi_boston});

    auto blend1 = ColorFilterContents::MakeBlend(
        BlendMode::kScreen,
        {FilterInput::Make(blend0), fi_bridge, fi_bridge, fi_bridge});

    Entity entity;
    entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
                        Matrix::MakeTranslation({500, 300}) *
                        Matrix::MakeScale(Vector2{0.5, 0.5}));
    entity.SetContents(blend1);
    return entity.Render(context, pass);
  };
  ASSERT_TRUE(OpenPlaygroundHere(callback));
}

TEST_P(EntityTest, GaussianBlurFilter) {
  auto boston =
      CreateTextureForFixture("boston.jpg", /*enable_mipmapping=*/true);
  ASSERT_TRUE(boston);

  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
    const char* input_type_names[] = {"Texture", "Solid Color"};
    const char* blur_type_names[] = {"Image blur", "Mask blur"};
    const char* pass_variation_names[] = {"New"};
    const char* blur_style_names[] = {"Normal", "Solid", "Outer", "Inner"};
    const char* tile_mode_names[] = {"Clamp", "Repeat", "Mirror", "Decal"};
    const FilterContents::BlurStyle blur_styles[] = {
        FilterContents::BlurStyle::kNormal, FilterContents::BlurStyle::kSolid,
        FilterContents::BlurStyle::kOuter, FilterContents::BlurStyle::kInner};
    const Entity::TileMode tile_modes[] = {
        Entity::TileMode::kClamp, Entity::TileMode::kRepeat,
        Entity::TileMode::kMirror, Entity::TileMode::kDecal};

    // UI state.
    static int selected_input_type = 0;
    static Color input_color = Color::Black();
    static int selected_blur_type = 0;
    static int selected_pass_variation = 0;
    static bool combined_sigma = false;
    static float blur_amount_coarse[2] = {0, 0};
    static float blur_amount_fine[2] = {10, 10};
    static int selected_blur_style = 0;
    static int selected_tile_mode = 3;
    static Color cover_color(1, 0, 0, 0.2);
    static Color bounds_color(0, 1, 0, 0.1);
    static float offset[2] = {500, 400};
    static float rotation = 0;
    static float scale[2] = {0.65, 0.65};
    static float skew[2] = {0, 0};
    static float path_rect[4] = {0, 0,
                                 static_cast<float>(boston->GetSize().width),
                                 static_cast<float>(boston->GetSize().height)};

    ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
    {
      ImGui::Combo("Input type", &selected_input_type, input_type_names,
                   sizeof(input_type_names) / sizeof(char*));
      if (selected_input_type == 0) {
        ImGui::SliderFloat("Input opacity", &input_color.alpha, 0, 1);
      } else {
        ImGui::ColorEdit4("Input color",
                          reinterpret_cast<float*>(&input_color));
      }
      ImGui::Combo("Blur type", &selected_blur_type, blur_type_names,
                   sizeof(blur_type_names) / sizeof(char*));
      if (selected_blur_type == 0) {
        ImGui::Combo("Pass variation", &selected_pass_variation,
                     pass_variation_names,
                     sizeof(pass_variation_names) / sizeof(char*));
      }
      ImGui::Checkbox("Combined sigma", &combined_sigma);
      if (combined_sigma) {
        ImGui::SliderFloat("Sigma (coarse)", blur_amount_coarse, 0, 1000);
        ImGui::SliderFloat("Sigma (fine)", blur_amount_fine, 0, 10);
        blur_amount_coarse[1] = blur_amount_coarse[0];
        blur_amount_fine[1] = blur_amount_fine[0];
      } else {
        ImGui::SliderFloat2("Sigma (coarse)", blur_amount_coarse, 0, 1000);
        ImGui::SliderFloat2("Sigma (fine)", blur_amount_fine, 0, 10);
      }
      ImGui::Combo("Blur style", &selected_blur_style, blur_style_names,
                   sizeof(blur_style_names) / sizeof(char*));
      ImGui::Combo("Tile mode", &selected_tile_mode, tile_mode_names,
                   sizeof(tile_mode_names) / sizeof(char*));
      ImGui::ColorEdit4("Cover color", reinterpret_cast<float*>(&cover_color));
      ImGui::ColorEdit4("Bounds color",
                        reinterpret_cast<float*>(&bounds_color));
      ImGui::SliderFloat2("Translation", offset, 0,
                          pass.GetRenderTargetSize().width);
      ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
      ImGui::SliderFloat2("Scale", scale, 0, 3);
      ImGui::SliderFloat2("Skew", skew, -3, 3);
      ImGui::SliderFloat4("Path XYWH", path_rect, -1000, 1000);
    }
    ImGui::End();

    auto blur_sigma_x = Sigma{blur_amount_coarse[0] + blur_amount_fine[0]};
    auto blur_sigma_y = Sigma{blur_amount_coarse[1] + blur_amount_fine[1]};

    std::shared_ptr<Contents> input;
    Size input_size;

    auto input_rect =
        Rect::MakeXYWH(path_rect[0], path_rect[1], path_rect[2], path_rect[3]);
    if (selected_input_type == 0) {
      auto texture = std::make_shared<TextureContents>();
      texture->SetSourceRect(Rect::MakeSize(boston->GetSize()));
      texture->SetDestinationRect(input_rect);
      texture->SetTexture(boston);
      texture->SetOpacity(input_color.alpha);

      input = texture;
      input_size = input_rect.GetSize();
    } else {
      auto fill = std::make_shared<SolidColorContents>();
      fill->SetColor(input_color);
      fill->SetGeometry(
          Geometry::MakeFillPath(PathBuilder{}.AddRect(input_rect).TakePath()));

      input = fill;
      input_size = input_rect.GetSize();
    }

    std::shared_ptr<FilterContents> blur;
    switch (selected_pass_variation) {
      case 0:
        blur = std::make_shared<GaussianBlurFilterContents>(
            blur_sigma_x.sigma, blur_sigma_y.sigma,
            tile_modes[selected_tile_mode], blur_styles[selected_blur_style],
            /*geometry=*/nullptr);
        blur->SetInputs({FilterInput::Make(input)});
        break;
      case 1:
        blur = FilterContents::MakeGaussianBlur(
            FilterInput::Make(input), blur_sigma_x, blur_sigma_y,
            tile_modes[selected_tile_mode], blur_styles[selected_blur_style]);
        break;
    };
    FML_CHECK(blur);

    auto mask_blur = FilterContents::MakeBorderMaskBlur(
        FilterInput::Make(input), blur_sigma_x, blur_sigma_y,
        blur_styles[selected_blur_style]);

    auto ctm = Matrix::MakeScale(GetContentScale()) *
               Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
               Matrix::MakeRotationZ(Radians(rotation)) *
               Matrix::MakeScale(Vector2(scale[0], scale[1])) *
               Matrix::MakeSkew(skew[0], skew[1]) *
               Matrix::MakeTranslation(-Point(input_size) / 2);

    auto target_contents = selected_blur_type == 0 ? blur : mask_blur;

    Entity entity;
    entity.SetContents(target_contents);
    entity.SetTransform(ctm);

    entity.Render(context, pass);

    // Renders a red "cover" rectangle that shows the original position of the
    // unfiltered input.
    Entity cover_entity;
    cover_entity.SetContents(SolidColorContents::Make(
        PathBuilder{}.AddRect(input_rect).TakePath(), cover_color));
    cover_entity.SetTransform(ctm);

    cover_entity.Render(context, pass);

    // Renders a green bounding rect of the target filter.
    Entity bounds_entity;
    std::optional<Rect> target_contents_coverage =
        target_contents->GetCoverage(entity);
    if (target_contents_coverage.has_value()) {
      bounds_entity.SetContents(SolidColorContents::Make(
          PathBuilder{}
              .AddRect(target_contents->GetCoverage(entity).value())
              .TakePath(),
          bounds_color));
      bounds_entity.SetTransform(Matrix());

      bounds_entity.Render(context, pass);
    }

    return true;
  };
  ASSERT_TRUE(OpenPlaygroundHere(callback));
}

TEST_P(EntityTest, MorphologyFilter) {
  auto boston = CreateTextureForFixture("boston.jpg");
  ASSERT_TRUE(boston);

  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
    const char* morphology_type_names[] = {"Dilate", "Erode"};
    const FilterContents::MorphType morphology_types[] = {
        FilterContents::MorphType::kDilate, FilterContents::MorphType::kErode};
    static Color input_color = Color::Black();
    // UI state.
    static int selected_morphology_type = 0;
    static float radius[2] = {20, 20};
    static Color cover_color(1, 0, 0, 0.2);
    static Color bounds_color(0, 1, 0, 0.1);
    static float offset[2] = {500, 400};
    static float rotation = 0;
    static float scale[2] = {0.65, 0.65};
    static float skew[2] = {0, 0};
    static float path_rect[4] = {0, 0,
                                 static_cast<float>(boston->GetSize().width),
                                 static_cast<float>(boston->GetSize().height)};
    static float effect_transform_scale = 1;

    ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
    {
      ImGui::Combo("Morphology type", &selected_morphology_type,
                   morphology_type_names,
                   sizeof(morphology_type_names) / sizeof(char*));
      ImGui::SliderFloat2("Radius", radius, 0, 200);
      ImGui::SliderFloat("Input opacity", &input_color.alpha, 0, 1);
      ImGui::ColorEdit4("Cover color", reinterpret_cast<float*>(&cover_color));
      ImGui::ColorEdit4("Bounds color",
                        reinterpret_cast<float*>(&bounds_color));
      ImGui::SliderFloat2("Translation", offset, 0,
                          pass.GetRenderTargetSize().width);
      ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
      ImGui::SliderFloat2("Scale", scale, 0, 3);
      ImGui::SliderFloat2("Skew", skew, -3, 3);
      ImGui::SliderFloat4("Path XYWH", path_rect, -1000, 1000);
      ImGui::SliderFloat("Effect transform scale", &effect_transform_scale, 0,
                         3);
    }
    ImGui::End();

    std::shared_ptr<Contents> input;
    Size input_size;

    auto input_rect =
        Rect::MakeXYWH(path_rect[0], path_rect[1], path_rect[2], path_rect[3]);
    auto texture = std::make_shared<TextureContents>();
    texture->SetSourceRect(Rect::MakeSize(boston->GetSize()));
    texture->SetDestinationRect(input_rect);
    texture->SetTexture(boston);
    texture->SetOpacity(input_color.alpha);

    input = texture;
    input_size = input_rect.GetSize();

    auto contents = FilterContents::MakeMorphology(
        FilterInput::Make(input), Radius{radius[0]}, Radius{radius[1]},
        morphology_types[selected_morphology_type]);
    contents->SetEffectTransform(Matrix::MakeScale(
        Vector2{effect_transform_scale, effect_transform_scale}));

    auto ctm = Matrix::MakeScale(GetContentScale()) *
               Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
               Matrix::MakeRotationZ(Radians(rotation)) *
               Matrix::MakeScale(Vector2(scale[0], scale[1])) *
               Matrix::MakeSkew(skew[0], skew[1]) *
               Matrix::MakeTranslation(-Point(input_size) / 2);

    Entity entity;
    entity.SetContents(contents);
    entity.SetTransform(ctm);

    entity.Render(context, pass);

    // Renders a red "cover" rectangle that shows the original position of the
    // unfiltered input.
    Entity cover_entity;
    cover_entity.SetContents(SolidColorContents::Make(
        PathBuilder{}.AddRect(input_rect).TakePath(), cover_color));
    cover_entity.SetTransform(ctm);

    cover_entity.Render(context, pass);

    // Renders a green bounding rect of the target filter.
    Entity bounds_entity;
    bounds_entity.SetContents(SolidColorContents::Make(
        PathBuilder{}.AddRect(contents->GetCoverage(entity).value()).TakePath(),
        bounds_color));
    bounds_entity.SetTransform(Matrix());

    bounds_entity.Render(context, pass);

    return true;
  };
  ASSERT_TRUE(OpenPlaygroundHere(callback));
}

TEST_P(EntityTest, SetBlendMode) {
  Entity entity;
  ASSERT_EQ(entity.GetBlendMode(), BlendMode::kSourceOver);
  entity.SetBlendMode(BlendMode::kClear);
  ASSERT_EQ(entity.GetBlendMode(), BlendMode::kClear);
}

TEST_P(EntityTest, ContentsGetBoundsForEmptyPathReturnsNullopt) {
  Entity entity;
  entity.SetContents(std::make_shared<SolidColorContents>());
  ASSERT_FALSE(entity.GetCoverage().has_value());
}

TEST_P(EntityTest, SolidStrokeCoverageIsCorrect) {
  {
    auto geometry = Geometry::MakeStrokePath(
        PathBuilder{}.AddLine({0, 0}, {10, 10}).TakePath(), 4.0, 4.0,
        Cap::kButt, Join::kBevel);

    Entity entity;
    auto contents = std::make_unique<SolidColorContents>();
    contents->SetGeometry(std::move(geometry));
    contents->SetColor(Color::Black());
    entity.SetContents(std::move(contents));
    auto actual = entity.GetCoverage();
    auto expected = Rect::MakeLTRB(-2, -2, 12, 12);
    ASSERT_TRUE(actual.has_value());
    ASSERT_RECT_NEAR(actual.value(), expected);
  }

  // Cover the Cap::kSquare case.
  {
    auto geometry = Geometry::MakeStrokePath(
        PathBuilder{}.AddLine({0, 0}, {10, 10}).TakePath(), 4.0, 4.0,
        Cap::kSquare, Join::kBevel);

    Entity entity;
    auto contents = std::make_unique<SolidColorContents>();
    contents->SetGeometry(std::move(geometry));
    contents->SetColor(Color::Black());
    entity.SetContents(std::move(contents));
    auto actual = entity.GetCoverage();
    auto expected =
        Rect::MakeLTRB(-sqrt(8), -sqrt(8), 10 + sqrt(8), 10 + sqrt(8));
    ASSERT_TRUE(actual.has_value());
    ASSERT_RECT_NEAR(actual.value(), expected);
  }

  // Cover the Join::kMiter case.
  {
    auto geometry = Geometry::MakeStrokePath(
        PathBuilder{}.AddLine({0, 0}, {10, 10}).TakePath(), 4.0, 2.0,
        Cap::kSquare, Join::kMiter);

    Entity entity;
    auto contents = std::make_unique<SolidColorContents>();
    contents->SetGeometry(std::move(geometry));
    contents->SetColor(Color::Black());
    entity.SetContents(std::move(contents));
    auto actual = entity.GetCoverage();
    auto expected = Rect::MakeLTRB(-4, -4, 14, 14);
    ASSERT_TRUE(actual.has_value());
    ASSERT_RECT_NEAR(actual.value(), expected);
  }
}

TEST_P(EntityTest, BorderMaskBlurCoverageIsCorrect) {
  auto fill = std::make_shared<SolidColorContents>();
  fill->SetGeometry(Geometry::MakeFillPath(
      PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()));
  fill->SetColor(Color::CornflowerBlue());
  auto border_mask_blur = FilterContents::MakeBorderMaskBlur(
      FilterInput::Make(fill), Radius{3}, Radius{4});

  {
    Entity e;
    e.SetTransform(Matrix());
    auto actual = border_mask_blur->GetCoverage(e);
    auto expected = Rect::MakeXYWH(-3, -4, 306, 408);
    ASSERT_TRUE(actual.has_value());
    ASSERT_RECT_NEAR(actual.value(), expected);
  }

  {
    Entity e;
    e.SetTransform(Matrix::MakeRotationZ(Radians{kPi / 4}));
    auto actual = border_mask_blur->GetCoverage(e);
    auto expected = Rect::MakeXYWH(-287.792, -4.94975, 504.874, 504.874);
    ASSERT_TRUE(actual.has_value());
    ASSERT_RECT_NEAR(actual.value(), expected);
  }
}

TEST_P(EntityTest, DrawAtlasNoColor) {
  // Draws the image as four squares stiched together.
  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
  auto size = atlas->GetSize();
  // Divide image into four quadrants.
  Scalar half_width = size.width / 2;
  Scalar half_height = size.height / 2;
  std::vector<Rect> texture_coordinates = {
      Rect::MakeLTRB(0, 0, half_width, half_height),
      Rect::MakeLTRB(half_width, 0, size.width, half_height),
      Rect::MakeLTRB(0, half_height, half_width, size.height),
      Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
  // Position quadrants adjacent to eachother.
  std::vector<Matrix> transforms = {
      Matrix::MakeTranslation({0, 0, 0}),
      Matrix::MakeTranslation({half_width, 0, 0}),
      Matrix::MakeTranslation({0, half_height, 0}),
      Matrix::MakeTranslation({half_width, half_height, 0})};
  std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();

  contents->SetTransforms(std::move(transforms));
  contents->SetTextureCoordinates(std::move(texture_coordinates));
  contents->SetTexture(atlas);
  contents->SetBlendMode(BlendMode::kSource);

  Entity e;
  e.SetTransform(Matrix::MakeScale(GetContentScale()));
  e.SetContents(contents);

  ASSERT_TRUE(OpenPlaygroundHere(std::move(e)));
}

TEST_P(EntityTest, DrawAtlasWithColorAdvanced) {
  // Draws the image as four squares stiched together.
  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
  auto size = atlas->GetSize();
  // Divide image into four quadrants.
  Scalar half_width = size.width / 2;
  Scalar half_height = size.height / 2;
  std::vector<Rect> texture_coordinates = {
      Rect::MakeLTRB(0, 0, half_width, half_height),
      Rect::MakeLTRB(half_width, 0, size.width, half_height),
      Rect::MakeLTRB(0, half_height, half_width, size.height),
      Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
  // Position quadrants adjacent to eachother.
  std::vector<Matrix> transforms = {
      Matrix::MakeTranslation({0, 0, 0}),
      Matrix::MakeTranslation({half_width, 0, 0}),
      Matrix::MakeTranslation({0, half_height, 0}),
      Matrix::MakeTranslation({half_width, half_height, 0})};
  std::vector<Color> colors = {Color::Red(), Color::Green(), Color::Blue(),
                               Color::Yellow()};
  std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();

  contents->SetTransforms(std::move(transforms));
  contents->SetTextureCoordinates(std::move(texture_coordinates));
  contents->SetTexture(atlas);
  contents->SetColors(colors);
  contents->SetBlendMode(BlendMode::kModulate);

  Entity e;
  e.SetTransform(Matrix::MakeScale(GetContentScale()));
  e.SetContents(contents);

  ASSERT_TRUE(OpenPlaygroundHere(std::move(e)));
}

TEST_P(EntityTest, DrawAtlasWithColorSimple) {
  // Draws the image as four squares stiched together. Because blend modes
  // aren't implented this ends up as four solid color blocks.
  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
  auto size = atlas->GetSize();
  // Divide image into four quadrants.
  Scalar half_width = size.width / 2;
  Scalar half_height = size.height / 2;
  std::vector<Rect> texture_coordinates = {
      Rect::MakeLTRB(0, 0, half_width, half_height),
      Rect::MakeLTRB(half_width, 0, size.width, half_height),
      Rect::MakeLTRB(0, half_height, half_width, size.height),
      Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
  // Position quadrants adjacent to eachother.
  std::vector<Matrix> transforms = {
      Matrix::MakeTranslation({0, 0, 0}),
      Matrix::MakeTranslation({half_width, 0, 0}),
      Matrix::MakeTranslation({0, half_height, 0}),
      Matrix::MakeTranslation({half_width, half_height, 0})};
  std::vector<Color> colors = {Color::Red(), Color::Green(), Color::Blue(),
                               Color::Yellow()};
  std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();

  contents->SetTransforms(std::move(transforms));
  contents->SetTextureCoordinates(std::move(texture_coordinates));
  contents->SetTexture(atlas);
  contents->SetColors(colors);
  contents->SetBlendMode(BlendMode::kSourceATop);

  Entity e;
  e.SetTransform(Matrix::MakeScale(GetContentScale()));
  e.SetContents(contents);

  ASSERT_TRUE(OpenPlaygroundHere(std::move(e)));
}

TEST_P(EntityTest, DrawAtlasUsesProvidedCullRectForCoverage) {
  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
  auto size = atlas->GetSize();

  Scalar half_width = size.width / 2;
  Scalar half_height = size.height / 2;
  std::vector<Rect> texture_coordinates = {
      Rect::MakeLTRB(0, 0, half_width, half_height),
      Rect::MakeLTRB(half_width, 0, size.width, half_height),
      Rect::MakeLTRB(0, half_height, half_width, size.height),
      Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
  std::vector<Matrix> transforms = {
      Matrix::MakeTranslation({0, 0, 0}),
      Matrix::MakeTranslation({half_width, 0, 0}),
      Matrix::MakeTranslation({0, half_height, 0}),
      Matrix::MakeTranslation({half_width, half_height, 0})};

  std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();

  contents->SetTransforms(std::move(transforms));
  contents->SetTextureCoordinates(std::move(texture_coordinates));
  contents->SetTexture(atlas);
  contents->SetBlendMode(BlendMode::kSource);

  auto transform = Matrix::MakeScale(GetContentScale());
  Entity e;
  e.SetTransform(transform);
  e.SetContents(contents);

  ASSERT_EQ(contents->GetCoverage(e).value(),
            Rect::MakeSize(size).TransformBounds(transform));

  contents->SetCullRect(Rect::MakeLTRB(0, 0, 10, 10));

  ASSERT_EQ(contents->GetCoverage(e).value(),
            Rect::MakeLTRB(0, 0, 10, 10).TransformBounds(transform));
}

TEST_P(EntityTest, DrawAtlasWithOpacity) {
  // Draws the image as four squares stiched together slightly
  // opaque
  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
  auto size = atlas->GetSize();
  // Divide image into four quadrants.
  Scalar half_width = size.width / 2;
  Scalar half_height = size.height / 2;
  std::vector<Rect> texture_coordinates = {
      Rect::MakeLTRB(0, 0, half_width, half_height),
      Rect::MakeLTRB(half_width, 0, size.width, half_height),
      Rect::MakeLTRB(0, half_height, half_width, size.height),
      Rect::MakeLTRB(half_width, half_height, size.width, size.height)};
  // Position quadrants adjacent to eachother.
  std::vector<Matrix> transforms = {
      Matrix::MakeTranslation({0, 0, 0}),
      Matrix::MakeTranslation({half_width, 0, 0}),
      Matrix::MakeTranslation({0, half_height, 0}),
      Matrix::MakeTranslation({half_width, half_height, 0})};

  std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();

  contents->SetTransforms(std::move(transforms));
  contents->SetTextureCoordinates(std::move(texture_coordinates));
  contents->SetTexture(atlas);
  contents->SetBlendMode(BlendMode::kSource);
  contents->SetAlpha(0.5);

  Entity e;
  e.SetTransform(Matrix::MakeScale(GetContentScale()));
  e.SetContents(contents);

  ASSERT_TRUE(OpenPlaygroundHere(std::move(e)));
}

TEST_P(EntityTest, DrawAtlasNoColorFullSize) {
  auto atlas = CreateTextureForFixture("bay_bridge.jpg");
  auto size = atlas->GetSize();
  std::vector<Rect> texture_coordinates = {
      Rect::MakeLTRB(0, 0, size.width, size.height)};
  std::vector<Matrix> transforms = {Matrix::MakeTranslation({0, 0, 0})};
  std::shared_ptr<AtlasContents> contents = std::make_shared<AtlasContents>();

  contents->SetTransforms(std::move(transforms));
  contents->SetTextureCoordinates(std::move(texture_coordinates));
  contents->SetTexture(atlas);
  contents->SetBlendMode(BlendMode::kSource);

  Entity e;
  e.SetTransform(Matrix::MakeScale(GetContentScale()));
  e.SetContents(contents);

  ASSERT_TRUE(OpenPlaygroundHere(std::move(e)));
}

TEST_P(EntityTest, SolidFillCoverageIsCorrect) {
  // No transform
  {
    auto fill = std::make_shared<SolidColorContents>();
    fill->SetColor(Color::CornflowerBlue());
    auto expected = Rect::MakeLTRB(100, 110, 200, 220);
    fill->SetGeometry(
        Geometry::MakeFillPath(PathBuilder{}.AddRect(expected).TakePath()));

    auto coverage = fill->GetCoverage({});
    ASSERT_TRUE(coverage.has_value());
    ASSERT_RECT_NEAR(coverage.value(), expected);
  }

  // Entity transform
  {
    auto fill = std::make_shared<SolidColorContents>();
    fill->SetColor(Color::CornflowerBlue());
    fill->SetGeometry(Geometry::MakeFillPath(
        PathBuilder{}.AddRect(Rect::MakeLTRB(100, 110, 200, 220)).TakePath()));

    Entity entity;
    entity.SetTransform(Matrix::MakeTranslation(Vector2(4, 5)));
    entity.SetContents(std::move(fill));

    auto coverage = entity.GetCoverage();
    auto expected = Rect::MakeLTRB(104, 115, 204, 225);
    ASSERT_TRUE(coverage.has_value());
    ASSERT_RECT_NEAR(coverage.value(), expected);
  }

  // No coverage for fully transparent colors
  {
    auto fill = std::make_shared<SolidColorContents>();
    fill->SetColor(Color::WhiteTransparent());
    fill->SetGeometry(Geometry::MakeFillPath(
        PathBuilder{}.AddRect(Rect::MakeLTRB(100, 110, 200, 220)).TakePath()));

    auto coverage = fill->GetCoverage({});
    ASSERT_FALSE(coverage.has_value());
  }
}

TEST_P(EntityTest, SolidFillShouldRenderIsCorrect) {
  // No path.
  {
    auto fill = std::make_shared<SolidColorContents>();
    fill->SetColor(Color::CornflowerBlue());
    ASSERT_FALSE(fill->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
    ASSERT_FALSE(
        fill->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
  }

  // With path.
  {
    auto fill = std::make_shared<SolidColorContents>();
    fill->SetColor(Color::CornflowerBlue());
    fill->SetGeometry(Geometry::MakeFillPath(
        PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath()));
    ASSERT_TRUE(fill->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
    ASSERT_FALSE(
        fill->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
  }

  // With paint cover.
  {
    auto fill = std::make_shared<SolidColorContents>();
    fill->SetColor(Color::CornflowerBlue());
    fill->SetGeometry(Geometry::MakeCover());
    ASSERT_TRUE(fill->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
    ASSERT_TRUE(
        fill->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
  }
}

TEST_P(EntityTest, DoesNotCullEntitiesByDefault) {
  auto fill = std::make_shared<SolidColorContents>();
  fill->SetColor(Color::CornflowerBlue());
  fill->SetGeometry(
      Geometry::MakeRect(Rect::MakeLTRB(-1000, -1000, -900, -900)));

  Entity entity;
  entity.SetContents(fill);

  // Even though the entity is offscreen, this should still render because we do
  // not compute the coverage intersection by default.
  EXPECT_TRUE(entity.ShouldRender(Rect::MakeLTRB(0, 0, 100, 100)));
}

TEST_P(EntityTest, ClipContentsShouldRenderIsCorrect) {
  // For clip ops, `ShouldRender` should always return true.

  // Clip.
  {
    auto clip = std::make_shared<ClipContents>();
    ASSERT_TRUE(clip->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
    clip->SetGeometry(Geometry::MakeFillPath(
        PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath()));
    ASSERT_TRUE(clip->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
    ASSERT_TRUE(
        clip->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
  }

  // Clip restore.
  {
    auto restore = std::make_shared<ClipRestoreContents>();
    ASSERT_TRUE(
        restore->ShouldRender(Entity{}, Rect::MakeSize(Size{100, 100})));
    ASSERT_TRUE(
        restore->ShouldRender(Entity{}, Rect::MakeLTRB(-100, -100, -50, -50)));
  }
}

TEST_P(EntityTest, ClipContentsGetClipCoverageIsCorrect) {
  // Intersection: No stencil coverage, no geometry.
  {
    auto clip = std::make_shared<ClipContents>();
    clip->SetClipOperation(Entity::ClipOperation::kIntersect);
    auto result = clip->GetClipCoverage(Entity{}, Rect{});

    ASSERT_FALSE(result.coverage.has_value());
  }

  // Intersection: No stencil coverage, with geometry.
  {
    auto clip = std::make_shared<ClipContents>();
    clip->SetClipOperation(Entity::ClipOperation::kIntersect);
    clip->SetGeometry(Geometry::MakeFillPath(
        PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 100, 100)).TakePath()));
    auto result = clip->GetClipCoverage(Entity{}, Rect{});

    ASSERT_FALSE(result.coverage.has_value());
  }

  // Intersection: With stencil coverage, no geometry.
  {
    auto clip = std::make_shared<ClipContents>();
    clip->SetClipOperation(Entity::ClipOperation::kIntersect);
    auto result =
        clip->GetClipCoverage(Entity{}, Rect::MakeLTRB(0, 0, 100, 100));

    ASSERT_FALSE(result.coverage.has_value());
  }

  // Intersection: With stencil coverage, with geometry.
  {
    auto clip = std::make_shared<ClipContents>();
    clip->SetClipOperation(Entity::ClipOperation::kIntersect);
    clip->SetGeometry(Geometry::MakeFillPath(
        PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 50, 50)).TakePath()));
    auto result =
        clip->GetClipCoverage(Entity{}, Rect::MakeLTRB(0, 0, 100, 100));

    ASSERT_TRUE(result.coverage.has_value());
    ASSERT_RECT_NEAR(result.coverage.value(), Rect::MakeLTRB(0, 0, 50, 50));
    ASSERT_EQ(result.type, Contents::ClipCoverage::Type::kAppend);
  }

  // Difference: With stencil coverage, with geometry.
  {
    auto clip = std::make_shared<ClipContents>();
    clip->SetClipOperation(Entity::ClipOperation::kDifference);
    clip->SetGeometry(Geometry::MakeFillPath(
        PathBuilder{}.AddRect(Rect::MakeLTRB(0, 0, 50, 50)).TakePath()));
    auto result =
        clip->GetClipCoverage(Entity{}, Rect::MakeLTRB(0, 0, 100, 100));

    ASSERT_TRUE(result.coverage.has_value());
    ASSERT_RECT_NEAR(result.coverage.value(), Rect::MakeLTRB(0, 0, 100, 100));
    ASSERT_EQ(result.type, Contents::ClipCoverage::Type::kAppend);
  }
}

TEST_P(EntityTest, RRectShadowTest) {
  auto callback = [&](ContentContext& context, RenderPass& pass) {
    static Color color = Color::Red();
    static float corner_radius = 100;
    static float blur_radius = 100;
    static bool show_coverage = false;
    static Color coverage_color = Color::Green().WithAlpha(0.2);

    ImGui::Begin("Controls", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
    ImGui::SliderFloat("Corner radius", &corner_radius, 0, 300);
    ImGui::SliderFloat("Blur radius", &blur_radius, 0, 300);
    ImGui::ColorEdit4("Color", reinterpret_cast<Scalar*>(&color));
    ImGui::Checkbox("Show coverage", &show_coverage);
    if (show_coverage) {
      ImGui::ColorEdit4("Coverage color",
                        reinterpret_cast<Scalar*>(&coverage_color));
    }
    ImGui::End();

    static PlaygroundPoint top_left_point(Point(200, 200), 30, Color::White());
    static PlaygroundPoint bottom_right_point(Point(600, 400), 30,
                                              Color::White());
    auto [top_left, bottom_right] =
        DrawPlaygroundLine(top_left_point, bottom_right_point);
    auto rect =
        Rect::MakeLTRB(top_left.x, top_left.y, bottom_right.x, bottom_right.y);

    auto contents = std::make_unique<SolidRRectBlurContents>();
    contents->SetRRect(rect, {corner_radius, corner_radius});
    contents->SetColor(color);
    contents->SetSigma(Radius(blur_radius));

    Entity entity;
    entity.SetTransform(Matrix::MakeScale(GetContentScale()));
    entity.SetContents(std::move(contents));
    entity.Render(context, pass);

    auto coverage = entity.GetCoverage();
    if (show_coverage && coverage.has_value()) {
      auto bounds_contents = std::make_unique<SolidColorContents>();
      bounds_contents->SetGeometry(Geometry::MakeFillPath(
          PathBuilder{}.AddRect(entity.GetCoverage().value()).TakePath()));
      bounds_contents->SetColor(coverage_color.Premultiply());
      Entity bounds_entity;
      bounds_entity.SetContents(std::move(bounds_contents));
      bounds_entity.Render(context, pass);
    }

    return true;
  };
  ASSERT_TRUE(OpenPlaygroundHere(callback));
}

TEST_P(EntityTest, ColorMatrixFilterCoverageIsCorrect) {
  // Set up a simple color background.
  auto fill = std::make_shared<SolidColorContents>();
  fill->SetGeometry(Geometry::MakeFillPath(
      PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()));
  fill->SetColor(Color::Coral());

  // Set the color matrix filter.
  ColorMatrix matrix = {
      1, 1, 1, 1, 1,  //
      1, 1, 1, 1, 1,  //
      1, 1, 1, 1, 1,  //
      1, 1, 1, 1, 1,  //
  };

  auto filter =
      ColorFilterContents::MakeColorMatrix(FilterInput::Make(fill), matrix);

  Entity e;
  e.SetTransform(Matrix());

  // Confirm that the actual filter coverage matches the expected coverage.
  auto actual = filter->GetCoverage(e);
  auto expected = Rect::MakeXYWH(0, 0, 300, 400);

  ASSERT_TRUE(actual.has_value());
  ASSERT_RECT_NEAR(actual.value(), expected);
}

TEST_P(EntityTest, ColorMatrixFilterEditable) {
  auto bay_bridge = CreateTextureForFixture("bay_bridge.jpg");
  ASSERT_TRUE(bay_bridge);

  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
    // UI state.
    static ColorMatrix color_matrix = {
        1, 0, 0, 0, 0,  //
        0, 3, 0, 0, 0,  //
        0, 0, 1, 0, 0,  //
        0, 0, 0, 1, 0,  //
    };
    static float offset[2] = {500, 400};
    static float rotation = 0;
    static float scale[2] = {0.65, 0.65};
    static float skew[2] = {0, 0};

    // Define the ImGui
    ImGui::Begin("Color Matrix", nullptr, ImGuiWindowFlags_AlwaysAutoResize);
    {
      std::string label = "##1";
      for (int i = 0; i < 20; i += 5) {
        ImGui::InputScalarN(label.c_str(), ImGuiDataType_Float,
                            &(color_matrix.array[i]), 5, nullptr, nullptr,
                            "%.2f", 0);
        label[2]++;
      }

      ImGui::SliderFloat2("Translation", &offset[0], 0,
                          pass.GetRenderTargetSize().width);
      ImGui::SliderFloat("Rotation", &rotation, 0, kPi * 2);
      ImGui::SliderFloat2("Scale", &scale[0], 0, 3);
      ImGui::SliderFloat2("Skew", &skew[0], -3, 3);
    }
    ImGui::End();

    // Set the color matrix filter.
    auto filter = ColorFilterContents::MakeColorMatrix(
        FilterInput::Make(bay_bridge), color_matrix);

    // Define the entity with the color matrix filter.
    Entity entity;
    entity.SetTransform(
        Matrix::MakeScale(GetContentScale()) *
        Matrix::MakeTranslation(Vector3(offset[0], offset[1])) *
        Matrix::MakeRotationZ(Radians(rotation)) *
        Matrix::MakeScale(Vector2(scale[0], scale[1])) *
        Matrix::MakeSkew(skew[0], skew[1]) *
        Matrix::MakeTranslation(-Point(bay_bridge->GetSize()) / 2));
    entity.SetContents(filter);
    entity.Render(context, pass);

    return true;
  };

  ASSERT_TRUE(OpenPlaygroundHere(callback));
}

TEST_P(EntityTest, LinearToSrgbFilterCoverageIsCorrect) {
  // Set up a simple color background.
  auto fill = std::make_shared<SolidColorContents>();
  fill->SetGeometry(Geometry::MakeFillPath(
      PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()));
  fill->SetColor(Color::MintCream());

  auto filter =
      ColorFilterContents::MakeLinearToSrgbFilter(FilterInput::Make(fill));

  Entity e;
  e.SetTransform(Matrix());

  // Confirm that the actual filter coverage matches the expected coverage.
  auto actual = filter->GetCoverage(e);
  auto expected = Rect::MakeXYWH(0, 0, 300, 400);

  ASSERT_TRUE(actual.has_value());
  ASSERT_RECT_NEAR(actual.value(), expected);
}

TEST_P(EntityTest, LinearToSrgbFilter) {
  auto image = CreateTextureForFixture("kalimba.jpg");
  ASSERT_TRUE(image);

  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
    auto filtered =
        ColorFilterContents::MakeLinearToSrgbFilter(FilterInput::Make(image));

    // Define the entity that will serve as the control image as a Gaussian blur
    // filter with no filter at all.
    Entity entity_left;
    entity_left.SetTransform(Matrix::MakeScale(GetContentScale()) *
                             Matrix::MakeTranslation({100, 300}) *
                             Matrix::MakeScale(Vector2{0.5, 0.5}));
    auto unfiltered = FilterContents::MakeGaussianBlur(FilterInput::Make(image),
                                                       Sigma{0}, Sigma{0});
    entity_left.SetContents(unfiltered);

    // Define the entity that will be filtered from linear to sRGB.
    Entity entity_right;
    entity_right.SetTransform(Matrix::MakeScale(GetContentScale()) *
                              Matrix::MakeTranslation({500, 300}) *
                              Matrix::MakeScale(Vector2{0.5, 0.5}));
    entity_right.SetContents(filtered);
    return entity_left.Render(context, pass) &&
           entity_right.Render(context, pass);
  };

  ASSERT_TRUE(OpenPlaygroundHere(callback));
}

TEST_P(EntityTest, SrgbToLinearFilterCoverageIsCorrect) {
  // Set up a simple color background.
  auto fill = std::make_shared<SolidColorContents>();
  fill->SetGeometry(Geometry::MakeFillPath(
      PathBuilder{}.AddRect(Rect::MakeXYWH(0, 0, 300, 400)).TakePath()));
  fill->SetColor(Color::DeepPink());

  auto filter =
      ColorFilterContents::MakeSrgbToLinearFilter(FilterInput::Make(fill));

  Entity e;
  e.SetTransform(Matrix());

  // Confirm that the actual filter coverage matches the expected coverage.
  auto actual = filter->GetCoverage(e);
  auto expected = Rect::MakeXYWH(0, 0, 300, 400);

  ASSERT_TRUE(actual.has_value());
  ASSERT_RECT_NEAR(actual.value(), expected);
}

TEST_P(EntityTest, SrgbToLinearFilter) {
  auto image = CreateTextureForFixture("embarcadero.jpg");
  ASSERT_TRUE(image);

  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
    auto filtered =
        ColorFilterContents::MakeSrgbToLinearFilter(FilterInput::Make(image));

    // Define the entity that will serve as the control image as a Gaussian blur
    // filter with no filter at all.
    Entity entity_left;
    entity_left.SetTransform(Matrix::MakeScale(GetContentScale()) *
                             Matrix::MakeTranslation({100, 300}) *
                             Matrix::MakeScale(Vector2{0.5, 0.5}));
    auto unfiltered = FilterContents::MakeGaussianBlur(FilterInput::Make(image),
                                                       Sigma{0}, Sigma{0});
    entity_left.SetContents(unfiltered);

    // Define the entity that will be filtered from sRGB to linear.
    Entity entity_right;
    entity_right.SetTransform(Matrix::MakeScale(GetContentScale()) *
                              Matrix::MakeTranslation({500, 300}) *
                              Matrix::MakeScale(Vector2{0.5, 0.5}));
    entity_right.SetContents(filtered);
    return entity_left.Render(context, pass) &&
           entity_right.Render(context, pass);
  };

  ASSERT_TRUE(OpenPlaygroundHere(callback));
}

TEST_P(EntityTest, AtlasContentsSubAtlas) {
  auto boston = CreateTextureForFixture("boston.jpg");

  {
    auto contents = std::make_shared<AtlasContents>();
    contents->SetBlendMode(BlendMode::kSourceOver);
    contents->SetTexture(boston);
    contents->SetColors({
        Color::Red(),
        Color::Red(),
        Color::Red(),
    });
    contents->SetTextureCoordinates({
        Rect::MakeLTRB(0, 0, 10, 10),
        Rect::MakeLTRB(0, 0, 10, 10),
        Rect::MakeLTRB(0, 0, 10, 10),
    });
    contents->SetTransforms({
        Matrix::MakeTranslation(Vector2(0, 0)),
        Matrix::MakeTranslation(Vector2(100, 100)),
        Matrix::MakeTranslation(Vector2(200, 200)),
    });

    // Since all colors and sample rects are the same, there should
    // only be a single entry in the sub atlas.
    auto subatlas = contents->GenerateSubAtlas();
    ASSERT_EQ(subatlas->sub_texture_coords.size(), 1u);
  }

  {
    auto contents = std::make_shared<AtlasContents>();
    contents->SetBlendMode(BlendMode::kSourceOver);
    contents->SetTexture(boston);
    contents->SetColors({
        Color::Red(),
        Color::Green(),
        Color::Blue(),
    });
    contents->SetTextureCoordinates({
        Rect::MakeLTRB(0, 0, 10, 10),
        Rect::MakeLTRB(0, 0, 10, 10),
        Rect::MakeLTRB(0, 0, 10, 10),
    });
    contents->SetTransforms({
        Matrix::MakeTranslation(Vector2(0, 0)),
        Matrix::MakeTranslation(Vector2(100, 100)),
        Matrix::MakeTranslation(Vector2(200, 200)),
    });

    // Since all colors are different, there are three entires.
    auto subatlas = contents->GenerateSubAtlas();
    ASSERT_EQ(subatlas->sub_texture_coords.size(), 3u);

    // The translations are kept but the sample rects point into
    // different parts of the sub atlas.
    ASSERT_EQ(subatlas->result_texture_coords[0], Rect::MakeXYWH(0, 0, 10, 10));
    ASSERT_EQ(subatlas->result_texture_coords[1],
              Rect::MakeXYWH(11, 0, 10, 10));
    ASSERT_EQ(subatlas->result_texture_coords[2],
              Rect::MakeXYWH(22, 0, 10, 10));
  }
}

static Vector3 RGBToYUV(Vector3 rgb, YUVColorSpace yuv_color_space) {
  Vector3 yuv;
  switch (yuv_color_space) {
    case YUVColorSpace::kBT601FullRange:
      yuv.x = rgb.x * 0.299 + rgb.y * 0.587 + rgb.z * 0.114;
      yuv.y = rgb.x * -0.169 + rgb.y * -0.331 + rgb.z * 0.5 + 0.5;
      yuv.z = rgb.x * 0.5 + rgb.y * -0.419 + rgb.z * -0.081 + 0.5;
      break;
    case YUVColorSpace::kBT601LimitedRange:
      yuv.x = rgb.x * 0.257 + rgb.y * 0.516 + rgb.z * 0.100 + 0.063;
      yuv.y = rgb.x * -0.145 + rgb.y * -0.291 + rgb.z * 0.439 + 0.5;
      yuv.z = rgb.x * 0.429 + rgb.y * -0.368 + rgb.z * -0.071 + 0.5;
      break;
  }
  return yuv;
}

static std::vector<std::shared_ptr<Texture>> CreateTestYUVTextures(
    Context* context,
    YUVColorSpace yuv_color_space) {
  Vector3 red = {244.0 / 255.0, 67.0 / 255.0, 54.0 / 255.0};
  Vector3 green = {76.0 / 255.0, 175.0 / 255.0, 80.0 / 255.0};
  Vector3 blue = {33.0 / 255.0, 150.0 / 255.0, 243.0 / 255.0};
  Vector3 white = {1.0, 1.0, 1.0};
  Vector3 red_yuv = RGBToYUV(red, yuv_color_space);
  Vector3 green_yuv = RGBToYUV(green, yuv_color_space);
  Vector3 blue_yuv = RGBToYUV(blue, yuv_color_space);
  Vector3 white_yuv = RGBToYUV(white, yuv_color_space);
  std::vector<Vector3> yuvs{red_yuv, green_yuv, blue_yuv, white_yuv};
  std::vector<uint8_t> y_data;
  std::vector<uint8_t> uv_data;
  for (int i = 0; i < 4; i++) {
    auto yuv = yuvs[i];
    uint8_t y = std::round(yuv.x * 255.0);
    uint8_t u = std::round(yuv.y * 255.0);
    uint8_t v = std::round(yuv.z * 255.0);
    for (int j = 0; j < 16; j++) {
      y_data.push_back(y);
    }
    for (int j = 0; j < 8; j++) {
      uv_data.push_back(j % 2 == 0 ? u : v);
    }
  }
  impeller::TextureDescriptor y_texture_descriptor;
  y_texture_descriptor.storage_mode = impeller::StorageMode::kHostVisible;
  y_texture_descriptor.format = PixelFormat::kR8UNormInt;
  y_texture_descriptor.size = {8, 8};
  auto y_texture =
      context->GetResourceAllocator()->CreateTexture(y_texture_descriptor);
  auto y_mapping = std::make_shared<fml::DataMapping>(y_data);
  if (!y_texture->SetContents(y_mapping)) {
    FML_DLOG(ERROR) << "Could not copy contents into Y texture.";
  }

  impeller::TextureDescriptor uv_texture_descriptor;
  uv_texture_descriptor.storage_mode = impeller::StorageMode::kHostVisible;
  uv_texture_descriptor.format = PixelFormat::kR8G8UNormInt;
  uv_texture_descriptor.size = {4, 4};
  auto uv_texture =
      context->GetResourceAllocator()->CreateTexture(uv_texture_descriptor);
  auto uv_mapping = std::make_shared<fml::DataMapping>(uv_data);
  if (!uv_texture->SetContents(uv_mapping)) {
    FML_DLOG(ERROR) << "Could not copy contents into UV texture.";
  }

  return {y_texture, uv_texture};
}

TEST_P(EntityTest, YUVToRGBFilter) {
  if (GetParam() == PlaygroundBackend::kOpenGLES) {
    // TODO(114588) : Support YUV to RGB filter on OpenGLES backend.
    GTEST_SKIP_("YUV to RGB filter is not supported on OpenGLES backend yet.");
  }

  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
    YUVColorSpace yuv_color_space_array[2]{YUVColorSpace::kBT601FullRange,
                                           YUVColorSpace::kBT601LimitedRange};
    for (int i = 0; i < 2; i++) {
      auto yuv_color_space = yuv_color_space_array[i];
      auto textures =
          CreateTestYUVTextures(GetContext().get(), yuv_color_space);
      auto filter_contents = FilterContents::MakeYUVToRGBFilter(
          textures[0], textures[1], yuv_color_space);
      Entity filter_entity;
      filter_entity.SetContents(filter_contents);
      auto snapshot = filter_contents->RenderToSnapshot(context, filter_entity);

      Entity entity;
      auto contents = TextureContents::MakeRect(Rect::MakeLTRB(0, 0, 256, 256));
      contents->SetTexture(snapshot->texture);
      contents->SetSourceRect(Rect::MakeSize(snapshot->texture->GetSize()));
      entity.SetContents(contents);
      entity.SetTransform(
          Matrix::MakeTranslation({static_cast<Scalar>(100 + 400 * i), 300}));
      entity.Render(context, pass);
    }
    return true;
  };
  ASSERT_TRUE(OpenPlaygroundHere(callback));
}

TEST_P(EntityTest, RuntimeEffect) {
  auto runtime_stages =
      OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
  auto runtime_stage =
      runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
  ASSERT_TRUE(runtime_stage);
  ASSERT_TRUE(runtime_stage->IsDirty());

  bool expect_dirty = true;
  Pipeline<PipelineDescriptor>* first_pipeline = nullptr;
  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
    EXPECT_EQ(runtime_stage->IsDirty(), expect_dirty);

    auto contents = std::make_shared<RuntimeEffectContents>();
    contents->SetGeometry(Geometry::MakeCover());

    contents->SetRuntimeStage(runtime_stage);

    struct FragUniforms {
      Vector2 iResolution;
      Scalar iTime;
    } frag_uniforms = {
        .iResolution = Vector2(GetWindowSize().width, GetWindowSize().height),
        .iTime = static_cast<Scalar>(GetSecondsElapsed()),
    };
    auto uniform_data = std::make_shared<std::vector<uint8_t>>();
    uniform_data->resize(sizeof(FragUniforms));
    memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
    contents->SetUniformData(uniform_data);

    Entity entity;
    entity.SetContents(contents);
    bool result = contents->Render(context, entity, pass);

    if (expect_dirty) {
      EXPECT_NE(first_pipeline, pass.GetCommands().back().pipeline.get());
      first_pipeline = pass.GetCommands().back().pipeline.get();
    } else {
      EXPECT_EQ(pass.GetCommands().back().pipeline.get(), first_pipeline);
    }

    expect_dirty = false;
    return result;
  };

  // Simulate some renders and hot reloading of the shader.
  auto content_context = GetContentContext();
  {
    RenderTarget target;
    testing::MockRenderPass mock_pass(GetContext(), target);
    callback(*content_context, mock_pass);
    callback(*content_context, mock_pass);

    // Dirty the runtime stage.
    runtime_stages = OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
    runtime_stage =
        runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];

    ASSERT_TRUE(runtime_stage->IsDirty());
    expect_dirty = true;

    callback(*content_context, mock_pass);
    callback(*content_context, mock_pass);
  }

  ASSERT_TRUE(OpenPlaygroundHere(callback));
}

TEST_P(EntityTest, RuntimeEffectCanSuccessfullyRender) {
  auto runtime_stages =
      OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
  auto runtime_stage =
      runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
  ASSERT_TRUE(runtime_stage);
  ASSERT_TRUE(runtime_stage->IsDirty());

  auto contents = std::make_shared<RuntimeEffectContents>();
  contents->SetGeometry(Geometry::MakeCover());

  contents->SetRuntimeStage(runtime_stage);

  struct FragUniforms {
    Vector2 iResolution;
    Scalar iTime;
  } frag_uniforms = {
      .iResolution = Vector2(GetWindowSize().width, GetWindowSize().height),
      .iTime = static_cast<Scalar>(GetSecondsElapsed()),
  };
  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
  uniform_data->resize(sizeof(FragUniforms));
  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
  contents->SetUniformData(uniform_data);

  Entity entity;
  entity.SetContents(contents);

  // Create a render target with a depth-stencil, similar to how EntityPass
  // does.
  RenderTarget target =
      GetContentContext()->GetRenderTargetCache()->CreateOffscreenMSAA(
          *GetContext(), {GetWindowSize().width, GetWindowSize().height}, 1,
          "RuntimeEffect Texture");
  testing::MockRenderPass pass(GetContext(), target);

  ASSERT_TRUE(contents->Render(*GetContentContext(), entity, pass));
  ASSERT_EQ(pass.GetCommands().size(), 1u);
  const auto& command = pass.GetCommands()[0];
  ASSERT_TRUE(command.pipeline->GetDescriptor()
                  .GetDepthStencilAttachmentDescriptor()
                  .has_value());
  ASSERT_TRUE(command.pipeline->GetDescriptor()
                  .GetFrontStencilAttachmentDescriptor()
                  .has_value());
}

TEST_P(EntityTest, RuntimeEffectSetsRightSizeWhenUniformIsStruct) {
  if (GetBackend() != PlaygroundBackend::kVulkan) {
    GTEST_SKIP() << "Test only applies to Vulkan";
  }

  auto runtime_stages =
      OpenAssetAsRuntimeStage("runtime_stage_example.frag.iplr");
  auto runtime_stage =
      runtime_stages[PlaygroundBackendToRuntimeStageBackend(GetBackend())];
  ASSERT_TRUE(runtime_stage);
  ASSERT_TRUE(runtime_stage->IsDirty());

  auto contents = std::make_shared<RuntimeEffectContents>();
  contents->SetGeometry(Geometry::MakeCover());

  contents->SetRuntimeStage(runtime_stage);

  struct FragUniforms {
    Vector2 iResolution;
    Scalar iTime;
  } frag_uniforms = {
      .iResolution = Vector2(GetWindowSize().width, GetWindowSize().height),
      .iTime = static_cast<Scalar>(GetSecondsElapsed()),
  };
  auto uniform_data = std::make_shared<std::vector<uint8_t>>();
  uniform_data->resize(sizeof(FragUniforms));
  memcpy(uniform_data->data(), &frag_uniforms, sizeof(FragUniforms));
  contents->SetUniformData(uniform_data);

  Entity entity;
  entity.SetContents(contents);

  auto context = GetContentContext();
  RenderTarget target;
  testing::MockRenderPass pass(GetContext(), target);
  ASSERT_TRUE(contents->Render(*context, entity, pass));
  ASSERT_EQ(pass.GetCommands().size(), 1u);
  const auto& command = pass.GetCommands()[0];
  ASSERT_EQ(command.fragment_bindings.buffers.size(), 1u);
  // 16 bytes:
  //   8 bytes for iResolution
  //   4 bytes for iTime
  //   4 bytes padding
  EXPECT_EQ(command.fragment_bindings.buffers[0].view.resource.range.length,
            16u);
}

TEST_P(EntityTest, InheritOpacityTest) {
  Entity entity;

  // Texture contents can always accept opacity.
  auto texture_contents = std::make_shared<TextureContents>();
  texture_contents->SetOpacity(0.5);
  ASSERT_TRUE(texture_contents->CanInheritOpacity(entity));

  texture_contents->SetInheritedOpacity(0.5);
  ASSERT_EQ(texture_contents->GetOpacity(), 0.25);
  texture_contents->SetInheritedOpacity(0.5);
  ASSERT_EQ(texture_contents->GetOpacity(), 0.25);

  // Solid color contents can accept opacity if their geometry
  // doesn't overlap.
  auto solid_color = std::make_shared<SolidColorContents>();
  solid_color->SetGeometry(
      Geometry::MakeRect(Rect::MakeLTRB(100, 100, 200, 200)));
  solid_color->SetColor(Color::Blue().WithAlpha(0.5));

  ASSERT_TRUE(solid_color->CanInheritOpacity(entity));

  solid_color->SetInheritedOpacity(0.5);
  ASSERT_EQ(solid_color->GetColor().alpha, 0.25);
  solid_color->SetInheritedOpacity(0.5);
  ASSERT_EQ(solid_color->GetColor().alpha, 0.25);

  // Color source contents can accept opacity if their geometry
  // doesn't overlap.
  auto tiled_texture = std::make_shared<TiledTextureContents>();
  tiled_texture->SetGeometry(
      Geometry::MakeRect(Rect::MakeLTRB(100, 100, 200, 200)));
  tiled_texture->SetOpacityFactor(0.5);

  ASSERT_TRUE(tiled_texture->CanInheritOpacity(entity));

  tiled_texture->SetInheritedOpacity(0.5);
  ASSERT_EQ(tiled_texture->GetOpacityFactor(), 0.25);
  tiled_texture->SetInheritedOpacity(0.5);
  ASSERT_EQ(tiled_texture->GetOpacityFactor(), 0.25);

  // Text contents can accept opacity if the text frames do not
  // overlap
  SkFont font = flutter::testing::CreateTestFontOfSize(30);
  auto blob = SkTextBlob::MakeFromString("A", font);
  auto frame = MakeTextFrameFromTextBlobSkia(blob);
  auto lazy_glyph_atlas =
      std::make_shared<LazyGlyphAtlas>(TypographerContextSkia::Make());
  lazy_glyph_atlas->AddTextFrame(*frame, 1.0f);

  auto text_contents = std::make_shared<TextContents>();
  text_contents->SetTextFrame(frame);
  text_contents->SetColor(Color::Blue().WithAlpha(0.5));

  ASSERT_TRUE(text_contents->CanInheritOpacity(entity));

  text_contents->SetInheritedOpacity(0.5);
  ASSERT_EQ(text_contents->GetColor().alpha, 0.25);
  text_contents->SetInheritedOpacity(0.5);
  ASSERT_EQ(text_contents->GetColor().alpha, 0.25);

  // Clips and restores trivially accept opacity.
  ASSERT_TRUE(ClipContents().CanInheritOpacity(entity));
  ASSERT_TRUE(ClipRestoreContents().CanInheritOpacity(entity));

  // Runtime effect contents can't accept opacity.
  auto runtime_effect = std::make_shared<RuntimeEffectContents>();
  ASSERT_FALSE(runtime_effect->CanInheritOpacity(entity));
}

TEST_P(EntityTest, ColorFilterWithForegroundColorAdvancedBlend) {
  auto image = CreateTextureForFixture("boston.jpg");
  auto filter = ColorFilterContents::MakeBlend(
      BlendMode::kColorBurn, FilterInput::Make({image}), Color::Red());

  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
    Entity entity;
    entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
                        Matrix::MakeTranslation({500, 300}) *
                        Matrix::MakeScale(Vector2{0.5, 0.5}));
    entity.SetContents(filter);
    return entity.Render(context, pass);
  };
  ASSERT_TRUE(OpenPlaygroundHere(callback));
}

TEST_P(EntityTest, ColorFilterWithForegroundColorClearBlend) {
  auto image = CreateTextureForFixture("boston.jpg");
  auto filter = ColorFilterContents::MakeBlend(
      BlendMode::kClear, FilterInput::Make({image}), Color::Red());

  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
    Entity entity;
    entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
                        Matrix::MakeTranslation({500, 300}) *
                        Matrix::MakeScale(Vector2{0.5, 0.5}));
    entity.SetContents(filter);
    return entity.Render(context, pass);
  };
  ASSERT_TRUE(OpenPlaygroundHere(callback));
}

TEST_P(EntityTest, ColorFilterWithForegroundColorSrcBlend) {
  auto image = CreateTextureForFixture("boston.jpg");
  auto filter = ColorFilterContents::MakeBlend(
      BlendMode::kSource, FilterInput::Make({image}), Color::Red());

  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
    Entity entity;
    entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
                        Matrix::MakeTranslation({500, 300}) *
                        Matrix::MakeScale(Vector2{0.5, 0.5}));
    entity.SetContents(filter);
    return entity.Render(context, pass);
  };
  ASSERT_TRUE(OpenPlaygroundHere(callback));
}

TEST_P(EntityTest, ColorFilterWithForegroundColorDstBlend) {
  auto image = CreateTextureForFixture("boston.jpg");
  auto filter = ColorFilterContents::MakeBlend(
      BlendMode::kDestination, FilterInput::Make({image}), Color::Red());

  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
    Entity entity;
    entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
                        Matrix::MakeTranslation({500, 300}) *
                        Matrix::MakeScale(Vector2{0.5, 0.5}));
    entity.SetContents(filter);
    return entity.Render(context, pass);
  };
  ASSERT_TRUE(OpenPlaygroundHere(callback));
}

TEST_P(EntityTest, ColorFilterWithForegroundColorSrcInBlend) {
  auto image = CreateTextureForFixture("boston.jpg");
  auto filter = ColorFilterContents::MakeBlend(
      BlendMode::kSourceIn, FilterInput::Make({image}), Color::Red());

  auto callback = [&](ContentContext& context, RenderPass& pass) -> bool {
    Entity entity;
    entity.SetTransform(Matrix::MakeScale(GetContentScale()) *
                        Matrix::MakeTranslation({500, 300}) *
                        Matrix::MakeScale(Vector2{0.5, 0.5}));
    entity.SetContents(filter);
    return entity.Render(context, pass);
  };
  ASSERT_TRUE(OpenPlaygroundHere(callback));
}

TEST_P(EntityTest, CoverageForStrokePathWithNegativeValuesInTransform) {
  auto arrow_head = PathBuilder{}
                        .MoveTo({50, 120})
                        .LineTo({120, 190})
                        .LineTo({190, 120})
                        .TakePath();
  auto geometry = Geometry::MakeStrokePath(arrow_head, 15.0, 4.0, Cap::kRound,
                                           Join::kRound);

  auto transform = Matrix::MakeTranslation({300, 300}) *
                   Matrix::MakeRotationZ(Radians(kPiOver2));
  EXPECT_LT(transform.e[0][0], 0.f);
  auto coverage = geometry->GetCoverage(transform);
  ASSERT_RECT_NEAR(coverage.value(), Rect::MakeXYWH(102.5, 342.5, 85, 155));
}

TEST_P(EntityTest, SolidColorContentsIsOpaque) {
  SolidColorContents contents;
  contents.SetColor(Color::CornflowerBlue());
  ASSERT_TRUE(contents.IsOpaque());
  contents.SetColor(Color::CornflowerBlue().WithAlpha(0.5));
  ASSERT_FALSE(contents.IsOpaque());
}

TEST_P(EntityTest, ConicalGradientContentsIsOpaque) {
  ConicalGradientContents contents;
  contents.SetColors({Color::CornflowerBlue()});
  ASSERT_FALSE(contents.IsOpaque());
  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
  ASSERT_FALSE(contents.IsOpaque());
}

TEST_P(EntityTest, LinearGradientContentsIsOpaque) {
  LinearGradientContents contents;
  contents.SetColors({Color::CornflowerBlue()});
  ASSERT_TRUE(contents.IsOpaque());
  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
  ASSERT_FALSE(contents.IsOpaque());
  contents.SetColors({Color::CornflowerBlue()});
  contents.SetTileMode(Entity::TileMode::kDecal);
  ASSERT_FALSE(contents.IsOpaque());
}

TEST_P(EntityTest, RadialGradientContentsIsOpaque) {
  RadialGradientContents contents;
  contents.SetColors({Color::CornflowerBlue()});
  ASSERT_TRUE(contents.IsOpaque());
  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
  ASSERT_FALSE(contents.IsOpaque());
  contents.SetColors({Color::CornflowerBlue()});
  contents.SetTileMode(Entity::TileMode::kDecal);
  ASSERT_FALSE(contents.IsOpaque());
}

TEST_P(EntityTest, SweepGradientContentsIsOpaque) {
  RadialGradientContents contents;
  contents.SetColors({Color::CornflowerBlue()});
  ASSERT_TRUE(contents.IsOpaque());
  contents.SetColors({Color::CornflowerBlue().WithAlpha(0.5)});
  ASSERT_FALSE(contents.IsOpaque());
  contents.SetColors({Color::CornflowerBlue()});
  contents.SetTileMode(Entity::TileMode::kDecal);
  ASSERT_FALSE(contents.IsOpaque());
}

TEST_P(EntityTest, TiledTextureContentsIsOpaque) {
  auto bay_bridge = CreateTextureForFixture("bay_bridge.jpg");
  TiledTextureContents contents;
  contents.SetTexture(bay_bridge);
  // This is a placeholder test. Images currently never decompress as opaque
  // (whether in Flutter or the playground), and so this should currently always
  // return false in practice.
  ASSERT_FALSE(contents.IsOpaque());
}

TEST_P(EntityTest, PointFieldGeometryDivisions) {
  // Square always gives 4 divisions.
  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(24.0, false), 4u);
  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(2.0, false), 4u);
  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(200.0, false), 4u);

  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(0.5, true), 4u);
  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(1.5, true), 8u);
  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(5.5, true), 24u);
  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(12.5, true), 34u);
  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(22.3, true), 22u);
  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(40.5, true), 40u);
  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(100.0, true), 100u);
  // Caps at 140.
  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(1000.0, true), 140u);
  ASSERT_EQ(PointFieldGeometry::ComputeCircleDivisions(20000.0, true), 140u);
}

TEST_P(EntityTest, PointFieldGeometryCoverage) {
  std::vector<Point> points = {{10, 20}, {100, 200}};
  auto geometry = Geometry::MakePointField(points, 5.0, false);
  ASSERT_EQ(*geometry->GetCoverage(Matrix()), Rect::MakeLTRB(5, 15, 105, 205));
  ASSERT_EQ(*geometry->GetCoverage(Matrix::MakeTranslation({30, 0, 0})),
            Rect::MakeLTRB(35, 15, 135, 205));
}

TEST_P(EntityTest, ColorFilterContentsWithLargeGeometry) {
  Entity entity;
  entity.SetTransform(Matrix::MakeScale(GetContentScale()));
  auto src_contents = std::make_shared<SolidColorContents>();
  src_contents->SetGeometry(
      Geometry::MakeRect(Rect::MakeLTRB(-300, -500, 30000, 50000)));
  src_contents->SetColor(Color::Red());

  auto dst_contents = std::make_shared<SolidColorContents>();
  dst_contents->SetGeometry(
      Geometry::MakeRect(Rect::MakeLTRB(300, 500, 20000, 30000)));
  dst_contents->SetColor(Color::Blue());

  auto contents = ColorFilterContents::MakeBlend(
      BlendMode::kSourceOver, {FilterInput::Make(dst_contents, false),
                               FilterInput::Make(src_contents, false)});
  entity.SetContents(std::move(contents));
  ASSERT_TRUE(OpenPlaygroundHere(std::move(entity)));
}

TEST_P(EntityTest, TextContentsCeilsGlyphScaleToDecimal) {
  ASSERT_EQ(TextFrame::RoundScaledFontSize(0.4321111f, 12), 0.43f);
  ASSERT_EQ(TextFrame::RoundScaledFontSize(0.5321111f, 12), 0.53f);
  ASSERT_EQ(TextFrame::RoundScaledFontSize(2.1f, 12), 2.1f);
  ASSERT_EQ(TextFrame::RoundScaledFontSize(0.0f, 12), 0.0f);
}

TEST_P(EntityTest, AdvancedBlendCoverageHintIsNotResetByEntityPass) {
  if (GetContext()->GetCapabilities()->SupportsFramebufferFetch()) {
    GTEST_SKIP() << "Backends that support framebuffer fetch dont use coverage "
                    "for advanced blends.";
  }

  auto contents = std::make_shared<SolidColorContents>();
  contents->SetGeometry(Geometry::MakeRect(Rect::MakeXYWH(100, 100, 100, 100)));
  contents->SetColor(Color::Red());

  Entity entity;
  entity.SetTransform(Matrix::MakeScale(Vector3(2, 2, 1)));
  entity.SetBlendMode(BlendMode::kColorBurn);
  entity.SetContents(contents);

  auto coverage = entity.GetCoverage();
  EXPECT_TRUE(coverage.has_value());

  auto pass = std::make_unique<EntityPass>();
  std::shared_ptr<RenderTargetCache> render_target_allocator =
      std::make_shared<RenderTargetCache>(GetContext()->GetResourceAllocator());
  auto stencil_config = RenderTarget::AttachmentConfig{
      .storage_mode = StorageMode::kDevicePrivate,
      .load_action = LoadAction::kClear,
      .store_action = StoreAction::kDontCare,
      .clear_color = Color::BlackTransparent()};
  auto rt = render_target_allocator->CreateOffscreen(
      *GetContext(), ISize::MakeWH(1000, 1000),
      /*mip_count=*/1, "Offscreen", RenderTarget::kDefaultColorAttachmentConfig,
      stencil_config);
  auto content_context = ContentContext(
      GetContext(), TypographerContextSkia::Make(), render_target_allocator);
  pass->AddEntity(std::move(entity));

  EXPECT_TRUE(pass->Render(content_context, rt));

  auto contains_size = [&render_target_allocator](ISize size) -> bool {
    return std::find_if(render_target_allocator->GetRenderTargetDataBegin(),
                        render_target_allocator->GetRenderTargetDataEnd(),
                        [&size](const auto& data) {
                          return data.config.size == size;
                        }) != render_target_allocator->GetRenderTargetDataEnd();
  };

  EXPECT_TRUE(contains_size(ISize(1000, 1000)))
      << "The root texture wasn't allocated";
  EXPECT_TRUE(contains_size(ISize(200, 200)))
      << "The ColorBurned texture wasn't allocated (100x100 scales up 2x)";
}

TEST_P(EntityTest, SpecializationConstantsAreAppliedToVariants) {
  auto content_context =
      ContentContext(GetContext(), TypographerContextSkia::Make());

  auto default_color_burn = content_context.GetBlendColorBurnPipeline(
      {.has_depth_stencil_attachments = false});
  auto alt_color_burn = content_context.GetBlendColorBurnPipeline(
      {.has_depth_stencil_attachments = true});

  ASSERT_NE(default_color_burn, alt_color_burn);
  ASSERT_EQ(default_color_burn->GetDescriptor().GetSpecializationConstants(),
            alt_color_burn->GetDescriptor().GetSpecializationConstants());

  auto decal_supported = static_cast<Scalar>(
      GetContext()->GetCapabilities()->SupportsDecalSamplerAddressMode());
  std::vector<Scalar> expected_constants = {5, decal_supported};
  ASSERT_EQ(default_color_burn->GetDescriptor().GetSpecializationConstants(),
            expected_constants);
}

TEST_P(EntityTest, DecalSpecializationAppliedToMorphologyFilter) {
  auto content_context =
      ContentContext(GetContext(), TypographerContextSkia::Make());

  auto default_color_burn = content_context.GetMorphologyFilterPipeline({});

  auto decal_supported = static_cast<Scalar>(
      GetContext()->GetCapabilities()->SupportsDecalSamplerAddressMode());
  std::vector<Scalar> expected_constants = {decal_supported};
  ASSERT_EQ(default_color_burn->GetDescriptor().GetSpecializationConstants(),
            expected_constants);
}

// This doesn't really tell you if the hashes will have frequent
// collisions, but since this type is only used to hash a bounded
// set of options, we can just compare benchmarks.
TEST_P(EntityTest, ContentContextOptionsHasReasonableHashFunctions) {
  ContentContextOptions opts;
  auto hash_a = ContentContextOptions::Hash{}(opts);

  opts.blend_mode = BlendMode::kColorBurn;
  auto hash_b = ContentContextOptions::Hash{}(opts);

  opts.has_depth_stencil_attachments = false;
  auto hash_c = ContentContextOptions::Hash{}(opts);

  opts.primitive_type = PrimitiveType::kPoint;
  auto hash_d = ContentContextOptions::Hash{}(opts);

  EXPECT_NE(hash_a, hash_b);
  EXPECT_NE(hash_b, hash_c);
  EXPECT_NE(hash_c, hash_d);
}

#ifdef FML_OS_LINUX
TEST_P(EntityTest, FramebufferFetchVulkanBindingOffsetIsTheSame) {
  // Using framebuffer fetch on Vulkan requires that we maintain a subpass input
  // binding that we don't have a good route for configuring with the current
  // metadata approach. This test verifies that the binding value doesn't change
  // from the expected constant.
  // See also:
  //   * impeller/renderer/backend/vulkan/binding_helpers_vk.cc
  //   * impeller/entity/shaders/blending/framebuffer_blend.frag
  // This test only works on Linux because macOS hosts incorrectly populate the
  // Vulkan descriptor sets based on the MSL compiler settings.

  bool expected_layout = false;
  for (const DescriptorSetLayout& layout : FramebufferBlendColorBurnPipeline::
           FragmentShader::kDescriptorSetLayouts) {
    if (layout.binding == 64 &&
        layout.descriptor_type == DescriptorType::kInputAttachment) {
      expected_layout = true;
    }
  }
  EXPECT_TRUE(expected_layout);
}
#endif

TEST_P(EntityTest, FillPathGeometryGetPositionBufferReturnsExpectedMode) {
  RenderTarget target;
  testing::MockRenderPass mock_pass(GetContext(), target);

  auto get_result = [this, &mock_pass](const Path& path) {
    auto geometry = Geometry::MakeFillPath(
        path, /* inner rect */ Rect::MakeLTRB(0, 0, 100, 100));
    return geometry->GetPositionBuffer(*GetContentContext(), {}, mock_pass);
  };

  // Convex path
  {
    GeometryResult result =
        get_result(PathBuilder{}
                       .AddRect(Rect::MakeLTRB(0, 0, 100, 100))
                       .SetConvexity(Convexity::kConvex)
                       .TakePath());
    EXPECT_EQ(result.mode, GeometryResult::Mode::kNormal);
  }

  // Concave path
  {
    Path path = PathBuilder{}
                    .MoveTo({0, 0})
                    .LineTo({100, 0})
                    .LineTo({100, 100})
                    .LineTo({50, 50})
                    .Close()
                    .TakePath();
    GeometryResult result = get_result(path);
    if constexpr (ContentContext::kEnableStencilThenCover) {
      EXPECT_EQ(result.mode, GeometryResult::Mode::kNonZero);
    } else {
      EXPECT_EQ(result.mode, GeometryResult::Mode::kNormal);
    }
  }
}

}  // namespace testing
}  // namespace impeller

// NOLINTEND(bugprone-unchecked-optional-access)
