/*
 * Copyright 2023 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/SkAlphaType.h"
#include "include/core/SkBitmap.h"
#include "include/core/SkCanvas.h"
#include "include/core/SkColor.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkColorType.h"
#include "include/core/SkImage.h"
#include "include/core/SkImageInfo.h"
#include "include/core/SkMatrix.h"
#include "include/core/SkPaint.h"
#include "include/core/SkPicture.h"
#include "include/core/SkPictureRecorder.h"
#include "include/core/SkPoint.h"
#include "include/core/SkRect.h"
#include "include/core/SkRefCnt.h"
#include "include/core/SkSamplingOptions.h"
#include "include/core/SkScalar.h"
#include "include/core/SkSize.h"
#include "include/core/SkStream.h"
#include "include/core/SkString.h"
#include "include/core/SkSurface.h"
#include "include/core/SkTiledImageUtils.h"
#include "include/encode/SkPngEncoder.h"
#include "include/gpu/GpuTypes.h"
#include "include/private/base/SkAssert.h"
#include "src/core/SkSamplingPriv.h"
#include "tests/Test.h"
#include "tests/TestUtils.h"
#include "tools/ToolUtils.h"

#if defined(SK_GANESH)
#include "include/gpu/GrDirectContext.h"
#include "include/gpu/ganesh/SkSurfaceGanesh.h"
#include "src/gpu/ganesh/GrDirectContextPriv.h"
#include "src/gpu/ganesh/GrResourceCache.h"
#include "src/gpu/ganesh/GrSurface.h"
#include "src/gpu/ganesh/GrTexture.h"
#include "tests/CtsEnforcement.h"
struct GrContextOptions;
#endif

#if defined(SK_GRAPHITE)
#include "include/gpu/graphite/Context.h"
#include "include/gpu/graphite/Recorder.h"
#include "include/gpu/graphite/Surface.h"
#include "src/gpu/graphite/Caps.h"
#include "src/gpu/graphite/RecorderPriv.h"
#include "src/gpu/graphite/Texture.h"
#else
namespace skgpu { namespace graphite { class Recorder; } }
#endif

#include <atomic>
#include <functional>
#include <initializer_list>
#include <string.h>
#include <utility>

extern int gOverrideMaxTextureSize;
extern std::atomic<int> gNumTilesDrawn;

namespace {

// Draw a white border around the edge (to test strict constraints) and
// a Hilbert curve inside of that (so the effects of (mis) sampling are evident).
 void draw(SkCanvas* canvas, int imgSize, int whiteBandWidth,
           int desiredLineWidth, int desiredDepth) {
    const int kPad = desiredLineWidth;

    canvas->clear(SK_ColorWHITE);

    SkPaint innerRect;
    innerRect.setColor(SK_ColorDKGRAY);
    canvas->drawRect(SkRect::MakeIWH(imgSize, imgSize).makeInset(whiteBandWidth, whiteBandWidth),
                     innerRect);

    int desiredDrawSize = imgSize - 2 * kPad - 2 * whiteBandWidth;
    ToolUtils::HilbertGenerator gen(desiredDrawSize, desiredLineWidth, desiredDepth);

    canvas->translate(kPad + whiteBandWidth, imgSize - kPad - whiteBandWidth);
    gen.draw(canvas);
}


sk_sp<SkImage> make_big_bitmap_image(int imgSize, int whiteBandWidth,
                                     int desiredLineWidth, int desiredDepth) {
    SkBitmap bm;

    bm.allocN32Pixels(imgSize, imgSize, /* isOpaque= */ true);
    SkCanvas canvas(bm);

    draw(&canvas, imgSize, whiteBandWidth, desiredLineWidth, desiredDepth);

    bm.setImmutable();
    return bm.asImage();
}

sk_sp<SkImage> make_big_picture_image(int imgSize, int whiteBandWidth,
                                      int desiredLineWidth, int desiredDepth) {
    sk_sp<SkPicture> pic;

    {
        SkPictureRecorder recorder;
        SkCanvas* canvas = recorder.beginRecording(SkRect::MakeIWH(imgSize, imgSize));
        draw(canvas, imgSize, whiteBandWidth, desiredLineWidth, desiredDepth);
        pic = recorder.finishRecordingAsPicture();
    }

    return SkImages::DeferredFromPicture(std::move(pic),
                                         { imgSize, imgSize },
                                         /* matrix= */ nullptr,
                                         /* paint= */ nullptr,
                                         SkImages::BitDepth::kU8,
                                         SkColorSpace::MakeSRGB());
}


