/*
 * 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/SkCanvas.h"
#include "include/core/SkPixmap.h"
#include "include/core/SkPoint.h"
#include "include/gpu/graphite/Context.h"
#include "include/gpu/graphite/Recorder.h"
#include "include/gpu/graphite/Recording.h"
#include "include/gpu/graphite/Surface.h"
#include "src/gpu/graphite/RecordingPriv.h"
#include "src/gpu/graphite/Surface_Graphite.h"
#include "src/gpu/graphite/TextureProxyView.h"

namespace skgpu::graphite {

constexpr SkIVector kNoOffset = SkIVector::Make(0, 0);
constexpr SkIRect kEmptyClip = SkIRect::MakeEmpty();

using DrawCallback = std::function<void(SkCanvas*)>;

struct Expectation {
    int fX;
    int fY;
    SkColor4f fColor;
};

void run_test(skiatest::Reporter* reporter,
              Context* context,
              SkISize surfaceSize,
              SkISize recordingSize,
              SkIVector replayOffset,
              SkIRect replayClip,
              skgpu::Mipmapped canvasMipmapped,
              skgpu::Mipmapped targetMipmapped,
              DrawCallback draw,
              const std::vector<Expectation>& expectations) {
    const SkImageInfo surfaceImageInfo = SkImageInfo::Make(
            surfaceSize, SkColorType::kRGBA_8888_SkColorType, SkAlphaType::kPremul_SkAlphaType);

    std::unique_ptr<Recorder> surfaceRecorder = context->makeRecorder();
    sk_sp<SkSurface> surface =
            SkSurfaces::RenderTarget(surfaceRecorder.get(), surfaceImageInfo, canvasMipmapped);
    Surface* graphiteSurface = static_cast<Surface*>(surface.get());
    REPORTER_ASSERT(reporter, graphiteSurface->target().proxy()->provenance().isClientRequest());
    const TextureInfo& textureInfo = graphiteSurface->target().proxy()->textureInfo();

    // Flush the initial clear added by MakeGraphite.
    std::unique_ptr<skgpu::graphite::Recording> surfaceRecording = surfaceRecorder->snap();
    context->insertRecording({surfaceRecording.get()});

    // Snap a recording without a bound target.
    const SkImageInfo recordingImageInfo = surfaceImageInfo.makeDimensions(recordingSize);
    std::unique_ptr<Recorder> recorder = context->makeRecorder();
    SkCanvas* canvas = recorder->makeDeferredCanvas(recordingImageInfo, textureInfo);
    draw(canvas);
    std::unique_ptr<Recording> recording = recorder->snap();

    // Play back recording. If the mipmap settings don't match, we have to create a new surface.
    if (canvasMipmapped != targetMipmapped) {
        surface =
                SkSurfaces::RenderTarget(surfaceRecorder.get(), surfaceImageInfo, targetMipmapped);
        // Flush the initial clear for this new surface.
        surfaceRecording = surfaceRecorder->snap();
        context->insertRecording({surfaceRecording.get()});
    }
    context->insertRecording({recording.get(), surface.get(), replayOffset, replayClip});

    // Read pixels.
    SkBitmap bitmap;
    SkPixmap pixmap;
    bitmap.allocPixels(surfaceImageInfo);
    SkAssertResult(bitmap.peekPixels(&pixmap));
    if (!surface->readPixels(pixmap, 0, 0)) {
        ERRORF(reporter, "readPixels failed");
        return;
    }

    // Veryify expectations are met and recording is uninstantiated.
    REPORTER_ASSERT(reporter, !recording->priv().isTargetProxyInstantiated());
    for (const Expectation& e : expectations) {
        SkColor4f color = pixmap.getColor4f(e.fX, e.fY);
#ifdef SK_DEBUG
        if (color != e.fColor) {
            SkDebugf("Wrong color at %d, %d\n\texpected: %f %f %f %f\n\tactual: %f %f %f %f",
                     e.fX,
                     e.fY,
                     e.fColor.fR,
                     e.fColor.fG,
                     e.fColor.fB,
                     e.fColor.fA,
                     color.fR,
                     color.fG,
                     color.fB,
                     color.fA);
        }
#endif
        REPORTER_ASSERT(reporter, color == e.fColor);
    }
}

// Tests that clear does not clear an entire replayed-to surface if recorded onto a smaller surface.
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(RecordingSurfacesTestClear, reporter, context,
                                   CtsEnforcement::kApiLevel_202404) {
    SkISize surfaceSize = SkISize::Make(8, 4);
    SkISize recordingSize = SkISize::Make(4, 4);

    auto draw = [](SkCanvas* canvas) { canvas->clear(SkColors::kRed); };

    std::vector<Expectation> expectations = {{0, 0, SkColors::kRed},
                                             {4, 0, SkColors::kTransparent}};

    run_test(reporter,
             context,
             surfaceSize,
             recordingSize,
             kNoOffset,
             kEmptyClip,
             skgpu::Mipmapped::kNo,
             skgpu::Mipmapped::kNo,
             draw,
             expectations);
}

// Tests that a draw is translated correctly when replayed with an offset.
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(RecordingSurfacesTestDraw, reporter, context,
                                   CtsEnforcement::kApiLevel_202504) {
    SkISize surfaceSize = SkISize::Make(8, 4);
    SkISize recordingSize = SkISize::Make(4, 4);
    SkIVector replayOffset = SkIVector::Make(4, 0);

    auto draw = [](SkCanvas* canvas) {
        canvas->drawIRect(SkIRect::MakeXYWH(0, 0, 4, 4), SkPaint(SkColors::kRed));
    };


    std::vector<Expectation> expectations = {{0, 0, SkColors::kTransparent},
                                             {4, 0, SkColors::kRed}};

    run_test(reporter,
             context,
             surfaceSize,
             recordingSize,
             replayOffset,
             kEmptyClip,
             skgpu::Mipmapped::kNo,
             skgpu::Mipmapped::kNo,
             draw,
             expectations);
}

// Tests that writePixels is translated correctly when replayed with an offset.
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(RecordingSurfacesTestWritePixels, reporter, context,
                                   CtsEnforcement::kApiLevel_202404) {
    SkBitmap bitmap;
    bitmap.allocN32Pixels(4, 4, true);
    SkCanvas bitmapCanvas(bitmap);
    SkPaint paint;
    paint.setColor(SkColors::kRed);
    bitmapCanvas.drawIRect(SkIRect::MakeXYWH(0, 0, 4, 4), paint);

    SkISize surfaceSize = SkISize::Make(8, 4);
    SkISize recordingSize = SkISize::Make(4, 4);
    SkIVector replayOffset = SkIVector::Make(4, 0);

    auto draw = [&bitmap](SkCanvas* canvas) { canvas->writePixels(bitmap, 0, 0); };

    std::vector<Expectation> expectations = {{0, 0, SkColors::kTransparent},
                                             {4, 0, SkColors::kRed}};

    run_test(reporter,
             context,
             surfaceSize,
             recordingSize,
             replayOffset,
             kEmptyClip,
             skgpu::Mipmapped::kNo,
             skgpu::Mipmapped::kNo,
             draw,
             expectations);
}

// Tests that the result of writePixels is cropped correctly when offscreen.
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(RecordingSurfacesTestWritePixelsOffscreen, reporter, context,
                                   CtsEnforcement::kApiLevel_202404) {
    SkBitmap bitmap;
    bitmap.allocN32Pixels(4, 4, true);
    SkCanvas bitmapCanvas(bitmap);
    SkPaint paint;
    paint.setColor(SkColors::kRed);
    bitmapCanvas.drawIRect(SkIRect::MakeXYWH(0, 0, 4, 4), paint);
    paint.setColor(SkColors::kGreen);
    bitmapCanvas.drawIRect(SkIRect::MakeXYWH(2, 2, 2, 2), paint);

    SkISize surfaceSize = SkISize::Make(4, 4);
    SkISize recordingSize = SkISize::Make(4, 4);
    SkIVector replayOffset = SkIVector::Make(-2, -2);

    auto draw = [&bitmap](SkCanvas* canvas) { canvas->writePixels(bitmap, 0, 0); };

    std::vector<Expectation> expectations = {{0, 0, SkColors::kGreen}};

    run_test(reporter,
             context,
             surfaceSize,
             recordingSize,
             replayOffset,
             kEmptyClip,
             skgpu::Mipmapped::kNo,
             skgpu::Mipmapped::kNo,
             draw,
             expectations);
}

// Tests that the result of a draw is cropped correctly with a provided clip on replay.
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(RecordingSurfacesTestDrawWithClip, reporter, context,
                                   CtsEnforcement::kApiLevel_202504) {
    SkISize surfaceSize = SkISize::Make(8, 4);
    SkISize recordingSize = SkISize::Make(8, 4);

    auto draw = [](SkCanvas* canvas) {
        canvas->drawIRect(SkIRect::MakeXYWH(0, 0, 4, 4), SkPaint(SkColors::kRed));
        canvas->drawIRect(SkIRect::MakeXYWH(4, 0, 4, 4), SkPaint(SkColors::kGreen));
    };

    {
        // Test that the clip applies in translated space.
        SkIVector replayOffset = SkIVector::Make(4, 0);
        SkIRect replayClip = SkIRect::MakeXYWH(0, 0, 2, 4);

        std::vector<Expectation> expectations = {{0, 0, SkColors::kTransparent},
                                                 {4, 0, SkColors::kRed},
                                                 {6, 0, SkColors::kTransparent}};

        run_test(reporter,
                 context,
                 surfaceSize,
                 recordingSize,
                 replayOffset,
                 replayClip,
                 skgpu::Mipmapped::kNo,
                 skgpu::Mipmapped::kNo,
                 draw,
                 expectations);
    }

    {
        // Test that the draw is not translated by the clip.
        SkIRect replayClip = SkIRect::MakeXYWH(4, 0, 2, 4);

        std::vector<Expectation> expectations = {{4, 0, SkColors::kGreen}};

        run_test(reporter,
                 context,
                 surfaceSize,
                 recordingSize,
                 kNoOffset,
                 replayClip,
                 skgpu::Mipmapped::kNo,
                 skgpu::Mipmapped::kNo,
                 draw,
                 expectations);
    }
}

// Tests that a scissor translated to negative coordinates is applied correctly.
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(RecordingSurfacesTestNegativeClip,
                                   reporter,
                                   context,
                                   CtsEnforcement::kApiLevel_202604) {
    SkISize surfaceSize = SkISize::Make(4, 4);
    SkISize recordingSize = SkISize::Make(4, 4);

    auto draw = [](SkCanvas* canvas) {
        canvas->clipIRect(SkIRect::MakeWH(4, 4));
        canvas->drawIRect(SkIRect::MakeWH(4, 4), SkPaint(SkColors::kRed));
    };

    SkIVector replayOffset = SkIVector::Make(-2, 0);

    std::vector<Expectation> expectations = {{0, 0, SkColors::kRed},
                                             {2, 0, SkColors::kTransparent}};

    run_test(reporter,
             context,
             surfaceSize,
             recordingSize,
             replayOffset,
             kEmptyClip,
             skgpu::Mipmapped::kNo,
             skgpu::Mipmapped::kNo,
             draw,
             expectations);
}

// Tests that the result of writePixels is cropped correctly with a provided clip on replay.
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(RecordingSurfacesTestWritePixelsWithClip, reporter, context,
                                   CtsEnforcement::kApiLevel_202504) {
    SkBitmap bitmap;
    bitmap.allocN32Pixels(4, 4, true);
    SkCanvas bitmapCanvas(bitmap);
    SkPaint paint;
    paint.setColor(SkColors::kRed);
    bitmapCanvas.drawIRect(SkIRect::MakeXYWH(0, 0, 4, 4), paint);

    SkISize surfaceSize = SkISize::Make(8, 4);
    SkISize recordingSize = SkISize::Make(4, 4);
    SkIVector replayOffset = SkIVector::Make(4, 0);
    SkIRect replayClip = SkIRect::MakeXYWH(0, 0, 2, 4);

    auto draw = [&bitmap](SkCanvas* canvas) { canvas->writePixels(bitmap, 0, 0); };

    std::vector<Expectation> expectations = {{0, 0, SkColors::kTransparent},
                                             {4, 0, SkColors::kRed},
                                             {6, 0, SkColors::kTransparent}};

    run_test(reporter,
             context,
             surfaceSize,
             recordingSize,
             replayOffset,
             replayClip,
             skgpu::Mipmapped::kNo,
             skgpu::Mipmapped::kNo,
             draw,
             expectations);
}

DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(RecordingSurfacesTestMipmapped, reporter, context,
                                   CtsEnforcement::kApiLevel_202504) {
    SkISize recordingSize = SkISize::Make(1, 1);

    auto draw = [](SkCanvas* canvas) { canvas->clear(SkColors::kRed); };

    {
        SkISize surfaceSize = SkISize::Make(1, 1);

        std::vector<Expectation> expectations = {{0, 0, SkColors::kRed}};

        run_test(reporter,
                 context,
                 surfaceSize,
                 recordingSize,
                 kNoOffset,
                 kEmptyClip,
                 skgpu::Mipmapped::kYes,
                 skgpu::Mipmapped::kYes,
                 draw,
                 expectations);
    }

    {
        // Test that draw fails if canvas and surface mipmap settings don't match.
        SkISize surfaceSize = SkISize::Make(1, 1);

        std::vector<Expectation> expectations = {{0, 0, SkColors::kTransparent}};

        run_test(reporter,
                 context,
                 surfaceSize,
                 recordingSize,
                 kNoOffset,
                 kEmptyClip,
                 skgpu::Mipmapped::kYes,
                 skgpu::Mipmapped::kNo,
                 draw,
                 expectations);

        run_test(reporter,
                 context,
                 surfaceSize,
                 recordingSize,
                 kNoOffset,
                 kEmptyClip,
                 skgpu::Mipmapped::kNo,
                 skgpu::Mipmapped::kYes,
                 draw,
                 expectations);
    }

    {
        // Test that draw fails if canvas and surface dimensions don't match.
        SkISize surfaceSize = SkISize::Make(2, 1);

        std::vector<Expectation> expectations = {{0, 0, SkColors::kTransparent}};

        run_test(reporter,
                 context,
                 surfaceSize,
                 recordingSize,
                 kNoOffset,
                 kEmptyClip,
                 skgpu::Mipmapped::kYes,
                 skgpu::Mipmapped::kYes,
                 draw,
                 expectations);
    }

    {
        // Test that draw fails if offset is provided.
        SkISize surfaceSize = SkISize::Make(1, 1);
        SkIVector replayOffset = SkIVector::Make(1, 0);

        std::vector<Expectation> expectations = {{0, 0, SkColors::kTransparent}};

        run_test(reporter,
                 context,
                 surfaceSize,
                 recordingSize,
                 replayOffset,
                 kEmptyClip,
                 skgpu::Mipmapped::kYes,
                 skgpu::Mipmapped::kYes,
                 draw,
                 expectations);
    }

    {
        // Test that draw fails if clip is provided.
        SkISize surfaceSize = SkISize::Make(1, 1);
        SkIRect replayClip = SkIRect::MakeXYWH(0, 0, 1, 1);

        std::vector<Expectation> expectations = {{0, 0, SkColors::kTransparent}};

        run_test(reporter,
                 context,
                 surfaceSize,
                 recordingSize,
                 kNoOffset,
                 replayClip,
                 skgpu::Mipmapped::kYes,
                 skgpu::Mipmapped::kYes,
                 draw,
                 expectations);
    }
}

DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(RecordingSurfacesTestMipmappedWritePixels, reporter, context,
                                   CtsEnforcement::kApiLevel_202504) {
    SkBitmap bitmap;
    bitmap.allocN32Pixels(1, 1, true);
    SkCanvas bitmapCanvas(bitmap);
    SkPaint paint;
    paint.setColor(SkColors::kRed);
    bitmapCanvas.drawIRect(SkIRect::MakeXYWH(0, 0, 1, 1), paint);

    SkISize recordingSize = SkISize::Make(1, 1);
    SkISize surfaceSize = SkISize::Make(1, 1);

    auto draw = [&bitmap](SkCanvas* canvas) { canvas->writePixels(bitmap, 0, 0); };

    std::vector<Expectation> expectations = {{0, 0, SkColors::kRed}};

    run_test(reporter,
             context,
             surfaceSize,
             recordingSize,
             kNoOffset,
             kEmptyClip,
             skgpu::Mipmapped::kYes,
             skgpu::Mipmapped::kYes,
             draw,
             expectations);
}

// Tests that you can't create two deferred canvases before snapping the first.
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(RecordingSurfacesTestTwoCanvases, reporter, context,
                                   CtsEnforcement::kApiLevel_202504) {
    const SkImageInfo kImageInfo = SkImageInfo::Make(SkISize::Make(1, 1),
                                                     SkColorType::kRGBA_8888_SkColorType,
                                                     SkAlphaType::kPremul_SkAlphaType);
    std::unique_ptr<Recorder> recorder = context->makeRecorder();
    sk_sp<SkSurface> surface =
            SkSurfaces::RenderTarget(recorder.get(), kImageInfo, skgpu::Mipmapped::kNo);
    const TextureInfo& textureInfo =
            static_cast<Surface*>(surface.get())->target().proxy()->textureInfo();

    // First canvas is created successfully.
    REPORTER_ASSERT(reporter, recorder->makeDeferredCanvas(kImageInfo, textureInfo) != nullptr);
    // Second canvas fails to be created.
    REPORTER_ASSERT(reporter, recorder->makeDeferredCanvas(kImageInfo, textureInfo) == nullptr);
}

// Tests that inserting a recording with a surface does not crash even if no draws to a deferred
// canvas were recorded.
DEF_GRAPHITE_TEST_FOR_ALL_CONTEXTS(RecordingSurfacesTestUnnecessarySurface, reporter, context,
                                   CtsEnforcement::kApiLevel_202504) {
    const SkImageInfo kImageInfo = SkImageInfo::Make(SkISize::Make(1, 1),
                                                     SkColorType::kRGBA_8888_SkColorType,
                                                     SkAlphaType::kPremul_SkAlphaType);
    std::unique_ptr<Recorder> recorder = context->makeRecorder();

    sk_sp<SkSurface> surface =
            SkSurfaces::RenderTarget(recorder.get(), kImageInfo, skgpu::Mipmapped::kNo);
    std::unique_ptr<Recording> recording = recorder->snap();
    REPORTER_ASSERT(reporter, context->insertRecording({recording.get(), surface.get()}));
}

}  // namespace skgpu::graphite
