// Copyright 2013 The Flutter Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.

#include "flutter/flow/display_list_canvas.h"
#include "flutter/flow/layers/physical_shape_layer.h"

#include "third_party/skia/include/core/SkColor.h"
#include "third_party/skia/include/core/SkImageInfo.h"
#include "third_party/skia/include/core/SkPath.h"
#include "third_party/skia/include/core/SkPictureRecorder.h"
#include "third_party/skia/include/core/SkRRect.h"
#include "third_party/skia/include/core/SkRSXform.h"
#include "third_party/skia/include/core/SkSurface.h"
#include "third_party/skia/include/core/SkTextBlob.h"
#include "third_party/skia/include/core/SkVertices.h"
#include "third_party/skia/include/effects/SkBlenders.h"
#include "third_party/skia/include/effects/SkDashPathEffect.h"
#include "third_party/skia/include/effects/SkDiscretePathEffect.h"
#include "third_party/skia/include/effects/SkGradientShader.h"
#include "third_party/skia/include/effects/SkImageFilters.h"

#include <cmath>

#include "gtest/gtest.h"

namespace flutter {
namespace testing {

constexpr int TestWidth = 200;
constexpr int TestHeight = 200;
constexpr int RenderWidth = 100;
constexpr int RenderHeight = 100;
constexpr int RenderLeft = (TestWidth - RenderWidth) / 2;
constexpr int RenderTop = (TestHeight - RenderHeight) / 2;
constexpr int RenderRight = RenderLeft + RenderWidth;
constexpr int RenderBottom = RenderTop + RenderHeight;
constexpr int RenderCenterX = (RenderLeft + RenderRight) / 2;
constexpr int RenderCenterY = (RenderTop + RenderBottom) / 2;
constexpr SkScalar RenderRadius = std::min(RenderWidth, RenderHeight) / 2.0;
constexpr SkScalar RenderCornerRadius = RenderRadius / 5.0;

constexpr SkPoint TestCenter = SkPoint::Make(TestWidth / 2, TestHeight / 2);
constexpr SkRect TestBounds = SkRect::MakeWH(TestWidth, TestHeight);
constexpr SkRect RenderBounds =
    SkRect::MakeLTRB(RenderLeft, RenderTop, RenderRight, RenderBottom);

class CanvasCompareTester {
 private:
  // If a test is using any shadow operations then we cannot currently
  // record those in an SkCanvas and play it back into a DisplayList
  // because internally the operation gets encapsulated in a Skia
  // ShadowRec which is not exposed by their headers. For operations
  // that use shadows, we can perform a lot of tests, but not the tests
  // that require SkCanvas->DisplayList transfers.
  // See: https://bugs.chromium.org/p/skia/issues/detail?id=12125
  static bool TestingDrawShadows;
  // The CPU renders nothing for drawVertices with a Blender.
  // See: https://bugs.chromium.org/p/skia/issues/detail?id=12200
  static bool TestingDrawVertices;
  // The CPU renders nothing for drawAtlas with a Blender.
  // See: https://bugs.chromium.org/p/skia/issues/detail?id=12199
  static bool TestingDrawAtlas;

 public:
  typedef const std::function<void(SkCanvas*, SkPaint&)> CvRenderer;
  typedef const std::function<void(DisplayListBuilder&)> DlRenderer;

  // All of the tests should eventually use this method except for the
  // tests that call |RenderNoAttributes| because they do not use the
  // SkPaint object.
  // But there are a couple of conditions beyond our control which require
  // the use of one of the variant methods below (|RenderShadows|,
  // |RenderVertices|, |RenderAtlas|).
  static void RenderAll(CvRenderer& cv_renderer, DlRenderer& dl_renderer) {
    RenderWithAttributes(cv_renderer, dl_renderer);
    RenderWithTransforms(cv_renderer, dl_renderer);
    RenderWithClips(cv_renderer, dl_renderer);
  }

  // Used by the tests that render shadows to deal with a condition where
  // we cannot recapture the shadow information from an SkCanvas stream
  // due to the DrawShadowRec used by Skia is not properly exported.
  // See: https://bugs.chromium.org/p/skia/issues/detail?id=12125
  static void RenderShadows(CvRenderer& cv_renderer, DlRenderer& dl_renderer) {
    TestingDrawShadows = true;
    RenderNoAttributes(cv_renderer, dl_renderer);
    TestingDrawShadows = false;
  }

  // Used by the tests that call drawVertices to avoid using an SkBlender
  // during testing because the CPU renderer appears not to render anything.
  // See: https://bugs.chromium.org/p/skia/issues/detail?id=12200
  static void RenderVertices(CvRenderer& cv_renderer, DlRenderer& dl_renderer) {
    TestingDrawVertices = true;
    RenderAll(cv_renderer, dl_renderer);
    TestingDrawVertices = false;
  }

  // Used by the tests that call drawAtlas to avoid using an SkBlender
  // during testing because the CPU renderer appears not to render anything.
  // See: https://bugs.chromium.org/p/skia/issues/detail?id=12199
  static void RenderAtlas(CvRenderer& cv_renderer, DlRenderer& dl_renderer) {
    TestingDrawAtlas = true;
    RenderAll(cv_renderer, dl_renderer);
    TestingDrawAtlas = false;
  }

  // Used by the tests that call a draw method that does not take a paint
  // call. Those tests could use |RenderAll| but there would be a lot of
  // wasted test runs that prepare an SkPaint that is never used.
  static void RenderNoAttributes(CvRenderer& cv_renderer,
                                 DlRenderer& dl_renderer) {
    RenderWith([=](SkCanvas*, SkPaint& p) {},  //
               [=](DisplayListBuilder& d) {},  //
               cv_renderer, dl_renderer, "Base Test");
    RenderWithTransforms(cv_renderer, dl_renderer);
    RenderWithClips(cv_renderer, dl_renderer);
  }

  static void RenderWithSaveRestore(CvRenderer& cv_renderer,
                                    DlRenderer& dl_renderer) {
    SkRect clip = SkRect::MakeLTRB(0, 0, 10, 10);
    SkRect rect = SkRect::MakeLTRB(5, 5, 15, 15);
    SkColor save_layer_color = SkColorSetARGB(0x7f, 0x00, 0xff, 0xff);
    RenderWith(
        [=](SkCanvas* cv, SkPaint& p) {
          cv->save();
          cv->clipRect(clip, SkClipOp::kIntersect, false);
          cv->drawRect(rect, p);
          cv->restore();
        },
        [=](DisplayListBuilder& b) {
          b.save();
          b.clipRect(clip, false, SkClipOp::kIntersect);
          b.drawRect(rect);
          b.restore();
        },
        cv_renderer, dl_renderer, "With prior save/clip/restore");
    RenderWith(
        [=](SkCanvas* cv, SkPaint& p) {
          SkPaint save_p;
          save_p.setColor(save_layer_color);
          cv->saveLayer(RenderBounds, &save_p);
          cv->drawRect(rect, p);
        },
        [=](DisplayListBuilder& b) {
          b.setColor(save_layer_color);
          b.saveLayer(&RenderBounds, true);
          b.setColor(SkPaint().getColor());
          b.drawRect(rect);
        },
        cv_renderer, dl_renderer, "With saveLayer");
  }

