/*
 * Copyright 2022 Google LLC
 *
 * 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/core/SkBitmap.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkImageGenerator.h"
#include "include/core/SkPicture.h"
#include "include/core/SkPictureRecorder.h"
#include "include/core/SkSpan.h"
#include "include/gpu/graphite/Context.h"
#include "include/gpu/graphite/Image.h"
#include "include/gpu/graphite/Recording.h"
#include "include/gpu/graphite/Surface.h"
#include "include/private/SkTo.h"
#include "src/core/SkMipmapBuilder.h"
#include "src/gpu/graphite/Caps.h"
#include "src/gpu/graphite/RecorderPriv.h"
#include "src/gpu/graphite/Surface_Graphite.h"
#include "src/image/SkImage_Base.h"
#include "tests/ComparePixels.h"
#include "tools/ToolUtils.h"
#include "tools/graphite/GraphiteToolUtils.h"

using namespace skgpu::graphite;
using Mipmapped = skgpu::Mipmapped;

namespace {

const SkISize kSurfaceSize = { 16, 16 };
const SkISize kImageSize = { 32, 32 };

constexpr SkColor4f kBaseImageColor = SkColors::kYellow;
constexpr SkColor4f kFirstMipLevelColor = SkColors::kRed;
constexpr SkColor4f kBackgroundColor = SkColors::kBlue;

sk_sp<SkImage> create_and_attach_mipmaps(sk_sp<SkImage> img) {
    constexpr SkColor4f mipLevelColors[] = {
            kFirstMipLevelColor,
            SkColors::kGreen,
            SkColors::kMagenta,
            SkColors::kCyan,
            SkColors::kWhite,
    };

    SkMipmapBuilder builder(img->imageInfo());

    int count = builder.countLevels();

    SkASSERT_RELEASE(count == SkToInt(std::size(mipLevelColors)));

    for (int i = 0; i < count; ++i) {
        SkPixmap pm = builder.level(i);
        pm.erase(mipLevelColors[i]);
    }

    return builder.attachTo(img);
}

sk_sp<SkImage> create_raster(Mipmapped mipmapped) {
    SkImageInfo ii = SkImageInfo::Make(kImageSize.width(),
                                       kImageSize.height(),
                                       kRGBA_8888_SkColorType,
                                       kPremul_SkAlphaType);
    SkBitmap bm;
    if (!bm.tryAllocPixels(ii)) {
        return nullptr;
    }

    bm.eraseColor(kBaseImageColor);

    sk_sp<SkImage> img = SkImages::RasterFromBitmap(bm);

    if (mipmapped == Mipmapped::kYes) {
        img = create_and_attach_mipmaps(std::move(img));
    }

    return img;
}

/* 0 */
sk_sp<SkImage> create_raster_backed_image_no_mipmaps(Recorder*) {
    return create_raster(Mipmapped::kNo);
}

/* 1 */
sk_sp<SkImage> create_raster_backed_image_with_mipmaps(Recorder*) {
    return create_raster(Mipmapped::kYes);
}

/* 2 */
sk_sp<SkImage> create_gpu_backed_image_no_mipmaps(Recorder* recorder) {
    sk_sp<SkImage> raster = create_raster(Mipmapped::kNo);
    return SkImages::TextureFromImage(recorder, raster, {false});
}

/* 3 */
sk_sp<SkImage> create_gpu_backed_image_with_mipmaps(Recorder* recorder) {
    sk_sp<SkImage> raster = create_raster(Mipmapped::kYes);
    return SkImages::TextureFromImage(recorder, raster, {true});
}

