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

#include "tests/Test.h"

#include "include/private/SkFloatingPoint.h"
#include "src/core/SkGeometry.h"
#include "src/gpu/geometry/GrPathUtils.h"
#include "src/gpu/mock/GrMockOpTarget.h"
#include "src/gpu/tessellate/GrStrokeIndirectTessellator.h"
#include "src/gpu/tessellate/GrStrokeTessellateShader.h"
#include "src/gpu/tessellate/GrTessellationPathRenderer.h"
#include "src/gpu/tessellate/GrWangsFormula.h"

static sk_sp<GrDirectContext> make_mock_context() {
    GrMockOptions mockOptions;
    mockOptions.fDrawInstancedSupport = true;
    mockOptions.fMaxTessellationSegments = 64;
    mockOptions.fMapBufferFlags = GrCaps::kCanMap_MapFlag;
    mockOptions.fConfigOptions[(int)GrColorType::kAlpha_8].fRenderability =
            GrMockOptions::ConfigOptions::Renderability::kMSAA;
    mockOptions.fConfigOptions[(int)GrColorType::kAlpha_8].fTexturable = true;
    mockOptions.fIntegerSupport = true;

    GrContextOptions ctxOptions;
    ctxOptions.fGpuPathRenderers = GpuPathRenderers::kTessellation;

    return GrDirectContext::MakeMock(&mockOptions, ctxOptions);
}

static void test_stroke(skiatest::Reporter* r, GrDirectContext* ctx, GrMockOpTarget* target,
                        const SkPath& path, SkRandom& rand) {
    SkStrokeRec stroke(SkStrokeRec::kFill_InitStyle);
    stroke.setStrokeStyle(.1f);
    for (auto join : {SkPaint::kMiter_Join, SkPaint::kRound_Join}) {
        stroke.setStrokeParams(SkPaint::kButt_Cap, join, 4);
        for (int i = 0; i < 16; ++i) {
            float scale = ldexpf(rand.nextF() + 1, i);
            auto matrix = SkMatrix::Scale(scale, scale);
            GrStrokeTessellator::PathStrokeList pathStrokeList(path, stroke, SK_PMColor4fWHITE);
            GrStrokeIndirectTessellator tessellator(GrStrokeTessellateShader::ShaderFlags::kNone,
                                                    matrix, &pathStrokeList, path.countVerbs(),
                                                    target->allocator());
            tessellator.verifyResolveLevels(r, target, matrix, path, stroke);
            tessellator.prepare(target, path.countVerbs());
            tessellator.verifyBuffers(r, target, matrix, stroke);
        }
    }
}

