/*
 * 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 "tests/Test.h"

#include "include/core/SkColorFilter.h"
#include "include/core/SkPromiseImageTexture.h"
#include "include/gpu/GrBackendSurface.h"
#include "include/gpu/GrDirectContext.h"
#include "src/gpu/ganesh/GrDirectContextPriv.h"
#include "src/gpu/ganesh/GrGpu.h"
#include "src/gpu/ganesh/GrResourceProvider.h"
#include "src/gpu/ganesh/GrTexture.h"
#include "src/image/SkImage_Gpu.h"
#include "tools/gpu/ManagedBackendTexture.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) {}
    sk_sp<SkPromiseImageTexture> fTexture;
    skiatest::Reporter* fReporter;
    bool fShared;
    int fFulfillCount = 0;
    int fReleaseCount = 0;

    static sk_sp<SkPromiseImageTexture> Fulfill(void* self) {
        auto checker = static_cast<PromiseTextureChecker*>(self);
        checker->fFulfillCount++;
        return checker->fTexture;
    }
    static void Release(void* self) { static_cast<PromiseTextureChecker*>(self)->fReleaseCount++; }
};

enum class ReleaseBalanceExpectation {
    kBalanced,
    kAllUnbalanced,
    kUnknown,
    kUnbalancedByOne,
    kBalancedOrOffByOne,
};

static void check_fulfill_and_release_cnts(skiatest::Reporter* reporter,
                                           const PromiseTextureChecker& promiseChecker,
                                           int expectedFulfillCnt,
                                           ReleaseBalanceExpectation releaseBalanceExpecation) {
    REPORTER_ASSERT(reporter, promiseChecker.fFulfillCount == expectedFulfillCnt);
    if (!expectedFulfillCnt) {
        // Release and Done should only ever be called after Fulfill.
        REPORTER_ASSERT(reporter, !promiseChecker.fReleaseCount);
        return;
    }
    int releaseDiff = promiseChecker.fFulfillCount - promiseChecker.fReleaseCount;
    switch (releaseBalanceExpecation) {
        case ReleaseBalanceExpectation::kBalanced:
            REPORTER_ASSERT(reporter, !releaseDiff);
            break;
        case ReleaseBalanceExpectation::kAllUnbalanced:
            REPORTER_ASSERT(reporter, releaseDiff == promiseChecker.fFulfillCount);
            break;
        case ReleaseBalanceExpectation::kUnknown:
            REPORTER_ASSERT(reporter,
                            releaseDiff >= 0 && releaseDiff <= promiseChecker.fFulfillCount);
            break;
        case ReleaseBalanceExpectation::kUnbalancedByOne:
            REPORTER_ASSERT(reporter, releaseDiff == 1);
            break;
        case ReleaseBalanceExpectation::kBalancedOrOffByOne:
            REPORTER_ASSERT(reporter, releaseDiff == 0 || releaseDiff == 1);
            break;
    }
}

static void check_unfulfilled(const PromiseTextureChecker& promiseChecker,
                              skiatest::Reporter* reporter) {
    check_fulfill_and_release_cnts(reporter, promiseChecker, 0,
                                   ReleaseBalanceExpectation::kBalanced);
}

static void check_only_fulfilled(skiatest::Reporter* reporter,
                                 const PromiseTextureChecker& promiseChecker,
                                 int expectedFulfillCnt = 1) {
    check_fulfill_and_release_cnts(reporter, promiseChecker, expectedFulfillCnt,
                                   ReleaseBalanceExpectation::kAllUnbalanced);
}

static void check_all_flushed_but_not_synced(skiatest::Reporter* reporter,
                                             const PromiseTextureChecker& promiseChecker,
                                             GrBackendApi api,
                                             int expectedFulfillCnt = 1) {
    ReleaseBalanceExpectation releaseBalanceExpectation = ReleaseBalanceExpectation::kBalanced;
    // On Vulkan and D3D Done isn't guaranteed to be called until a sync has occurred.
    if (api == GrBackendApi::kVulkan || api == GrBackendApi::kDirect3D) {
        releaseBalanceExpectation = expectedFulfillCnt == 1
                                            ? ReleaseBalanceExpectation::kBalancedOrOffByOne
                                            : ReleaseBalanceExpectation::kUnknown;
    }
    check_fulfill_and_release_cnts(reporter, promiseChecker, expectedFulfillCnt,
                                   releaseBalanceExpectation);
}

static void check_all_done(skiatest::Reporter* reporter,
                           const PromiseTextureChecker& promiseChecker,
                           int expectedFulfillCnt = 1) {
    check_fulfill_and_release_cnts(reporter, promiseChecker, expectedFulfillCnt,
                                   ReleaseBalanceExpectation::kBalanced);
}

DEF_GPUTEST_FOR_RENDERING_CONTEXTS(PromiseImageTest, reporter, ctxInfo, CtsEnforcement::kNever) {
    const int kWidth = 10;
    const int kHeight = 10;

    auto ctx = ctxInfo.directContext();

    GrBackendTexture backendTex = ctx->createBackendTexture(kWidth,
                                                            kHeight,
                                                            kRGBA_8888_SkColorType,
                                                            SkColors::kTransparent,
                                                            GrMipmapped::kNo,
                                                            GrRenderable::kYes,
                                                            GrProtected::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->threadSafeProxy(),
                                                          backendFormat,
                                                          {kWidth, kHeight},
                                                          GrMipmapped::kNo,
                                                          texOrigin,
                                                          kRGBA_8888_SkColorType,
                                                          kPremul_SkAlphaType,
                                                          nullptr,
                                                          PromiseTextureChecker::Fulfill,
                                                          PromiseTextureChecker::Release,
                                                          &promiseChecker));

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

    canvas->drawImage(refImg, 0, 0);
    check_unfulfilled(promiseChecker, reporter);

    surface->flushAndSubmit();
    // We still own the image so we should not have called Release or Done.
    check_only_fulfilled(reporter, promiseChecker);

    ctx->submit(true);
    check_only_fulfilled(reporter, promiseChecker);

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

    surface->flushAndSubmit(true);

    // Image should still be fulfilled from the first time we drew/flushed it.
    check_only_fulfilled(reporter, promiseChecker);

    canvas->drawImage(refImg, 0, 0);
    surface->flushAndSubmit();
    check_only_fulfilled(reporter, promiseChecker);

    canvas->drawImage(refImg, 0, 0);
    refImg.reset();
    // We no longer own the image but the last draw is still unflushed.
    check_only_fulfilled(reporter, promiseChecker);

    surface->flushAndSubmit();
    // Flushing should have called Release. Depending on the backend and timing it may have called
    // done.
    check_all_flushed_but_not_synced(reporter, promiseChecker, ctx->backend());
    ctx->submit(true);
    // Now Done should definitely have been called.
    check_all_done(reporter, promiseChecker);

    ctx->deleteBackendTexture(backendTex);
}

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

    // Different ways of killing contexts.
    using DeathFn = std::function<void(sk_gpu_test::GrContextFactory*, GrDirectContext*)>;
    DeathFn destroy = [](sk_gpu_test::GrContextFactory* factory, GrDirectContext*) {
        factory->destroyContexts();
    };
    DeathFn abandon = [](sk_gpu_test::GrContextFactory* factory, GrDirectContext* dContext) {
        dContext->abandonContext();
    };
    DeathFn releaseResourcesAndAbandon = [](sk_gpu_test::GrContextFactory* factory,
                                            GrDirectContext* dContext) {
        dContext->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
        // Also problematic on Dawn; see http://skbug.com/10326
        // And Direct3D, for similar reasons.
        GrBackendApi api = sk_gpu_test::GrContextFactory::ContextTypeBackend(contextType);
        if (api == GrBackendApi::kVulkan || api == GrBackendApi::kDawn ||
            api == GrBackendApi::kDirect3D) {
            continue;
        }
        DeathFn contextKillers[] = {destroy, abandon, releaseResourcesAndAbandon};
        for (const DeathFn& contextDeath : contextKillers) {
            sk_gpu_test::GrContextFactory factory;
            auto ctx = factory.get(contextType);
            if (!ctx) {
                continue;
            }

            auto mbet = sk_gpu_test::ManagedBackendTexture::MakeWithoutData(ctx,
                                                                            kWidth,
                                                                            kHeight,
                                                                            kAlpha_8_SkColorType,
                                                                            GrMipmapped::kNo,
                                                                            GrRenderable::kNo);
            if (!mbet) {
                ERRORF(reporter, "Could not create texture alpha texture.");
                continue;
            }

            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(mbet->texture(), reporter, false);
            sk_sp<SkImage> image(SkImage_Gpu::MakePromiseTexture(ctx->threadSafeProxy(),
                                                                 mbet->texture().getBackendFormat(),
                                                                 {kWidth, kHeight},
                                                                 GrMipmapped::kNo,
                                                                 kTopLeft_GrSurfaceOrigin,
                                                                 kAlpha_8_SkColorType,
                                                                 kPremul_SkAlphaType,
                                                                 /*color space*/ nullptr,
                                                                 PromiseTextureChecker::Fulfill,
                                                                 PromiseTextureChecker::Release,
                                                                 &promiseChecker));
            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->flushAndSubmit();
            contextDeath(&factory, ctx);

            check_all_done(reporter, promiseChecker);
        }
    }
}

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

    auto dContext = ctxInfo.directContext();

    GrBackendTexture backendTex = dContext->createBackendTexture(kWidth,
                                                                 kHeight,
                                                                 kAlpha_8_SkColorType,
                                                                 SkColors::kTransparent,
                                                                 GrMipmapped::kNo,
                                                                 GrRenderable::kNo,
                                                                 GrProtected::kNo);
    REPORTER_ASSERT(reporter, backendTex.isValid());

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

    PromiseTextureChecker promiseChecker(backendTex, reporter, false);
    sk_sp<SkImage> image(SkImage_Gpu::MakePromiseTexture(dContext->threadSafeProxy(),
                                                         backendTex.getBackendFormat(),
                                                         {kWidth, kHeight},
                                                         GrMipmapped::kNo,
                                                         kTopLeft_GrSurfaceOrigin,
                                                         kAlpha_8_SkColorType,
                                                         kPremul_SkAlphaType,
                                                         nullptr,
                                                         PromiseTextureChecker::Fulfill,
                                                         PromiseTextureChecker::Release,
                                                         &promiseChecker));
    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 kMaxBytes = 1;
    dContext->setResourceCacheLimit(kMaxBytes);
    SkTArray<sk_sp<GrTexture>> textures;
    for (int i = 0; i < 5; ++i) {
        auto format = dContext->priv().caps()->getDefaultBackendFormat(GrColorType::kRGBA_8888,
                                                                       GrRenderable::kNo);
        textures.emplace_back(dContext->priv().resourceProvider()->createTexture(
                {100, 100},
                format,
                GrTextureType::k2D,
                GrRenderable::kNo,
                1,
                GrMipmapped::kNo,
                SkBudgeted::kYes,
                GrProtected::kNo,
                /*label=*/"PromiseImageTextureFullCacheTest"));
        REPORTER_ASSERT(reporter, textures[i]);
    }

    size_t bytesUsed;

    dContext->getResourceCacheUsage(nullptr, &bytesUsed);
    REPORTER_ASSERT(reporter, bytesUsed > kMaxBytes);

    // Relying on the asserts in the promiseImageChecker to ensure that fulfills and releases are
    // properly ordered.
    canvas->drawImage(image, 0, 0);
    surface->flushAndSubmit();
    canvas->drawImage(image, 1, 0);
    surface->flushAndSubmit();
    canvas->drawImage(image, 2, 0);
    surface->flushAndSubmit();
    canvas->drawImage(image, 3, 0);
    surface->flushAndSubmit();
    canvas->drawImage(image, 4, 0);
    surface->flushAndSubmit();
    canvas->drawImage(image, 5, 0);
    surface->flushAndSubmit();
    // Must call these to ensure that all callbacks are performed before the checker is destroyed.
    image.reset();
    dContext->flushAndSubmit(true);

    dContext->deleteBackendTexture(backendTex);
}