/* 4 */
sk_sp<SkImage> create_picture_backed_image(Recorder*) {
    SkIRect r = SkIRect::MakeWH(kImageSize.width(), kImageSize.height());
    SkPaint paint;
    paint.setColor(kBaseImageColor);

    SkPictureRecorder recorder;
    SkCanvas* canvas = recorder.beginRecording(SkRect::Make(r));
    canvas->drawIRect(r, paint);
    sk_sp<SkPicture> picture = recorder.finishRecordingAsPicture();

    return SkImages::DeferredFromPicture(std::move(picture),
                                         r.size(),
                                         /* matrix= */ nullptr,
                                         /* paint= */ nullptr,
                                         SkImages::BitDepth::kU8,
                                         SkColorSpace::MakeSRGB());
}

/* 5 */
sk_sp<SkImage> create_bitmap_generator_backed_image(Recorder*) {

    class BitmapBackedGenerator final : public SkImageGenerator {
    public:
        BitmapBackedGenerator()
                : SkImageGenerator(SkImageInfo::Make(kImageSize.width(),
                                                     kImageSize.height(),
                                                     kRGBA_8888_SkColorType,
                                                     kPremul_SkAlphaType)) {
        }

        bool onGetPixels(const SkImageInfo& dstInfo,
                         void* pixels,
                         size_t rowBytes,
                         const Options&) override {

            if (dstInfo.dimensions() != kImageSize) {
                return false;
            }

            SkBitmap bm;
            if (!bm.tryAllocPixels(dstInfo)) {
                return false;
            }

            bm.eraseColor(kBaseImageColor);

            return bm.readPixels(dstInfo, pixels, rowBytes, 0, 0);
        }
    };

    std::unique_ptr<SkImageGenerator> gen(new BitmapBackedGenerator());

    return SkImages::DeferredFromGenerator(std::move(gen));
}

bool check_img(skiatest::Reporter* reporter,
               Context* context,
               Recorder* recorder,
               SkImage* imageToDraw,
               bool useShader,
               Mipmapped mipmapped,
               const char* testcase,
               const SkColor4f& expectedColor) {
    SkImageInfo ii = SkImageInfo::Make(kSurfaceSize, kRGBA_8888_SkColorType, kPremul_SkAlphaType);

    SkBitmap result;
    result.allocPixels(ii);
    SkPixmap pm;

    SkAssertResult(result.peekPixels(&pm));

    {
        sk_sp<SkSurface> surface = SkSurfaces::RenderTarget(recorder, ii);
        if (!surface) {
            ERRORF(reporter, "Surface creation failed");
            return false;
        }

        SkCanvas* canvas = surface->getCanvas();

        canvas->clear(kBackgroundColor);

        SkSamplingOptions sampling = (mipmapped == Mipmapped::kYes)
                ? SkSamplingOptions(SkFilterMode::kLinear, SkMipmapMode::kNearest)
                : SkSamplingOptions(SkFilterMode::kLinear);

        SkRect rectToDraw = SkRect::MakeWH(kSurfaceSize.width(), kSurfaceSize.height());
        if (useShader) {
            SkPaint imagePaint;
            SkMatrix localMatrix = SkMatrix::RectToRect(SkRect::Make(imageToDraw->bounds()),
                                                        rectToDraw);
            imagePaint.setShader(imageToDraw->makeShader(sampling, &localMatrix));
            canvas->drawRect(rectToDraw, imagePaint);
        } else {
            canvas->drawImageRect(imageToDraw, rectToDraw, sampling);
        }

        if (!surface->readPixels(pm, 0, 0)) {
            ERRORF(reporter, "readPixels failed");
            return false;
        }
    }

    auto error = std::function<ComparePixmapsErrorReporter>(
            [&](int x, int y, const float diffs[4]) {
                ERRORF(reporter,
                       "case %s %s %s: expected (%.1f %.1f %.1f %.1f) got (%.1f, %.1f, %.1f, %.1f)",
                       testcase,
                       (mipmapped == Mipmapped::kYes) ? "w/ mipmaps" : "w/o mipmaps",
                       useShader ? "imageShader" : "drawImageRect",
                       expectedColor.fR, expectedColor.fG, expectedColor.fB, expectedColor.fA,
                       expectedColor.fR-diffs[0], expectedColor.fG-diffs[1],
                       expectedColor.fB-diffs[2], expectedColor.fA-diffs[3]);
            });
    static constexpr float kTol[] = {0, 0, 0, 0};
    CheckSolidPixels(expectedColor, pm, kTol, error);

    return true;
}

