//
// Copyright 2016 The ANGLE Project Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
//
// VaryingPacking_unittest.cpp:
//   Tests for ANGLE's internal varying packing algorithm.
//

#include <gtest/gtest.h>
// 'None' is defined as 'struct None {};' in
// third_party/googletest/src/googletest/include/gtest/internal/gtest-type-util.h.
// But 'None' is also define as a numberic constant 0L in <X11/X.h>.
// So we need to include gtest first to avoid such conflict.

#include "libANGLE/Program.h"
#include "libANGLE/VaryingPacking.h"

using namespace gl;

namespace
{

class VaryingPackingTest : public ::testing::TestWithParam<GLuint>
{
  protected:
    VaryingPackingTest() {}

    bool testVaryingPacking(const std::vector<sh::Varying> &shVaryings,
                            VaryingPacking *varyingPacking)
    {
        std::vector<PackedVarying> packedVaryings;
        for (const auto &shVarying : shVaryings)
        {
            packedVaryings.push_back(PackedVarying(shVarying, shVarying.interpolation));
        }

        InfoLog infoLog;
        std::vector<std::string> transformFeedbackVaryings;

        return varyingPacking->packUserVaryings(infoLog, packedVaryings);
    }

    // Uses the "relaxed" ANGLE packing mode.
    bool packVaryings(GLuint maxVaryings, const std::vector<sh::Varying> &shVaryings)
    {
        VaryingPacking varyingPacking(maxVaryings, PackMode::ANGLE_RELAXED);
        return testVaryingPacking(shVaryings, &varyingPacking);
    }

    // Uses the stricter WebGL style packing rules.
    bool packVaryingsStrict(GLuint maxVaryings, const std::vector<sh::Varying> &shVaryings)
    {
        VaryingPacking varyingPacking(maxVaryings, PackMode::WEBGL_STRICT);
        return testVaryingPacking(shVaryings, &varyingPacking);
    }

    const int kMaxVaryings = GetParam();
};

std::vector<sh::Varying> MakeVaryings(GLenum type, size_t count, size_t arraySize)
{
    std::vector<sh::Varying> varyings;

    for (size_t index = 0; index < count; ++index)
    {
        std::stringstream strstr;
        strstr << type << index;

        sh::Varying varying;
        varying.type       = type;
        varying.precision  = GL_MEDIUM_FLOAT;
        varying.name       = strstr.str();
        varying.mappedName = strstr.str();
        if (arraySize > 0)
        {
            varying.arraySizes.push_back(static_cast<unsigned int>(arraySize));
        }
        varying.staticUse     = true;
        varying.interpolation = sh::INTERPOLATION_FLAT;
        varying.isInvariant   = false;

        varyings.push_back(varying);
    }

    return varyings;
}

void AddVaryings(std::vector<sh::Varying> *varyings, GLenum type, size_t count, size_t arraySize)
{
    const auto &newVaryings = MakeVaryings(type, count, arraySize);
    varyings->insert(varyings->end(), newVaryings.begin(), newVaryings.end());
}

// Test that a single varying can't overflow the packing.
TEST_P(VaryingPackingTest, OneVaryingLargerThanMax)
{
    ASSERT_FALSE(packVaryings(1, MakeVaryings(GL_FLOAT_MAT4, 1, 0)));
}

// This will overflow the available varying space.
TEST_P(VaryingPackingTest, MaxPlusOneVaryingVec3)
{
    ASSERT_FALSE(packVaryings(kMaxVaryings, MakeVaryings(GL_FLOAT_VEC3, kMaxVaryings + 1, 0)));
}

// This will overflow the available varying space.
TEST_P(VaryingPackingTest, MaxPlusOneVaryingVec3Array)
{
    ASSERT_FALSE(packVaryings(kMaxVaryings, MakeVaryings(GL_FLOAT_VEC3, kMaxVaryings / 2 + 1, 2)));
}

// This will overflow the available varying space.
TEST_P(VaryingPackingTest, MaxVaryingVec3AndOneVec2)
{
    std::vector<sh::Varying> varyings = MakeVaryings(GL_FLOAT_VEC3, kMaxVaryings, 0);
    AddVaryings(&varyings, GL_FLOAT_VEC2, 1, 0);
    ASSERT_FALSE(packVaryings(kMaxVaryings, varyings));
}

// This should work since two vec2s are packed in a single register.
TEST_P(VaryingPackingTest, MaxPlusOneVaryingVec2)
{
    ASSERT_TRUE(packVaryings(kMaxVaryings, MakeVaryings(GL_FLOAT_VEC2, kMaxVaryings + 1, 0)));
}

// Same for this one as above.
TEST_P(VaryingPackingTest, TwiceMaxVaryingVec2)
{
    ASSERT_TRUE(packVaryings(kMaxVaryings, MakeVaryings(GL_FLOAT_VEC2, kMaxVaryings * 2, 0)));
}

// This should not work since it overflows available varying space.
TEST_P(VaryingPackingTest, TooManyVaryingVec2)
{
    ASSERT_FALSE(packVaryings(kMaxVaryings, MakeVaryings(GL_FLOAT_VEC2, kMaxVaryings * 2 + 1, 0)));
}

// This should work according to the example GL packing rules - the float varyings are slotted
// into the end of the vec3 varying arrays.
TEST_P(VaryingPackingTest, MaxVaryingVec3ArrayAndFloatArrays)
{
    std::vector<sh::Varying> varyings = MakeVaryings(GL_FLOAT_VEC3, kMaxVaryings / 2, 2);
    AddVaryings(&varyings, GL_FLOAT, kMaxVaryings / 2, 2);
    ASSERT_TRUE(packVaryings(kMaxVaryings, varyings));
}

// This should not work - it has one too many float arrays.
TEST_P(VaryingPackingTest, MaxVaryingVec3ArrayAndMaxPlusOneFloatArray)
{
    std::vector<sh::Varying> varyings = MakeVaryings(GL_FLOAT_VEC3, kMaxVaryings / 2, 2);
    AddVaryings(&varyings, GL_FLOAT, kMaxVaryings / 2 + 1, 2);
    ASSERT_FALSE(packVaryings(kMaxVaryings, varyings));
}

// WebGL should fail to pack max+1 vec2 arrays, unlike our more relaxed packing.
TEST_P(VaryingPackingTest, MaxPlusOneMat2VaryingsFailsWebGL)
{
    auto varyings = MakeVaryings(GL_FLOAT_MAT2, kMaxVaryings / 2 + 1, 0);
    ASSERT_FALSE(packVaryingsStrict(kMaxVaryings, varyings));
}

// Makes separate tests for different values of kMaxVaryings.
INSTANTIATE_TEST_SUITE_P(, VaryingPackingTest, ::testing::Values(1, 4, 8));

}  // anonymous namespace
