//
// Copyright (c) 2015 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.
//
// Extension_test.cpp
//   Test that shaders need various extensions to be compiled.
//

#include "angle_gl.h"
#include "gtest/gtest.h"
#include "GLSLANG/ShaderLang.h"

static const char *FragDepthExtShdr[] =
{
    // First string of the shader. The required pragma declaration.
    "#extension GL_EXT_frag_depth : enable\n",

    // Second string of the shader. The rest of the shader body.
    "void main() { gl_FragDepthEXT = 1.0; }\n"
};

static const char *StandDerivExtShdr[] =
{
    // First string of the shader. The required pragma declaration.
    "#extension GL_OES_standard_derivatives : enable\n",

    // Second string of the shader. The rest of the shader body.
    "precision mediump float;\n"
    "varying vec2 texCoord;\n"
    "void main() { gl_FragColor = vec4(dFdx(texCoord.x), dFdy(texCoord.y), fwidth(texCoord.x), 1.0); }\n"
};

static const char *TextureLODShdr[] =
{
    // First string of the shader. The required pragma declaration.
    "#extension GL_EXT_shader_texture_lod : enable\n",

    // Second string of the shader. The rest of the shader body.
    "precision mediump float;\n"
    "varying vec2 texCoord0v;\n"
    "uniform float lod;\n"
    "uniform sampler2D tex;\n"
    "void main() { vec4 color = texture2DLodEXT(tex, texCoord0v, lod); }\n"
};

class ShaderExtensionTest : public testing::Test
{
  public:
    ShaderExtensionTest() {}

  protected:
    virtual void SetUp()
    {
        sh::InitBuiltInResources(&mResources);
        mCompiler = nullptr;
    }

    virtual void TearDown()
    {
        DestroyCompiler();
    }

    void DestroyCompiler()
    {
        if (mCompiler)
        {
            sh::Destruct(mCompiler);
            mCompiler = nullptr;
        }
    }

    void InitializeCompiler()
    {
        DestroyCompiler();
        mCompiler = sh::ConstructCompiler(GL_FRAGMENT_SHADER, SH_WEBGL_SPEC,
                                          SH_GLSL_COMPATIBILITY_OUTPUT, &mResources);
        ASSERT_TRUE(mCompiler != nullptr) << "Compiler could not be constructed.";
    }

    void TestShaderExtension(const char **shaderStrings, int stringCount, bool expectation)
    {
        bool success                  = sh::Compile(mCompiler, shaderStrings, stringCount, 0);
        const std::string &compileLog = sh::GetInfoLog(mCompiler);
        EXPECT_EQ(expectation, success) << compileLog;
    }

  protected:
    ShBuiltInResources mResources;
    ShHandle mCompiler;
};

TEST_F(ShaderExtensionTest, FragDepthExtRequiresExt)
{
    // Extension is required to compile properly.
    mResources.EXT_frag_depth = 0;
    InitializeCompiler();
    TestShaderExtension(FragDepthExtShdr, 2, false);
}

TEST_F(ShaderExtensionTest, FragDepthExtRequiresPragma)
{
    // Pragma is required to compile properly.
    mResources.EXT_frag_depth = 1;
    InitializeCompiler();
    TestShaderExtension(&FragDepthExtShdr[1], 1, false);
}

TEST_F(ShaderExtensionTest, FragDepthExtCompiles)
{
    // Test that it compiles properly with extension enabled.
    mResources.EXT_frag_depth = 1;
    InitializeCompiler();
    TestShaderExtension(FragDepthExtShdr, 2, true);
}

TEST_F(ShaderExtensionTest, FragDepthExtResetsInternalStates)
{
    // Test that extension internal states are reset properly between compiles.
    mResources.EXT_frag_depth = 1;
    InitializeCompiler();

    TestShaderExtension(FragDepthExtShdr, 2, true);
    TestShaderExtension(&FragDepthExtShdr[1], 1, false);
    TestShaderExtension(FragDepthExtShdr, 2, true);
}

TEST_F(ShaderExtensionTest, StandDerivExtRequiresExt)
{
    // Extension is required to compile properly.
    mResources.OES_standard_derivatives = 0;
    InitializeCompiler();
    TestShaderExtension(StandDerivExtShdr, 2, false);
}

TEST_F(ShaderExtensionTest, StandDerivExtRequiresPragma)
{
    // Pragma is required to compile properly.
    mResources.OES_standard_derivatives = 1;
    InitializeCompiler();
    TestShaderExtension(&StandDerivExtShdr[1], 1, false);
}

TEST_F(ShaderExtensionTest, StandDerivExtCompiles)
{
    // Test that it compiles properly with extension enabled.
    mResources.OES_standard_derivatives = 1;
    InitializeCompiler();
    TestShaderExtension(StandDerivExtShdr, 2, true);
}

TEST_F(ShaderExtensionTest, StandDerivExtResetsInternalStates)
{
    // Test that extension internal states are reset properly between compiles.
    mResources.OES_standard_derivatives = 1;
    InitializeCompiler();

    TestShaderExtension(StandDerivExtShdr, 2, true);
    TestShaderExtension(&StandDerivExtShdr[1], 1, false);
    TestShaderExtension(StandDerivExtShdr, 2, true);
    TestShaderExtension(&StandDerivExtShdr[1], 1, false);
}

TEST_F(ShaderExtensionTest, TextureLODExtRequiresExt)
{
    // Extension is required to compile properly.
    mResources.EXT_shader_texture_lod = 0;
    InitializeCompiler();
    TestShaderExtension(TextureLODShdr, 2, false);
}

TEST_F(ShaderExtensionTest, TextureLODExtRequiresPragma)
{
    // Pragma is required to compile properly.
    mResources.EXT_shader_texture_lod = 1;
    InitializeCompiler();
    TestShaderExtension(&TextureLODShdr[1], 1, false);
}

TEST_F(ShaderExtensionTest, TextureLODExtCompiles)
{
    // Test that it compiles properly with extension enabled.
    mResources.EXT_shader_texture_lod = 1;
    InitializeCompiler();
    TestShaderExtension(TextureLODShdr, 2, true);
}

TEST_F(ShaderExtensionTest, TextureLODExtResetsInternalStates)
{
    // Test that extension internal states are reset properly between compiles.
    mResources.EXT_shader_texture_lod = 1;
    InitializeCompiler();

    TestShaderExtension(&TextureLODShdr[1], 1, false);
    TestShaderExtension(TextureLODShdr, 2, true);
    TestShaderExtension(&TextureLODShdr[1], 1, false);
    TestShaderExtension(TextureLODShdr, 2, true);
}

// Test a bug where we could modify the value of a builtin variable.
TEST_F(ShaderExtensionTest, BuiltinRewritingBug)
{
    mResources.MaxDrawBuffers = 4;
    mResources.EXT_draw_buffers = 1;
    InitializeCompiler();

    const std::string &shaderString =
        "#extension GL_EXT_draw_buffers : require\n"
        "precision mediump float;\n"
        "void main() {\n"
        "    gl_FragData[gl_MaxDrawBuffers] = vec4(0.0);\n"
        "}";

    const char *shaderStrings[] = { shaderString.c_str() };

    TestShaderExtension(shaderStrings, 1, false);
    TestShaderExtension(shaderStrings, 1, false);
}