using FactoryT = sk_sp<SkImage> (*)(Recorder*);

struct TestCase {
    const char* fTestCase;
    FactoryT    fFactory;
    SkColor4f   fExpectedColors[2];   /* [ w/o mipmaps, w/ mipmaps ] */
};

void run_test(skiatest::Reporter* reporter,
              Context* context,
              Recorder* recorder,
              SkSpan<const TestCase> testcases) {

    for (auto t : testcases) {
        for (auto mm : { Mipmapped::kNo, Mipmapped::kYes }) {
            for (bool useShader : { false, true }) {
                sk_sp<SkImage> image = t.fFactory(recorder);

                check_img(reporter, context, recorder, image.get(), useShader, mm,
                        t.fTestCase, t.fExpectedColors[static_cast<int>(mm)]);
            }
        }
    }
}

} // anonymous namespace

// This test creates a bunch of solid yellow images in different ways and then draws them into a
// smaller surface (w/ src mode) that has been initialized to solid blue. When mipmap levels
// are possible to be specified the first mipmap level is made red. Thus, when mipmapping
// is allowed and it is specified as the sample mode, the drawn image will be red.

// For the Default ImageProvider (which does _no_ caching and conversion) the expectations are:
//
//    0) raster-backed image w/o mipmaps
//                    drawn w/o mipmapping    --> dropped draw (blue)
//                    drawn w/ mipmapping     --> dropped draw (blue)
//
//    1) raster-backed image w/ mipmaps
//                    drawn w/o mipmapping    --> dropped draw (blue)
//                    drawn w/ mipmapping     --> dropped draw (blue)
//
//    2) Graphite-backed w/o mipmaps
//                    drawn w/o mipmapping    --> drawn (yellow)
//                    drawn w/ mipmapping     --> drawn (yellow) - mipmap filtering is dropped
//
//    3) Graphite-backed w/ mipmaps
//                    drawn w/o mipmapping    --> drawn (yellow)
//                    drawn w/ mipmapping     --> drawn (red)
//
//    4) picture-backed image
//                    drawn w/o mipmapping    --> dropped draw (blue)
//                    drawn w/ mipmapping     --> dropped draw (blue)
//
//    5) bitmap-backed-generator based image
//                    drawn w/o mipmapping    --> dropped draw (blue)
//                    drawn w/ mipmapping     --> dropped draw (blue)
//
DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(ImageProviderTest_Graphite_Default, reporter, context,
                                         CtsEnforcement::kApiLevel_202404) {
    TestCase testcases[] = {
        { "0", create_raster_backed_image_no_mipmaps,   { kBackgroundColor, kBackgroundColor } },
        { "1", create_raster_backed_image_with_mipmaps, { kBackgroundColor, kBackgroundColor } },
        { "2", create_gpu_backed_image_no_mipmaps,      { kBaseImageColor,  kBaseImageColor } },
        { "3", create_gpu_backed_image_with_mipmaps,    { kBaseImageColor,  kFirstMipLevelColor } },
        { "4", create_picture_backed_image,             { kBackgroundColor, kBackgroundColor } },
        { "5", create_bitmap_generator_backed_image,    { kBackgroundColor, kBackgroundColor }  },
    };

    std::unique_ptr<Recorder> recorder = context->makeRecorder();

    run_test(reporter, context, recorder.get(), testcases);
}

