/*
 * Copyright 2018 Google Inc.
 *
 * Use of this source code is governed by a BSD-style license that can be
 * found in the LICENSE file.
 */

#include "SkExchange.h"
#include "Test.h"

#include "GrBackendSurface.h"
#include "GrContextPriv.h"
#include "GrGpu.h"
#include "GrTexture.h"
#include "SkImage_Gpu.h"
#include "SkPromiseImageTexture.h"

using namespace sk_gpu_test;

struct PromiseTextureChecker {
    // shared indicates whether the backend texture is used to fulfill more than one promise
    // image.
    explicit PromiseTextureChecker(const GrBackendTexture& tex, skiatest::Reporter* reporter,
                                   bool shared)
            : fTexture(SkPromiseImageTexture::Make(tex))
            , fReporter(reporter)
            , fShared(shared)
            , fFulfillCount(0)
            , fReleaseCount(0)
            , fDoneCount(0) {}
    sk_sp<SkPromiseImageTexture> fTexture;
    skiatest::Reporter* fReporter;
    bool fShared;
    int fFulfillCount;
    int fReleaseCount;
    int fDoneCount;
    GrBackendTexture fLastFulfilledTexture;

    /**
     * Replaces the backend texture that this checker will return from fulfill. Also, transfers
     * ownership of the previous PromiseImageTexture to the caller, if they want to control when
     * it is deleted. The default argument will remove the existing texture without installing a
     * valid replacement.
     */
    sk_sp<const SkPromiseImageTexture> replaceTexture(
            const GrBackendTexture& tex = GrBackendTexture()) {
        return skstd::exchange(fTexture, SkPromiseImageTexture::Make(tex));
    }

    SkTArray<GrUniqueKey> uniqueKeys() const {
        return fTexture->testingOnly_uniqueKeysToInvalidate();
    }

    static sk_sp<SkPromiseImageTexture> Fulfill(void* self) {
        auto checker = static_cast<PromiseTextureChecker*>(self);
        checker->fFulfillCount++;
        checker->fLastFulfilledTexture = checker->fTexture->backendTexture();
        return checker->fTexture;
    }
    static void Release(void* self) {
        auto checker = static_cast<PromiseTextureChecker*>(self);
        checker->fReleaseCount++;
        if (!checker->fShared) {
            // This is only used in a single threaded fashion with a single promise image. So
            // every fulfill should be balanced by a release before the next fulfill.
            REPORTER_ASSERT(checker->fReporter, checker->fReleaseCount == checker->fFulfillCount);
        }
    }
    static void Done(void* self) {
        static_cast<PromiseTextureChecker*>(self)->fDoneCount++;
    }
};

enum class ReleaseBalanceExpecation {
    kBalanced,
    kBalancedOrPlusOne,
    kAny
};

static bool check_fulfill_and_release_cnts(const PromiseTextureChecker& promiseChecker,
                                           ReleaseBalanceExpecation balanceExpecation,
                                           int expectedFulfillCnt,
                                           int expectedReleaseCnt,
                                           bool expectedRequired,
                                           int expectedDoneCnt,
                                           skiatest::Reporter* reporter) {
    bool result = true;
    int countDiff = promiseChecker.fFulfillCount - promiseChecker.fReleaseCount;
    // FulfillCount should always equal ReleaseCount or be at most one higher
    if (countDiff != 0) {
        if (balanceExpecation == ReleaseBalanceExpecation::kBalanced) {
            result = false;
            REPORTER_ASSERT(reporter, 0 == countDiff);
        } else if (countDiff != 1 &&
                   balanceExpecation == ReleaseBalanceExpecation::kBalancedOrPlusOne) {
            result = false;
            REPORTER_ASSERT(reporter, 0 == countDiff || 1 == countDiff);
        } else if (countDiff < 0) {
            result = false;
            REPORTER_ASSERT(reporter, countDiff >= 0);
        }
    }

    int fulfillDiff = expectedFulfillCnt - promiseChecker.fFulfillCount;
    REPORTER_ASSERT(reporter, fulfillDiff >= 0);
    if (fulfillDiff != 0) {
        if (expectedRequired) {
            result = false;
            REPORTER_ASSERT(reporter, expectedFulfillCnt == promiseChecker.fFulfillCount);
        } else if (fulfillDiff > 1) {
            result = false;
            REPORTER_ASSERT(reporter, fulfillDiff <= 1);
        }
    }

    int releaseDiff = expectedReleaseCnt - promiseChecker.fReleaseCount;
    REPORTER_ASSERT(reporter, releaseDiff >= 0);
    if (releaseDiff != 0) {
        if (expectedRequired) {
            result = false;
            REPORTER_ASSERT(reporter, expectedReleaseCnt == promiseChecker.fReleaseCount);
        } else if (releaseDiff > 1) {
            result = false;
            REPORTER_ASSERT(reporter, releaseDiff <= 1);
        }
    }

    if (expectedDoneCnt != promiseChecker.fDoneCount) {
        result = false;
        REPORTER_ASSERT(reporter, expectedDoneCnt == promiseChecker.fDoneCount);
    }

    return result;
}