  static void RenderWithAttributes(CvRenderer& cv_renderer,
                                   DlRenderer& dl_renderer) {
    RenderWith([=](SkCanvas*, SkPaint& p) {},  //
               [=](DisplayListBuilder& d) {},  //
               cv_renderer, dl_renderer, "Base Test");

    RenderWith([=](SkCanvas*, SkPaint& p) { p.setAntiAlias(true); },  //
               [=](DisplayListBuilder& b) { b.setAA(true); },         //
               cv_renderer, dl_renderer, "AA == True");
    RenderWith([=](SkCanvas*, SkPaint& p) { p.setAntiAlias(false); },  //
               [=](DisplayListBuilder& b) { b.setAA(false); },         //
               cv_renderer, dl_renderer, "AA == False");

    RenderWith([=](SkCanvas*, SkPaint& p) { p.setDither(true); },  //
               [=](DisplayListBuilder& b) { b.setDither(true); },  //
               cv_renderer, dl_renderer, "Dither == True");
    RenderWith([=](SkCanvas*, SkPaint& p) { p.setDither(false); },  //
               [=](DisplayListBuilder& b) { b.setDither(false); },  //
               cv_renderer, dl_renderer, "Dither = False");

    RenderWith([=](SkCanvas*, SkPaint& p) { p.setColor(SK_ColorBLUE); },  //
               [=](DisplayListBuilder& b) { b.setColor(SK_ColorBLUE); },  //
               cv_renderer, dl_renderer, "Color == Blue");
    RenderWith([=](SkCanvas*, SkPaint& p) { p.setColor(SK_ColorGREEN); },  //
               [=](DisplayListBuilder& b) { b.setColor(SK_ColorGREEN); },  //
               cv_renderer, dl_renderer, "Color == Green");

    RenderWithStrokes(cv_renderer, dl_renderer);

    {
      // half opaque cyan
      SkColor blendableColor = SkColorSetARGB(0x7f, 0x00, 0xff, 0xff);
      SkColor bg = SK_ColorWHITE;

      RenderWith(
          [=](SkCanvas*, SkPaint& p) {
            p.setBlendMode(SkBlendMode::kSrcIn);
            p.setColor(blendableColor);
          },
          [=](DisplayListBuilder& b) {
            b.setBlendMode(SkBlendMode::kSrcIn);
            b.setColor(blendableColor);
          },
          cv_renderer, dl_renderer, "Blend == SrcIn", &bg);
      RenderWith(
          [=](SkCanvas*, SkPaint& p) {
            p.setBlendMode(SkBlendMode::kDstIn);
            p.setColor(blendableColor);
          },
          [=](DisplayListBuilder& b) {
            b.setBlendMode(SkBlendMode::kDstIn);
            b.setColor(blendableColor);
          },
          cv_renderer, dl_renderer, "Blend == DstIn", &bg);
    }

    if (!(TestingDrawAtlas || TestingDrawVertices)) {
      sk_sp<SkBlender> blender =
          SkBlenders::Arithmetic(0.25, 0.25, 0.25, 0.25, false);
      {
        RenderWith([=](SkCanvas*, SkPaint& p) { p.setBlender(blender); },
                   [=](DisplayListBuilder& b) { b.setBlender(blender); },
                   cv_renderer, dl_renderer,
                   "ImageFilter == Blender Arithmetic 0.25-false");
      }
      ASSERT_TRUE(blender->unique()) << "Blender Cleanup";
      blender = SkBlenders::Arithmetic(0.25, 0.25, 0.25, 0.25, true);
      {
        RenderWith([=](SkCanvas*, SkPaint& p) { p.setBlender(blender); },
                   [=](DisplayListBuilder& b) { b.setBlender(blender); },
                   cv_renderer, dl_renderer,
                   "ImageFilter == Blender Arithmetic 0.25-true");
      }
      ASSERT_TRUE(blender->unique()) << "Blender Cleanup";
    }

    {
      sk_sp<SkImageFilter> filter =
          SkImageFilters::Blur(5.0, 5.0, SkTileMode::kDecal, nullptr, nullptr);
      {
        RenderWith([=](SkCanvas*, SkPaint& p) { p.setImageFilter(filter); },
                   [=](DisplayListBuilder& b) { b.setImageFilter(filter); },
                   cv_renderer, dl_renderer, "ImageFilter == Decal Blur 5");
      }
      ASSERT_TRUE(filter->unique()) << "ImageFilter Cleanup";
      filter =
          SkImageFilters::Blur(5.0, 5.0, SkTileMode::kClamp, nullptr, nullptr);
      {
        RenderWith([=](SkCanvas*, SkPaint& p) { p.setImageFilter(filter); },
                   [=](DisplayListBuilder& b) { b.setImageFilter(filter); },
                   cv_renderer, dl_renderer, "ImageFilter == Clamp Blur 5");
      }
      ASSERT_TRUE(filter->unique()) << "ImageFilter Cleanup";
    }

    {
      // clang-format off
      constexpr float rotate_color_matrix[20] = {
          0, 1, 0, 0, 0,
          0, 0, 1, 0, 0,
          1, 0, 0, 0, 0,
          0, 0, 0, 1, 0,
      };
      constexpr float invert_color_matrix[20] = {
        -1.0,    0,    0, 1.0,   0,
           0, -1.0,    0, 1.0,   0,
           0,    0, -1.0, 1.0,   0,
         1.0,  1.0,  1.0, 1.0,   0,
      };
      // clang-format on
      sk_sp<SkColorFilter> filter = SkColorFilters::Matrix(rotate_color_matrix);
      {
        SkColor bg = SK_ColorWHITE;
        RenderWith(
            [=](SkCanvas*, SkPaint& p) {
              p.setColor(SK_ColorYELLOW);
              p.setColorFilter(filter);
            },
            [=](DisplayListBuilder& b) {
              b.setColor(SK_ColorYELLOW);
              b.setColorFilter(filter);
            },
            cv_renderer, dl_renderer, "ColorFilter == RotateRGB", &bg);
      }
      ASSERT_TRUE(filter->unique()) << "ColorFilter Cleanup";
      filter = SkColorFilters::Matrix(invert_color_matrix);
      {
        SkColor bg = SK_ColorWHITE;
        RenderWith(
            [=](SkCanvas*, SkPaint& p) {
              p.setColor(SK_ColorYELLOW);
              p.setColorFilter(filter);
            },
            [=](DisplayListBuilder& b) {
              b.setColor(SK_ColorYELLOW);
              b.setInvertColors(true);
            },
            cv_renderer, dl_renderer, "ColorFilter == Invert", &bg);
      }
      ASSERT_TRUE(filter->unique()) << "ColorFilter Cleanup";
    }

    {
      // Discrete path effects need a stroke width for drawPointsAsPoints
      // to do something realistic
      sk_sp<SkPathEffect> effect = SkDiscretePathEffect::Make(3, 5);
      {
        // Discrete path effects need a stroke width for drawPointsAsPoints
        // to do something realistic
        RenderWith(
            [=](SkCanvas*, SkPaint& p) {
              p.setStrokeWidth(5.0);
              p.setPathEffect(effect);
            },
            [=](DisplayListBuilder& b) {
              b.setStrokeWidth(5.0);
              b.setPathEffect(effect);
            },
            cv_renderer, dl_renderer, "PathEffect == Discrete-3-5");
      }
      ASSERT_TRUE(effect->unique()) << "PathEffect Cleanup";
      effect = SkDiscretePathEffect::Make(2, 3);
      {
        RenderWith(
            [=](SkCanvas*, SkPaint& p) {
              p.setStrokeWidth(5.0);
              p.setPathEffect(effect);
            },
            [=](DisplayListBuilder& b) {
              b.setStrokeWidth(5.0);
              b.setPathEffect(effect);
            },
            cv_renderer, dl_renderer, "PathEffect == Discrete-2-3");
      }
      ASSERT_TRUE(effect->unique()) << "PathEffect Cleanup";
    }

    {
      sk_sp<SkMaskFilter> filter =
          SkMaskFilter::MakeBlur(kNormal_SkBlurStyle, 5.0);
      {
        RenderWith([=](SkCanvas*, SkPaint& p) { p.setMaskFilter(filter); },
                   [=](DisplayListBuilder& b) { b.setMaskFilter(filter); },
                   cv_renderer, dl_renderer, "MaskFilter == Blur 5");
      }
      ASSERT_TRUE(filter->unique()) << "MaskFilter Cleanup";
      {
        RenderWith([=](SkCanvas*, SkPaint& p) { p.setMaskFilter(filter); },
                   [=](DisplayListBuilder& b) {
                     b.setMaskBlurFilter(kNormal_SkBlurStyle, 5.0);
                   },
                   cv_renderer, dl_renderer, "MaskFilter == Blur(Normal, 5.0)");
      }
      ASSERT_TRUE(filter->unique()) << "MaskFilter Cleanup";
    }

    {
      SkPoint end_points[] = {
          SkPoint::Make(RenderBounds.fLeft, RenderBounds.fTop),
          SkPoint::Make(RenderBounds.fRight, RenderBounds.fBottom),
      };
      SkColor colors[] = {
          SK_ColorGREEN,
          SK_ColorYELLOW,
          SK_ColorBLUE,
      };
      float stops[] = {
          0.0,
          0.5,
          1.0,
      };
      sk_sp<SkShader> shader = SkGradientShader::MakeLinear(
          end_points, colors, stops, 3, SkTileMode::kMirror, 0, nullptr);
      {
        RenderWith([=](SkCanvas*, SkPaint& p) { p.setShader(shader); },
                   [=](DisplayListBuilder& b) { b.setShader(shader); },
                   cv_renderer, dl_renderer, "LinearGradient GYB");
      }
      ASSERT_TRUE(shader->unique()) << "Shader Cleanup";
    }
  }

