/*
 * 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/gpu/graphite/BackendTexture.h"

#include "include/core/SkCanvas.h"
#include "include/core/SkColorFilter.h"
#include "include/core/SkColorSpace.h"
#include "include/core/SkSurface.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/gpu/graphite/YUVABackendTextures.h"
#include "src/gpu/graphite/Caps.h"
#include "src/gpu/graphite/ContextPriv.h"
#include "src/gpu/graphite/RecordingPriv.h"
#include "tests/Test.h"
#include "tools/graphite/GraphiteTestContext.h"

using namespace skgpu::graphite;

namespace {

struct PromiseImageChecker {
    PromiseImageChecker() = default;

    void checkImageReleased(skiatest::Reporter* reporter, int expectedReleaseCnt) {
        REPORTER_ASSERT(reporter, expectedReleaseCnt == fImageReleaseCount);
    }

    int fImageReleaseCount = 0;

    static void ImageRelease(void* self) {
        auto checker = reinterpret_cast<PromiseImageChecker*>(self);

        checker->fImageReleaseCount++;
    }
};

struct PromiseTextureChecker {
    PromiseTextureChecker() = default;

    explicit PromiseTextureChecker(const BackendTexture& backendTex) {
        fBackendTextures[0] = backendTex;
    }

    explicit PromiseTextureChecker(const BackendTexture& backendTex0,
                                   const BackendTexture& backendTex1)
            : fHasTwoBackendTextures(true) {
        fBackendTextures[0] = backendTex0;
        fBackendTextures[1] = backendTex1;
    }

    int totalReleaseCount() const { return fTextureReleaseCounts[0] + fTextureReleaseCounts[1]; }

    bool fHasTwoBackendTextures = false;
    BackendTexture fBackendTextures[2];
    int fFulfillCount = 0;
    int fTextureReleaseCounts[2] = { 0, 0 };

    static std::tuple<BackendTexture, void*> Fulfill(void* self) {
        auto checker = reinterpret_cast<PromiseTextureChecker*>(self);

        checker->fFulfillCount++;

        if (checker->fHasTwoBackendTextures) {
            int whichToUse = checker->fFulfillCount % 2;
            return { checker->fBackendTextures[whichToUse],
                     &checker->fTextureReleaseCounts[whichToUse] };
        } else {
            return { checker->fBackendTextures[0], &checker->fTextureReleaseCounts[0] };
        }
    }

    static void TextureRelease(void* context) {
        int* releaseCount = reinterpret_cast<int*>(context);

        (*releaseCount)++;
    }
};

enum class ReleaseBalanceExpectation {
    kBalanced,
    kOffByOne,     // fulfill calls ahead of release calls by 1
    kOffByTwo,     // fulfill calls ahead of release calls by 2
    kFulfillsOnly, // 'n' fulfill calls, 0 release calls
};

void check_fulfill_and_release_cnts(skiatest::Reporter* reporter,
                                    const PromiseImageChecker& promiseImageChecker,
                                    const PromiseTextureChecker* promiseTextureCheckers,
                                    int expectedFulfillCnt,
                                    ReleaseBalanceExpectation releaseBalanceExpectation) {
    // If one fulfill fails the following ones won't be called, so we check the max value
    int maxFulfillCnt = 0;
    for (int i = 0; i < 4; ++i) {
        maxFulfillCnt = std::max(promiseTextureCheckers[i].fFulfillCount, maxFulfillCnt);
        if (!expectedFulfillCnt) {
            // Release should only ever be called after Fulfill.
            REPORTER_ASSERT(reporter, promiseImageChecker.fImageReleaseCount == 0);
            REPORTER_ASSERT(reporter, promiseTextureCheckers[i].totalReleaseCount() == 0);
            return;
        }

        if (promiseTextureCheckers[i].fFulfillCount) {
            int releaseDiff = promiseTextureCheckers[i].fFulfillCount -
                              promiseTextureCheckers[i].totalReleaseCount();
            switch (releaseBalanceExpectation) {
                case ReleaseBalanceExpectation::kBalanced:
                    SkASSERT(!releaseDiff);
                    REPORTER_ASSERT(reporter, !releaseDiff);
                    break;
                case ReleaseBalanceExpectation::kOffByOne:
                    SkASSERT(releaseDiff == 1);
                    REPORTER_ASSERT(reporter, releaseDiff == 1);
                    break;
                case ReleaseBalanceExpectation::kOffByTwo:
                    SkASSERT(releaseDiff == 2);
                    REPORTER_ASSERT(reporter, releaseDiff == 2);
                    break;
                case ReleaseBalanceExpectation::kFulfillsOnly:
                    REPORTER_ASSERT(reporter, promiseTextureCheckers[i].totalReleaseCount() == 0);
                    break;
            }
        }
    }
    SkASSERT(maxFulfillCnt == expectedFulfillCnt);
    REPORTER_ASSERT(reporter, maxFulfillCnt == expectedFulfillCnt);
}

void check_unfulfilled(const PromiseImageChecker& promiseImageChecker,
                       const PromiseTextureChecker* promiseTextureCheckers,
                       skiatest::Reporter* reporter) {
    check_fulfill_and_release_cnts(reporter, promiseImageChecker, promiseTextureCheckers,
                                   /* expectedFulfillCnt= */ 0,
                                   ReleaseBalanceExpectation::kBalanced);
}

