/*
 * 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/ganesh/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"
#include "tools/GpuToolUtils.h"
#else
namespace skgpu { namespace graphite { class Recorder; } }
#endif

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

#if defined(SK_GANESH) && defined(GPU_TEST_UTILS)
extern int gOverrideMaxTextureSizeGanesh;
extern std::atomic<int> gNumTilesDrawnGanesh;
#endif

#if defined(SK_GRAPHITE) && defined(GPU_TEST_UTILS)
extern int gOverrideMaxTextureSizeGraphite;
extern std::atomic<int> gNumTilesDrawnGraphite;
#endif

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) {
        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
#if defined(SK_GANESH) && defined(GPU_TEST_UTILS)
                            gOverrideMaxTextureSizeGanesh = 0;
#endif
#if defined(SK_GRAPHITE) && defined(GPU_TEST_UTILS)
                            gOverrideMaxTextureSizeGraphite = 0;
#endif
                            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));
#if defined(SK_GANESH) && defined(GPU_TEST_UTILS)
                            if (canvas->recordingContext()) {
                                int actualNumTiles =
                                        gNumTilesDrawnGanesh.load(std::memory_order_acquire);
                                REPORTER_ASSERT(reporter, actualNumTiles == 0);
                            }
#endif
#if defined(SK_GRAPHITE) && defined(GPU_TEST_UTILS)
                            if (canvas->recorder()) {
                                int actualNumTiles =
                                        gNumTilesDrawnGraphite.load(std::memory_order_acquire);
                                REPORTER_ASSERT(reporter, actualNumTiles == 0);
                            }
#endif
                            canvas->restore();

                            // Then, force 4x4 tiling
#if defined(SK_GANESH) && defined(GPU_TEST_UTILS)
                            gOverrideMaxTextureSizeGanesh = kOverrideMaxTextureSize;
#endif
#if defined(SK_GRAPHITE) && defined(GPU_TEST_UTILS)
                            gOverrideMaxTextureSizeGraphite = kOverrideMaxTextureSize;
#endif

                            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));
#if defined(SK_GANESH) && defined(GPU_TEST_UTILS)
                            if (canvas->recordingContext()) {
                                int actualNumTiles =
                                        gNumTilesDrawnGanesh.load(std::memory_order_acquire);
                                REPORTER_ASSERT(reporter,
                                                numDesiredTiles == actualNumTiles,
                                                "mismatch expected: %d actual: %d\n",
                                                numDesiredTiles,
                                                actualNumTiles);
                            }
#endif
#if defined(SK_GRAPHITE) && defined(GPU_TEST_UTILS)
                            if (canvas->recorder()) {
                                int actualNumTiles =
                                        gNumTilesDrawnGraphite.load(std::memory_order_acquire);
                                REPORTER_ASSERT(reporter,
                                                numDesiredTiles == actualNumTiles,
                                                "mismatch expected: %d actual: %d\n",
                                                numDesiredTiles,
                                                actualNumTiles);
                            }
#endif

                            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);
                        }
                    }
                }
            }
        }
    }
    // Reset tiling behavior
#if defined(SK_GANESH) && defined(GPU_TEST_UTILS)
    gOverrideMaxTextureSizeGanesh = 0;
#endif
#if defined(SK_GRAPHITE) && defined(GPU_TEST_UTILS)
    gOverrideMaxTextureSizeGraphite = 0;
#endif
}

// 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();

#if defined(SK_GANESH) && defined(GPU_TEST_UTILS)
    gOverrideMaxTextureSizeGanesh = kOverrideMaxTextureSize;
#endif
#if defined(SK_GRAPHITE) && defined(GPU_TEST_UTILS)
    gOverrideMaxTextureSizeGraphite = kOverrideMaxTextureSize;
#endif
    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);

    // reset to default behavior
#if defined(SK_GANESH) && defined(GPU_TEST_UTILS)
    gOverrideMaxTextureSizeGanesh = 0;
#endif
#if defined(SK_GRAPHITE) && defined(GPU_TEST_UTILS)
    gOverrideMaxTextureSizeGraphite = 0;
#endif
}

} // anonymous namespace

#if defined(SK_GANESH)

// TODO(b/306005622): fix in SkQP and move to CtsEnforcement::kNextRelease
DEF_GANESH_TEST_FOR_RENDERING_CONTEXTS(BigImageTest_Ganesh,
                                       reporter,
                                       ctxInfo,
                                       CtsEnforcement::kNever) {
    auto dContext = ctxInfo.directContext();

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

// TODO(b/306005622): fix in SkQP and move to CtsEnforcement::kNextRelease
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)

// TODO(b/306005622): fix in SkQP and move to CtsEnforcement::kNextRelease
DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(BigImageTest_Graphite,
                                         reporter,
                                         context,
                                         CtsEnforcement::kNever) {
    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::kApiLevel_V) {
    std::unique_ptr<skgpu::graphite::Recorder> recorder =
            context->makeRecorder(ToolUtils::CreateTestingRecorderOptions());

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

#endif // SK_GRAPHITE