DEF_TEST(tessellate_GrStrokeIndirectTessellator, r) {
    auto ctx = make_mock_context();
    auto target = std::make_unique<GrMockOpTarget>(ctx);
    SkRandom rand;

    // Empty strokes.
    SkPath path = SkPath();
    test_stroke(r, ctx.get(), target.get(), path, rand);
    path.moveTo(1,1);
    test_stroke(r, ctx.get(), target.get(), path, rand);
    path.moveTo(1,1);
    test_stroke(r, ctx.get(), target.get(), path, rand);
    path.close();
    test_stroke(r, ctx.get(), target.get(), path, rand);
    path.moveTo(1,1);
    test_stroke(r, ctx.get(), target.get(), path, rand);

    // Single line.
    path = SkPath().lineTo(1,1);
    test_stroke(r, ctx.get(), target.get(), path, rand);
    path.close();
    test_stroke(r, ctx.get(), target.get(), path, rand);

    // Single quad.
    path = SkPath().quadTo(1,0,1,1);
    test_stroke(r, ctx.get(), target.get(), path, rand);
    path.close();
    test_stroke(r, ctx.get(), target.get(), path, rand);

    // Single cubic.
    path = SkPath().cubicTo(1,0,0,1,1,1);
    test_stroke(r, ctx.get(), target.get(), path, rand);
    path.close();
    test_stroke(r, ctx.get(), target.get(), path, rand);

    // All types of lines.
    path.reset();
    for (int i = 0; i < (1 << 4); ++i) {
        path.moveTo((i>>0)&1, (i>>1)&1);
        path.lineTo((i>>2)&1, (i>>3)&1);
        path.close();
    }
    test_stroke(r, ctx.get(), target.get(), path, rand);

    // All types of quads.
    path.reset();
    for (int i = 0; i < (1 << 6); ++i) {
        path.moveTo((i>>0)&1, (i>>1)&1);
        path.quadTo((i>>2)&1, (i>>3)&1, (i>>4)&1, (i>>5)&1);
        path.close();
    }
    test_stroke(r, ctx.get(), target.get(), path, rand);

    // All types of cubics.
    path.reset();
    for (int i = 0; i < (1 << 8); ++i) {
        path.moveTo((i>>0)&1, (i>>1)&1);
        path.cubicTo((i>>2)&1, (i>>3)&1, (i>>4)&1, (i>>5)&1, (i>>6)&1, (i>>7)&1);
        path.close();
    }
    test_stroke(r, ctx.get(), target.get(), path, rand);

    {
        // This cubic has a convex-180 chop at T=1-"epsilon"
        static const uint32_t hexPts[] = {0x3ee0ac74, 0x3f1e061a, 0x3e0fc408, 0x3f457230,
                                          0x3f42ac7c, 0x3f70d76c, 0x3f4e6520, 0x3f6acafa};
        SkPoint pts[4];
        memcpy(pts, hexPts, sizeof(pts));
        test_stroke(r, ctx.get(), target.get(),
                    SkPath().moveTo(pts[0]).cubicTo(pts[1], pts[2], pts[3]).close(), rand);
    }

    // Random paths.
    for (int j = 0; j < 50; ++j) {
        path.reset();
        // Empty contours behave differently if closed.
        path.moveTo(0,0);
        path.moveTo(0,0);
        path.close();
        path.moveTo(0,0);
        SkPoint startPoint = {rand.nextF(), rand.nextF()};
        path.moveTo(startPoint);
        // Degenerate curves get skipped.
        path.lineTo(startPoint);
        path.quadTo(startPoint, startPoint);
        path.cubicTo(startPoint, startPoint, startPoint);
        for (int i = 0; i < 100; ++i) {
            switch (rand.nextRangeU(0, 4)) {
                case 0:
                    path.lineTo(rand.nextF(), rand.nextF());
                    break;
                case 1:
                    path.quadTo(rand.nextF(), rand.nextF(), rand.nextF(), rand.nextF());
                    break;
                case 2:
                case 3:
                case 4:
                    path.cubicTo(rand.nextF(), rand.nextF(), rand.nextF(), rand.nextF(),
                                 rand.nextF(), rand.nextF());
                    break;
                default:
                    SkUNREACHABLE;
            }
            if (i % 19 == 0) {
                switch (i/19 % 4) {
                    case 0:
                        break;
                    case 1:
                        path.lineTo(startPoint);
                        break;
                    case 2:
                        path.quadTo(SkPoint::Make(1.1f, 1.1f), startPoint);
                        break;
                    case 3:
                        path.cubicTo(SkPoint::Make(1.1f, 1.1f), SkPoint::Make(1.1f, 1.1f),
                                     startPoint);
                        break;
                }
                path.close();
                if (rand.nextU() & 1) {  // Implicit or explicit move?
                    startPoint = {rand.nextF(), rand.nextF()};
                    path.moveTo(startPoint);
                }
            }
        }
        test_stroke(r, ctx.get(), target.get(), path, rand);
    }
}

// Returns the control point for the first/final join of a contour.
// If the contour is not closed, returns the start point.
static SkPoint get_contour_closing_control_point(SkPathPriv::RangeIter iter,
                                                 const SkPathPriv::RangeIter& end) {
    auto [verb, p, w] = *iter;
    SkASSERT(verb == SkPathVerb::kMove);
    // Peek ahead to find the last control point.
    SkPoint startPoint=p[0], lastControlPoint=p[0];
    for (++iter; iter != end; ++iter) {
        auto [verb, p, w] = *iter;
        switch (verb) {
            case SkPathVerb::kMove:
                return startPoint;
            case SkPathVerb::kCubic:
                if (p[2] != p[3]) {
                    lastControlPoint = p[2];
                    break;
                }
                [[fallthrough]];
            case SkPathVerb::kQuad:
                if (p[1] != p[2]) {
                    lastControlPoint = p[1];
                    break;
                }
                [[fallthrough]];
            case SkPathVerb::kLine:
                if (p[0] != p[1]) {
                    lastControlPoint = p[0];
                }
                break;
            case SkPathVerb::kConic:
                SkUNREACHABLE;
            case SkPathVerb::kClose:
                return (p[0] == startPoint) ? lastControlPoint : p[0];
        }
    }
    return startPoint;
}