const char* get_sampling_str(const SkSamplingOptions& sampling) {
    if (sampling.isAniso()) {
        return "Aniso";
    } else if (sampling.useCubic) {
        return "Cubic";
    } else if (sampling.mipmap != SkMipmapMode::kNone) {
        return "Mipmap";
    } else if (sampling.filter == SkFilterMode::kLinear) {
        return "Linear";
    } else {
        return "NN";
    }
}

SkString create_label(GrDirectContext* dContext,
                      const char* generator,
                      const SkSamplingOptions& sampling,
                      int scale,
                      int rot,
                      SkCanvas::SrcRectConstraint constraint,
                      int numTiles) {
    SkString label;
    label.appendf("%s-%s-%s-%d-%d-%s-%d",
                  dContext ? "ganesh" : "graphite",
                  generator,
                  get_sampling_str(sampling),
                  scale,
                  rot,
                  constraint == SkCanvas::kFast_SrcRectConstraint ? "fast" : "strict",
                  numTiles);
    return label;
 }

void potentially_write_to_png(const char* directory,
                              const SkString& label,
                              const SkBitmap& bm) {
    constexpr bool kWriteOutImages = false;

    if constexpr(kWriteOutImages) {
        SkString filename;
        filename.appendf("//%s//%s.png", directory, label.c_str());

        SkFILEWStream file(filename.c_str());
        SkAssertResult(file.isValid());

        SkAssertResult(SkPngEncoder::Encode(&file, bm.pixmap(), {}));
    }
}

bool check_pixels(skiatest::Reporter* reporter,
                  const SkBitmap& expected,
                  const SkBitmap& actual,
                  const SkString& label,
                  int rot) {
    static const float kTols[4]    = { 0.008f, 0.008f, 0.008f, 0.008f };   // ~ 2/255
    static const float kRotTols[4] = { 0.024f, 0.024f, 0.024f, 0.024f };   // ~ 6/255

    auto error = std::function<ComparePixmapsErrorReporter>(
            [&](int x, int y, const float diffs[4]) {
                SkASSERT(x >= 0 && y >= 0);
                ERRORF(reporter, "%s: mismatch at %d, %d (%f, %f, %f %f)",
                       label.c_str(), x, y, diffs[0], diffs[1], diffs[2], diffs[3]);
            });

    return ComparePixels(expected.pixmap(), actual.pixmap(), rot ? kRotTols : kTols, error);
}

// Return a clip rect that will result in the number of desired tiles being used. The trick
// is that the clip rect also has to work when rotated.
SkRect clip_rect(SkRect dstRect, int numDesiredTiles) {
    dstRect.outset(5, 5);

    switch (numDesiredTiles) {
        case 0:
            return { dstRect.fLeft-64, dstRect.fTop-64, dstRect.fLeft-63, dstRect.fTop-63 };
        case 4: {
            // Upper left 4x4
            float outset = 0.125f * dstRect.width() * SK_ScalarRoot2Over2;
            SkPoint center = dstRect.center();
            return { center.fX - outset, center.fY - outset,
                     center.fX + outset, center.fY + outset };
        }
        case 9: {
            // Upper left 3x3
            float outset = 0.25f * dstRect.width() * SK_ScalarRoot2Over2;
            SkPoint center = dstRect.center();
            center.offset(-dstRect.width()/8.0f, -dstRect.height()/8.0f);
            return { center.fX - outset, center.fY - outset,
                     center.fX + outset, center.fY + outset };
        }
    }

    return dstRect; // all 16 tiles
}

