/*
 * Copyright 2019 Google LLC
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "include/core/SkMatrix.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkScalar.h"
#include "include/core/SkTypes.h"
#include "include/private/gpu/ganesh/GrTypesPriv.h"
#include "src/gpu/ganesh/geometry/GrQuad.h"
#include "src/gpu/ganesh/geometry/GrQuadUtils.h"
#include "tests/Test.h"

#define ASSERT(cond) REPORTER_ASSERT(r, cond)
#define ASSERTF(cond, ...) REPORTER_ASSERT(r, cond, __VA_ARGS__)
#define TEST(name) DEF_TEST(GrQuadCrop##name, r)
#define ASSERT_NEARLY_EQUAL(expected, actual) \
    ASSERTF(SkScalarNearlyEqual(expected, actual), "expected: %f, actual: %f", \
            expected, actual)

// Make the base rect contain the origin and have unique edge values so that each transform
// produces a different axis-aligned rectangle.
static const SkRect kDrawRect = SkRect::MakeLTRB(-5.f, -6.f, 10.f, 11.f);

static void run_crop_axis_aligned_test(skiatest::Reporter* r, const SkRect& clipRect, GrAA clipAA,
                                       const SkMatrix& viewMatrix, const SkMatrix* localMatrix) {
    // Should use run_crop_fully_covers_test for non-rect matrices
    SkASSERT(viewMatrix.rectStaysRect());

    DrawQuad quad = {GrQuad::MakeFromRect(kDrawRect, viewMatrix),
                     GrQuad::MakeFromRect(kDrawRect, localMatrix ? *localMatrix : SkMatrix::I()),
                     clipAA == GrAA::kYes ? GrQuadAAFlags::kNone : GrQuadAAFlags::kAll};

    bool exact = GrQuadUtils::CropToRect(clipRect, clipAA, &quad, /* calc. locals */ !!localMatrix);
    ASSERTF(exact, "Expected exact crop");
    ASSERTF(quad.fDevice.quadType() == GrQuad::Type::kAxisAligned,
            "Expected quad to remain axis-aligned");

    // Since we remained a rectangle, the bounds will exactly match the coordinates
    SkRect expectedBounds = viewMatrix.mapRect(kDrawRect);
    SkAssertResult(expectedBounds.intersect(clipRect));

    SkRect actualBounds = quad.fDevice.bounds();
    ASSERT_NEARLY_EQUAL(expectedBounds.fLeft, actualBounds.fLeft);
    ASSERT_NEARLY_EQUAL(expectedBounds.fTop, actualBounds.fTop);
    ASSERT_NEARLY_EQUAL(expectedBounds.fRight, actualBounds.fRight);
    ASSERT_NEARLY_EQUAL(expectedBounds.fBottom, actualBounds.fBottom);

    // Confirm that local coordinates match up with clipped edges and the transform
    SkMatrix invViewMatrix;
    SkAssertResult(viewMatrix.invert(&invViewMatrix));

    if (localMatrix) {
        SkMatrix toLocal = SkMatrix::Concat(*localMatrix, invViewMatrix);

        for (int p = 0; p < 4; ++p) {
            SkPoint expectedPoint = toLocal.mapPoint(quad.fDevice.point(p));
            SkPoint actualPoint = quad.fLocal.point(p);

            ASSERT_NEARLY_EQUAL(expectedPoint.fX, actualPoint.fX);
            ASSERT_NEARLY_EQUAL(expectedPoint.fY, actualPoint.fY);
        }
    }

    // Confirm that the edge flags match, by mapping clip rect to drawRect space and
    // comparing to the original draw rect edges
    SkRect drawClip = invViewMatrix.mapRect(clipRect);
    if (drawClip.fLeft > kDrawRect.fLeft) {
        if (clipAA == GrAA::kYes) {
            ASSERTF(quad.fEdgeFlags & GrQuadAAFlags::kLeft, "Expected left edge AA set");
        } else {
            ASSERTF(!(quad.fEdgeFlags & GrQuadAAFlags::kLeft), "Expected left edge AA unset");
        }
    }
    if (drawClip.fRight < kDrawRect.fRight) {
        if (clipAA == GrAA::kYes) {
            ASSERTF(quad.fEdgeFlags & GrQuadAAFlags::kRight, "Expected right edge AA set");
        } else {
            ASSERTF(!(quad.fEdgeFlags & GrQuadAAFlags::kRight),  "Expected right edge AA unset");
        }
    }
    if (drawClip.fTop > kDrawRect.fTop) {
        if (clipAA == GrAA::kYes) {
            ASSERTF(quad.fEdgeFlags & GrQuadAAFlags::kTop, "Expected top edge AA set");
        } else {
            ASSERTF(!(quad.fEdgeFlags & GrQuadAAFlags::kTop), "Expected top edge AA unset");
        }
    }
    if (drawClip.fBottom < kDrawRect.fBottom) {
        if (clipAA == GrAA::kYes) {
            ASSERTF(quad.fEdgeFlags & GrQuadAAFlags::kBottom, "Expected bottom edge AA set");
        } else {
            ASSERTF(!(quad.fEdgeFlags & GrQuadAAFlags::kBottom), "Expected bottom edge AA unset");
        }
    }
}