void check_fulfilled_ahead_by_one(skiatest::Reporter* reporter,
                                  const PromiseImageChecker& promiseImageChecker,
                                  const PromiseTextureChecker* promiseTextureCheckers,
                                  int expectedFulfillCnt) {
    check_fulfill_and_release_cnts(reporter, promiseImageChecker, promiseTextureCheckers,
                                   expectedFulfillCnt, ReleaseBalanceExpectation::kOffByOne);
}

void check_fulfilled_ahead_by_two(skiatest::Reporter* reporter,
                                  const PromiseImageChecker& promiseImageChecker,
                                  const PromiseTextureChecker* promiseTextureCheckers,
                                  int expectedFulfillCnt) {
    check_fulfill_and_release_cnts(reporter, promiseImageChecker, promiseTextureCheckers,
                                   expectedFulfillCnt, ReleaseBalanceExpectation::kOffByTwo);
}

void check_all_done(skiatest::Reporter* reporter,
                    const PromiseImageChecker& promiseImageChecker,
                    const PromiseTextureChecker* promiseTextureCheckers,
                    int expectedFulfillCnt) {
    check_fulfill_and_release_cnts(reporter, promiseImageChecker, promiseTextureCheckers,
                                   expectedFulfillCnt, ReleaseBalanceExpectation::kBalanced);
}

void check_fulfills_only(skiatest::Reporter* reporter,
                         const PromiseImageChecker& promiseImageChecker,
                         const PromiseTextureChecker* promiseTextureCheckers,
                         int expectedFulfillCnt) {
    check_fulfill_and_release_cnts(reporter, promiseImageChecker, promiseTextureCheckers,
                                   expectedFulfillCnt, ReleaseBalanceExpectation::kFulfillsOnly);
}

struct TestCtx {
    TestCtx() {}

    ~TestCtx() {
        for (int i = 0; i < 8; ++i) {
            if (fBackendTextures[i].isValid()) {
                fContext->deleteBackendTexture(fBackendTextures[i]);
            }
        }
    }

    Context* fContext;
    std::unique_ptr<Recorder> fRecorder;
    BackendTexture fBackendTextures[8];
    PromiseImageChecker fPromiseImageChecker;
    SkImages::GraphitePromiseImageContext fImageContext = &fPromiseImageChecker;
    PromiseTextureChecker fPromiseTextureCheckers[4];
    SkImages::GraphitePromiseTextureFulfillContext fTextureContexts[4] = {
        &fPromiseTextureCheckers[0],
        &fPromiseTextureCheckers[1],
        &fPromiseTextureCheckers[2],
        &fPromiseTextureCheckers[3],
    };
    sk_sp<SkImage> fImg;
    sk_sp<SkSurface> fSurface;
};