// For the Testing ImageProvider (which does some caching and conversion) the expectations are:
//
//    0) raster-backed image w/o mipmaps
//                    drawn w/o mipmapping    --> drawn (yellow) - auto-converted
//                    drawn w/ mipmapping     --> drawn (yellow) - auto-converted
//
//    1) raster-backed image w/ mipmaps
//                    drawn w/o mipmapping    --> drawn (yellow) - auto-converted
//                    drawn w/ mipmapping     --> drawn (red) - auto-converted
//
//    2) Graphite-backed w/o mipmaps
//                    drawn w/o mipmapping    --> drawn (yellow)
//                    drawn w/ mipmapping     --> drawn (yellow) - mipmap filtering is dropped
//
//    3) Graphite-backed w/ mipmaps
//                    drawn w/o mipmapping    --> drawn (yellow)
//                    drawn w/ mipmapping     --> drawn (red)
//
//    4) picture-backed image
//                    drawn w/o mipmapping    --> drawn (yellow) - auto-converted
//                    drawn w/ mipmapping     --> drawn (yellow) - mipmaps auto generated
//
//    5) bitmap-backed-generator based image
//                    drawn w/o mipmapping    --> drawn (yellow) - auto-converted
//                    drawn w/ mipmapping     --> drawn (yellow) - auto-converted
//
DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(ImageProviderTest_Graphite_Testing, reporter, context,
                                         CtsEnforcement::kApiLevel_202404) {
    static const TestCase testcases[] = {
        { "0", create_raster_backed_image_no_mipmaps,   { kBaseImageColor, kBaseImageColor } },
        { "1", create_raster_backed_image_with_mipmaps, { kBaseImageColor, kFirstMipLevelColor } },
        { "2", create_gpu_backed_image_no_mipmaps,      { kBaseImageColor, kBaseImageColor } },
        { "3", create_gpu_backed_image_with_mipmaps,    { kBaseImageColor, kFirstMipLevelColor } },
        { "4", create_picture_backed_image,             { kBaseImageColor, kBaseImageColor } },
        { "5", create_bitmap_generator_backed_image,    { kBaseImageColor, kBaseImageColor } },
    };

    RecorderOptions options = ToolUtils::CreateTestingRecorderOptions();
    std::unique_ptr<skgpu::graphite::Recorder> recorder = context->makeRecorder(options);

    run_test(reporter, context, recorder.get(), testcases);
}