// Test case where promise image fulfill returns nullptr.
DEF_GPUTEST_FOR_RENDERING_CONTEXTS(PromiseImageNullFulfill,
                                   reporter,
                                   ctxInfo,
                                   CtsEnforcement::kNever) {
    const int kWidth = 10;
    const int kHeight = 10;

    auto dContext = ctxInfo.directContext();

    GrBackendFormat backendFormat =
            dContext->defaultBackendFormat(kRGBA_8888_SkColorType, GrRenderable::kYes);
    if (!backendFormat.isValid()) {
        ERRORF(reporter, "No valid default kRGBA_8888 texture format.");
        return;
    }

    struct Counts {
        int fFulfillCount = 0;
        int fReleaseCount = 0;
    } counts;
    auto fulfill = [](SkDeferredDisplayListRecorder::PromiseImageTextureContext ctx) {
        ++static_cast<Counts*>(ctx)->fFulfillCount;
        return sk_sp<SkPromiseImageTexture>();
    };
    auto release = [](SkDeferredDisplayListRecorder::PromiseImageTextureContext ctx) {
        ++static_cast<Counts*>(ctx)->fReleaseCount;
    };
    GrSurfaceOrigin texOrigin = kTopLeft_GrSurfaceOrigin;
    sk_sp<SkImage> refImg(SkImage_Gpu::MakePromiseTexture(dContext->threadSafeProxy(),
                                                          backendFormat,
                                                          {kWidth, kHeight},
                                                          GrMipmapped::kNo,
                                                          texOrigin,
                                                          kRGBA_8888_SkColorType,
                                                          kPremul_SkAlphaType,
                                                          nullptr,
                                                          fulfill,
                                                          release,
                                                          &counts));

    SkImageInfo info = SkImageInfo::MakeN32Premul(kWidth, kHeight);
    sk_sp<SkSurface> surface = SkSurface::MakeRenderTarget(dContext, SkBudgeted::kNo, info);
    SkCanvas* canvas = surface->getCanvas();
    // Draw the image a few different ways.
    canvas->drawImage(refImg, 0, 0);
    SkPaint paint;
    paint.setColorFilter(SkColorFilters::LinearToSRGBGamma());
    canvas->drawImage(refImg, 0, 0, SkSamplingOptions(), &paint);
    auto shader = refImg->makeShader(SkSamplingOptions());
    REPORTER_ASSERT(reporter, shader);
    paint.setShader(std::move(shader));
    canvas->drawRect(SkRect::MakeWH(1,1), paint);
    paint.setShader(nullptr);
    refImg.reset();
    surface->flushAndSubmit();
    // We should only call each callback once and we should have made all the calls by this point.
    REPORTER_ASSERT(reporter, counts.fFulfillCount == 1);
    REPORTER_ASSERT(reporter, counts.fReleaseCount == 1);
}