void setup_test_context(Context* context,
                        skiatest::Reporter* reporter,
                        TestCtx* testCtx,
                        SkISize dimensions,
                        Volatile isVolatile,
                        bool invalidBackendTex) {
    testCtx->fContext = context;

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

    skgpu::Protected isProtected = skgpu::Protected(caps->protectedSupport());

    testCtx->fRecorder = context->makeRecorder();

    testCtx->fPromiseImageChecker = PromiseImageChecker();

    TextureInfo textureInfo[4];
    for (int i = 0; i < 4; ++i) {
        textureInfo[i] = caps->getDefaultSampledTextureInfo(kAlpha_8_SkColorType,
                                                            skgpu::Mipmapped::kNo,
                                                            isProtected,
                                                            skgpu::Renderable::kYes);

        if (invalidBackendTex) {
            // Having invalid backend textures will invalidate all the fulfill calls
            REPORTER_ASSERT(reporter, !testCtx->fBackendTextures[i].isValid());
            REPORTER_ASSERT(reporter, !testCtx->fBackendTextures[i+4].isValid());
        } else {
            testCtx->fBackendTextures[i] =
                    testCtx->fRecorder->createBackendTexture(dimensions, textureInfo[i]);
            REPORTER_ASSERT(reporter, testCtx->fBackendTextures[i].isValid());

            if (isVolatile == Volatile::kYes) {
                testCtx->fBackendTextures[i+4] =
                        testCtx->fRecorder->createBackendTexture(dimensions, textureInfo[i]);
                REPORTER_ASSERT(reporter, testCtx->fBackendTextures[i+4].isValid());
            }
        }

        if (isVolatile == Volatile::kYes) {
            testCtx->fPromiseTextureCheckers[i] =
                    PromiseTextureChecker(testCtx->fBackendTextures[i],
                                          testCtx->fBackendTextures[i+4]);
        } else {
            testCtx->fPromiseTextureCheckers[i] =
                     PromiseTextureChecker(testCtx->fBackendTextures[i]);
        }
    }

    SkYUVAInfo yuvaInfo(dimensions,
                        SkYUVAInfo::PlaneConfig::kY_U_V_A,
                        SkYUVAInfo::Subsampling::k444,
                        kJPEG_Full_SkYUVColorSpace);
    YUVABackendTextureInfo yuvaBackendInfo(yuvaInfo,
                                           textureInfo,
                                           skgpu::Mipmapped::kNo);

    testCtx->fImg = SkImages::PromiseTextureFromYUVA(testCtx->fRecorder.get(),
                                                     yuvaBackendInfo,
                                                     SkColorSpace::MakeSRGBLinear(),
                                                     isVolatile,
                                                     PromiseTextureChecker::Fulfill,
                                                     PromiseImageChecker::ImageRelease,
                                                     PromiseTextureChecker::TextureRelease,
                                                     testCtx->fImageContext,
                                                     testCtx->fTextureContexts);

    SkImageInfo ii = SkImageInfo::Make(dimensions.fWidth,
                                       dimensions.fHeight,
                                       kRGBA_8888_SkColorType,
                                       kPremul_SkAlphaType);
    testCtx->fSurface = SkSurfaces::RenderTarget(testCtx->fRecorder.get(), ii);
}

} // anonymous namespace