// Here we're testing that the RequiredProperties parameter to makeTextureImage and makeSubset
// works as expected.
DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(Make_TextureImage_Subset_Test, reporter, context,
                                         CtsEnforcement::kApiLevel_202404) {
    static const struct {
        std::string name;
        FactoryT fFactory;
    } testcases[] = {
        { "raster_no_mips",    create_raster_backed_image_no_mipmaps   },
        { "raster_with_mips",  create_raster_backed_image_with_mipmaps },
        { "texture_no_mips",   create_gpu_backed_image_no_mipmaps      },
        { "texture_with_mips", create_gpu_backed_image_with_mipmaps    },
        { "picture_backed",    create_picture_backed_image             },
        { "image_generator",   create_bitmap_generator_backed_image    },
    };

    const SkIRect kFakeSubset = SkIRect::MakeWH(kImageSize.width(), kImageSize.height());
    const SkIRect kTrueSubset = kFakeSubset.makeInset(4, 4);

    std::unique_ptr<Recorder> recorderUP = context->makeRecorder();
    auto recorder = recorderUP.get();

    for (const auto& test : testcases) {
        sk_sp<SkImage> orig = test.fFactory(recorder);
        skiatest::ReporterContext subtest(reporter, test.name);
        for (bool mipmapped : {false, true}) {
            skiatest::ReporterContext subtest2(reporter,
                                               SkStringPrintf("mipmaps: %d", (int)mipmapped));
            sk_sp<SkImage> i = SkImages::TextureFromImage(recorder, orig, {mipmapped});

            // makeTextureImage has an optimization which allows Mipmaps on an Image if it
            // would take extra work to remove them.
            bool mipmapOptAllowed = orig->hasMipmaps() && !mipmapped;

            REPORTER_ASSERT(reporter, i->isTextureBacked());
            REPORTER_ASSERT(
                    reporter,
                    (i->hasMipmaps() == mipmapped) || (i->hasMipmaps() && mipmapOptAllowed));

            // SkImage::makeSubset should "leave an image where it is", that is, return a
            // texture backed image iff the original image was texture backed. Otherwise,
            // it will return a raster image.
            i = orig->makeSubset(recorder, kTrueSubset, {mipmapped});
            REPORTER_ASSERT(reporter, orig->isTextureBacked() == i->isTextureBacked(),
                            "orig texture status %d != subset texture status %d",
                            orig->isTextureBacked(), i->isTextureBacked());
            if (i->isTextureBacked()) {
                REPORTER_ASSERT(reporter, i->dimensions() == kTrueSubset.size());
                REPORTER_ASSERT(reporter, i->hasMipmaps() == mipmapped);
            }

            i = orig->makeSubset(recorder, kFakeSubset, {mipmapped});
            REPORTER_ASSERT(reporter, orig->isTextureBacked() == i->isTextureBacked(),
                            "orig texture status %d != subset texture status %d",
                            orig->isTextureBacked(), i->isTextureBacked());
            if (i->isTextureBacked()) {
                REPORTER_ASSERT(reporter, i->dimensions() == kFakeSubset.size());
                REPORTER_ASSERT(
                        reporter,
                        i->hasMipmaps() == mipmapped || (i->hasMipmaps() && mipmapOptAllowed));
            }

            // SubsetTextureFrom should always return a texture-backed image
            i = SkImages::SubsetTextureFrom(recorder, orig.get(), kTrueSubset, {mipmapped});
            REPORTER_ASSERT(reporter, i->isTextureBacked());
            REPORTER_ASSERT(reporter, i->dimensions() == kTrueSubset.size());
            REPORTER_ASSERT(reporter, i->hasMipmaps() == mipmapped);

            if (!orig->isTextureBacked()) {
                i = SkImages::TextureFromImage(nullptr, orig, {mipmapped});
                REPORTER_ASSERT(reporter, !i);

                // Make sure makeSubset w/o a recorder works as expected
                i = orig->makeSubset(nullptr, kTrueSubset, {mipmapped});
                REPORTER_ASSERT(reporter, !i->isTextureBacked());
                REPORTER_ASSERT(reporter, i->dimensions() == kTrueSubset.size());
                // Picture-backed images don't support mipmaps but check the other types.
                if (as_IB(i)->type() != SkImage_Base::Type::kLazyPicture) {
                    REPORTER_ASSERT(reporter, i->hasMipmaps() == mipmapped);
                }

                i = orig->makeSubset(nullptr, kFakeSubset, {mipmapped});
                REPORTER_ASSERT(reporter, !i->isTextureBacked());
                REPORTER_ASSERT(reporter, i->dimensions() == kFakeSubset.size());
                // Picture-backed images don't support mipmaps but check the other types.
                if (as_IB(i)->type() != SkImage_Base::Type::kLazyPicture) {
                    REPORTER_ASSERT(reporter, i->hasMipmaps() == mipmapped);
                }
            }
        }
    }
}

namespace {

// NOTE: makeColorTypeAndSpace relies on rendering; depending on the path renderer strategy, this
// also can require that it support MSAA attachments (required at a higher level in Device).
// Technically, these internal operations wouldn't trigger MSAA, but there isn't a system to have
// internal surfaces skip that validation. b/507427401 would address this, in which case we can
// remove the MSAA checks.
SkColorType pick_colortype(const Caps* caps, bool mipmapped) {
    auto mm = mipmapped ? skgpu::Mipmapped::kYes : skgpu::Mipmapped::kNo;
    TextureInfo info = caps->getDefaultSampledTextureInfo(
            kRGB_565_SkColorType, mm, skgpu::Protected::kNo, skgpu::Renderable::kYes);
    if (info.isValid() && caps->getCompatibleMSAASampleCount(info) > SampleCount::k1) {
        return kRGB_565_SkColorType;
    }

    info = caps->getDefaultSampledTextureInfo(
            kRGBA_F16_SkColorType, mm, skgpu::Protected::kNo, skgpu::Renderable::kYes);
    if (info.isValid() && caps->getCompatibleMSAASampleCount(info) > SampleCount::k1) {
        return kRGBA_F16_SkColorType;
    }

    info = caps->getDefaultSampledTextureInfo(
            kRGBA_1010102_SkColorType, mm, skgpu::Protected::kNo, skgpu::Renderable::kYes);
    if (info.isValid() && caps->getCompatibleMSAASampleCount(info) > SampleCount::k1) {
        return kRGBA_1010102_SkColorType;
    }

    return kUnknown_SkColorType;
}

} // anonymous namespace