DEF_GPUTEST_FOR_RENDERING_CONTEXTS(PromiseImageTestNoDelayedRelease, reporter, ctxInfo) {
    const int kWidth = 10;
    const int kHeight = 10;

    GrContext* ctx = ctxInfo.grContext();
    GrGpu* gpu = ctx->priv().getGpu();

    for (bool releaseImageEarly : {true, false}) {
        GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture(
                nullptr, kWidth, kHeight, GrColorType::kRGBA_8888, true, GrMipMapped::kNo);
        REPORTER_ASSERT(reporter, backendTex.isValid());

        GrBackendFormat backendFormat = backendTex.getBackendFormat();
        REPORTER_ASSERT(reporter, backendFormat.isValid());

        PromiseTextureChecker promiseChecker(backendTex, reporter, false);
        GrSurfaceOrigin texOrigin = kTopLeft_GrSurfaceOrigin;
        sk_sp<SkImage> refImg(
                SkImage_Gpu::MakePromiseTexture(
                        ctx, backendFormat, kWidth, kHeight,
                        GrMipMapped::kNo, texOrigin,
                        kRGBA_8888_SkColorType, kPremul_SkAlphaType,
                        nullptr,
                        PromiseTextureChecker::Fulfill,
                        PromiseTextureChecker::Release,
                        PromiseTextureChecker::Done,
                        &promiseChecker,
                        SkDeferredDisplayListRecorder::DelayReleaseCallback::kNo));

        SkImageInfo info = SkImageInfo::MakeN32Premul(kWidth, kHeight);
        sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, info);
        SkCanvas* canvas = surface->getCanvas();

        int expectedFulfillCnt = 0;
        int expectedReleaseCnt = 0;
        int expectedDoneCnt = 0;
        ReleaseBalanceExpecation balanceExpecation = ReleaseBalanceExpecation::kBalanced;

        canvas->drawImage(refImg, 0, 0);
        REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
                                                                 balanceExpecation,
                                                                 expectedFulfillCnt,
                                                                 expectedReleaseCnt,
                                                                 true,
                                                                 expectedDoneCnt,
                                                                 reporter));

        bool isVulkan = GrBackendApi::kVulkan == ctx->backend();
        canvas->flush();
        expectedFulfillCnt++;
        expectedReleaseCnt++;
        if (isVulkan) {
            balanceExpecation = ReleaseBalanceExpecation::kBalancedOrPlusOne;
        }
        REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
                                                                 balanceExpecation,
                                                                 expectedFulfillCnt,
                                                                 expectedReleaseCnt,
                                                                 !isVulkan,
                                                                 expectedDoneCnt,
                                                                 reporter));

        gpu->testingOnly_flushGpuAndSync();
        balanceExpecation = ReleaseBalanceExpecation::kBalanced;
        REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
                                                                 balanceExpecation,
                                                                 expectedFulfillCnt,
                                                                 expectedReleaseCnt,
                                                                 true,
                                                                 expectedDoneCnt,
                                                                 reporter));

        canvas->drawImage(refImg, 0, 0);
        canvas->drawImage(refImg, 0, 0);

        canvas->flush();
        expectedFulfillCnt++;
        expectedReleaseCnt++;

        gpu->testingOnly_flushGpuAndSync();
        REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
                                                                 balanceExpecation,
                                                                 expectedFulfillCnt,
                                                                 expectedReleaseCnt,
                                                                 true,
                                                                 expectedDoneCnt,
                                                                 reporter));

        // Now test code path on Vulkan where we released the texture, but the GPU isn't done with
        // resource yet and we do another draw. We should only call fulfill on the first draw and
        // use the cached GrBackendTexture on the second. Release should only be called after the
        // second draw is finished.
        canvas->drawImage(refImg, 0, 0);
        canvas->flush();
        expectedFulfillCnt++;
        expectedReleaseCnt++;
        if (isVulkan) {
            balanceExpecation = ReleaseBalanceExpecation::kBalancedOrPlusOne;
        }
        REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
                                                                 balanceExpecation,
                                                                 expectedFulfillCnt,
                                                                 expectedReleaseCnt,
                                                                 !isVulkan,
                                                                 expectedDoneCnt,
                                                                 reporter));

        canvas->drawImage(refImg, 0, 0);

        if (releaseImageEarly) {
            refImg.reset();
        }

        REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
                                                                 balanceExpecation,
                                                                 expectedFulfillCnt,
                                                                 expectedReleaseCnt,
                                                                 !isVulkan,
                                                                 expectedDoneCnt,
                                                                 reporter));

        canvas->flush();
        expectedFulfillCnt++;

        gpu->testingOnly_flushGpuAndSync();
        expectedReleaseCnt++;
        if (releaseImageEarly) {
            expectedDoneCnt++;
        }
        balanceExpecation = ReleaseBalanceExpecation::kBalanced;
        REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
                                                                 balanceExpecation,
                                                                 expectedFulfillCnt,
                                                                 expectedReleaseCnt,
                                                                 !isVulkan,
                                                                 expectedDoneCnt,
                                                                 reporter));
        expectedFulfillCnt = promiseChecker.fFulfillCount;
        expectedReleaseCnt = promiseChecker.fReleaseCount;

        if (!releaseImageEarly) {
            refImg.reset();
            expectedDoneCnt++;
        }

        REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
                                                                 balanceExpecation,
                                                                 expectedFulfillCnt,
                                                                 expectedReleaseCnt,
                                                                 true,
                                                                 expectedDoneCnt,
                                                                 reporter));

        gpu->deleteTestingOnlyBackendTexture(backendTex);
    }
}

