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

#include "Test.h"

#if SK_SUPPORT_GPU
#include "GrClip.h"
#include "GrContext.h"
#include "GrContextPriv.h"
#include "GrProxyProvider.h"
#include "GrRenderTargetContext.h"
#include "GrResourceProvider.h"
#include "GrTexture.h"
#include "effects/GrSimpleTextureEffect.h"

template <typename I>
static SK_WHEN(std::is_integral<I>::value && 4 == sizeof(I), void)
check_pixels(skiatest::Reporter* reporter, int w, int h, const I exepctedData[],
             const I actualData[], const char* testName) {
    for (int j = 0; j < h; ++j) {
        for (int i = 0; i < w; ++i) {
            I expected = exepctedData[j * w + i];
            I actual = actualData[j * w + i];
            if (expected != actual) {
                ERRORF(reporter, "[%s] Expected 0x08%x, got 0x%08x at %d, %d.", testName, expected,
                       actual, i, j);
                return;
            }
        }
    }
}

DEF_GPUTEST_FOR_RENDERING_CONTEXTS(IntTexture, reporter, ctxInfo) {
    GrContext* context = ctxInfo.grContext();
    if (!context->caps()->isConfigTexturable(kRGBA_8888_sint_GrPixelConfig)) {
        return;
    }

    GrProxyProvider* proxyProvider = context->contextPriv().proxyProvider();
    auto resourceProvider = context->contextPriv().resourceProvider();

    static const int kS = UINT8_MAX + 1;
    static const size_t kRowBytes = kS * sizeof(int32_t);

    GrSurfaceDesc desc;
    desc.fOrigin = kTopLeft_GrSurfaceOrigin;
    desc.fConfig = kRGBA_8888_sint_GrPixelConfig;
    desc.fWidth = kS;
    desc.fHeight = kS;

    std::unique_ptr<int32_t[]> testData(new int32_t[kS * kS]);
    for (int j = 0; j < kS; ++j) {
        for (int i = 0; i < kS; ++i) {
            uint32_t r = i - INT8_MIN;
            uint32_t g = j - INT8_MIN;
            uint32_t b = INT8_MAX - r;
            uint32_t a = INT8_MAX - g;
            testData.get()[j * kS + i] = (a << 24) | (b << 16) | (g << 8) | r;
        }
    }

    // Test that attempting to create a integer texture with multiple MIP levels fails.
    {
        GrMipLevel levels[2];
        levels[0].fPixels = testData.get();
        levels[0].fRowBytes = kRowBytes;
        levels[1].fPixels = testData.get();
        levels[1].fRowBytes = (kS / 2) * sizeof(int32_t);

        sk_sp<GrTextureProxy> temp = proxyProvider->createMipMapProxy(
                                                                desc, SkBudgeted::kYes, levels, 2);
        REPORTER_ASSERT(reporter, !temp);
    }

    sk_sp<GrSurfaceContext> sContext;
    // Test that we can create a non-mipmapped integer texture.
    {
        sk_sp<GrTextureProxy> proxy = proxyProvider->createTextureProxy(desc, SkBudgeted::kYes,
                                                                        testData.get(), kRowBytes);
        REPORTER_ASSERT(reporter, proxy);
        if (!proxy) {
            return;
        }

        sContext = context->contextPriv().makeWrappedSurfaceContext(std::move(proxy));
        if (!sContext) {
            return;
        }
    }

    std::unique_ptr<int32_t[]> readData(new int32_t[kS * kS]);
    // Test that reading to a non-integer config fails.
    {
        bool success = context->contextPriv().readSurfacePixels(sContext.get(),
                                                                0, 0, kS, kS,
                                                                kRGBA_8888_GrPixelConfig,
                                                                nullptr, readData.get());
        REPORTER_ASSERT(reporter, !success);
    }
    {
        std::unique_ptr<uint16_t[]> halfData(new uint16_t[4 * kS * kS]);
        bool success = context->contextPriv().readSurfacePixels(sContext.get(),
                                                                0, 0, kS, kS,
                                                                kRGBA_half_GrPixelConfig,
                                                                nullptr, halfData.get());
        REPORTER_ASSERT(reporter, !success);
    }
    {
        // Can read back as ints. (ES only requires being able to read back into 32bit ints which
        // we don't support. Right now this test is counting on GR_RGBA_INTEGER/GL_BYTE being the
        // implementation-dependent second format).
        sk_bzero(readData.get(), sizeof(int32_t) * kS * kS);
        bool success = context->contextPriv().readSurfacePixels(sContext.get(),
                                                                0, 0, kS, kS,
                                                                kRGBA_8888_sint_GrPixelConfig,
                                                                nullptr, readData.get());
        REPORTER_ASSERT(reporter, success);
        if (success) {
            check_pixels(reporter, kS, kS, testData.get(), readData.get(), "readPixels");
        }
    }
    {
        // readPixels should fail if we attempt to use the unpremul flag with an integer texture.
        bool success = context->contextPriv().readSurfacePixels(
                                                sContext.get(),
                                                0, 0, kS, kS,
                                                kRGBA_8888_sint_GrPixelConfig,
                                                nullptr, readData.get(), 0,
                                                GrContextPriv::kUnpremul_PixelOpsFlag);
        REPORTER_ASSERT(reporter, !success);
    }

    // Test that copying from one integer texture to another succeeds.
    {
        sk_sp<GrSurfaceContext> dstContext(GrSurfaceProxy::TestCopy(context, desc,
                                                                    sContext->asSurfaceProxy()));
        REPORTER_ASSERT(reporter, dstContext);
        if (!dstContext || !dstContext->asTextureProxy()) {
            return;
        }

        sk_bzero(readData.get(), sizeof(int32_t) * kS * kS);
        bool success = context->contextPriv().readSurfacePixels(dstContext.get(), 0, 0, kS, kS,
                                                                kRGBA_8888_sint_GrPixelConfig,
                                                                nullptr, readData.get());
        REPORTER_ASSERT(reporter, success);
        if (success) {
            check_pixels(reporter, kS, kS, testData.get(), readData.get(), "copyIntegerToInteger");
        }
    }


    // Test that copying to a non-integer (8888) texture fails.
    {
        GrSurfaceDesc nonIntDesc = desc;
        nonIntDesc.fConfig = kRGBA_8888_GrPixelConfig;

        sk_sp<GrSurfaceContext> dstContext(GrSurfaceProxy::TestCopy(context, nonIntDesc,
                                                                    sContext->asSurfaceProxy()));
        REPORTER_ASSERT(reporter, !dstContext);
    }

    // Test that copying to a non-integer (RGBA_half) texture fails.
    if (context->caps()->isConfigTexturable(kRGBA_half_GrPixelConfig)) {
        GrSurfaceDesc nonIntDesc = desc;
        nonIntDesc.fConfig = kRGBA_half_GrPixelConfig;

        sk_sp<GrSurfaceContext> dstContext(GrSurfaceProxy::TestCopy(context, nonIntDesc,
                                                                    sContext->asSurfaceProxy()));
        REPORTER_ASSERT(reporter, !dstContext);
    }

    // We overwrite the top left quarter of the texture with the bottom right quarter of the
    // original data.
    const void* bottomRightQuarter = testData.get() + kS / 2 * kS + kS / 2;

    {
        // Can't write pixels from a non-int config.
        bool success = context->contextPriv().writeSurfacePixels(sContext.get(),
                                                                 0, 0, kS/2, kS/2,
                                                                 kRGBA_8888_GrPixelConfig, nullptr,
                                                                 bottomRightQuarter, kRowBytes);
        REPORTER_ASSERT(reporter, !success);
    }
    {
        // Can't use unpremul flag.
        bool success = context->contextPriv().writeSurfacePixels(
                                            sContext.get(),
                                            0, 0, kS/2, kS/2,
                                            kRGBA_8888_sint_GrPixelConfig,
                                            nullptr,
                                            bottomRightQuarter, kRowBytes,
                                            GrContextPriv::kUnpremul_PixelOpsFlag);
        REPORTER_ASSERT(reporter, !success);
    }
    {
        bool success = context->contextPriv().writeSurfacePixels(sContext.get(),
                                                                 0, 0, kS/2, kS/2,
                                                                 kRGBA_8888_sint_GrPixelConfig,
                                                                 nullptr,
                                                                 bottomRightQuarter, kRowBytes);
        REPORTER_ASSERT(reporter, success);
        if (!success) {
            return;
        }

        sk_bzero(readData.get(), sizeof(int32_t) * kS * kS);
        success = context->contextPriv().readSurfacePixels(sContext.get(),
                                                           0, 0, kS, kS,
                                                           kRGBA_8888_sint_GrPixelConfig,
                                                           nullptr, readData.get(), 0);
        REPORTER_ASSERT(reporter, success);
        if (!success) {
            return;
        }
        std::unique_ptr<int32_t[]> overwrittenTestData(new int32_t[kS * kS]);
        memcpy(overwrittenTestData.get(), testData.get(), sizeof(int32_t) * kS * kS);
        char* dst = (char*)overwrittenTestData.get();
        char* src = (char*)(testData.get() + kS/2 * kS + kS/2);
        for (int i = 0; i < kS/2; ++i) {
            memcpy(dst, src, sizeof(int32_t) * kS/2);
            dst += kRowBytes;
            src += kRowBytes;
        }
        check_pixels(reporter, kS, kS, overwrittenTestData.get(), readData.get(), "overwrite");
    }

    // Test drawing from the integer texture to a fixed point texture. To avoid any premul issues
    // we init the int texture with 0s and 1s and make alpha always be 1. We expect that 1s turn
    // into 0xffs and zeros stay zero.
    std::unique_ptr<uint32_t[]> expectedData(new uint32_t[kS * kS]);
    std::unique_ptr<uint32_t[]> actualData(new uint32_t[kS * kS]);
    for (int i = 0; i < kS*kS; ++i) {
        int32_t a = 0x1;
        int32_t b = ((i & 0x1) ? 1 : 0);
        int32_t g = ((i & 0x1) ? 0 : 1);
        int32_t r = ((i & 0x2) ? 1 : 0);
        testData.get()[i] = (a << 24) | (b << 16) | (g << 8) | r;
        expectedData.get()[i] = ((0xFF * a) << 24) | ((0xFF * b) << 16) |
                                ((0xFF * g) << 8) | (0xFF * r);
    }
    context->contextPriv().writeSurfacePixels(sContext.get(),
                                              0, 0, kS, kS,
                                              kRGBA_8888_sint_GrPixelConfig, nullptr,
                                              testData.get(), 0);

    sk_sp<GrRenderTargetContext> rtContext = context->makeDeferredRenderTargetContext(
            SkBackingFit::kExact, kS, kS, kRGBA_8888_GrPixelConfig, nullptr);

    struct {
        GrSamplerState::Filter fMode;
        const char* fName;
    } kNamedFilters[] = {{GrSamplerState::Filter::kNearest, "filter-none"},
                         {GrSamplerState::Filter::kBilerp, "filter-bilerp"},
                         {GrSamplerState::Filter::kMipMap, "filter-mipmap"}};

    for (auto filter : kNamedFilters) {
        auto fp = GrSimpleTextureEffect::Make(sContext->asTextureProxyRef(), SkMatrix::I(),
                                              filter.fMode);
        REPORTER_ASSERT(reporter, fp);
        if (!fp) {
            return;
        }
        rtContext->clear(nullptr, 0xDDAABBCC, GrRenderTargetContext::CanClearFullscreen::kYes);
        GrPaint paint;
        paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
        paint.addColorFragmentProcessor(std::move(fp));
        rtContext->drawPaint(GrNoClip(), std::move(paint), SkMatrix::I());
        SkImageInfo readInfo = SkImageInfo::Make(kS, kS, kRGBA_8888_SkColorType,
                                                 kPremul_SkAlphaType);
        rtContext->readPixels(readInfo, actualData.get(), 0, 0, 0);
        check_pixels(reporter, kS, kS, expectedData.get(), actualData.get(), filter.fName);
    }

    {
        // No rendering to integer textures.
        GrSurfaceDesc intRTDesc = desc;
        intRTDesc.fFlags = kRenderTarget_GrSurfaceFlag;
        sk_sp<GrTexture> temp(resourceProvider->createTexture(intRTDesc, SkBudgeted::kYes));
        REPORTER_ASSERT(reporter, !temp);
    }
}

#endif