static bool check_resolve_level(skiatest::Reporter* r,  float numCombinedSegments,
                                int8_t actualLevel, float tolerance, bool printError = true) {
    int8_t expectedLevel = sk_float_nextlog2(numCombinedSegments);
    if ((actualLevel > expectedLevel &&
         actualLevel > sk_float_nextlog2(numCombinedSegments + tolerance)) ||
        (actualLevel < expectedLevel &&
         actualLevel < sk_float_nextlog2(numCombinedSegments - tolerance))) {
        if (printError) {
            ERRORF(r, "expected %f segments => resolveLevel=%i (got %i)\n",
                   numCombinedSegments, expectedLevel, actualLevel);
        }
        return false;
    }
    return true;
}

static bool check_first_resolve_levels(skiatest::Reporter* r,
                                       const SkTArray<float>& firstNumSegments,
                                       int8_t** nextResolveLevel, float tolerance) {
    for (float numSegments : firstNumSegments) {
        if (numSegments < 0) {
            int8_t val = *(*nextResolveLevel)++;
            REPORTER_ASSERT(r, val == (int)numSegments);
            continue;
        }
        // The first stroke's resolve levels aren't  written out until the end of
        // the contour.
        if (!check_resolve_level(r, numSegments, *(*nextResolveLevel)++, tolerance)) {
            return false;
        }
    }
    return true;
}

static float test_tolerance(SkPaint::Join joinType) {
    // Ensure our fast approximation falls within 1.15 tessellation segments of the "correct"
    // answer. This is more than good enough when our matrix scale can go up to 2^17.
    float tolerance = 1.15f;
    if (joinType == SkPaint::kRound_Join) {
        // We approximate two different angles when there are round joins. Double the tolerance.
        tolerance *= 2;
    }
    return tolerance;
}