static void run_crop_fully_covered_test(skiatest::Reporter* r, GrAA clipAA,
                                        const SkMatrix& viewMatrix, const SkMatrix* localMatrix) {
    // Should use run_crop_axis_aligned for rect transforms since that verifies more behavior
    SkASSERT(!viewMatrix.rectStaysRect());

    // Test what happens when the geometry fully covers the crop rect. Given a fixed crop,
    // use the provided view matrix to derive the "input" geometry that we know covers the crop.
    SkMatrix invViewMatrix;
    SkAssertResult(viewMatrix.invert(&invViewMatrix));

    SkRect containsCrop = kDrawRect; // Use kDrawRect as the crop rect for this test
    containsCrop.outset(10.f, 10.f);
    SkRect drawRect = invViewMatrix.mapRect(containsCrop);

    DrawQuad quad = {GrQuad::MakeFromRect(drawRect, viewMatrix),
                     GrQuad::MakeFromRect(drawRect, localMatrix ? *localMatrix : SkMatrix::I()),
                     clipAA == GrAA::kYes ? GrQuadAAFlags::kNone : GrQuadAAFlags::kAll};

    if (localMatrix) {
        DrawQuad originalQuad = quad;

        bool exact = GrQuadUtils::CropToRect(kDrawRect, clipAA, &quad);
        // Currently non-rect matrices don't know how to update local coordinates, so the crop
        // doesn't know how to restrict itself and should leave the inputs unmodified
        ASSERTF(!exact, "Expected crop to be not exact");
        ASSERTF(quad.fEdgeFlags == originalQuad.fEdgeFlags,
                "Expected edge flags not to be modified");

        for (int i = 0; i < 4; ++i) {
            ASSERT_NEARLY_EQUAL(originalQuad.fDevice.x(i), quad.fDevice.x(i));
            ASSERT_NEARLY_EQUAL(originalQuad.fDevice.y(i), quad.fDevice.y(i));
            ASSERT_NEARLY_EQUAL(originalQuad.fDevice.w(i), quad.fDevice.w(i));

            ASSERT_NEARLY_EQUAL(originalQuad.fLocal.x(i), quad.fLocal.x(i));
            ASSERT_NEARLY_EQUAL(originalQuad.fLocal.y(i), quad.fLocal.y(i));
            ASSERT_NEARLY_EQUAL(originalQuad.fLocal.w(i), quad.fLocal.w(i));
        }
    } else {
        // Since no local coordinates were provided, and the input draw geometry is known to
        // fully cover the crop rect, the quad should be updated to match cropRect exactly,
        // unless it's perspective in which case we don't do anything since the code isn't
        // numerically robust enough.
        DrawQuad originalQuad = quad;
        bool exact = GrQuadUtils::CropToRect(kDrawRect, clipAA, &quad, /* calc. local */ false);
        if (originalQuad.fDevice.quadType() == GrQuad::Type::kPerspective) {
            ASSERTF(!exact, "Expected no change for perspective");
            for (int i = 0; i < 4; ++i) {
                ASSERTF(originalQuad.fDevice.x(i) == quad.fDevice.x(i));
                ASSERTF(originalQuad.fDevice.y(i) == quad.fDevice.y(i));
                ASSERTF(originalQuad.fDevice.w(i) == quad.fDevice.w(i));
            }
            return;
        }

        ASSERTF(exact, "Expected crop to be exact");
        GrQuadAAFlags expectedFlags = clipAA == GrAA::kYes ? GrQuadAAFlags::kAll
                                                           : GrQuadAAFlags::kNone;
        ASSERTF(expectedFlags == quad.fEdgeFlags,
                "Expected edge flags do not match clip AA setting");
        ASSERTF(quad.fDevice.quadType() == GrQuad::Type::kAxisAligned, "Unexpected quad type");

        ASSERT_NEARLY_EQUAL(kDrawRect.fLeft, quad.fDevice.x(0));
        ASSERT_NEARLY_EQUAL(kDrawRect.fTop, quad.fDevice.y(0));
        ASSERT_NEARLY_EQUAL(1.f, quad.fDevice.w(0));

        ASSERT_NEARLY_EQUAL(kDrawRect.fLeft, quad.fDevice.x(1));
        ASSERT_NEARLY_EQUAL(kDrawRect.fBottom, quad.fDevice.y(1));
        ASSERT_NEARLY_EQUAL(1.f, quad.fDevice.w(1));

        ASSERT_NEARLY_EQUAL(kDrawRect.fRight, quad.fDevice.x(2));
        ASSERT_NEARLY_EQUAL(kDrawRect.fTop, quad.fDevice.y(2));
        ASSERT_NEARLY_EQUAL(1.f, quad.fDevice.w(2));

        ASSERT_NEARLY_EQUAL(kDrawRect.fRight, quad.fDevice.x(3));
        ASSERT_NEARLY_EQUAL(kDrawRect.fBottom, quad.fDevice.y(3));
        ASSERT_NEARLY_EQUAL(1.f, quad.fDevice.w(3));
    }
}

