/*
 * 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 "SkTypes.h"
#include "SkPoint.h"
#include "Test.h"
#include <vector>

#if SK_SUPPORT_GPU

#include "GrAppliedClip.h"
#include "GrRenderTargetContext.h"
#include "GrRenderTargetPriv.h"
#include "GrTypesPriv.h"
#include "gl/GrGLGpu.h"
#include "gl/debug/DebugGLTestContext.h"

typedef std::vector<SkPoint> SamplePattern;

static const SamplePattern kTestPatterns[] = {
    SamplePattern{ // Intel on mac, msaa8, offscreen.
        {0.562500, 0.312500},
        {0.437500, 0.687500},
        {0.812500, 0.562500},
        {0.312500, 0.187500},
        {0.187500, 0.812500},
        {0.062500, 0.437500},
        {0.687500, 0.937500},
        {0.937500, 0.062500}
    },

    SamplePattern{ // Intel on mac, msaa8, on-screen.
        {0.562500, 0.687500},
        {0.437500, 0.312500},
        {0.812500, 0.437500},
        {0.312500, 0.812500},
        {0.187500, 0.187500},
        {0.062500, 0.562500},
        {0.687500, 0.062500},
        {0.937500, 0.937500}
    },

    SamplePattern{ // NVIDIA, msaa16.
        {0.062500, 0.000000},
        {0.250000, 0.125000},
        {0.187500, 0.375000},
        {0.437500, 0.312500},
        {0.500000, 0.062500},
        {0.687500, 0.187500},
        {0.750000, 0.437500},
        {0.937500, 0.250000},
        {0.000000, 0.500000},
        {0.312500, 0.625000},
        {0.125000, 0.750000},
        {0.375000, 0.875000},
        {0.562500, 0.562500},
        {0.812500, 0.687500},
        {0.625000, 0.812500},
        {0.875000, 0.937500}
    },

    SamplePattern{ // NVIDIA, mixed samples, 16:1.
        {0.250000, 0.125000},
        {0.625000, 0.812500},
        {0.500000, 0.062500},
        {0.812500, 0.687500},
        {0.187500, 0.375000},
        {0.875000, 0.937500},
        {0.125000, 0.750000},
        {0.750000, 0.437500},
        {0.937500, 0.250000},
        {0.312500, 0.625000},
        {0.437500, 0.312500},
        {0.000000, 0.500000},
        {0.375000, 0.875000},
        {0.687500, 0.187500},
        {0.062500, 0.000000},
        {0.562500, 0.562500}
    }
};
constexpr int numTestPatterns = SK_ARRAY_COUNT(kTestPatterns);

class TestSampleLocationsInterface : public SkNoncopyable {
public:
    virtual void overrideSamplePattern(const SamplePattern&) = 0;
    virtual ~TestSampleLocationsInterface() {}
};

void assert_equal(skiatest::Reporter* reporter, const SamplePattern& pattern,
                  const GrGpu::MultisampleSpecs& specs, bool flipY) {
    GrAlwaysAssert(specs.fSampleLocations);
    if ((int)pattern.size() != specs.fEffectiveSampleCnt) {
        REPORT_FAILURE(reporter, "", SkString("Sample pattern has wrong number of samples."));
        return;
    }
    for (int i = 0; i < specs.fEffectiveSampleCnt; ++i) {
        SkPoint expectedLocation = specs.fSampleLocations[i];
        if (flipY) {
            expectedLocation.fY = 1 - expectedLocation.fY;
        }
        if (pattern[i] != expectedLocation) {
            REPORT_FAILURE(reporter, "", SkString("Sample pattern has wrong sample location."));
            return;
        }
    }
}

static int pick_random_sample_count(int testPatternSize, SkRandom* rand, const GrCaps* caps) {
    GrAlwaysAssert(testPatternSize > 1 && SkIsPow2(testPatternSize));
    int randSampCnt = rand->nextRangeU(1 + testPatternSize / 2, testPatternSize);
    do {
        int cnt = caps->getSampleCount(randSampCnt, kRGBA_8888_GrPixelConfig);
        if (cnt) {
            return cnt;
        }
        --randSampCnt;
    } while (randSampCnt);
    // This test assumes an MSAA kRGBA_8888 RTC can be created.
    GrAlwaysAssert(false);
    return 0;
}

void test_sampleLocations(skiatest::Reporter* reporter, TestSampleLocationsInterface* testInterface,
                          GrContext* ctx) {
    SkRandom rand;
    sk_sp<GrRenderTargetContext> bottomUps[numTestPatterns];
    sk_sp<GrRenderTargetContext> topDowns[numTestPatterns];
    for (int i = 0; i < numTestPatterns; ++i) {
        int patternSize = (int)kTestPatterns[i].size();
        int randNumSamples = pick_random_sample_count(patternSize, &rand, ctx->caps());
        bottomUps[i] = ctx->makeDeferredRenderTargetContext(
                SkBackingFit::kExact, 100, 100, kRGBA_8888_GrPixelConfig, nullptr, randNumSamples,
                GrMipMapped::kNo, kBottomLeft_GrSurfaceOrigin);
        randNumSamples = pick_random_sample_count(patternSize, &rand, ctx->caps());
        topDowns[i] = ctx->makeDeferredRenderTargetContext(
                SkBackingFit::kExact, 100, 100, kRGBA_8888_GrPixelConfig, nullptr, randNumSamples,
                GrMipMapped::kNo, kTopLeft_GrSurfaceOrigin);
    }

    // Ensure all sample locations get queried and/or cached properly.
    for (int repeat = 0; repeat < 2; ++repeat) {
        for (int i = 0; i < numTestPatterns; ++i) {
            testInterface->overrideSamplePattern(kTestPatterns[i]);
            for (GrRenderTargetContext* rtc : {bottomUps[i].get(), topDowns[i].get()}) {
                GrPipeline dummyPipeline(rtc->asRenderTargetProxy(),
                                         GrPipeline::ScissorState::kDisabled,
                                         SkBlendMode::kSrcOver);
                GrRenderTarget* rt = rtc->accessRenderTarget();
                assert_equal(reporter, kTestPatterns[i],
                             rt->renderTargetPriv().getMultisampleSpecs(dummyPipeline),
                             kBottomLeft_GrSurfaceOrigin == rtc->asSurfaceProxy()->origin());
            }
        }
    }

}

////////////////////////////////////////////////////////////////////////////////////////////////////

class GLTestSampleLocationsInterface : public TestSampleLocationsInterface, public GrGLInterface {
public:
    GLTestSampleLocationsInterface() : fTestContext(sk_gpu_test::CreateDebugGLTestContext()) {
        fStandard = fTestContext->gl()->fStandard;
        fExtensions = fTestContext->gl()->fExtensions;
        fFunctions = fTestContext->gl()->fFunctions;

        fFunctions.fGetIntegerv = [&](GrGLenum pname, GrGLint* params) {
            GrAlwaysAssert(GR_GL_EFFECTIVE_RASTER_SAMPLES != pname);
            if (GR_GL_SAMPLES == pname) {
                GrAlwaysAssert(!fSamplePattern.empty());
                *params = (int)fSamplePattern.size();
            } else {
                fTestContext->gl()->fFunctions.fGetIntegerv(pname, params);
            }
        };

        fFunctions.fGetMultisamplefv = [&](GrGLenum pname, GrGLuint index, GrGLfloat* val) {
            GrAlwaysAssert(GR_GL_SAMPLE_POSITION == pname);
            val[0] = fSamplePattern[index].fX;
            val[1] = fSamplePattern[index].fY;
        };
    }

    operator GrBackendContext() {
        return reinterpret_cast<GrBackendContext>(static_cast<GrGLInterface*>(this));
    }

    void overrideSamplePattern(const SamplePattern& newPattern) override {
        fSamplePattern = newPattern;
    }

private:
    std::unique_ptr<sk_gpu_test::GLTestContext> fTestContext;
    SamplePattern                               fSamplePattern;
};

DEF_GPUTEST(GLSampleLocations, reporter, /* options */) {
    auto testInterface = sk_make_sp<GLTestSampleLocationsInterface>();
    sk_sp<GrContext> ctx(GrContext::MakeGL(testInterface));

    // This test relies on at least 2 samples.
    int supportedSample = ctx->caps()->getSampleCount(2, kRGBA_8888_GrPixelConfig);
    if (supportedSample < 2) {
        return;
    }
    test_sampleLocations(reporter, testInterface.get(), ctx.get());
}

#endif