  static void RenderWithStrokes(CvRenderer& cv_renderer,
                                DlRenderer& dl_renderer) {
    RenderWith(
        [=](SkCanvas*, SkPaint& p) { p.setStyle(SkPaint::kFill_Style); },
        [=](DisplayListBuilder& b) { b.setDrawStyle(SkPaint::kFill_Style); },
        cv_renderer, dl_renderer, "Fill");
    RenderWith(
        [=](SkCanvas*, SkPaint& p) { p.setStyle(SkPaint::kStroke_Style); },
        [=](DisplayListBuilder& b) { b.setDrawStyle(SkPaint::kStroke_Style); },
        cv_renderer, dl_renderer, "Stroke + defaults");

    RenderWith(
        [=](SkCanvas*, SkPaint& p) {
          p.setStyle(SkPaint::kFill_Style);
          p.setStrokeWidth(10.0);
        },
        [=](DisplayListBuilder& b) {
          b.setDrawStyle(SkPaint::kFill_Style);
          b.setStrokeWidth(10.0);
        },
        cv_renderer, dl_renderer, "Fill + unnecessary StrokeWidth 10");

    RenderWith(
        [=](SkCanvas*, SkPaint& p) {
          p.setStyle(SkPaint::kStroke_Style);
          p.setStrokeWidth(10.0);
        },
        [=](DisplayListBuilder& b) {
          b.setDrawStyle(SkPaint::kStroke_Style);
          b.setStrokeWidth(10.0);
        },
        cv_renderer, dl_renderer, "Stroke Width 10");
    RenderWith(
        [=](SkCanvas*, SkPaint& p) {
          p.setStyle(SkPaint::kStroke_Style);
          p.setStrokeWidth(5.0);
        },
        [=](DisplayListBuilder& b) {
          b.setDrawStyle(SkPaint::kStroke_Style);
          b.setStrokeWidth(5.0);
        },
        cv_renderer, dl_renderer, "Stroke Width 5");

    RenderWith(
        [=](SkCanvas*, SkPaint& p) {
          p.setStyle(SkPaint::kStroke_Style);
          p.setStrokeWidth(5.0);
          p.setStrokeCap(SkPaint::kButt_Cap);
        },
        [=](DisplayListBuilder& b) {
          b.setDrawStyle(SkPaint::kStroke_Style);
          b.setStrokeWidth(5.0);
          b.setCaps(SkPaint::kButt_Cap);
        },
        cv_renderer, dl_renderer, "Stroke Width 5, Butt Cap");
    RenderWith(
        [=](SkCanvas*, SkPaint& p) {
          p.setStyle(SkPaint::kStroke_Style);
          p.setStrokeWidth(5.0);
          p.setStrokeCap(SkPaint::kRound_Cap);
        },
        [=](DisplayListBuilder& b) {
          b.setDrawStyle(SkPaint::kStroke_Style);
          b.setStrokeWidth(5.0);
          b.setCaps(SkPaint::kRound_Cap);
        },
        cv_renderer, dl_renderer, "Stroke Width 5, Round Cap");

    RenderWith(
        [=](SkCanvas*, SkPaint& p) {
          p.setStyle(SkPaint::kStroke_Style);
          p.setStrokeWidth(5.0);
          p.setStrokeJoin(SkPaint::kBevel_Join);
        },
        [=](DisplayListBuilder& b) {
          b.setDrawStyle(SkPaint::kStroke_Style);
          b.setStrokeWidth(5.0);
          b.setJoins(SkPaint::kBevel_Join);
        },
        cv_renderer, dl_renderer, "Stroke Width 5, Bevel Join");
    RenderWith(
        [=](SkCanvas*, SkPaint& p) {
          p.setStyle(SkPaint::kStroke_Style);
          p.setStrokeWidth(5.0);
          p.setStrokeJoin(SkPaint::kRound_Join);
        },
        [=](DisplayListBuilder& b) {
          b.setDrawStyle(SkPaint::kStroke_Style);
          b.setStrokeWidth(5.0);
          b.setJoins(SkPaint::kRound_Join);
        },
        cv_renderer, dl_renderer, "Stroke Width 5, Round Join");

    RenderWith(
        [=](SkCanvas*, SkPaint& p) {
          p.setStyle(SkPaint::kStroke_Style);
          p.setStrokeWidth(5.0);
          p.setStrokeMiter(100.0);
          p.setStrokeJoin(SkPaint::kMiter_Join);
        },
        [=](DisplayListBuilder& b) {
          b.setDrawStyle(SkPaint::kStroke_Style);
          b.setStrokeWidth(5.0);
          b.setMiterLimit(100.0);
          b.setJoins(SkPaint::kMiter_Join);
        },
        cv_renderer, dl_renderer, "Stroke Width 5, Miter 100");

    RenderWith(
        [=](SkCanvas*, SkPaint& p) {
          p.setStyle(SkPaint::kStroke_Style);
          p.setStrokeWidth(5.0);
          p.setStrokeMiter(0.0);
          p.setStrokeJoin(SkPaint::kMiter_Join);
        },
        [=](DisplayListBuilder& b) {
          b.setDrawStyle(SkPaint::kStroke_Style);
          b.setStrokeWidth(5.0);
          b.setMiterLimit(0.0);
          b.setJoins(SkPaint::kMiter_Join);
        },
        cv_renderer, dl_renderer, "Stroke Width 5, Miter 0");

    {
      const SkScalar TestDashes1[] = {4.0, 2.0};
      const SkScalar TestDashes2[] = {1.0, 1.5};
      sk_sp<SkPathEffect> effect = SkDashPathEffect::Make(TestDashes1, 2, 0.0f);
      {
        RenderWith(
            [=](SkCanvas*, SkPaint& p) {
              p.setStyle(SkPaint::kStroke_Style);
              p.setStrokeWidth(5.0);
              p.setPathEffect(effect);
            },
            [=](DisplayListBuilder& b) {
              b.setDrawStyle(SkPaint::kStroke_Style);
              b.setStrokeWidth(5.0);
              b.setPathEffect(effect);
            },
            cv_renderer, dl_renderer, "PathEffect == Dash-4-2");
      }
      ASSERT_TRUE(effect->unique()) << "PathEffect Cleanup";
      effect = SkDashPathEffect::Make(TestDashes2, 2, 0.0f);
      {
        RenderWith(
            [=](SkCanvas*, SkPaint& p) {
              p.setStyle(SkPaint::kStroke_Style);
              p.setStrokeWidth(5.0);
              p.setPathEffect(effect);
            },
            [=](DisplayListBuilder& b) {
              b.setDrawStyle(SkPaint::kStroke_Style);
              b.setStrokeWidth(5.0);
              b.setPathEffect(effect);
            },
            cv_renderer, dl_renderer, "PathEffect == Dash-1-1.5");
      }
      ASSERT_TRUE(effect->unique()) << "PathEffect Cleanup";
    }
  }