DEF_CONDITIONAL_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(NonVolatileGraphiteYUVAPromiseImageTest,
                                                     reporter,
                                                     context,
                                                     testGpuContext,
                                                     true,
                                                     CtsEnforcement::kApiLevel_202404) {
    constexpr SkISize kDimensions { 16, 16 };

    TestCtx testContext;
    setup_test_context(context, reporter, &testContext,
                       kDimensions, Volatile::kNo, /* invalidBackendTex= */ false);

    {
        SkCanvas* canvas = testContext.fSurface->getCanvas();

        canvas->drawImage(testContext.fImg, 0, 0);
        check_unfulfilled(testContext.fPromiseImageChecker, testContext.fPromiseTextureCheckers,
                          reporter);

        std::unique_ptr<Recording> recording = testContext.fRecorder->snap();
        check_unfulfilled(testContext.fPromiseImageChecker, testContext.fPromiseTextureCheckers,
                          reporter); // NVPIs not fulfilled at snap

        REPORTER_ASSERT(reporter, context->insertRecording({ recording.get() }));
        check_fulfilled_ahead_by_one(reporter, testContext.fPromiseImageChecker,
                                     testContext.fPromiseTextureCheckers,
                                     /* expectedFulfillCnt= */ 1); // NVPIs fulfilled at insert
    }

    context->submit(SyncToCpu::kNo);
    // testContext.fImg still has a ref so we should not have called TextureRelease.
    check_fulfilled_ahead_by_one(reporter, testContext.fPromiseImageChecker,
                                 testContext.fPromiseTextureCheckers,
                                 /* expectedFulfillCnt= */ 1);

    testGpuContext->syncedSubmit(context);

    check_fulfilled_ahead_by_one(reporter, testContext.fPromiseImageChecker,
                                 testContext.fPromiseTextureCheckers,
                                 /* expectedFulfillCnt= */ 1);

    // Test that more draws and insertions don't refulfill the NVPI
    {
        SkCanvas* canvas = testContext.fSurface->getCanvas();

        canvas->drawImage(testContext.fImg, 0, 0);
        canvas->drawImage(testContext.fImg, 0, 0);

        std::unique_ptr<Recording> recording = testContext.fRecorder->snap();
        check_fulfilled_ahead_by_one(reporter, testContext.fPromiseImageChecker,
                                     testContext.fPromiseTextureCheckers,
                                     /* expectedFulfillCnt= */ 1); // No new fulfill

        REPORTER_ASSERT(reporter, context->insertRecording({ recording.get() }));
        // testContext.fImg should still be fulfilled from the first time we inserted a Recording.
        check_fulfilled_ahead_by_one(reporter, testContext.fPromiseImageChecker,
                                     testContext.fPromiseTextureCheckers,
                                     /* expectedFulfillCnt= */ 1);
    }

    testGpuContext->syncedSubmit(context);

    check_fulfilled_ahead_by_one(reporter, testContext.fPromiseImageChecker,
                                 testContext.fPromiseTextureCheckers, /* expectedFulfillCnt= */ 1);

    // Test that dropping the SkImage's ref doesn't change anything
    {
        SkCanvas* canvas = testContext.fSurface->getCanvas();

        canvas->drawImage(testContext.fImg, 0, 0);
        testContext.fImg.reset();

        std::unique_ptr<Recording> recording = testContext.fRecorder->snap();
        check_fulfilled_ahead_by_one(reporter, testContext.fPromiseImageChecker,
                                     testContext.fPromiseTextureCheckers,
                                     /* expectedFulfillCnt= */ 1);

        REPORTER_ASSERT(reporter, context->insertRecording({ recording.get() }));
        check_fulfilled_ahead_by_one(reporter, testContext.fPromiseImageChecker,
                                     testContext.fPromiseTextureCheckers,
                                     /* expectedFulfillCnt= */ 1);
    }

    // fImg's proxy is reffed by the recording so, despite fImg being reset earlier,
    // the imageRelease callback doesn't occur until the recording is deleted.
    testContext.fPromiseImageChecker.checkImageReleased(reporter, /* expectedReleaseCnt= */ 1);

    // testContext.fImg no longer holds a ref but the last recording is still not submitted.
    check_fulfilled_ahead_by_one(reporter, testContext.fPromiseImageChecker,
                                 testContext.fPromiseTextureCheckers, /* expectedFulfillCnt= */ 1);

    testGpuContext->syncedSubmit(context);

    // Now TextureRelease should definitely have been called.
    check_all_done(reporter, testContext.fPromiseImageChecker, testContext.fPromiseTextureCheckers,
                   /* expectedFulfillCnt= */ 1);
}