DEF_GPUTEST_FOR_RENDERING_CONTEXTS(PromiseImageTestDelayedRelease, reporter, ctxInfo) {
    const int kWidth = 10;
    const int kHeight = 10;

    GrContext* ctx = ctxInfo.grContext();
    GrGpu* gpu = ctx->priv().getGpu();

    GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture(
            nullptr, kWidth, kHeight, GrColorType::kRGBA_8888, true, GrMipMapped::kNo);
    REPORTER_ASSERT(reporter, backendTex.isValid());

    GrBackendFormat backendFormat = backendTex.getBackendFormat();
    REPORTER_ASSERT(reporter, backendFormat.isValid());

    PromiseTextureChecker promiseChecker(backendTex, reporter, false);
    GrSurfaceOrigin texOrigin = kTopLeft_GrSurfaceOrigin;
    sk_sp<SkImage> refImg(
            SkImage_Gpu::MakePromiseTexture(
                    ctx, backendFormat, kWidth, kHeight,
                    GrMipMapped::kNo, texOrigin,
                    kRGBA_8888_SkColorType, kPremul_SkAlphaType,
                    nullptr,
                    PromiseTextureChecker::Fulfill,
                    PromiseTextureChecker::Release,
                    PromiseTextureChecker::Done,
                    &promiseChecker,
                    SkDeferredDisplayListRecorder::DelayReleaseCallback::kYes));

    SkImageInfo info = SkImageInfo::MakeN32Premul(kWidth, kHeight);
    sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, info);
    SkCanvas* canvas = surface->getCanvas();

    int expectedFulfillCnt = 0;
    int expectedReleaseCnt = 0;
    int expectedDoneCnt = 0;
    ReleaseBalanceExpecation balanceExpecation = ReleaseBalanceExpecation::kBalanced;

    canvas->drawImage(refImg, 0, 0);
    REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
                                                             balanceExpecation,
                                                             expectedFulfillCnt,
                                                             expectedReleaseCnt,
                                                             true,
                                                             expectedDoneCnt,
                                                             reporter));

    bool isVulkan = GrBackendApi::kVulkan == ctx->backend();
    canvas->flush();
    expectedFulfillCnt++;
    // Because we've delayed release, we expect a +1 balance.
    balanceExpecation = ReleaseBalanceExpecation::kBalancedOrPlusOne;
    REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
                                                             balanceExpecation,
                                                             expectedFulfillCnt,
                                                             expectedReleaseCnt,
                                                             !isVulkan,
                                                             expectedDoneCnt,
                                                             reporter));

    gpu->testingOnly_flushGpuAndSync();
    REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
                                                             balanceExpecation,
                                                             expectedFulfillCnt,
                                                             expectedReleaseCnt,
                                                             true,
                                                             expectedDoneCnt,
                                                             reporter));

    canvas->drawImage(refImg, 0, 0);
    canvas->drawImage(refImg, 0, 0);

    canvas->flush();

    gpu->testingOnly_flushGpuAndSync();
    REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
                                                             balanceExpecation,
                                                             expectedFulfillCnt,
                                                             expectedReleaseCnt,
                                                             true,
                                                             expectedDoneCnt,
                                                             reporter));

    canvas->drawImage(refImg, 0, 0);
    canvas->flush();
    REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
                                                             balanceExpecation,
                                                             expectedFulfillCnt,
                                                             expectedReleaseCnt,
                                                             !isVulkan,
                                                             expectedDoneCnt,
                                                             reporter));

    canvas->drawImage(refImg, 0, 0);

    refImg.reset();

    REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
                                                             balanceExpecation,
                                                             expectedFulfillCnt,
                                                             expectedReleaseCnt,
                                                             !isVulkan,
                                                             expectedDoneCnt,
                                                             reporter));

    canvas->flush();
    gpu->testingOnly_flushGpuAndSync();
    // We released the image already and we flushed and synced.
    balanceExpecation = ReleaseBalanceExpecation::kBalanced;
    expectedReleaseCnt++;
    expectedDoneCnt++;
    REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
                                                             balanceExpecation,
                                                             expectedFulfillCnt,
                                                             expectedReleaseCnt,
                                                             !isVulkan,
                                                             expectedDoneCnt,
                                                             reporter));

    gpu->deleteTestingOnlyBackendTexture(backendTex);
}