  static void RenderWithTransforms(CvRenderer& cv_renderer,
                                   DlRenderer& dl_renderer) {
    RenderWith([=](SkCanvas* c, SkPaint&) { c->translate(5, 10); },  //
               [=](DisplayListBuilder& b) { b.translate(5, 10); },   //
               cv_renderer, dl_renderer, "Translate 5, 10");
    RenderWith([=](SkCanvas* c, SkPaint&) { c->scale(1.05, 1.05); },  //
               [=](DisplayListBuilder& b) { b.scale(1.05, 1.05); },   //
               cv_renderer, dl_renderer, "Scale +5%");
    RenderWith([=](SkCanvas* c, SkPaint&) { c->rotate(5); },  //
               [=](DisplayListBuilder& b) { b.rotate(5); },   //
               cv_renderer, dl_renderer, "Rotate 5 degrees");
    RenderWith([=](SkCanvas* c, SkPaint&) { c->skew(0.05, 0.05); },  //
               [=](DisplayListBuilder& b) { b.skew(0.05, 0.05); },   //
               cv_renderer, dl_renderer, "Skew 5%");
    {
      SkMatrix tx = SkMatrix::MakeAll(1.1, 0.1, 1.05, 0.05, 1, 1, 0, 0, 1);
      RenderWith([=](SkCanvas* c, SkPaint&) { c->concat(tx); },  //
                 [=](DisplayListBuilder& b) {
                   b.transform2x3(tx[0], tx[1], tx[2],  //
                                  tx[3], tx[4], tx[5]);
                 },  //
                 cv_renderer, dl_renderer, "Transform 2x3");
    }
    {
      SkMatrix tx = SkMatrix::MakeAll(1.1, 0.1, 1.05, 0.05, 1, 1, 0, 0, 1.01);
      RenderWith([=](SkCanvas* c, SkPaint&) { c->concat(tx); },  //
                 [=](DisplayListBuilder& b) {
                   b.transform3x3(tx[0], tx[1], tx[2],  //
                                  tx[3], tx[4], tx[5],  //
                                  tx[6], tx[7], tx[8]);
                 },  //
                 cv_renderer, dl_renderer, "Transform 3x3");
    }
  }

  static void RenderWithClips(CvRenderer& cv_renderer,
                              DlRenderer& dl_renderer) {
    SkRect r_clip = RenderBounds.makeInset(15.5, 15.5);
    RenderWith(
        [=](SkCanvas* c, SkPaint&) {
          c->clipRect(r_clip, SkClipOp::kIntersect, false);
        },
        [=](DisplayListBuilder& b) {
          b.clipRect(r_clip, false, SkClipOp::kIntersect);
        },
        cv_renderer, dl_renderer, "Hard ClipRect inset by 15.5");
    RenderWith(
        [=](SkCanvas* c, SkPaint&) {
          c->clipRect(r_clip, SkClipOp::kIntersect, true);
        },
        [=](DisplayListBuilder& b) {
          b.clipRect(r_clip, true, SkClipOp::kIntersect);
        },
        cv_renderer, dl_renderer, "AA ClipRect inset by 15.5");
    RenderWith(
        [=](SkCanvas* c, SkPaint&) {
          c->clipRect(r_clip, SkClipOp::kDifference, false);
        },
        [=](DisplayListBuilder& b) {
          b.clipRect(r_clip, false, SkClipOp::kDifference);
        },
        cv_renderer, dl_renderer, "Hard ClipRect Diff, inset by 15.5");
    SkRRect rr_clip = SkRRect::MakeRectXY(r_clip, 1.8, 2.7);
    RenderWith(
        [=](SkCanvas* c, SkPaint&) {
          c->clipRRect(rr_clip, SkClipOp::kIntersect, false);
        },
        [=](DisplayListBuilder& b) {
          b.clipRRect(rr_clip, false, SkClipOp::kIntersect);
        },
        cv_renderer, dl_renderer, "Hard ClipRRect inset by 15.5");
    RenderWith(
        [=](SkCanvas* c, SkPaint&) {
          c->clipRRect(rr_clip, SkClipOp::kIntersect, true);
        },
        [=](DisplayListBuilder& b) {
          b.clipRRect(rr_clip, true, SkClipOp::kIntersect);
        },
        cv_renderer, dl_renderer, "AA ClipRRect inset by 15.5");
    RenderWith(
        [=](SkCanvas* c, SkPaint&) {
          c->clipRRect(rr_clip, SkClipOp::kDifference, false);
        },
        [=](DisplayListBuilder& b) {
          b.clipRRect(rr_clip, false, SkClipOp::kDifference);
        },
        cv_renderer, dl_renderer, "Hard ClipRRect Diff, inset by 15.5");
    SkPath path_clip = SkPath();
    path_clip.setFillType(SkPathFillType::kEvenOdd);
    path_clip.addRect(r_clip);
    path_clip.addCircle(RenderCenterX, RenderCenterY, 1.0);
    RenderWith(
        [=](SkCanvas* c, SkPaint&) {
          c->clipPath(path_clip, SkClipOp::kIntersect, false);
        },
        [=](DisplayListBuilder& b) {
          b.clipPath(path_clip, false, SkClipOp::kIntersect);
        },
        cv_renderer, dl_renderer, "Hard ClipPath inset by 15.5");
    RenderWith(
        [=](SkCanvas* c, SkPaint&) {
          c->clipPath(path_clip, SkClipOp::kIntersect, true);
        },
        [=](DisplayListBuilder& b) {
          b.clipPath(path_clip, true, SkClipOp::kIntersect);
        },
        cv_renderer, dl_renderer, "AA ClipPath inset by 15.5");
    RenderWith(
        [=](SkCanvas* c, SkPaint&) {
          c->clipPath(path_clip, SkClipOp::kDifference, false);
        },
        [=](DisplayListBuilder& b) {
          b.clipPath(path_clip, false, SkClipOp::kDifference);
        },
        cv_renderer, dl_renderer, "Hard ClipPath Diff, inset by 15.5");
  }

  static SkRect getSkBounds(CvRenderer& cv_setup, CvRenderer& cv_render) {
    SkPictureRecorder recorder;
    SkRTreeFactory rtree_factory;
    SkCanvas* cv = recorder.beginRecording(TestBounds, &rtree_factory);
    SkPaint p;
    cv_setup(cv, p);
    cv_render(cv, p);
    return recorder.finishRecordingAsPicture()->cullRect();
  }