DEF_CONDITIONAL_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(
        NonVolatileGraphiteYUVAPromiseImageFulfillFailureTest,
        reporter,
        context,
        testGpuContext,
        true,
        CtsEnforcement::kApiLevel_202404) {
    constexpr SkISize kDimensions { 16, 16 };

    TestCtx testContext;
    setup_test_context(context, reporter, &testContext,
                       kDimensions, Volatile::kNo, /* invalidBackendTex= */ true);

    // Draw the image a few different ways.
    {
        SkCanvas* canvas = testContext.fSurface->getCanvas();

        canvas->drawImage(testContext.fImg, 0, 0);
        check_unfulfilled(testContext.fPromiseImageChecker, testContext.fPromiseTextureCheckers,
                          reporter);

        std::unique_ptr<Recording> recording = testContext.fRecorder->snap();
        check_unfulfilled(testContext.fPromiseImageChecker, testContext.fPromiseTextureCheckers,
                          reporter);

        REPORTER_ASSERT(reporter, !context->insertRecording({ recording.get() }));
        check_fulfilled_ahead_by_one(reporter, testContext.fPromiseImageChecker,
                                     testContext.fPromiseTextureCheckers,
                                     /* expectedFulfillCnt= */ 1);

        // Test that reinserting gives uninstantiated PromiseImages a second chance
        REPORTER_ASSERT(reporter, !context->insertRecording({ recording.get() }));
        check_fulfills_only(reporter, testContext.fPromiseImageChecker,
                            testContext.fPromiseTextureCheckers, /* expectedFulfillCnt= */ 2);
    }

    {
        SkCanvas* canvas = testContext.fSurface->getCanvas();

        SkPaint paint;
        paint.setColorFilter(SkColorFilters::LinearToSRGBGamma());
        canvas->drawImage(testContext.fImg, 0, 0, SkSamplingOptions(), &paint);

        std::unique_ptr<Recording> recording = testContext.fRecorder->snap();
        check_fulfills_only(reporter, testContext.fPromiseImageChecker,
                            testContext.fPromiseTextureCheckers, /* expectedFulfillCnt= */ 2);

        REPORTER_ASSERT(reporter, !context->insertRecording({ recording.get() }));
        check_fulfills_only(reporter, testContext.fPromiseImageChecker,
                            testContext.fPromiseTextureCheckers, /* expectedFulfillCnt= */ 3);
    }

    {
        SkCanvas* canvas = testContext.fSurface->getCanvas();

        sk_sp<SkShader> shader = testContext.fImg->makeShader(SkSamplingOptions());
        REPORTER_ASSERT(reporter, shader);

        SkPaint paint;
        paint.setShader(std::move(shader));
        canvas->drawRect(SkRect::MakeWH(1, 1), paint);

        std::unique_ptr<Recording> recording = testContext.fRecorder->snap();
        check_fulfills_only(reporter, testContext.fPromiseImageChecker,
                            testContext.fPromiseTextureCheckers, /* expectedFulfillCnt= */ 3);

        REPORTER_ASSERT(reporter, !context->insertRecording({ recording.get() }));
        check_fulfills_only(reporter, testContext.fPromiseImageChecker,
                            testContext.fPromiseTextureCheckers, /* expectedFulfillCnt= */ 4);
    }

    testContext.fSurface.reset();
    testContext.fImg.reset();

    // Despite fulfill failing 4x, the imageRelease callback still fires
    testContext.fPromiseImageChecker.checkImageReleased(reporter, /* expectedReleaseCnt= */ 1);

    testGpuContext->syncedSubmit(context);
    // fulfill should've been called 4x while release should never have been called
    check_fulfills_only(reporter, testContext.fPromiseImageChecker,
                        testContext.fPromiseTextureCheckers, /* expectedFulfillCnt= */ 4);
}

DEF_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(NonVolatileGraphiteYUVAPromiseImageCreationFailureTest,
                                         reporter,
                                         context,
                                         CtsEnforcement::kApiLevel_202404) {
    // Note: these dimensions are invalid and will cause MakeGraphitePromiseTexture to fail
    constexpr SkISize kDimensions { 0, 0 };

    TestCtx testContext;
    setup_test_context(context, reporter, &testContext,
                       kDimensions, Volatile::kNo, /* invalidBackendTex= */ true);

    SkASSERT(!testContext.fImg);

    // Despite MakeGraphitePromiseTexture failing, ImageRelease is called
    REPORTER_ASSERT(reporter, testContext.fPromiseImageChecker.fImageReleaseCount == 1);
    for (int i = 0; i < 4; ++i) {
        REPORTER_ASSERT(reporter, testContext.fPromiseTextureCheckers[i].fFulfillCount == 0);
        REPORTER_ASSERT(reporter, testContext.fPromiseTextureCheckers[i].totalReleaseCount() == 0);
    }
}