// Tests replacing the backing texture for a promise image after a release and then refulfilling in
// the SkDeferredDisplayListRecorder::DelayReleaseCallback::kNo case.
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(PromiseImageTextureReuse, reporter, ctxInfo) {
    const int kWidth = 10;
    const int kHeight = 10;

    GrContext* ctx = ctxInfo.grContext();
    GrGpu* gpu = ctx->priv().getGpu();

    GrBackendTexture backendTex1 = gpu->createTestingOnlyBackendTexture(
            nullptr, kWidth, kHeight, GrColorType::kRGBA_8888, false, GrMipMapped::kNo);
    GrBackendTexture backendTex2 = gpu->createTestingOnlyBackendTexture(
            nullptr, kWidth, kHeight, GrColorType::kRGBA_8888, false, GrMipMapped::kNo);
    GrBackendTexture backendTex3 = gpu->createTestingOnlyBackendTexture(
            nullptr, kWidth, kHeight, GrColorType::kRGBA_8888, false, GrMipMapped::kNo);
    REPORTER_ASSERT(reporter, backendTex1.isValid());
    REPORTER_ASSERT(reporter, backendTex2.isValid());
    REPORTER_ASSERT(reporter, backendTex3.isValid());

    GrBackendFormat backendFormat = backendTex1.getBackendFormat();
    REPORTER_ASSERT(reporter, backendFormat.isValid());
    REPORTER_ASSERT(reporter, backendFormat == backendTex2.getBackendFormat());
    REPORTER_ASSERT(reporter, backendFormat == backendTex3.getBackendFormat());

    PromiseTextureChecker promiseChecker(backendTex1, reporter, true);
    GrSurfaceOrigin texOrigin = kTopLeft_GrSurfaceOrigin;
    sk_sp<SkImage> refImg(
            SkImage_Gpu::MakePromiseTexture(
                    ctx, backendFormat, kWidth, kHeight,
                    GrMipMapped::kNo, texOrigin,
                    kRGBA_8888_SkColorType, kPremul_SkAlphaType,
                    nullptr,
                    PromiseTextureChecker::Fulfill,
                    PromiseTextureChecker::Release,
                    PromiseTextureChecker::Done,
                    &promiseChecker,
                    SkDeferredDisplayListRecorder::DelayReleaseCallback::kNo));

    SkImageInfo info =
            SkImageInfo::Make(kWidth, kHeight, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
    sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, info);
    SkCanvas* canvas = surface->getCanvas();

    int expectedFulfillCnt = 0;
    int expectedReleaseCnt = 0;
    int expectedDoneCnt = 0;

    canvas->drawImage(refImg, 0, 0);
    canvas->drawImage(refImg, 5, 5);
    ReleaseBalanceExpecation balanceExpecation = ReleaseBalanceExpecation::kBalanced;
    REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
                                                             balanceExpecation,
                                                             expectedFulfillCnt,
                                                             expectedReleaseCnt,
                                                             true,
                                                             expectedDoneCnt,
                                                             reporter));

    bool isVulkan = GrBackendApi::kVulkan == ctx->backend();
    canvas->flush();
    expectedFulfillCnt++;
    expectedReleaseCnt++;
    if (isVulkan) {
        balanceExpecation = ReleaseBalanceExpecation::kBalancedOrPlusOne;
    }
    REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
                                                             balanceExpecation,
                                                             expectedFulfillCnt,
                                                             expectedReleaseCnt,
                                                             !isVulkan,
                                                             expectedDoneCnt,
                                                             reporter));
    REPORTER_ASSERT(reporter, GrBackendTexture::TestingOnly_Equals(
                                      promiseChecker.fLastFulfilledTexture, backendTex1));
    // We should have put a GrTexture for this fulfillment into the cache.
    auto keys = promiseChecker.uniqueKeys();
    REPORTER_ASSERT(reporter, keys.count() == 1);
    GrUniqueKey texKey1;
    if (keys.count()) {
        texKey1 = keys[0];
    }
    REPORTER_ASSERT(reporter, texKey1.isValid());
    REPORTER_ASSERT(reporter, ctx->priv().resourceProvider()->findByUniqueKey<>(texKey1));

    gpu->testingOnly_flushGpuAndSync();
    balanceExpecation = ReleaseBalanceExpecation::kBalanced;
    REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
                                                             balanceExpecation,
                                                             expectedFulfillCnt,
                                                             expectedReleaseCnt,
                                                             true,
                                                             expectedDoneCnt,
                                                             reporter));
    REPORTER_ASSERT(reporter,
                    GrBackendTexture::TestingOnly_Equals(
                            promiseChecker.replaceTexture()->backendTexture(), backendTex1));
    gpu->deleteTestingOnlyBackendTexture(backendTex1);

    ctx->priv().getResourceCache()->purgeAsNeeded();
    // We should have invalidated the key on the previously cached texture (after ensuring
    // invalidation messages have been processed by calling purgeAsNeeded.)
    REPORTER_ASSERT(reporter, !ctx->priv().resourceProvider()->findByUniqueKey<>(texKey1));

    promiseChecker.replaceTexture(backendTex2);

    canvas->drawImage(refImg, 0, 0);
    REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
                                                             balanceExpecation,
                                                             expectedFulfillCnt,
                                                             expectedReleaseCnt,
                                                             true,
                                                             expectedDoneCnt,
                                                             reporter));

    canvas->flush();
    expectedFulfillCnt++;
    expectedReleaseCnt++;
    if (isVulkan) {
        balanceExpecation = ReleaseBalanceExpecation::kBalancedOrPlusOne;
    }
    // Second texture should be in the cache.
    keys = promiseChecker.uniqueKeys();
    REPORTER_ASSERT(reporter, keys.count() == 1);
    GrUniqueKey texKey2;
    if (keys.count()) {
        texKey2 = keys[0];
    }
    REPORTER_ASSERT(reporter, texKey2.isValid() && texKey2 != texKey1);
    REPORTER_ASSERT(reporter, ctx->priv().resourceProvider()->findByUniqueKey<>(texKey2));

    REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
                                                             balanceExpecation,
                                                             expectedFulfillCnt,
                                                             expectedReleaseCnt,
                                                             !isVulkan,
                                                             expectedDoneCnt,
                                                             reporter));
    REPORTER_ASSERT(reporter, GrBackendTexture::TestingOnly_Equals(
                                      promiseChecker.fLastFulfilledTexture, backendTex2));

    gpu->testingOnly_flushGpuAndSync();
    balanceExpecation = ReleaseBalanceExpecation::kBalanced;
    REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
                                                             balanceExpecation,
                                                             expectedFulfillCnt,
                                                             expectedReleaseCnt,
                                                             true,
                                                             expectedDoneCnt,
                                                             reporter));

    // Because we have kept the SkPromiseImageTexture alive, we should be able to use it again and
    // hit the cache.
    ctx->priv().getResourceCache()->purgeAsNeeded();
    REPORTER_ASSERT(reporter, ctx->priv().resourceProvider()->findByUniqueKey<>(texKey2));

    canvas->drawImage(refImg, 0, 0);

    canvas->flush();
    gpu->testingOnly_flushGpuAndSync();
    expectedFulfillCnt++;
    expectedReleaseCnt++;
    REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
                                                             balanceExpecation,
                                                             expectedFulfillCnt,
                                                             expectedReleaseCnt,
                                                             true,
                                                             expectedDoneCnt,
                                                             reporter));

    // Make sure we didn't add another key and that the second texture is still alive in the cache.
    keys = promiseChecker.uniqueKeys();
    REPORTER_ASSERT(reporter, keys.count() == 1);
    if (keys.count()) {
        REPORTER_ASSERT(reporter, texKey2 == keys[0]);
    }
    ctx->priv().getResourceCache()->purgeAsNeeded();
    REPORTER_ASSERT(reporter, ctx->priv().resourceProvider()->findByUniqueKey<>(texKey2));

    // Now we test keeping tex2 alive but fulfilling with a new texture.
    sk_sp<const SkPromiseImageTexture> promiseImageTexture2 =
            promiseChecker.replaceTexture(backendTex3);
    REPORTER_ASSERT(reporter, GrBackendTexture::TestingOnly_Equals(
                                      promiseImageTexture2->backendTexture(), backendTex2));

    canvas->drawImage(refImg, 0, 0);

    canvas->flush();
    gpu->testingOnly_flushGpuAndSync();
    expectedFulfillCnt++;
    expectedReleaseCnt++;
    REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
                                                             balanceExpecation,
                                                             expectedFulfillCnt,
                                                             expectedReleaseCnt,
                                                             true,
                                                             expectedDoneCnt,
                                                             reporter));

    keys = promiseChecker.uniqueKeys();
    REPORTER_ASSERT(reporter, keys.count() == 1);
    GrUniqueKey texKey3;
    if (keys.count()) {
        texKey3 = keys[0];
    }
    ctx->priv().getResourceCache()->purgeAsNeeded();
    REPORTER_ASSERT(reporter, !ctx->priv().resourceProvider()->findByUniqueKey<>(texKey2));
    REPORTER_ASSERT(reporter, ctx->priv().resourceProvider()->findByUniqueKey<>(texKey3));
    gpu->deleteTestingOnlyBackendTexture(promiseImageTexture2->backendTexture());

    // Make a new promise image also backed by texture 3.
    sk_sp<SkImage> refImg2(
            SkImage_Gpu::MakePromiseTexture(
                    ctx, backendFormat, kWidth, kHeight,
                    GrMipMapped::kNo, texOrigin,
                    kRGBA_8888_SkColorType, kPremul_SkAlphaType,
                    nullptr,
                    PromiseTextureChecker::Fulfill,
                    PromiseTextureChecker::Release,
                    PromiseTextureChecker::Done,
                    &promiseChecker,
                    SkDeferredDisplayListRecorder::DelayReleaseCallback::kNo));
    canvas->drawImage(refImg, 0, 0);
    canvas->drawImage(refImg2, 1, 1);

    canvas->flush();
    gpu->testingOnly_flushGpuAndSync();
    expectedFulfillCnt += 2;
    expectedReleaseCnt += 2;
    REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
                                                             balanceExpecation,
                                                             expectedFulfillCnt,
                                                             expectedReleaseCnt,
                                                             true,
                                                             expectedDoneCnt,
                                                             reporter));

    // The two images should share a single GrTexture by using the same key. The key is only
    // dependent on the pixel config and the PromiseImageTexture key.
    keys = promiseChecker.uniqueKeys();
    REPORTER_ASSERT(reporter, keys.count() == 1);
    if (keys.count() > 0) {
        REPORTER_ASSERT(reporter, texKey3 == keys[0]);
    }
    ctx->priv().getResourceCache()->purgeAsNeeded();

    // If we delete the SkPromiseImageTexture we should trigger both key removals.
    REPORTER_ASSERT(reporter,
                    GrBackendTexture::TestingOnly_Equals(
                            promiseChecker.replaceTexture()->backendTexture(), backendTex3));

    ctx->priv().getResourceCache()->purgeAsNeeded();
    REPORTER_ASSERT(reporter, !ctx->priv().resourceProvider()->findByUniqueKey<>(texKey3));
    gpu->deleteTestingOnlyBackendTexture(backendTex3);

    // After deleting each image we should get a done call.
    refImg.reset();
    ++expectedDoneCnt;
    REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
                                                             balanceExpecation,
                                                             expectedFulfillCnt,
                                                             expectedReleaseCnt,
                                                             true,
                                                             expectedDoneCnt,
                                                             reporter));
    refImg2.reset();
    ++expectedDoneCnt;
    REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
                                                             balanceExpecation,
                                                             expectedFulfillCnt,
                                                             expectedReleaseCnt,
                                                             true,
                                                             expectedDoneCnt,
                                                             reporter));
}