  static void RenderWith(CvRenderer& cv_setup,
                         DlRenderer& dl_setup,
                         CvRenderer& cv_render,
                         DlRenderer& dl_render,
                         const std::string info,
                         const SkColor* bg = nullptr) {
    // surface1 is direct rendering via SkCanvas to SkSurface
    // DisplayList mechanisms are not involved in this operation
    sk_sp<SkSurface> ref_surface = makeSurface(bg);
    SkPaint paint1;
    cv_setup(ref_surface->getCanvas(), paint1);
    cv_render(ref_surface->getCanvas(), paint1);
    SkRect ref_bounds = getSkBounds(cv_setup, cv_render);
    SkPixmap ref_pixels;
    ASSERT_TRUE(ref_surface->peekPixels(&ref_pixels)) << info;
    ASSERT_EQ(ref_pixels.width(), TestWidth) << info;
    ASSERT_EQ(ref_pixels.height(), TestHeight) << info;
    ASSERT_EQ(ref_pixels.info().bytesPerPixel(), 4) << info;
    checkPixels(&ref_pixels, ref_bounds, info, bg);

    {
      // This sequence plays the provided equivalently constructed
      // DisplayList onto the SkCanvas of the surface
      // DisplayList => direct rendering
      sk_sp<SkSurface> test_surface = makeSurface(bg);
      DisplayListBuilder builder(TestBounds);
      dl_setup(builder);
      dl_render(builder);
      sk_sp<DisplayList> display_list = builder.Build();
      SkRect dl_bounds = display_list->bounds();
#ifdef DISPLAY_LIST_BOUNDS_ACCURACY_CHECKING
      if (dl_bounds != ref_bounds) {
        FML_LOG(ERROR) << "For " << info;
        FML_LOG(ERROR) << "ref: " << ref_bounds.fLeft << ", " << ref_bounds.fTop
                       << " => " << ref_bounds.fRight << ", "
                       << ref_bounds.fBottom;
        FML_LOG(ERROR) << "dl: " << dl_bounds.fLeft << ", " << dl_bounds.fTop
                       << " => " << dl_bounds.fRight << ", "
                       << dl_bounds.fBottom;
        if (!dl_bounds.contains(ref_bounds)) {
          FML_LOG(ERROR) << "DisplayList bounds are too small!";
        }
      }
#endif  // DISPLAY_LIST_BOUNDS_ACCURACY_CHECKING
      // This sometimes triggers, but when it triggers and I examine
      // the ref_bounds, they are always unnecessarily large and
      // since the pixel OOB tests in the compare method do not
      // trigger, we will trust the DL bounds.
      // EXPECT_TRUE(dl_bounds.contains(ref_bounds)) << info;
      display_list->RenderTo(test_surface->getCanvas());
      compareToReference(test_surface.get(), &ref_pixels, info + " (DL render)",
                         &dl_bounds, bg);
    }

    // This test cannot work if the rendering is using shadows until
    // we can access the Skia ShadowRec via public headers.
    if (!TestingDrawShadows) {
      // This sequence renders SkCanvas calls to a DisplayList and then
      // plays them back on SkCanvas to SkSurface
      // SkCanvas calls => DisplayList => rendering
      sk_sp<SkSurface> test_surface = makeSurface(bg);
      DisplayListCanvasRecorder dl_recorder(TestBounds);
      SkPaint test_paint;
      cv_setup(&dl_recorder, test_paint);
      cv_render(&dl_recorder, test_paint);
      dl_recorder.builder()->Build()->RenderTo(test_surface->getCanvas());
      compareToReference(test_surface.get(), &ref_pixels,
                         info + " (Sk->DL render)", nullptr, nullptr);
    }

    {
      // This sequence renders the SkCanvas calls to an SkPictureRecorder and
      // renders the DisplayList calls to a DisplayListBuilder and then
      // renders both back under a transform (scale(2x)) to see if their
      // rendering is affected differently by a change of matrix between
      // recording time and rendering time.
      const int TestWidth2 = TestWidth * 2;
      const int TestHeight2 = TestHeight * 2;
      const SkScalar TestScale = 2.0;

      SkPictureRecorder sk_recorder;
      SkCanvas* ref_canvas = sk_recorder.beginRecording(TestBounds);
      SkPaint ref_paint;
      cv_setup(ref_canvas, ref_paint);
      cv_render(ref_canvas, ref_paint);
      sk_sp<SkPicture> ref_picture = sk_recorder.finishRecordingAsPicture();
      sk_sp<SkSurface> ref_surface2 = makeSurface(bg, TestWidth2, TestHeight2);
      SkCanvas* ref_canvas2 = ref_surface2->getCanvas();
      ref_canvas2->scale(TestScale, TestScale);
      ref_picture->playback(ref_canvas2);
      SkPixmap ref_pixels2;
      ASSERT_TRUE(ref_surface2->peekPixels(&ref_pixels2)) << info;
      ASSERT_EQ(ref_pixels2.width(), TestWidth2) << info;
      ASSERT_EQ(ref_pixels2.height(), TestHeight2) << info;
      ASSERT_EQ(ref_pixels2.info().bytesPerPixel(), 4) << info;

      DisplayListBuilder builder(TestBounds);
      dl_setup(builder);
      dl_render(builder);
      sk_sp<DisplayList> display_list = builder.Build();
      sk_sp<SkSurface> test_surface = makeSurface(bg, TestWidth2, TestHeight2);
      SkCanvas* test_canvas = test_surface->getCanvas();
      test_canvas->scale(TestScale, TestScale);
      display_list->RenderTo(test_canvas);
      compareToReference(test_surface.get(), &ref_pixels2,
                         info + " (SKP/DL render scaled 2x)", nullptr, nullptr,
                         TestWidth2, TestHeight2, false);
    }
  }

  static void checkPixels(SkPixmap* ref_pixels,
                          SkRect ref_bounds,
                          const std::string info,
                          const SkColor* bg) {
    SkPMColor untouched = (bg) ? SkPreMultiplyColor(*bg) : 0;
    int pixels_touched = 0;
    int pixels_oob = 0;
    for (int y = 0; y < TestHeight; y++) {
      const uint32_t* ref_row = ref_pixels->addr32(0, y);
      for (int x = 0; x < TestWidth; x++) {
        if (ref_row[x] != untouched) {
          pixels_touched++;
          if (!ref_bounds.intersects(SkRect::MakeXYWH(x, y, 1, 1))) {
            pixels_oob++;
          }
        }
      }
    }
    ASSERT_EQ(pixels_oob, 0) << info;
    ASSERT_GT(pixels_touched, 0) << info;
  }

  static void compareToReference(SkSurface* test_surface,
                                 SkPixmap* reference,
                                 const std::string info,
                                 SkRect* bounds,
                                 const SkColor* bg,
                                 int width = TestWidth,
                                 int height = TestHeight,
                                 bool printMismatches = false) {
    SkPMColor untouched = (bg) ? SkPreMultiplyColor(*bg) : 0;
    SkPixmap test_pixels;
    ASSERT_TRUE(test_surface->peekPixels(&test_pixels)) << info;
    ASSERT_EQ(test_pixels.width(), width) << info;
    ASSERT_EQ(test_pixels.height(), height) << info;
    ASSERT_EQ(test_pixels.info().bytesPerPixel(), 4) << info;

    int pixels_different = 0;
    int pixels_oob = 0;
    int minX = width;
    int minY = height;
    int maxX = 0;
    int maxY = 0;
    for (int y = 0; y < height; y++) {
      const uint32_t* ref_row = reference->addr32(0, y);
      const uint32_t* test_row = test_pixels.addr32(0, y);
      for (int x = 0; x < width; x++) {
        if (bounds && test_row[x] != untouched) {
          if (minX > x)
            minX = x;
          if (minY > y)
            minY = y;
          if (maxX < x)
            maxX = x;
          if (maxY < y)
            maxY = y;
          if (!bounds->intersects(SkRect::MakeXYWH(x, y, 1, 1))) {
            pixels_oob++;
          }
        }
        if (test_row[x] != ref_row[x]) {
          if (printMismatches) {
            FML_LOG(ERROR) << "pix[" << x << ", " << y
                           << "] mismatch: " << std::hex << test_row[x]
                           << "(test) != (ref)" << ref_row[x] << std::dec;
          }
          pixels_different++;
        }
      }
    }
#ifdef DISPLAY_LIST_BOUNDS_ACCURACY_CHECKING
    if (bounds && *bounds != SkRect::MakeLTRB(minX, minY, maxX + 1, maxY + 1)) {
      FML_LOG(ERROR) << "inaccurate bounds for " << info;
      FML_LOG(ERROR) << "dl: " << bounds->fLeft << ", " << bounds->fTop
                     << " => " << bounds->fRight << ", " << bounds->fBottom;
      FML_LOG(ERROR) << "pixels: " << minX << ", " << minY << " => "
                     << (maxX + 1) << ", " << (maxY + 1);
    }
#endif  // DISPLAY_LIST_BOUNDS_ACCURACY_CHECKING
    ASSERT_EQ(pixels_oob, 0) << info;
    ASSERT_EQ(pixels_different, 0) << info;
  }

  static sk_sp<SkSurface> makeSurface(const SkColor* bg,
                                      int width = TestWidth,
                                      int height = TestHeight) {
    sk_sp<SkSurface> surface = SkSurface::MakeRasterN32Premul(width, height);
    if (bg) {
      surface->getCanvas()->drawColor(*bg);
    }
    return surface;
  }

  static const sk_sp<SkImage> testImage;
  static const sk_sp<SkImage> makeTestImage() {
    sk_sp<SkSurface> surface =
        SkSurface::MakeRasterN32Premul(RenderWidth, RenderHeight);
    SkCanvas* canvas = surface->getCanvas();
    SkPaint p0, p1;
    p0.setStyle(SkPaint::kFill_Style);
    p0.setColor(SK_ColorGREEN);
    p1.setStyle(SkPaint::kFill_Style);
    p1.setColor(SK_ColorBLUE);
    // Some pixels need some transparency for DstIn testing
    p1.setAlpha(128);
    int cbdim = 5;
    for (int y = 0; y < RenderHeight; y += cbdim) {
      for (int x = 0; x < RenderWidth; x += cbdim) {
        SkPaint& cellp = ((x + y) & 1) == 0 ? p0 : p1;
        canvas->drawRect(SkRect::MakeXYWH(x, y, cbdim, cbdim), cellp);
      }
    }
    return surface->makeImageSnapshot();
  }