void GrStrokeIndirectTessellator::verifyResolveLevels(skiatest::Reporter* r,
                                                      GrMockOpTarget* target,
                                                      const SkMatrix& viewMatrix,
                                                      const SkPath& path,
                                                      const SkStrokeRec& stroke) {
    auto tolerances = GrStrokeTolerances::MakeNonHairline(viewMatrix.getMaxScale(),
                                                          stroke.getWidth());
    int8_t resolveLevelForCircles = SkTPin<float>(
            sk_float_nextlog2(tolerances.fNumRadialSegmentsPerRadian * SK_ScalarPI),
            1, kMaxResolveLevel);
    float tolerance = test_tolerance(stroke.getJoin());
    int8_t* nextResolveLevel = fResolveLevels;
    auto iterate = SkPathPriv::Iterate(path);
    SkSTArray<3, float> firstNumSegments;
    bool isFirstStroke = true;
    SkPoint startPoint = {0,0};
    SkPoint lastControlPoint;
    for (auto iter = iterate.begin(); iter != iterate.end(); ++iter) {
        auto [verb, pts, w] = *iter;
        switch (verb) {
            int n;
            SkPoint chops[10];
            case SkPathVerb::kMove:
                startPoint = pts[0];
                lastControlPoint = get_contour_closing_control_point(iter, iterate.end());
                if (!check_first_resolve_levels(r, firstNumSegments, &nextResolveLevel,
                                                tolerance)) {
                    return;
                }
                firstNumSegments.reset();
                isFirstStroke = true;
                break;
            case SkPathVerb::kLine:
                if (pts[0] == pts[1]) {
                    break;
                }
                if (stroke.getJoin() == SkPaint::kRound_Join) {
                    float rotation = SkMeasureAngleBetweenVectors(pts[0] - lastControlPoint,
                                                                  pts[1] - pts[0]);
                    float numSegments = rotation * tolerances.fNumRadialSegmentsPerRadian;
                    if (isFirstStroke) {
                        firstNumSegments.push_back(numSegments);
                    } else if (!check_resolve_level(r, numSegments, *nextResolveLevel++,
                                                    tolerance)) {
                        return;
                    }
                }
                lastControlPoint = pts[0];
                isFirstStroke = false;
                break;
            case SkPathVerb::kQuad: {
                if (pts[0] == pts[1] && pts[1] == pts[2]) {
                    break;
                }
                SkVector a = pts[1] - pts[0];
                SkVector b = pts[2] - pts[1];
                bool hasCusp = (a.cross(b) == 0 && a.dot(b) < 0);
                if (hasCusp) {
                    // The quad has a cusp. Make sure we wrote out a -resolveLevelForCircles.
                    if (isFirstStroke) {
                        firstNumSegments.push_back(-resolveLevelForCircles);
                    } else {
                        REPORTER_ASSERT(r, *nextResolveLevel++ == -resolveLevelForCircles);
                    }
                }
                float numParametricSegments = (hasCusp) ? 0 : GrWangsFormula::quadratic(
                        tolerances.fParametricPrecision, pts);
                float rotation = (hasCusp) ? 0 : SkMeasureQuadRotation(pts);
                if (stroke.getJoin() == SkPaint::kRound_Join) {
                    SkVector controlPoint = (pts[0] == pts[1]) ? pts[2] : pts[1];
                    rotation += SkMeasureAngleBetweenVectors(pts[0] - lastControlPoint,
                                                             controlPoint - pts[0]);
                }
                float numRadialSegments = rotation * tolerances.fNumRadialSegmentsPerRadian;
                float numSegments = numParametricSegments + numRadialSegments;
                if (!hasCusp || stroke.getJoin() == SkPaint::kRound_Join) {
                    if (isFirstStroke) {
                        firstNumSegments.push_back(numSegments);
                    } else if (!check_resolve_level(r, numSegments, *nextResolveLevel++,
                                                    tolerance)) {
                        return;
                    }
                }
                lastControlPoint = (pts[2] == pts[1]) ? pts[0] : pts[1];
                isFirstStroke = false;
                break;
            }
            case SkPathVerb::kCubic: {
                if (pts[0] == pts[1] && pts[1] == pts[2] && pts[2] == pts[3]) {
                    break;
                }
                float T[2];
                bool areCusps = false;
                n = GrPathUtils::findCubicConvex180Chops(pts, T, &areCusps);
                SkChopCubicAt(pts, chops, T, n);
                if (n > 0) {
                    int cuspResolveLevel = (areCusps) ? resolveLevelForCircles : 0;
                    int signal = -((n << 4) | cuspResolveLevel);
                    if (isFirstStroke) {
                        firstNumSegments.push_back((float)signal);
                    } else {
                        REPORTER_ASSERT(r, *nextResolveLevel++ == signal);
                    }
                }
                for (int i = 0; i <= n; ++i) {
                    // Find the number of segments with our unoptimized approach and make sure
                    // it matches the answer we got already.
                    SkPoint* p = chops + i*3;
                    float numParametricSegments =
                            GrWangsFormula::cubic(tolerances.fParametricPrecision, p);
                    SkVector tan0 =
                            ((p[0] == p[1]) ? (p[1] == p[2]) ? p[3] : p[2] : p[1]) - p[0];
                    SkVector tan1 =
                            p[3] - ((p[3] == p[2]) ? (p[2] == p[1]) ? p[0] : p[1] : p[2]);
                    float rotation = SkMeasureAngleBetweenVectors(tan0, tan1);
                    if (i == 0 && stroke.getJoin() == SkPaint::kRound_Join) {
                        rotation += SkMeasureAngleBetweenVectors(p[0] - lastControlPoint, tan0);
                    }
                    float numRadialSegments = rotation * tolerances.fNumRadialSegmentsPerRadian;
                    float numSegments = numParametricSegments + numRadialSegments;
                    if (isFirstStroke) {
                        firstNumSegments.push_back(numSegments);
                    } else if (!check_resolve_level(r, numSegments, *nextResolveLevel++,
                                                    tolerance)) {
                        return;
                    }
                }
                lastControlPoint =
                        (pts[3] == pts[2]) ? (pts[2] == pts[1]) ? pts[0] : pts[1] : pts[2];
                isFirstStroke = false;
                break;
            }
            case SkPathVerb::kConic:
                SkUNREACHABLE;
            case SkPathVerb::kClose:
                if (pts[0] != startPoint) {
                    SkASSERT(!isFirstStroke);
                    if (stroke.getJoin() == SkPaint::kRound_Join) {
                        // Line from pts[0] to startPoint, with a preceding join.
                        float rotation = SkMeasureAngleBetweenVectors(pts[0] - lastControlPoint,
                                                                      startPoint - pts[0]);
                        if (!check_resolve_level(
                                r, rotation * tolerances.fNumRadialSegmentsPerRadian,
                                *nextResolveLevel++, tolerance)) {
                            return;
                        }
                    }
                }
                if (!check_first_resolve_levels(r, firstNumSegments, &nextResolveLevel,
                                                tolerance)) {
                    return;
                }
                firstNumSegments.reset();
                isFirstStroke = true;
                break;
        }
    }
    if (!check_first_resolve_levels(r, firstNumSegments, &nextResolveLevel, tolerance)) {
        return;
    }
    firstNumSegments.reset();
    SkASSERT(nextResolveLevel == fResolveLevels + fResolveLevelArrayCount);
}