DEF_CONDITIONAL_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(VolatileGraphiteYUVAPromiseImageTest,
                                                     reporter,
                                                     context,
                                                     testGpuContext,
                                                     true,
                                                     CtsEnforcement::kApiLevel_202404) {
    constexpr SkISize kDimensions { 16, 16 };

    TestCtx testContext;
    setup_test_context(context, reporter, &testContext,
                       kDimensions, Volatile::kYes, /* invalidBackendTex= */ false);

    {
        SkCanvas* canvas = testContext.fSurface->getCanvas();

        canvas->drawImage(testContext.fImg, 0, 0);
        check_unfulfilled(testContext.fPromiseImageChecker, testContext.fPromiseTextureCheckers,
                          reporter);

        std::unique_ptr<Recording> recording = testContext.fRecorder->snap();
        // Nothing happens at snap time for VPIs
        check_unfulfilled(testContext.fPromiseImageChecker, testContext.fPromiseTextureCheckers,
                          reporter);

        REPORTER_ASSERT(reporter, context->insertRecording({ recording.get() }));
        check_fulfilled_ahead_by_one(reporter, testContext.fPromiseImageChecker,
                                     testContext.fPromiseTextureCheckers,
                                     /* expectedFulfillCnt= */ 1);  // VPIs fulfilled on insert

        // Test that multiple insertions will clobber prior fulfills
        REPORTER_ASSERT(reporter, context->insertRecording({ recording.get() }));
        check_fulfilled_ahead_by_two(reporter, testContext.fPromiseImageChecker,
                                     testContext.fPromiseTextureCheckers,
                                     /* expectedFulfillCnt= */ 2);
    }

    testGpuContext->syncedSubmit(context);
    check_all_done(reporter, testContext.fPromiseImageChecker, testContext.fPromiseTextureCheckers,
                   /* expectedFulfillCnt= */ 2);

    for (int i = 0; i < 4; ++i) {
        REPORTER_ASSERT(reporter,
                        testContext.fPromiseTextureCheckers[i].fTextureReleaseCounts[0] == 1);
        REPORTER_ASSERT(reporter,
                        testContext.fPromiseTextureCheckers[i].fTextureReleaseCounts[1] == 1);
    }

    {
        SkCanvas* canvas = testContext.fSurface->getCanvas();

        canvas->drawImage(testContext.fImg, 0, 0);
        canvas->drawImage(testContext.fImg, 0, 0);

        std::unique_ptr<Recording> recording = testContext.fRecorder->snap();
        // Nothing happens at snap time for volatile images
        check_all_done(reporter, testContext.fPromiseImageChecker,
                       testContext.fPromiseTextureCheckers, /* expectedFulfillCnt= */ 2);

        REPORTER_ASSERT(reporter, context->insertRecording({ recording.get() }));
        check_fulfilled_ahead_by_one(reporter, testContext.fPromiseImageChecker,
                                     testContext.fPromiseTextureCheckers,
                                     /* expectedFulfillCnt= */ 3);

        REPORTER_ASSERT(reporter, context->insertRecording({ recording.get() }));
        check_fulfilled_ahead_by_two(reporter, testContext.fPromiseImageChecker,
                                     testContext.fPromiseTextureCheckers,
                                     /* expectedFulfillCnt= */ 4);
    }

    testGpuContext->syncedSubmit(context);
    check_all_done(reporter, testContext.fPromiseImageChecker, testContext.fPromiseTextureCheckers,
                   /* expectedFulfillCnt= */ 4);

    for (int i = 0; i < 4; ++i) {
        REPORTER_ASSERT(reporter,
                        testContext.fPromiseTextureCheckers[i].fTextureReleaseCounts[0] == 2);
        REPORTER_ASSERT(reporter,
                        testContext.fPromiseTextureCheckers[i].fTextureReleaseCounts[1] == 2);
    }

    {
        SkCanvas* canvas = testContext.fSurface->getCanvas();

        canvas->drawImage(testContext.fImg, 0, 0);
        testContext.fImg.reset();

        std::unique_ptr<Recording> recording = testContext.fRecorder->snap();
        // Nothing happens at snap time for volatile images
        check_all_done(reporter, testContext.fPromiseImageChecker,
                       testContext.fPromiseTextureCheckers, /* expectedFulfillCnt= */ 4);

        REPORTER_ASSERT(reporter, context->insertRecording({ recording.get() }));
        check_fulfilled_ahead_by_one(reporter, testContext.fPromiseImageChecker,
                                     testContext.fPromiseTextureCheckers,
                                     /* expectedFulfillCnt= */ 5);

        REPORTER_ASSERT(reporter, context->insertRecording({ recording.get() }));
        check_fulfilled_ahead_by_two(reporter, testContext.fPromiseImageChecker,
                                     testContext.fPromiseTextureCheckers,
                                     /* expectedFulfillCnt= */ 6);
    }

    // testContext.fImg no longer holds a ref but the last recordings are still not submitted.
    check_fulfilled_ahead_by_two(reporter, testContext.fPromiseImageChecker,
                                 testContext.fPromiseTextureCheckers,
                                 /* expectedFulfillCnt= */ 6);

    testGpuContext->syncedSubmit(context);

    // Now all Releases should definitely have been called.
    check_all_done(reporter, testContext.fPromiseImageChecker, testContext.fPromiseTextureCheckers,
                   /* expectedFulfillCnt= */ 6);

    for (int i = 0; i < 4; ++i) {
        REPORTER_ASSERT(reporter,
                        testContext.fPromiseTextureCheckers[i].fTextureReleaseCounts[0] == 3);
        REPORTER_ASSERT(reporter,
                        testContext.fPromiseTextureCheckers[i].fTextureReleaseCounts[1] == 3);
    }
}