  static sk_sp<SkTextBlob> MakeTextBlob(std::string string,
                                        SkScalar height = RenderHeight) {
    SkFont font(SkTypeface::MakeDefault(), height);
    return SkTextBlob::MakeFromText(string.c_str(), string.size(), font,
                                    SkTextEncoding::kUTF8);
  }
};

bool CanvasCompareTester::TestingDrawShadows = false;
bool CanvasCompareTester::TestingDrawVertices = false;
bool CanvasCompareTester::TestingDrawAtlas = false;

const sk_sp<SkImage> CanvasCompareTester::testImage =
    CanvasCompareTester::makeTestImage();

TEST(DisplayListCanvas, DrawPaint) {
  CanvasCompareTester::RenderAll(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        canvas->drawPaint(paint);
      },
      [=](DisplayListBuilder& builder) {  //
        builder.drawPaint();
      });
}

TEST(DisplayListCanvas, DrawColor) {
  CanvasCompareTester::RenderNoAttributes(     //
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        canvas->drawColor(SK_ColorMAGENTA);
      },
      [=](DisplayListBuilder& builder) {  //
        builder.drawColor(SK_ColorMAGENTA, SkBlendMode::kSrcOver);
      });
}

TEST(DisplayListCanvas, DrawLine) {
  SkRect rect = RenderBounds;
  SkPoint p1 = SkPoint::Make(rect.fLeft, rect.fTop);
  SkPoint p2 = SkPoint::Make(rect.fRight, rect.fBottom);

  CanvasCompareTester::RenderAll(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        canvas->drawLine(p1, p2, paint);
      },
      [=](DisplayListBuilder& builder) {  //
        builder.drawLine(p1, p2);
      });
}

TEST(DisplayListCanvas, DrawRect) {
  CanvasCompareTester::RenderAll(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        canvas->drawRect(RenderBounds, paint);
      },
      [=](DisplayListBuilder& builder) {  //
        builder.drawRect(RenderBounds);
      });
}

TEST(DisplayListCanvas, DrawOval) {
  SkRect rect = RenderBounds.makeInset(0, 10);

  CanvasCompareTester::RenderAll(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        canvas->drawOval(rect, paint);
      },
      [=](DisplayListBuilder& builder) {  //
        builder.drawOval(rect);
      });
}

TEST(DisplayListCanvas, DrawCircle) {
  CanvasCompareTester::RenderAll(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        canvas->drawCircle(TestCenter, RenderRadius, paint);
      },
      [=](DisplayListBuilder& builder) {  //
        builder.drawCircle(TestCenter, RenderRadius);
      });
}

TEST(DisplayListCanvas, DrawRRect) {
  SkRRect rrect =
      SkRRect::MakeRectXY(RenderBounds, RenderCornerRadius, RenderCornerRadius);
  CanvasCompareTester::RenderAll(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        canvas->drawRRect(rrect, paint);
      },
      [=](DisplayListBuilder& builder) {  //
        builder.drawRRect(rrect);
      });
}

TEST(DisplayListCanvas, DrawDRRect) {
  SkRRect outer =
      SkRRect::MakeRectXY(RenderBounds, RenderCornerRadius, RenderCornerRadius);
  SkRect innerBounds = RenderBounds.makeInset(30.0, 30.0);
  SkRRect inner =
      SkRRect::MakeRectXY(innerBounds, RenderCornerRadius, RenderCornerRadius);
  CanvasCompareTester::RenderAll(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        canvas->drawDRRect(outer, inner, paint);
      },
      [=](DisplayListBuilder& builder) {  //
        builder.drawDRRect(outer, inner);
      });
}

TEST(DisplayListCanvas, DrawPath) {
  SkPath path;
  path.moveTo(RenderCenterX, RenderTop);
  path.lineTo(RenderRight, RenderBottom);
  path.lineTo(RenderLeft, RenderCenterY);
  path.lineTo(RenderRight, RenderCenterY);
  path.lineTo(RenderLeft, RenderBottom);
  CanvasCompareTester::RenderAll(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        canvas->drawPath(path, paint);
      },
      [=](DisplayListBuilder& builder) {  //
        builder.drawPath(path);
      });
}

TEST(DisplayListCanvas, DrawArc) {
  CanvasCompareTester::RenderAll(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        canvas->drawArc(RenderBounds, 30, 270, false, paint);
      },
      [=](DisplayListBuilder& builder) {  //
        builder.drawArc(RenderBounds, 30, 270, false);
      });
}

TEST(DisplayListCanvas, DrawArcCenter) {
  CanvasCompareTester::RenderAll(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        canvas->drawArc(RenderBounds, 30, 270, true, paint);
      },
      [=](DisplayListBuilder& builder) {  //
        builder.drawArc(RenderBounds, 30, 270, true);
      });
}

TEST(DisplayListCanvas, DrawPointsAsPoints) {
  const SkScalar x0 = RenderLeft;
  const SkScalar x1 = (RenderLeft + RenderCenterX) * 0.5;
  const SkScalar x2 = RenderCenterX;
  const SkScalar x3 = (RenderRight + RenderCenterX) * 0.5;
  const SkScalar x4 = RenderRight;

  const SkScalar y0 = RenderTop;
  const SkScalar y1 = (RenderTop + RenderCenterY) * 0.5;
  const SkScalar y2 = RenderCenterY;
  const SkScalar y3 = (RenderBottom + RenderCenterY) * 0.5;
  const SkScalar y4 = RenderBottom;

  // clang-format off
  const SkPoint points[] = {
      {x0, y0}, {x1, y0}, {x2, y0}, {x3, y0}, {x4, y0},
      {x0, y1}, {x1, y1}, {x2, y1}, {x3, y1}, {x4, y1},
      {x0, y2}, {x1, y2}, {x2, y2}, {x3, y2}, {x4, y2},
      {x0, y3}, {x1, y3}, {x2, y3}, {x3, y3}, {x4, y3},
      {x0, y4}, {x1, y4}, {x2, y4}, {x3, y4}, {x4, y4},
  };
  // clang-format on

  const int count = sizeof(points) / sizeof(points[0]);
  CanvasCompareTester::RenderAll(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        SkPaint p = paint;
        p.setStyle(SkPaint::kStroke_Style);
        canvas->drawPoints(SkCanvas::kPoints_PointMode, count, points, p);
      },
      [=](DisplayListBuilder& builder) {  //
        builder.drawPoints(SkCanvas::kPoints_PointMode, count, points);
      });
}

TEST(DisplayListCanvas, DrawPointsAsLines) {
  const SkScalar x0 = RenderLeft;
  const SkScalar x1 = (RenderLeft + RenderCenterX) * 0.5;
  const SkScalar x2 = RenderCenterX;
  const SkScalar x3 = (RenderRight + RenderCenterX) * 0.5;
  const SkScalar x4 = RenderRight;

  const SkScalar y0 = RenderTop;
  const SkScalar y1 = (RenderTop + RenderCenterY) * 0.5;
  const SkScalar y2 = RenderCenterY;
  const SkScalar y3 = (RenderBottom + RenderCenterY) * 0.5;
  const SkScalar y4 = RenderBottom;

  // clang-format off
  const SkPoint points[] = {
      // Diagonals
      {x0, y0}, {x4, y4}, {x4, y0}, {x0, y4},
      // Inner box
      {x1, y1}, {x3, y1},
      {x3, y1}, {x3, y3},
      {x3, y3}, {x1, y3},
      {x1, y3}, {x1, y1},
      // Middle crosshair
      {x2, y1}, {x2, y3},
      {x1, y2}, {x3, y3},
  };
  // clang-format on

  const int count = sizeof(points) / sizeof(points[0]);
  ASSERT_TRUE((count & 1) == 0);
  CanvasCompareTester::RenderAll(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        SkPaint p = paint;
        p.setStyle(SkPaint::kStroke_Style);
        canvas->drawPoints(SkCanvas::kLines_PointMode, count, points, p);
      },
      [=](DisplayListBuilder& builder) {  //
        builder.drawPoints(SkCanvas::kLines_PointMode, count, points);
      });
}