bool difficult_case(const SkSamplingOptions& sampling,
                    int scale,
                    int rot,
                    SkCanvas::SrcRectConstraint constraint) {
    if (sampling.useCubic) {
        return false;  // cubic never causes any issues
    }

    if (constraint == SkCanvas::kStrict_SrcRectConstraint &&
            (sampling.mipmap != SkMipmapMode::kNone || sampling.filter == SkFilterMode::kLinear)) {
        // linear-filtered strict big image drawing is currently broken (b/286239467). The issue
        // is that the strict constraint is propagated to the child tiles which breaks the
        // interpolation expected in the middle of the large image.
        // Note that strict mipmapping is auto-downgraded to strict linear sampling.
        return true;
    }

    if (sampling.mipmap == SkMipmapMode::kLinear) {
        // Mipmapping is broken for anything other that 1-to-1 draws (b/286256104). The issue
        // is that the mipmaps are created for each tile individually so the higher levels differ
        // from what would be generated with the entire image. Mipmapped draws are off by ~20/255
        // at 4x and ~64/255 at 8x)
        return scale > 1;
    }

    if (sampling.filter == SkFilterMode::kNearest) {
        // Perhaps unsurprisingly, NN only passes on un-rotated 1-to-1 draws (off by ~187/255 at
        // different scales).
        return scale > 1 || rot > 0;
    }

    return false;
}