// Here we're testing that the RequiredProperties parameter of:
//    SkImage::makeColorSpace and
//    SkImage::makeColorTypeAndColorSpace
// works as expected.
DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(MakeColorSpace_Test, reporter, context,
                                         CtsEnforcement::kApiLevel_202404) {
    static const struct {
        std::string name;
        FactoryT fFactory;
        bool     fTextureBacked;
    } testcases[] = {
            { "raster_no_mips",    create_raster_backed_image_no_mipmaps,   false },
            { "raster_with_mips",  create_raster_backed_image_with_mipmaps, false },
            { "texture_no_mips",   create_gpu_backed_image_no_mipmaps,      true  },
            { "texture_with_mips", create_gpu_backed_image_with_mipmaps,    true  },
            { "picture_backed",    create_picture_backed_image,             false },
            { "image_generator",   create_bitmap_generator_backed_image,    false },
    };

    sk_sp<SkColorSpace> spin = SkColorSpace::MakeSRGB()->makeColorSpin();

    std::unique_ptr<Recorder> recorder = context->makeRecorder();

    const Caps* caps = recorder->priv().caps();

    for (const auto& testcase : testcases) {
        skiatest::ReporterContext subtest(reporter, testcase.name);
        sk_sp<SkImage> orig = testcase.fFactory(recorder.get());

        SkASSERT(orig->colorType() == kRGBA_8888_SkColorType ||
                 orig->colorType() == kBGRA_8888_SkColorType);
        SkASSERT(!orig->colorSpace() || orig->colorSpace() == SkColorSpace::MakeSRGB().get());

        for (bool mipmapped : {false, true}) {
            skiatest::ReporterContext subtest2(reporter,
                                               SkStringPrintf("mipmaps: %d", (int)mipmapped));
            sk_sp<SkImage> i = orig->makeColorSpace(recorder.get(), spin, {mipmapped});

            REPORTER_ASSERT(reporter, i != nullptr);
            REPORTER_ASSERT(reporter, i->isTextureBacked() == testcase.fTextureBacked);
            REPORTER_ASSERT(reporter, i->colorSpace() == spin.get());
            if (testcase.fTextureBacked) {
                REPORTER_ASSERT(reporter, i->hasMipmaps() == mipmapped);
            } else {
                REPORTER_ASSERT(reporter, !i->hasMipmaps());
            }

            SkColorType altCT = pick_colortype(caps, mipmapped);
            if (altCT == kUnknown_SkColorType) {
                // Unsupported on current device
                continue;
            }
            i = orig->makeColorTypeAndColorSpace(recorder.get(), altCT, spin, {mipmapped});

            REPORTER_ASSERT(reporter, i != nullptr);
            REPORTER_ASSERT(reporter, i->isTextureBacked() == testcase.fTextureBacked);
            REPORTER_ASSERT(reporter, i->colorType() == altCT);
            REPORTER_ASSERT(reporter, i->colorSpace() == spin.get());
            if (testcase.fTextureBacked) {
                REPORTER_ASSERT(reporter, i->hasMipmaps() == mipmapped);
            } else {
                REPORTER_ASSERT(reporter, !i->hasMipmaps());
            }
        }
    }
}