TEST(DisplayListCanvas, DrawPointsAsPolygon) {
  const SkPoint points[] = {
      SkPoint::Make(RenderLeft, RenderTop),
      SkPoint::Make(RenderRight, RenderBottom),
      SkPoint::Make(RenderRight, RenderTop),
      SkPoint::Make(RenderLeft, RenderBottom),
      SkPoint::Make(RenderLeft, RenderTop),
  };
  CanvasCompareTester::RenderAll(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        SkPaint p = paint;
        p.setStyle(SkPaint::kStroke_Style);
        canvas->drawPoints(SkCanvas::kPolygon_PointMode, 4, points, p);
      },
      [=](DisplayListBuilder& builder) {  //
        builder.drawPoints(SkCanvas::kPolygon_PointMode, 4, points);
      });
}

TEST(DisplayListCanvas, DrawVerticesWithColors) {
  const SkPoint pts[3] = {
      SkPoint::Make(RenderCenterX, RenderTop),
      SkPoint::Make(RenderLeft, RenderBottom),
      SkPoint::Make(RenderRight, RenderBottom),
  };
  const SkColor colors[3] = {SK_ColorRED, SK_ColorBLUE, SK_ColorGREEN};
  const sk_sp<SkVertices> vertices = SkVertices::MakeCopy(
      SkVertices::kTriangles_VertexMode, 3, pts, nullptr, colors);
  CanvasCompareTester::RenderVertices(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        canvas->drawVertices(vertices.get(), SkBlendMode::kSrcOver, paint);
      },
      [=](DisplayListBuilder& builder) {  //
        builder.drawVertices(vertices, SkBlendMode::kSrcOver);
      });
  ASSERT_TRUE(vertices->unique());
}

TEST(DisplayListCanvas, DrawVerticesWithImage) {
  const SkPoint pts[3] = {
      SkPoint::Make(RenderCenterX, RenderTop),
      SkPoint::Make(RenderLeft, RenderBottom),
      SkPoint::Make(RenderRight, RenderBottom),
  };
  const SkPoint tex[3] = {
      SkPoint::Make(RenderWidth / 2.0, 0),
      SkPoint::Make(0, RenderHeight),
      SkPoint::Make(RenderWidth, RenderHeight),
  };
  const sk_sp<SkVertices> vertices = SkVertices::MakeCopy(
      SkVertices::kTriangles_VertexMode, 3, pts, tex, nullptr);
  const sk_sp<SkShader> shader = CanvasCompareTester::testImage->makeShader(
      SkTileMode::kRepeat, SkTileMode::kRepeat, SkSamplingOptions());
  CanvasCompareTester::RenderVertices(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        paint.setShader(shader);
        canvas->drawVertices(vertices.get(), SkBlendMode::kSrcOver, paint);
      },
      [=](DisplayListBuilder& builder) {  //
        builder.setShader(shader);
        builder.drawVertices(vertices, SkBlendMode::kSrcOver);
      });
  ASSERT_TRUE(vertices->unique());
  ASSERT_TRUE(shader->unique());
}

TEST(DisplayListCanvas, DrawImageNearest) {
  CanvasCompareTester::RenderAll(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        canvas->drawImage(CanvasCompareTester::testImage, RenderLeft, RenderTop,
                          DisplayList::NearestSampling, &paint);
      },
      [=](DisplayListBuilder& builder) {  //
        builder.drawImage(CanvasCompareTester::testImage,
                          SkPoint::Make(RenderLeft, RenderTop),
                          DisplayList::NearestSampling);
      });
}

TEST(DisplayListCanvas, DrawImageLinear) {
  CanvasCompareTester::RenderAll(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        canvas->drawImage(CanvasCompareTester::testImage, RenderLeft, RenderTop,
                          DisplayList::LinearSampling, &paint);
      },
      [=](DisplayListBuilder& builder) {  //
        builder.drawImage(CanvasCompareTester::testImage,
                          SkPoint::Make(RenderLeft, RenderTop),
                          DisplayList::LinearSampling);
      });
}

TEST(DisplayListCanvas, DrawImageRectNearest) {
  SkRect src = SkRect::MakeIWH(RenderWidth, RenderHeight).makeInset(5, 5);
  SkRect dst = RenderBounds.makeInset(15.5, 10.5);
  CanvasCompareTester::RenderAll(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        canvas->drawImageRect(CanvasCompareTester::testImage, src, dst,
                              DisplayList::NearestSampling, &paint,
                              SkCanvas::kFast_SrcRectConstraint);
      },
      [=](DisplayListBuilder& builder) {  //
        builder.drawImageRect(CanvasCompareTester::testImage, src, dst,
                              DisplayList::NearestSampling);
      });
}

TEST(DisplayListCanvas, DrawImageRectLinear) {
  SkRect src = SkRect::MakeIWH(RenderWidth, RenderHeight).makeInset(5, 5);
  SkRect dst = RenderBounds.makeInset(15.5, 10.5);
  CanvasCompareTester::RenderAll(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        canvas->drawImageRect(CanvasCompareTester::testImage, src, dst,
                              DisplayList::LinearSampling, &paint,
                              SkCanvas::kFast_SrcRectConstraint);
      },
      [=](DisplayListBuilder& builder) {  //
        builder.drawImageRect(CanvasCompareTester::testImage, src, dst,
                              DisplayList::LinearSampling);
      });
}

TEST(DisplayListCanvas, DrawImageNineNearest) {
  SkIRect src = SkIRect::MakeWH(RenderWidth, RenderHeight).makeInset(5, 5);
  SkRect dst = RenderBounds.makeInset(15.5, 10.5);
  CanvasCompareTester::RenderAll(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        canvas->drawImageNine(CanvasCompareTester::testImage.get(), src, dst,
                              SkFilterMode::kNearest, &paint);
      },
      [=](DisplayListBuilder& builder) {  //
        builder.drawImageNine(CanvasCompareTester::testImage, src, dst,
                              SkFilterMode::kNearest);
      });
}

TEST(DisplayListCanvas, DrawImageNineLinear) {
  SkIRect src = SkIRect::MakeWH(RenderWidth, RenderHeight).makeInset(5, 5);
  SkRect dst = RenderBounds.makeInset(15.5, 10.5);
  CanvasCompareTester::RenderAll(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        canvas->drawImageNine(CanvasCompareTester::testImage.get(), src, dst,
                              SkFilterMode::kLinear, &paint);
      },
      [=](DisplayListBuilder& builder) {  //
        builder.drawImageNine(CanvasCompareTester::testImage, src, dst,
                              SkFilterMode::kLinear);
      });
}

TEST(DisplayListCanvas, DrawImageLatticeNearest) {
  const SkRect dst = RenderBounds.makeInset(15.5, 10.5);
  const int divX[] = {
      (RenderLeft + RenderCenterX) / 2,
      RenderCenterX,
      (RenderRight + RenderCenterX) / 2,
  };
  const int divY[] = {
      (RenderTop + RenderCenterY) / 2,
      RenderCenterY,
      (RenderBottom + RenderCenterY) / 2,
  };
  SkCanvas::Lattice lattice = {
      divX, divY, nullptr, 3, 3, nullptr, nullptr,
  };
  CanvasCompareTester::RenderAll(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        canvas->drawImageLattice(CanvasCompareTester::testImage.get(), lattice,
                                 dst, SkFilterMode::kNearest, &paint);
      },
      [=](DisplayListBuilder& builder) {                                   //
        builder.drawImageLattice(CanvasCompareTester::testImage, lattice,  //
                                 dst, SkFilterMode::kNearest, true);
      });
}

TEST(DisplayListCanvas, DrawImageLatticeLinear) {
  const SkRect dst = RenderBounds.makeInset(15.5, 10.5);
  const int divX[] = {
      (RenderLeft + RenderCenterX) / 2,
      RenderCenterX,
      (RenderRight + RenderCenterX) / 2,
  };
  const int divY[] = {
      (RenderTop + RenderCenterY) / 2,
      RenderCenterY,
      (RenderBottom + RenderCenterY) / 2,
  };
  SkCanvas::Lattice lattice = {
      divX, divY, nullptr, 3, 3, nullptr, nullptr,
  };
  CanvasCompareTester::RenderAll(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        canvas->drawImageLattice(CanvasCompareTester::testImage.get(), lattice,
                                 dst, SkFilterMode::kLinear, &paint);
      },
      [=](DisplayListBuilder& builder) {                                   //
        builder.drawImageLattice(CanvasCompareTester::testImage, lattice,  //
                                 dst, SkFilterMode::kLinear, true);
      });
}

