//
// Copyright 2020 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.
//
// Tests for GL_EXT_shader_non_constant_global_initializers
//

#include "common/mathutil.h"
#include "test_utils/ANGLETest.h"
#include "test_utils/gl_raii.h"

using namespace angle;

class ShaderNonConstGlobalInitializerTest : public ANGLETest
{
  protected:
    ShaderNonConstGlobalInitializerTest() : ANGLETest()
    {
        setWindowWidth(128);
        setWindowHeight(128);
    }

    void draw(GLuint program)
    {
        std::array<Vector4, 3> vertices;
        vertices[0] = {-1.0, -1.0, 0.0, 1.0};
        vertices[1] = {1.0, -1.0, 0.0, 1.0};
        vertices[2] = {0.0, 1.0, 0.0, 2.0};

        GLint positionLocation = glGetAttribLocation(program, "a_position");

        glVertexAttribPointer(positionLocation, 4, GL_FLOAT, GL_FALSE, 0, vertices.data());

        glEnableVertexAttribArray(positionLocation);

        glDrawArrays(GL_TRIANGLES, 0, 3);
    }
};

// Tests that the extension is disabled if not explicitly enabled- non constant initializers should
// be forbidden in all cases unless this extension is explicitly requested
TEST_P(ShaderNonConstGlobalInitializerTest, Disabled)
{
    const char *fragSrc = R"(#version 100

precision lowp float;

uniform float nondeterministic_uniform;

float nonConstInitializer();

float nonConstGlobal = nonConstInitializer();
float sideEffectGlobal = 0.0;

float nonConstInitializer() {
    sideEffectGlobal = 1.0;
    return nondeterministic_uniform;
}

void main()
{
    gl_FragColor = vec4(nondeterministic_uniform, nonConstGlobal, sideEffectGlobal, 1.0);
}
)";

    GLShader badFragment(GL_FRAGMENT_SHADER);
    glShaderSource(badFragment, 1, &fragSrc, nullptr);
    glCompileShader(badFragment);

    GLint compileResult;
    glGetShaderiv(badFragment, GL_COMPILE_STATUS, &compileResult);
    EXPECT_EQ(compileResult, 0);

    EXPECT_GL_NO_ERROR();
}

// Test that non constant initializers are evaluated correctly in ESSL 100
TEST_P(ShaderNonConstGlobalInitializerTest, v100)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_non_constant_global_initializers"));

    const char *fragSrc = R"(#version 100
#extension GL_EXT_shader_non_constant_global_initializers : require

precision lowp float;

#ifndef GL_EXT_shader_non_constant_global_initializers
#error GL_EXT_shader_non_constant_global_initializers is not defined
#endif

uniform float nondeterministic_uniform;

float nonConstInitializer();

float nonConstGlobal = nonConstInitializer();
float sideEffectGlobal = 0.0;

float nonConstInitializer() {
    sideEffectGlobal = 1.0;
    return nondeterministic_uniform;
}

void main()
{
    gl_FragColor = vec4(nondeterministic_uniform, nonConstGlobal, sideEffectGlobal, 1.0);
}
)";

    ANGLE_GL_PROGRAM(program, essl1_shaders::vs::Simple(), fragSrc);
    EXPECT_GL_NO_ERROR();

    glUseProgram(program);
    glUniform1f(glGetUniformLocation(program, "nondeterministic_uniform"), 1.0f);
    ASSERT_GL_NO_ERROR();

    draw(program);
    EXPECT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(64, 64, GLColor::white);
}

// Test that non constant initializers are evaluated correctly in ESSL 300
TEST_P(ShaderNonConstGlobalInitializerTest, v300es)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_non_constant_global_initializers"));

    const char *fragSrc = R"(#version 300 es
#extension GL_EXT_shader_non_constant_global_initializers : require

precision highp float;
out vec4 fragColor;

#ifndef GL_EXT_shader_non_constant_global_initializers
#error GL_EXT_shader_non_constant_global_initializers is not defined
#endif

uniform float nondeterministic_uniform;

float nonConstInitializer();

float nonConstGlobal = nonConstInitializer();
float sideEffectGlobal = 0.0;

float nonConstInitializer() {
    sideEffectGlobal = 1.0;
    return nondeterministic_uniform;
}

void main()
{
    fragColor = vec4(nondeterministic_uniform, nonConstGlobal, sideEffectGlobal, 1.0);
}
)";

    ANGLE_GL_PROGRAM(program, essl3_shaders::vs::Simple(), fragSrc);
    EXPECT_GL_NO_ERROR();

    glUseProgram(program);
    glUniform1f(glGetUniformLocation(program, "nondeterministic_uniform"), 1.0f);
    ASSERT_GL_NO_ERROR();

    draw(program);
    EXPECT_GL_NO_ERROR();

    EXPECT_PIXEL_COLOR_EQ(64, 64, GLColor::white);
}

ANGLE_INSTANTIATE_TEST_ES3(ShaderNonConstGlobalInitializerTest);