DEF_CONDITIONAL_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(
        VolatileGraphiteYUVAPromiseImageFulfillFailureTest,
        reporter,
        context,
        testGpuContext,
        true,
        CtsEnforcement::kApiLevel_202404) {
    constexpr SkISize kDimensions { 16, 16 };

    TestCtx testContext;
    setup_test_context(context, reporter, &testContext,
                       kDimensions, Volatile::kYes, /* invalidBackendTex= */ true);

    // Draw the image a few different ways.
    {
        SkCanvas* canvas = testContext.fSurface->getCanvas();

        canvas->drawImage(testContext.fImg, 0, 0);
        check_unfulfilled(testContext.fPromiseImageChecker, testContext.fPromiseTextureCheckers,
                          reporter);

        std::unique_ptr<Recording> recording = testContext.fRecorder->snap();
        check_unfulfilled(testContext.fPromiseImageChecker, testContext.fPromiseTextureCheckers,
                          reporter);

        REPORTER_ASSERT(reporter, !context->insertRecording({ recording.get() }));
        check_fulfills_only(reporter, testContext.fPromiseImageChecker,
                            testContext.fPromiseTextureCheckers, /* expectedFulfillCnt= */ 1);

        REPORTER_ASSERT(reporter, !context->insertRecording({ recording.get() }));
        check_fulfills_only(reporter, testContext.fPromiseImageChecker,
                            testContext.fPromiseTextureCheckers, /* expectedFulfillCnt= */ 2);
    }

    {
        SkCanvas* canvas = testContext.fSurface->getCanvas();

        SkPaint paint;
        paint.setColorFilter(SkColorFilters::LinearToSRGBGamma());
        canvas->drawImage(testContext.fImg, 0, 0, SkSamplingOptions(), &paint);

        std::unique_ptr<Recording> recording = testContext.fRecorder->snap();
        check_fulfills_only(reporter, testContext.fPromiseImageChecker,
                            testContext.fPromiseTextureCheckers, /* expectedFulfillCnt= */ 2);

        REPORTER_ASSERT(reporter, !context->insertRecording({ recording.get() }));
        check_fulfills_only(reporter, testContext.fPromiseImageChecker,
                            testContext.fPromiseTextureCheckers, /* expectedFulfillCnt= */ 3);

        REPORTER_ASSERT(reporter, !context->insertRecording({ recording.get() }));
        check_fulfills_only(reporter, testContext.fPromiseImageChecker,
                            testContext.fPromiseTextureCheckers, /* expectedFulfillCnt= */ 4);
    }

    {
        SkCanvas* canvas = testContext.fSurface->getCanvas();

        sk_sp<SkShader> shader = testContext.fImg->makeShader(SkSamplingOptions());
        REPORTER_ASSERT(reporter, shader);

        SkPaint paint;
        paint.setShader(std::move(shader));
        canvas->drawRect(SkRect::MakeWH(1, 1), paint);

        std::unique_ptr<Recording> recording = testContext.fRecorder->snap();
        check_fulfills_only(reporter, testContext.fPromiseImageChecker,
                            testContext.fPromiseTextureCheckers, /* expectedFulfillCnt= */ 4);

        REPORTER_ASSERT(reporter, !context->insertRecording({ recording.get() }));
        check_fulfills_only(reporter, testContext.fPromiseImageChecker,
                            testContext.fPromiseTextureCheckers, /* expectedFulfillCnt= */ 5);

        REPORTER_ASSERT(reporter, !context->insertRecording({ recording.get() }));
        check_fulfills_only(reporter, testContext.fPromiseImageChecker,
                            testContext.fPromiseTextureCheckers, /* expectedFulfillCnt= */ 6);
    }

    testContext.fSurface.reset();
    testContext.fImg.reset();

    testGpuContext->syncedSubmit(context);
    check_fulfills_only(reporter, testContext.fPromiseImageChecker,
                        testContext.fPromiseTextureCheckers, /* expectedFulfillCnt= */ 6);
}

