/*
 * 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 "GrFragmentProcessor.h"
#include "GrInvariantOutput.h"
#include "GrRenderTargetContext.h"
#include "GrTexture.h"
#include "glsl/GrGLSLFragmentProcessor.h"
#include "glsl/GrGLSLFragmentShaderBuilder.h"

DEF_GPUTEST_FOR_RENDERING_CONTEXTS(ImageStorageLoad, reporter, ctxInfo) {
    class TestFP : public GrFragmentProcessor {
    public:
        static sk_sp<GrFragmentProcessor> Make(sk_sp<GrTexture> texture, GrSLMemoryModel mm,
                                               GrSLRestrict restrict) {
            return sk_sp<GrFragmentProcessor>(new TestFP(std::move(texture), mm, restrict));
        }

        const char* name() const override { return "Image Load Test FP"; }

    private:
        TestFP(sk_sp<GrTexture> texture, GrSLMemoryModel mm, GrSLRestrict restrict)
                : fImageStorageAccess(std::move(texture), kRead_GrIOType, mm, restrict) {
            this->initClassID<TestFP>();
            this->setWillReadFragmentPosition();
            this->addImageStorageAccess(&fImageStorageAccess);
        }

        void onGetGLSLProcessorKey(const GrShaderCaps&, GrProcessorKeyBuilder*) const override {}

        void onComputeInvariantOutput(GrInvariantOutput* inout) const override {
            inout->setToUnknown(GrInvariantOutput::kWillNot_ReadInput);
        }

        bool onIsEqual(const GrFragmentProcessor& that) const override { return true; }

        GrGLSLFragmentProcessor* onCreateGLSLInstance() const override {
            class GLSLProcessor : public GrGLSLFragmentProcessor {
            public:
                GLSLProcessor() = default;
                void emitCode(EmitArgs& args) override {
                    const TestFP& tfp = args.fFp.cast<TestFP>();
                    GrGLSLFPFragmentBuilder* fb = args.fFragBuilder;
                    SkString imageLoadStr;
                    fb->codeAppendf("highp vec2 coord = %s.xy;",
                                    args.fFragBuilder->fragmentPosition());
                    fb->appendImageStorageLoad(&imageLoadStr, args.fImageStorages[0],
                                               "ivec2(coord)");
                    if (GrPixelConfigIsSint(tfp.fImageStorageAccess.texture()->config())) {
                        // Map the signed bytes so that when then get read back as unorm values they
                        // will have their original bit pattern.
                        fb->codeAppendf("highp ivec4 ivals = %s;", imageLoadStr.c_str());
                        // NV gives a linker error for this:
                        // fb->codeAppend("ivals +=
                        //                "mix(ivec4(0), ivec4(256), lessThan(ivals, ivec4(0)));");
                        fb->codeAppend("if (ivals.r < 0) { ivals.r += 256; }");
                        fb->codeAppend("if (ivals.g < 0) { ivals.g += 256; }");
                        fb->codeAppend("if (ivals.b < 0) { ivals.b += 256; }");
                        fb->codeAppend("if (ivals.a < 0) { ivals.a += 256; }");
                        fb->codeAppendf("%s = vec4(ivals)/255;", args.fOutputColor);
                    } else {
                        fb->codeAppendf("%s = %s;", args.fOutputColor, imageLoadStr.c_str());
                    }
                }
            };
            return new GLSLProcessor;
        }

        ImageStorageAccess fImageStorageAccess;
    };

    static constexpr int kS = 256;
    GrContext* context = ctxInfo.grContext();
    if (context->caps()->shaderCaps()->maxFragmentImageStorages() < 1) {
        return;
    }

    std::unique_ptr<uint32_t[]> data(new uint32_t[kS * kS]);
    for (int j = 0; j < kS; ++j) {
        for (int i = 0; i < kS; ++i) {
            data[i + kS * j] = GrColorPackRGBA(i, j, 0, 0);
        }
    }

    std::unique_ptr<uint32_t[]> idata(new uint32_t[kS * kS]);
    for (int j = 0; j < kS; ++j) {
        for (int i = 0; i < kS; ++i) {
            int8_t r = i - 128;
            int8_t g = j - 128;
            int8_t b = -128;
            int8_t a = -128;
            idata[i + kS * j] = ((uint8_t)a << 24) | ((uint8_t)b << 16) |
                                ((uint8_t)g << 8)  |  (uint8_t)r;
        }
    }

    // Currently image accesses always have "top left" semantics.
    GrSurfaceDesc desc;
    desc.fOrigin = kTopLeft_GrSurfaceOrigin;
    desc.fWidth = kS;
    desc.fHeight = kS;
    struct {
        GrPixelConfig fConfig;
        std::unique_ptr<uint32_t[]> fData;
    } tests[] = {
        {
           kRGBA_8888_GrPixelConfig,
           std::move(data)
        },
        {
           kRGBA_8888_sint_GrPixelConfig,
           std::move(idata)
        },
    };
    for (const auto& test : tests) {
        // This test should work with any memory model and with or without restrict
        for (auto mm : {GrSLMemoryModel::kNone,
                        GrSLMemoryModel::kCoherent,
                        GrSLMemoryModel::kVolatile}) {
            for (auto restrict : {GrSLRestrict::kNo, GrSLRestrict::kYes}) {
                if (!context->caps()->canConfigBeImageStorage(test.fConfig)) {
                    continue;
                }
                desc.fConfig = test.fConfig;
                sk_sp<GrTexture> imageStorageTexture(context->textureProvider()->createTexture(desc,
                    SkBudgeted::kYes, test.fData.get(), 0));

                sk_sp<GrRenderTargetContext> rtContext =
                    context->makeRenderTargetContext(SkBackingFit::kExact, kS, kS,
                                                     kRGBA_8888_GrPixelConfig, nullptr);
                GrPaint paint;
                paint.setPorterDuffXPFactory(SkBlendMode::kSrc);
                paint.addColorFragmentProcessor(TestFP::Make(imageStorageTexture, mm, restrict));
                rtContext->drawPaint(GrNoClip(), std::move(paint), SkMatrix::I());
                std::unique_ptr<uint32_t[]> readData(new uint32_t[kS * kS]);
                SkImageInfo info = SkImageInfo::Make(kS, kS, kRGBA_8888_SkColorType,
                                                     kPremul_SkAlphaType);
                rtContext->readPixels(info, readData.get(), 0, 0, 0);
                int failed = false;
                for (int j = 0; j < kS && !failed; ++j) {
                    for (int i = 0; i < kS && !failed; ++i) {
                        uint32_t d = test.fData[j * kS + i];
                        uint32_t rd = readData[j * kS + i];
                        if (d != rd) {
                            failed = true;
                            ERRORF(reporter, "Expected 0x%08x, got 0x%08x at %d, %d.", d, rd, i, j);
                        }
                    }
                }
            }
        }
    }
}

#endif