DEF_GPUTEST_FOR_RENDERING_CONTEXTS(PromiseImageTextureReuseDifferentConfig, reporter, ctxInfo) {
    // Try making two promise SkImages backed by the same texture but with different configs.
    // This will only be testable on backends where a single texture format (8bit red unorm) can
    // be used for alpha and gray image color types.

    const int kWidth = 10;
    const int kHeight = 10;

    GrContext* ctx = ctxInfo.grContext();
    GrGpu* gpu = ctx->priv().getGpu();

    GrBackendTexture backendTex1 = gpu->createTestingOnlyBackendTexture(
            nullptr, kWidth, kHeight, GrColorType::kGray_8, false, GrMipMapped::kNo);
    REPORTER_ASSERT(reporter, backendTex1.isValid());

    GrBackendTexture backendTex2 = gpu->createTestingOnlyBackendTexture(
            nullptr, kWidth, kHeight, GrColorType::kAlpha_8, false, GrMipMapped::kNo);
    REPORTER_ASSERT(reporter, backendTex2.isValid());
    if (backendTex1.getBackendFormat() != backendTex2.getBackendFormat()) {
        gpu->deleteTestingOnlyBackendTexture(backendTex1);
        return;
    }
    // We only needed this texture to check that alpha and gray color types use the same format.
    gpu->deleteTestingOnlyBackendTexture(backendTex2);

    SkImageInfo info =
            SkImageInfo::Make(kWidth, kHeight, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
    sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, info);
    SkCanvas* canvas = surface->getCanvas();

    for (auto delayRelease : {SkDeferredDisplayListRecorder::DelayReleaseCallback::kNo,
                              SkDeferredDisplayListRecorder::DelayReleaseCallback::kYes}) {
        PromiseTextureChecker promiseChecker(backendTex1, reporter, true);
        sk_sp<SkImage> alphaImg(SkImage_Gpu::MakePromiseTexture(
                ctx, backendTex1.getBackendFormat(), kWidth, kHeight, GrMipMapped::kNo,
                kTopLeft_GrSurfaceOrigin, kAlpha_8_SkColorType, kPremul_SkAlphaType, nullptr,
                PromiseTextureChecker::Fulfill, PromiseTextureChecker::Release,
                PromiseTextureChecker::Done, &promiseChecker, delayRelease));
        REPORTER_ASSERT(reporter, alphaImg);

        sk_sp<SkImage> grayImg(SkImage_Gpu::MakePromiseTexture(
                ctx, backendTex1.getBackendFormat(), kWidth, kHeight, GrMipMapped::kNo,
                kBottomLeft_GrSurfaceOrigin, kGray_8_SkColorType, kOpaque_SkAlphaType, nullptr,
                PromiseTextureChecker::Fulfill, PromiseTextureChecker::Release,
                PromiseTextureChecker::Done, &promiseChecker, delayRelease));
        REPORTER_ASSERT(reporter, grayImg);

        canvas->drawImage(alphaImg, 0, 0);
        canvas->drawImage(grayImg, 1, 1);
        canvas->flush();
        gpu->testingOnly_flushGpuAndSync();

        int expectedFulfillCnt = 2;
        int expectedReleaseCnt = 0;
        int expectedDoneCnt = 0;
        ReleaseBalanceExpecation balanceExpecation = ReleaseBalanceExpecation::kAny;
        if (delayRelease == SkDeferredDisplayListRecorder::DelayReleaseCallback::kNo) {
            expectedReleaseCnt = 2;
            balanceExpecation = ReleaseBalanceExpecation::kBalanced;
        }
        REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
                                                                 balanceExpecation,
                                                                 expectedFulfillCnt,
                                                                 expectedReleaseCnt,
                                                                 true,
                                                                 expectedDoneCnt,
                                                                 reporter));

        // Because they use different configs, each image should have created a different GrTexture
        // and they both should still be cached.
        ctx->priv().getResourceCache()->purgeAsNeeded();

        auto keys = promiseChecker.uniqueKeys();
        REPORTER_ASSERT(reporter, keys.count() == 2);
        for (const auto& key : keys) {
            auto surf = ctx->priv().resourceProvider()->findByUniqueKey<GrSurface>(key);
            REPORTER_ASSERT(reporter, surf && surf->asTexture());
            if (surf && surf->asTexture()) {
                REPORTER_ASSERT(reporter,
                                !GrBackendTexture::TestingOnly_Equals(
                                        backendTex1, surf->asTexture()->getBackendTexture()));
            }
        }

        // Change the backing texture, this should invalidate the keys.
        promiseChecker.replaceTexture();
        ctx->priv().getResourceCache()->purgeAsNeeded();

        for (const auto& key : keys) {
            auto surf = ctx->priv().resourceProvider()->findByUniqueKey<GrSurface>(key);
            REPORTER_ASSERT(reporter, !surf);
        }
    }
    gpu->deleteTestingOnlyBackendTexture(backendTex1);
}