// Test out dropping the Recorder prior to inserting the Recording
DEF_CONDITIONAL_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(GraphiteYUVAPromiseImageRecorderLoss,
                                                     reporter,
                                                     context,
                                                     testGpuContext,
                                                     true,
                                                     CtsEnforcement::kApiLevel_202404) {
    constexpr SkISize kDimensions{ 16, 16 };

    for (Volatile isVolatile : { Volatile::kNo, Volatile::kYes }) {
        TestCtx testContext;
        setup_test_context(context, reporter, &testContext,
                           kDimensions, isVolatile, /* invalidBackendTex= */ false);

        SkCanvas* canvas = testContext.fSurface->getCanvas();

        canvas->drawImage(testContext.fImg, 0, 0);
        check_unfulfilled(testContext.fPromiseImageChecker, testContext.fPromiseTextureCheckers,
                          reporter);

        std::unique_ptr<Recording> recording = testContext.fRecorder->snap();
        check_unfulfilled(testContext.fPromiseImageChecker, testContext.fPromiseTextureCheckers,
                          reporter);

        testContext.fRecorder.reset();  // Recorder drop

        REPORTER_ASSERT(reporter, context->insertRecording({ recording.get() }));
        check_fulfills_only(reporter, testContext.fPromiseImageChecker,
                            testContext.fPromiseTextureCheckers, /* expectedFulfillCnt= */ 1);

        testGpuContext->syncedSubmit(context);

        testContext.fSurface.reset();
        testContext.fImg.reset();
        recording.reset();

        check_all_done(reporter, testContext.fPromiseImageChecker,
                       testContext.fPromiseTextureCheckers, /* expectedFulfillCnt= */ 1);
    }
}

// Test out PromiseImages appearing in multiple Recordings. In particular, test that
// previous instantiations don't impact the Recording's collection of PromiseImages.
DEF_CONDITIONAL_GRAPHITE_TEST_FOR_RENDERING_CONTEXTS(GraphiteYUVAPromiseImageMultipleImgUses,
                                                     reporter,
                                                     context,
                                                     testGpuContext,
                                                     true,
                                                     CtsEnforcement::kApiLevel_202404) {
    constexpr SkISize kDimensions{ 16, 16 };

    static constexpr int kNumRecordings = 3;

    for (Volatile isVolatile : { Volatile::kNo, Volatile::kYes }) {
        int expectedVolatile = (isVolatile == Volatile::kYes) ? 4 : 0;
        int expectedNonVolatile = 4 - expectedVolatile;

        TestCtx testContext;
        setup_test_context(context, reporter, &testContext,
                           kDimensions, isVolatile, /* invalidBackendTex= */ false);

        std::unique_ptr<Recording> recordings[kNumRecordings];

        SkCanvas* canvas = testContext.fSurface->getCanvas();

        for (int i = 0; i < kNumRecordings; ++i) {
            canvas->drawImage(testContext.fImg, 0, 0);

            recordings[i] = testContext.fRecorder->snap();

            if (isVolatile == Volatile::kYes) {
                check_fulfills_only(reporter, testContext.fPromiseImageChecker,
                                    testContext.fPromiseTextureCheckers,
                                    /* expectedFulfillCnt= */ i);
            } else {
                check_fulfills_only(reporter, testContext.fPromiseImageChecker,
                                    testContext.fPromiseTextureCheckers,
                                    /* expectedFulfillCnt= */ i > 0 ? 1 : 0);
            }

            REPORTER_ASSERT(reporter,
                            recordings[i]->priv().numVolatilePromiseImages() == expectedVolatile);
            REPORTER_ASSERT(reporter,
                            recordings[i]->priv().numNonVolatilePromiseImages() ==
                            expectedNonVolatile);

            REPORTER_ASSERT(reporter, context->insertRecording({ recordings[i].get() }));

            if (isVolatile == Volatile::kYes) {
                check_fulfills_only(reporter, testContext.fPromiseImageChecker,
                                    testContext.fPromiseTextureCheckers,
                                    /* expectedFulfillCnt= */ i+1);
            } else {
                check_fulfills_only(reporter, testContext.fPromiseImageChecker,
                                    testContext.fPromiseTextureCheckers,
                                    /* expectedFulfillCnt= */ 1);
            }

            // Non-volatiles are cleared out after a successful insertion
            REPORTER_ASSERT(reporter, recordings[i]->priv().numNonVolatilePromiseImages() == 0);
        }

        testGpuContext->syncedSubmit(context);

        testContext.fSurface.reset();
        testContext.fImg.reset();
        for (int i = 0; i < kNumRecordings; ++i) {
            recordings[i].reset();
        }

        if (isVolatile == Volatile::kYes) {
            check_all_done(reporter, testContext.fPromiseImageChecker,
                           testContext.fPromiseTextureCheckers,
                           /* expectedFulfillCnt= */ kNumRecordings);
        } else {
            check_all_done(reporter, testContext.fPromiseImageChecker,
                           testContext.fPromiseTextureCheckers, /* expectedFulfillCnt= */ 1);
        }
    }
}