static void test_axis_aligned_all_clips(skiatest::Reporter* r, const SkMatrix& viewMatrix,
                                        const SkMatrix* localMatrix) {
    static const float kInsideEdge = SkScalarAbs(kDrawRect.fLeft) - 1.f;
    static const float kOutsideEdge = SkScalarAbs(kDrawRect.fBottom) + 1.f;
    static const float kIntersectEdge = SkScalarAbs(kDrawRect.fTop) + 1.f;

    static const SkRect kInsideClipRect = SkRect::MakeLTRB(-kInsideEdge, -kInsideEdge,
                                                           kInsideEdge, kInsideEdge);
    static const SkRect kContainsClipRect = SkRect::MakeLTRB(-kOutsideEdge, -kOutsideEdge,
                                                             kOutsideEdge, kOutsideEdge);
    static const SkRect kXYAxesClipRect = SkRect::MakeLTRB(-kIntersectEdge, -kIntersectEdge,
                                                           kIntersectEdge, kIntersectEdge);
    static const SkRect kXAxisClipRect = SkRect::MakeLTRB(-kIntersectEdge, -kOutsideEdge,
                                                          kIntersectEdge, kOutsideEdge);
    static const SkRect kYAxisClipRect = SkRect::MakeLTRB(-kOutsideEdge, -kIntersectEdge,
                                                          kOutsideEdge, kIntersectEdge);

    run_crop_axis_aligned_test(r, kInsideClipRect, GrAA::kNo, viewMatrix, localMatrix);
    run_crop_axis_aligned_test(r, kContainsClipRect, GrAA::kNo, viewMatrix, localMatrix);
    run_crop_axis_aligned_test(r, kXYAxesClipRect, GrAA::kNo, viewMatrix, localMatrix);
    run_crop_axis_aligned_test(r, kXAxisClipRect, GrAA::kNo, viewMatrix, localMatrix);
    run_crop_axis_aligned_test(r, kYAxisClipRect, GrAA::kNo, viewMatrix, localMatrix);

    run_crop_axis_aligned_test(r, kInsideClipRect, GrAA::kYes, viewMatrix, localMatrix);
    run_crop_axis_aligned_test(r, kContainsClipRect, GrAA::kYes, viewMatrix, localMatrix);
    run_crop_axis_aligned_test(r, kXYAxesClipRect, GrAA::kYes, viewMatrix, localMatrix);
    run_crop_axis_aligned_test(r, kXAxisClipRect, GrAA::kYes, viewMatrix, localMatrix);
    run_crop_axis_aligned_test(r, kYAxisClipRect, GrAA::kYes, viewMatrix, localMatrix);
}