// compare tiled and untiled draws - varying the parameters (e.g., sampling, rotation, fast vs.
// strict, etc).
void tiling_comparison_test(GrDirectContext* dContext,
                            skgpu::graphite::Recorder* recorder,
                            skiatest::Reporter* reporter) {
    // We're using the knowledge that the internal tile size is 1024. By creating kImageSize
    // sized images we know we'll get a 4x4 tiling regardless of the sampling.
    static const int kImageSize = 4096 - 4 * 2 * kBicubicFilterTexelPad;
    static const int kOverrideMaxTextureSize = 1024;

#if defined(SK_GANESH)
    if (dContext && dContext->maxTextureSize() < kImageSize) {
        // For the expected images we need to be able to draw w/o tiling
        return;
    }
#endif

#if defined(SK_GRAPHITE)
    if (recorder) {
        const skgpu::graphite::Caps* caps = recorder->priv().caps();
        if (caps->maxTextureSize() < kImageSize) {
            return;
        }
    }
#endif

    static const int kWhiteBandWidth = 4;
    const SkRect srcRect = SkRect::MakeIWH(kImageSize, kImageSize).makeInset(kWhiteBandWidth,
                                                                             kWhiteBandWidth);

    using GeneratorT = sk_sp<SkImage>(*)(int imgSize, int whiteBandWidth,
                                         int desiredLineWidth, int desiredDepth);

    static const struct {
        GeneratorT fGen;
        const char* fTag;
    } kGenerators[] = { { make_big_bitmap_image,  "BM" },
                        { make_big_picture_image, "Picture" } };

    static const SkSamplingOptions kSamplingOptions[] = {
        SkSamplingOptions(SkFilterMode::kNearest, SkMipmapMode::kNone),
        SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNone),
        // Note that Mipmapping gets auto-disabled with a strict-constraint
        SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kLinear),
        SkSamplingOptions(SkCubicResampler::CatmullRom()),
    };

    int numClippedTiles = 9;
    for (auto gen : kGenerators) {
        if (recorder && !strcmp(gen.fTag, "Picture")) {
            // In the picture-image case, the non-tiled code path draws the picture directly into a
            // gpu-backed surface while the tiled code path the picture is draws the picture into
            // a raster-backed surface. For Ganesh this works out, since both Ganesh and Raster
            // support non-AA rect draws. For Graphite the results are very different (since
            // Graphite always anti-aliases. Forcing all the rect draws to be AA doesn't work out
            // since AA introduces too much variance between both of the gpu backends and Raster -
            // which would obscure any errors introduced by tiling.
            continue;
        }

        sk_sp<SkImage> img = (*gen.fGen)(kImageSize,
                                         kWhiteBandWidth,
                                         /* desiredLineWidth= */ 16,
                                         /* desiredDepth= */ 7);
        numClippedTiles = (numClippedTiles == 9) ? 4 : 9;  // alternate to reduce the combinatorics

        for (int scale : { 1, 4, 8 }) {
            for (int rot : { 0, 45 }) {
                for (int numDesiredTiles : { numClippedTiles, 16 }) {
                    SkRect destRect = SkRect::MakeWH(srcRect.width()/scale,
                                                     srcRect.height()/scale);

                    SkMatrix m = SkMatrix::RotateDeg(rot, destRect.center());
                    SkIRect rotatedRect = m.mapRect(destRect).roundOut();
                    rotatedRect.outset(2, 2);   // outset to capture the constraint's effect

                    SkRect clipRect = clip_rect(destRect, numDesiredTiles);

                    auto destII = SkImageInfo::Make(rotatedRect.width(),
                                                    rotatedRect.height(),
                                                    kRGBA_8888_SkColorType,
                                                    kPremul_SkAlphaType);

                    SkBitmap expected, actual;
                    expected.allocPixels(destII);
                    actual.allocPixels(destII);

                    sk_sp<SkSurface> surface;

#if defined(SK_GANESH)
                    if (dContext) {
                        surface = SkSurfaces::RenderTarget(dContext,
                                                           skgpu::Budgeted::kNo,
                                                           destII);
                    }
#endif

#if defined(SK_GRAPHITE)
                    if (recorder) {
                        surface = SkSurfaces::RenderTarget(recorder, destII);
                    }
#endif

                    for (auto sampling : kSamplingOptions) {
                        for (auto constraint : { SkCanvas::kStrict_SrcRectConstraint,
                                                 SkCanvas::kFast_SrcRectConstraint }) {
                            if (difficult_case(sampling, scale, rot, constraint)) {
                                continue;
                            }

                            SkString label = create_label(dContext, gen.fTag, sampling, scale, rot,
                                                          constraint, numDesiredTiles);

                            SkCanvas* canvas = surface->getCanvas();

                            SkAutoCanvasRestore acr(canvas, /* doSave= */ true);

                            canvas->translate(-rotatedRect.fLeft, -rotatedRect.fTop);
                            if (sampling.useCubic || sampling.filter != SkFilterMode::kNearest) {
                                // NN sampling doesn't deal well w/ the (0.5, 0.5) offset but the
                                // other sampling modes need it to exercise strict vs. fast
                                // constraint in non-rotated draws
                                canvas->translate(0.5f, 0.5f);
                            }
                            canvas->concat(m);

                            // First, draw w/o tiling
                            gOverrideMaxTextureSize = 0;
                            gNumTilesDrawn.store(0, std::memory_order_relaxed);

                            canvas->clear(SK_ColorBLACK);
                            canvas->save();
                            canvas->clipRect(clipRect);

                            SkTiledImageUtils::DrawImageRect(canvas, img, srcRect, destRect,
                                                             sampling, /* paint= */ nullptr,
                                                             constraint);
                            SkAssertResult(surface->readPixels(expected, 0, 0));
                            int actualNumTiles = gNumTilesDrawn.load(std::memory_order_acquire);
                            REPORTER_ASSERT(reporter, actualNumTiles == 0);

                            canvas->restore();

                            // Then, force 4x4 tiling
                            gOverrideMaxTextureSize = kOverrideMaxTextureSize;

                            canvas->clear(SK_ColorBLACK);
                            canvas->save();
                            canvas->clipRect(clipRect);

                            SkTiledImageUtils::DrawImageRect(canvas, img, srcRect, destRect,
                                                             sampling, /* paint= */ nullptr,
                                                             constraint);
                            SkAssertResult(surface->readPixels(actual, 0, 0));

                            actualNumTiles = gNumTilesDrawn.load(std::memory_order_acquire);
                            REPORTER_ASSERT(reporter, numDesiredTiles == actualNumTiles,
                                            "mismatch expected: %d actual: %d\n",
                                            numDesiredTiles, actualNumTiles);

                            canvas->restore();

                            REPORTER_ASSERT(reporter, check_pixels(reporter, expected, actual,
                                                                   label, rot));

                            potentially_write_to_png("expected", label, expected);
                            potentially_write_to_png("actual", label, actual);
                        }
                    }
                }
            }
        }
    }
}