DEF_GPUTEST(PromiseImageTextureShutdown, reporter, ctxInfo) {
    const int kWidth = 10;
    const int kHeight = 10;

    // Different ways of killing contexts.
    using DeathFn = std::function<void(sk_gpu_test::GrContextFactory*, GrContext*)>;
    DeathFn destroy = [](sk_gpu_test::GrContextFactory* factory, GrContext* context) {
        factory->destroyContexts();
    };
    DeathFn abandon = [](sk_gpu_test::GrContextFactory* factory, GrContext* context) {
        context->abandonContext();
    };
    DeathFn releaseResourcesAndAbandon = [](sk_gpu_test::GrContextFactory* factory,
                                            GrContext* context) {
        context->releaseResourcesAndAbandonContext();
    };

    for (int type = 0; type < sk_gpu_test::GrContextFactory::kContextTypeCnt; ++type) {
        auto contextType = static_cast<sk_gpu_test::GrContextFactory::ContextType>(type);
        // These tests are difficult to get working with Vulkan. See http://skbug.com/8705
        // and http://skbug.com/8275
        GrBackendApi api = sk_gpu_test::GrContextFactory::ContextTypeBackend(contextType);
        if (api == GrBackendApi::kVulkan) {
            continue;
        }
        DeathFn contextKillers[] = {destroy, abandon, releaseResourcesAndAbandon};
        for (auto contextDeath : contextKillers) {
            sk_gpu_test::GrContextFactory factory;
            auto ctx = factory.get(contextType);
            if (!ctx) {
                continue;
            }
            GrGpu* gpu = ctx->priv().getGpu();

            GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture(
                    nullptr, kWidth, kHeight, GrColorType::kAlpha_8, false, GrMipMapped::kNo);
            REPORTER_ASSERT(reporter, backendTex.isValid());

            SkImageInfo info = SkImageInfo::Make(kWidth, kHeight, kRGBA_8888_SkColorType,
                                                 kPremul_SkAlphaType);
            sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, info);
            SkCanvas* canvas = surface->getCanvas();

            PromiseTextureChecker promiseChecker(backendTex, reporter, false);
            sk_sp<SkImage> image(SkImage_Gpu::MakePromiseTexture(
                    ctx, backendTex.getBackendFormat(), kWidth, kHeight, GrMipMapped::kNo,
                    kTopLeft_GrSurfaceOrigin, kAlpha_8_SkColorType, kPremul_SkAlphaType, nullptr,
                    PromiseTextureChecker::Fulfill, PromiseTextureChecker::Release,
                    PromiseTextureChecker::Done, &promiseChecker,
                    SkDeferredDisplayListRecorder::DelayReleaseCallback::kNo));
            REPORTER_ASSERT(reporter, image);

            canvas->drawImage(image, 0, 0);
            image.reset();
            // If the surface still holds a ref to the context then the factory will not be able
            // to destroy the context (and instead will release-all-and-abandon).
            surface.reset();

            ctx->flush();
            contextDeath(&factory, ctx);

            int expectedFulfillCnt = 1;
            int expectedReleaseCnt = 1;
            int expectedDoneCnt = 1;
            ReleaseBalanceExpecation balanceExpecation = ReleaseBalanceExpecation::kBalanced;
            REPORTER_ASSERT(reporter, check_fulfill_and_release_cnts(promiseChecker,
                                                                     balanceExpecation,
                                                                     expectedFulfillCnt,
                                                                     expectedReleaseCnt,
                                                                     true,
                                                                     expectedDoneCnt,
                                                                     reporter));
        }
    }
}