void GrStrokeIndirectTessellator::verifyBuffers(skiatest::Reporter* r, GrMockOpTarget* target,
                                                const SkMatrix& viewMatrix,
                                                const SkStrokeRec& stroke) {
    // Make sure the resolve level we assigned to each instance agrees with the actual data.
    struct IndirectInstance {
        SkPoint fPts[4];
        SkPoint fLastControlPoint;
        float fNumTotalEdges;
    };
    auto instance = static_cast<const IndirectInstance*>(target->peekStaticVertexData());
    auto* indirect = static_cast<const GrDrawIndirectCommand*>(target->peekStaticIndirectData());
    auto tolerances = GrStrokeTolerances::MakeNonHairline(viewMatrix.getMaxScale(),
                                                          stroke.getWidth());
    float tolerance = test_tolerance(stroke.getJoin());
    for (int i = 0; i < fChainedDrawIndirectCount; ++i) {
        int numExtraEdgesInJoin = (stroke.getJoin() == SkPaint::kMiter_Join) ? 4 : 3;
        int numStrokeEdges = indirect->fVertexCount/2 - numExtraEdgesInJoin;
        int numSegments = numStrokeEdges - 1;
        bool isPow2 = !(numSegments & (numSegments - 1));
        REPORTER_ASSERT(r, isPow2);
        int resolveLevel = sk_float_nextlog2(numSegments);
        REPORTER_ASSERT(r, 1 << resolveLevel == numSegments);
        for (unsigned j = 0; j < indirect->fInstanceCount; ++j) {
            SkASSERT(fabsf(instance->fNumTotalEdges) == indirect->fVertexCount/2);
            const SkPoint* p = instance->fPts;
            float numParametricSegments = GrWangsFormula::cubic(tolerances.fParametricPrecision, p);
            float alternateNumParametricSegments = numParametricSegments;
            if (p[0] == p[1] && p[2] == p[3]) {
                // We articulate lines as "p0,p0,p1,p1". This one might actually expect 0 parametric
                // segments.
                alternateNumParametricSegments = 0;
            }
            SkVector tan0 = ((p[0] == p[1]) ? (p[1] == p[2]) ? p[3] : p[2] : p[1]) - p[0];
            SkVector tan1 = p[3] - ((p[3] == p[2]) ? (p[2] == p[1]) ? p[0] : p[1] : p[2]);
            float rotation = SkMeasureAngleBetweenVectors(tan0, tan1);
            // Negative fNumTotalEdges means the curve is a chop, and chops always get treated as a
            // bevel join.
            if (stroke.getJoin() == SkPaint::kRound_Join && instance->fNumTotalEdges > 0) {
                SkVector lastTangent = p[0] - instance->fLastControlPoint;
                rotation += SkMeasureAngleBetweenVectors(lastTangent, tan0);
            }
            // Degenerate strokes are a special case that actually mean the GPU should draw a cusp
            // (i.e. circle).
            if (p[0] == p[1] && p[1] == p[2] && p[2] == p[3]) {
                rotation = SK_ScalarPI;
            }
            float numRadialSegments = rotation * tolerances.fNumRadialSegmentsPerRadian;
            float numSegments = numParametricSegments + numRadialSegments;
            float alternateNumSegments = alternateNumParametricSegments + numRadialSegments;
            if (!check_resolve_level(r, numSegments, resolveLevel, tolerance, false) &&
                !check_resolve_level(r, alternateNumSegments, resolveLevel, tolerance, true)) {
                return;
            }
            ++instance;
        }
        ++indirect;
    }
}