// In this test we draw the same bitmap-backed image twice and check that we only upload it once.
// Everything is set up for the bitmap-backed image to be split into 16 1024x1024 tiles.
void tiled_image_caching_test(GrDirectContext* dContext,
                              skgpu::graphite::Recorder* recorder,
                              skiatest::Reporter* reporter) {
    static const int kImageSize = 4096;
    static const int kOverrideMaxTextureSize = 1024;
    static const SkISize kExpectedTileSize { kOverrideMaxTextureSize, kOverrideMaxTextureSize };

    sk_sp<SkImage> img = make_big_bitmap_image(kImageSize,
                                               /* whiteBandWidth= */ 0,
                                               /* desiredLineWidth= */ 16,
                                               /* desiredDepth= */ 7);

    auto destII = SkImageInfo::Make(kImageSize, kImageSize,
                                    kRGBA_8888_SkColorType,
                                    kPremul_SkAlphaType);

    SkBitmap readback;
    readback.allocPixels(destII);

    sk_sp<SkSurface> surface;

#if defined(SK_GANESH)
    if (dContext) {
        surface = SkSurfaces::RenderTarget(dContext, skgpu::Budgeted::kNo, destII);
    }
#endif

#if defined(SK_GRAPHITE)
    if (recorder) {
        surface = SkSurfaces::RenderTarget(recorder, destII);
    }
#endif

    if (!surface) {
        return;
    }

    SkCanvas* canvas = surface->getCanvas();

    gOverrideMaxTextureSize = kOverrideMaxTextureSize;

    for (int i = 0; i < 2; ++i) {
        canvas->clear(SK_ColorBLACK);

        SkTiledImageUtils::DrawImage(canvas, img,
                                     /* x= */ 0, /* y= */ 0,
                                     SkSamplingOptions(SkFilterMode::kNearest, SkMipmapMode::kNone),
                                     /* paint= */ nullptr,
                                     SkCanvas::kFast_SrcRectConstraint);
        SkAssertResult(surface->readPixels(readback, 0, 0));
    }

    int numFound = 0;

#if defined(SK_GANESH)
    if (dContext) {
        GrResourceCache* cache = dContext->priv().getResourceCache();

        cache->visitSurfaces([&](const GrSurface* surf, bool /* purgeable */) {
            const GrTexture* tex = surf->asTexture();
            if (tex && tex->dimensions() == kExpectedTileSize) {
                ++numFound;
            }
        });
    }
#endif

#if defined(SK_GRAPHITE)
    if (recorder) {
        skgpu::graphite::ResourceCache* cache = recorder->priv().resourceCache();

        cache->visitTextures([&](const skgpu::graphite::Texture* tex, bool /* purgeable */) {
            if (tex->dimensions() == kExpectedTileSize) {
                ++numFound;
            }
        });
    }
#endif

    REPORTER_ASSERT(reporter, numFound == 16, "Expected: 16 Actual: %d", numFound);

    gOverrideMaxTextureSize = 0;
}

} // anonymous namespace

#if defined(SK_GANESH)

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(BigImageTest_Ganesh,
                                       reporter,
                                       ctxInfo,
                                       CtsEnforcement::kNever) {
    auto dContext = ctxInfo.directContext();

    tiling_comparison_test(dContext, /* recorder= */ nullptr, reporter);
}

DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(TiledDrawCacheTest_Ganesh,
                                       reporter,
                                       ctxInfo,
                                       CtsEnforcement::kNever) {
    auto dContext = ctxInfo.directContext();

    tiled_image_caching_test(dContext, /* recorder= */ nullptr, reporter);
}

#endif // SK_GANESH

#if defined(SK_GRAPHITE)

DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(BigImageTest_Graphite,
                                         reporter,
                                         context,
                                         CtsEnforcement::kNextRelease) {
    std::unique_ptr<skgpu::graphite::Recorder> recorder =
            context->makeRecorder(ToolUtils::CreateTestingRecorderOptions());

    tiling_comparison_test(/* dContext= */ nullptr, recorder.get(), reporter);
}

DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(TiledDrawCacheTest_Graphite,
                                         reporter,
                                         context,
                                         CtsEnforcement::kNextRelease) {
    std::unique_ptr<skgpu::graphite::Recorder> recorder =
            context->makeRecorder(ToolUtils::CreateTestingRecorderOptions());

    tiled_image_caching_test(/* dContext= */ nullptr, recorder.get(), reporter);
}

#endif // SK_GRAPHITE