static void test_axis_aligned(skiatest::Reporter* r, const SkMatrix& viewMatrix) {
    test_axis_aligned_all_clips(r, viewMatrix, nullptr);

    SkMatrix normalized = SkMatrix::RectToRectOrIdentity(kDrawRect, SkRect::MakeWH(1.f, 1.f));
    test_axis_aligned_all_clips(r, viewMatrix, &normalized);

    SkMatrix rotated;
    rotated.setRotate(45.f);
    test_axis_aligned_all_clips(r, viewMatrix, &rotated);

    SkMatrix perspective;
    perspective.setPerspY(0.001f);
    perspective.setSkewX(8.f / 25.f);
    test_axis_aligned_all_clips(r, viewMatrix, &perspective);
}

static void test_crop_fully_covered(skiatest::Reporter* r, const SkMatrix& viewMatrix) {
    run_crop_fully_covered_test(r, GrAA::kNo, viewMatrix, nullptr);
    run_crop_fully_covered_test(r, GrAA::kYes, viewMatrix, nullptr);

    SkMatrix normalized = SkMatrix::RectToRectOrIdentity(kDrawRect, SkRect::MakeWH(1.f, 1.f));
    run_crop_fully_covered_test(r, GrAA::kNo, viewMatrix, &normalized);
    run_crop_fully_covered_test(r, GrAA::kYes, viewMatrix, &normalized);

    SkMatrix rotated;
    rotated.setRotate(45.f);
    run_crop_fully_covered_test(r, GrAA::kNo, viewMatrix, &rotated);
    run_crop_fully_covered_test(r, GrAA::kYes, viewMatrix, &rotated);

    SkMatrix perspective;
    perspective.setPerspY(0.001f);
    perspective.setSkewX(8.f / 25.f);
    run_crop_fully_covered_test(r, GrAA::kNo, viewMatrix, &perspective);
    run_crop_fully_covered_test(r, GrAA::kYes, viewMatrix, &perspective);
}

TEST(AxisAligned) {
    test_axis_aligned(r, SkMatrix::I());
    test_axis_aligned(r, SkMatrix::Scale(-1.f, 1.f));
    test_axis_aligned(r, SkMatrix::Scale(1.f, -1.f));

    SkMatrix rotation;
    rotation.setRotate(90.f);
    test_axis_aligned(r, rotation);
    rotation.setRotate(180.f);
    test_axis_aligned(r, rotation);
    rotation.setRotate(270.f);
    test_axis_aligned(r, rotation);
}

TEST(FullyCovered) {
    SkMatrix rotation;
    rotation.setRotate(34.f);
    test_crop_fully_covered(r, rotation);

    SkMatrix skew;
    skew.setSkewX(0.3f);
    skew.setSkewY(0.04f);
    test_crop_fully_covered(r, skew);

    SkMatrix perspective;
    perspective.setPerspX(0.001f);
    perspective.setSkewY(8.f / 25.f);
    test_crop_fully_covered(r, perspective);
}