DEF_GPUTEST_FOR_RENDERING_CONTEXTS(PromiseImageTextureFullCache, reporter, ctxInfo) {
    const int kWidth = 10;
    const int kHeight = 10;

    GrContext* ctx = ctxInfo.grContext();
    GrGpu* gpu = ctx->priv().getGpu();

    GrBackendTexture backendTex = gpu->createTestingOnlyBackendTexture(
            nullptr, kWidth, kHeight, GrColorType::kAlpha_8, false, GrMipMapped::kNo);
    REPORTER_ASSERT(reporter, backendTex.isValid());

    SkImageInfo info =
            SkImageInfo::Make(kWidth, kHeight, kRGBA_8888_SkColorType, kPremul_SkAlphaType);
    sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(ctx, SkBudgeted::kNo, info);
    SkCanvas* canvas = surface->getCanvas();

    PromiseTextureChecker promiseChecker(backendTex, reporter, false);
    sk_sp<SkImage> image(SkImage_Gpu::MakePromiseTexture(
            ctx, backendTex.getBackendFormat(), kWidth, kHeight, GrMipMapped::kNo,
            kTopLeft_GrSurfaceOrigin, kAlpha_8_SkColorType, kPremul_SkAlphaType, nullptr,
            PromiseTextureChecker::Fulfill, PromiseTextureChecker::Release,
            PromiseTextureChecker::Done, &promiseChecker,
            SkDeferredDisplayListRecorder::DelayReleaseCallback::kNo));
    REPORTER_ASSERT(reporter, image);

    // Make the cache full. This tests that we don't preemptively purge cached textures for
    // fulfillment due to cache pressure.
    static constexpr int kMaxResources = 10;
    static constexpr int kMaxBytes = 100;
    ctx->setResourceCacheLimits(kMaxResources, kMaxBytes);
    sk_sp<GrTexture> textures[2 * kMaxResources];
    for (int i = 0; i < 2 * kMaxResources; ++i) {
        GrSurfaceDesc desc;
        desc.fConfig = kRGBA_8888_GrPixelConfig;
        desc.fWidth = desc.fHeight = 100;
        textures[i] = ctx->priv().resourceProvider()->createTexture(desc, SkBudgeted::kYes);
        REPORTER_ASSERT(reporter, textures[i]);
    }

    // Relying on the asserts in the promiseImageChecker to ensure that fulfills and releases are
    // properly ordered.
    canvas->drawImage(image, 0, 0);
    canvas->flush();
    canvas->drawImage(image, 1, 0);
    canvas->flush();
    canvas->drawImage(image, 2, 0);
    canvas->flush();
    canvas->drawImage(image, 3, 0);
    canvas->flush();
    canvas->drawImage(image, 4, 0);
    canvas->flush();
    canvas->drawImage(image, 5, 0);
    canvas->flush();
    // Must call this to ensure that all callbacks are performed before the checker is destroyed.
    gpu->testingOnly_flushGpuAndSync();
    gpu->deleteTestingOnlyBackendTexture(backendTex);
}