TEST(DisplayListCanvas, DrawAtlasNearest) {
  const SkRSXform xform[] = {
      {0.5, 0, RenderLeft, RenderRight},
      {0, 0.5, RenderCenterX, RenderCenterY},
  };
  const SkRect tex[] = {
      {0, 0, RenderWidth * 0.5, RenderHeight * 0.5},
      {RenderWidth * 0.5, RenderHeight * 0.5, RenderWidth, RenderHeight},
  };
  const SkColor colors[] = {
      SK_ColorBLUE,
      SK_ColorGREEN,
  };
  const sk_sp<SkImage> image = CanvasCompareTester::testImage;
  CanvasCompareTester::RenderAtlas(
      [=](SkCanvas* canvas, SkPaint& paint) {
        canvas->drawAtlas(image.get(), xform, tex, colors, 2,
                          SkBlendMode::kSrcOver, DisplayList::NearestSampling,
                          nullptr, &paint);
      },
      [=](DisplayListBuilder& builder) {
        builder.drawAtlas(image, xform, tex, colors, 2,  //
                          SkBlendMode::kSrcOver, DisplayList::NearestSampling,
                          nullptr);
      });
}

TEST(DisplayListCanvas, DrawAtlasLinear) {
  const SkRSXform xform[] = {
      {0.5, 0, RenderLeft, RenderRight},
      {0, 0.5, RenderCenterX, RenderCenterY},
  };
  const SkRect tex[] = {
      {0, 0, RenderWidth * 0.5, RenderHeight * 0.5},
      {RenderWidth * 0.5, RenderHeight * 0.5, RenderWidth, RenderHeight},
  };
  const SkColor colors[] = {
      SK_ColorBLUE,
      SK_ColorGREEN,
  };
  const sk_sp<SkImage> image = CanvasCompareTester::testImage;
  CanvasCompareTester::RenderAtlas(
      [=](SkCanvas* canvas, SkPaint& paint) {
        canvas->drawAtlas(image.get(), xform, tex, colors, 2,  //
                          SkBlendMode::kSrcOver, DisplayList::LinearSampling,
                          nullptr, &paint);
      },
      [=](DisplayListBuilder& builder) {
        builder.drawAtlas(image, xform, tex, colors, 2,  //
                          SkBlendMode::kSrcOver, DisplayList::LinearSampling,
                          nullptr);
      });
}

TEST(DisplayListCanvas, DrawPicture) {
  SkPictureRecorder recorder;
  SkCanvas* cv = recorder.beginRecording(RenderBounds);
  SkPaint p;
  p.setStyle(SkPaint::kFill_Style);
  p.setColor(SK_ColorBLUE);
  cv->drawOval(RenderBounds, p);
  sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture();
  CanvasCompareTester::RenderNoAttributes(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        canvas->drawPicture(picture, nullptr, nullptr);
      },
      [=](DisplayListBuilder& builder) {  //
        builder.drawPicture(picture, nullptr, false);
      });
}

TEST(DisplayListCanvas, DrawPictureWithMatrix) {
  SkPictureRecorder recorder;
  SkCanvas* cv = recorder.beginRecording(RenderBounds);
  SkPaint p;
  p.setStyle(SkPaint::kFill_Style);
  p.setColor(SK_ColorBLUE);
  cv->drawOval(RenderBounds, p);
  sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture();
  SkMatrix matrix = SkMatrix::Scale(0.95, 0.95);
  CanvasCompareTester::RenderNoAttributes(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        canvas->drawPicture(picture, &matrix, nullptr);
      },
      [=](DisplayListBuilder& builder) {  //
        builder.drawPicture(picture, &matrix, false);
      });
}

TEST(DisplayListCanvas, DrawPictureWithPaint) {
  SkPictureRecorder recorder;
  SkCanvas* cv = recorder.beginRecording(RenderBounds);
  SkPaint p;
  p.setStyle(SkPaint::kFill_Style);
  p.setColor(SK_ColorBLUE);
  cv->drawOval(RenderBounds, p);
  sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture();
  CanvasCompareTester::RenderAll(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        canvas->drawPicture(picture, nullptr, &paint);
      },
      [=](DisplayListBuilder& builder) {  //
        builder.drawPicture(picture, nullptr, true);
      });
}

TEST(DisplayListCanvas, DrawDisplayList) {
  DisplayListBuilder builder;
  builder.setDrawStyle(SkPaint::kFill_Style);
  builder.setColor(SK_ColorBLUE);
  builder.drawOval(RenderBounds);
  sk_sp<DisplayList> display_list = builder.Build();
  CanvasCompareTester::RenderNoAttributes(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        display_list->RenderTo(canvas);
      },
      [=](DisplayListBuilder& builder) {  //
        builder.drawDisplayList(display_list);
      });
}

TEST(DisplayListCanvas, DrawTextBlob) {
  // TODO(https://github.com/flutter/flutter/issues/82202): Remove once the
  // performance overlay can use Fuchsia's font manager instead of the empty
  // default.
#if defined(OS_FUCHSIA)
  GTEST_SKIP() << "Rendering comparisons require a valid default font manager";
#endif  // OS_FUCHSIA
  sk_sp<SkTextBlob> blob = CanvasCompareTester::MakeTextBlob("Test Blob");
  CanvasCompareTester::RenderNoAttributes(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        canvas->drawTextBlob(blob, RenderLeft, RenderBottom, paint);
      },
      [=](DisplayListBuilder& builder) {  //
        builder.drawTextBlob(blob, RenderLeft, RenderBottom);
      });
}

TEST(DisplayListCanvas, DrawShadow) {
  SkPath path;
  path.moveTo(RenderCenterX, RenderTop);
  path.lineTo(RenderRight, RenderBottom);
  path.lineTo(RenderLeft, RenderCenterY);
  path.lineTo(RenderRight, RenderCenterY);
  path.lineTo(RenderLeft, RenderBottom);
  path.close();
  const SkColor color = SK_ColorDKGRAY;
  const SkScalar elevation = 10;

  CanvasCompareTester::RenderShadows(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        PhysicalShapeLayer::DrawShadow(canvas, path, color, elevation, false,
                                       1.0);
      },
      [=](DisplayListBuilder& builder) {  //
        builder.drawShadow(path, color, elevation, false, 1.0);
      });
}

TEST(DisplayListCanvas, DrawOccludingShadow) {
  SkPath path;
  path.moveTo(RenderCenterX, RenderTop);
  path.lineTo(RenderRight, RenderBottom);
  path.lineTo(RenderLeft, RenderCenterY);
  path.lineTo(RenderRight, RenderCenterY);
  path.lineTo(RenderLeft, RenderBottom);
  path.close();
  const SkColor color = SK_ColorDKGRAY;
  const SkScalar elevation = 10;

  CanvasCompareTester::RenderShadows(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        PhysicalShapeLayer::DrawShadow(canvas, path, color, elevation, true,
                                       1.0);
      },
      [=](DisplayListBuilder& builder) {  //
        builder.drawShadow(path, color, elevation, true, 1.0);
      });
}

TEST(DisplayListCanvas, DrawShadowDpr) {
  SkPath path;
  path.moveTo(RenderCenterX, RenderTop);
  path.lineTo(RenderRight, RenderBottom);
  path.lineTo(RenderLeft, RenderCenterY);
  path.lineTo(RenderRight, RenderCenterY);
  path.lineTo(RenderLeft, RenderBottom);
  path.close();
  const SkColor color = SK_ColorDKGRAY;
  const SkScalar elevation = 10;

  CanvasCompareTester::RenderShadows(
      [=](SkCanvas* canvas, SkPaint& paint) {  //
        PhysicalShapeLayer::DrawShadow(canvas, path, color, elevation, false,
                                       2.5);
      },
      [=](DisplayListBuilder& builder) {  //
        builder.drawShadow(path, color, elevation, false, 2.5);
      });
}

}  // namespace testing
}  // namespace flutter
