//
// Copyright 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.
//

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

using namespace angle;

class CubeMapTextureTest : public ANGLETest
{
  protected:
    CubeMapTextureTest()
    {
        setWindowWidth(256);
        setWindowHeight(256);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
    }

    void testSetUp() override
    {
        mProgram = CompileProgram(essl1_shaders::vs::Simple(), essl1_shaders::fs::UniformColor());
        if (mProgram == 0)
        {
            FAIL() << "shader compilation failed.";
        }

        mColorLocation = glGetUniformLocation(mProgram, essl1_shaders::ColorUniform());

        glUseProgram(mProgram);

        glClearColor(0, 0, 0, 0);
        glClearDepthf(0.0);
        glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

        glEnable(GL_BLEND);
        glDisable(GL_DEPTH_TEST);

        ASSERT_GL_NO_ERROR();
    }

    void testTearDown() override { glDeleteProgram(mProgram); }

    void runSampleCoordinateTransformTest(const char *shader, const bool useES3);

    GLuint mProgram;
    GLint mColorLocation;
};

// Verify that rendering to the faces of a cube map consecutively will correctly render to each
// face.
TEST_P(CubeMapTextureTest, RenderToFacesConsecutively)
{
    // TODO: Diagnose and fix. http://anglebug.com/2954
    ANGLE_SKIP_TEST_IF(IsVulkan() && IsIntel() && IsWindows());

    // http://anglebug.com/3145
    ANGLE_SKIP_TEST_IF(IsVulkan() && IsIntel() && IsFuchsia());

    const GLfloat faceColors[] = {
        1.0f, 0.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 1.0f, 0.0f, 0.0f, 1.0f, 1.0f,
        1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 0.0f, 1.0f, 1.0f, 1.0f,
    };

    GLuint tex = 0;
    glGenTextures(1, &tex);
    glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
    for (GLenum face = 0; face < 6; face++)
    {
        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA, 1, 1, 0, GL_RGBA,
                     GL_UNSIGNED_BYTE, nullptr);
    }
    EXPECT_GL_NO_ERROR();

    GLuint fbo = 0;
    glGenFramebuffers(1, &fbo);
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    EXPECT_GL_NO_ERROR();

    for (GLenum face = 0; face < 6; face++)
    {
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                               GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, tex, 0);
        EXPECT_GL_NO_ERROR();

        glUseProgram(mProgram);

        const GLfloat *faceColor = faceColors + (face * 4);
        glUniform4f(mColorLocation, faceColor[0], faceColor[1], faceColor[2], faceColor[3]);

        drawQuad(mProgram, essl1_shaders::PositionAttrib(), 0.5f);
        EXPECT_GL_NO_ERROR();
    }

    for (GLenum face = 0; face < 6; face++)
    {
        glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                               GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, tex, 0);
        EXPECT_GL_NO_ERROR();

        const GLfloat *faceColor = faceColors + (face * 4);
        EXPECT_PIXEL_EQ(0, 0, faceColor[0] * 255, faceColor[1] * 255, faceColor[2] * 255,
                        faceColor[3] * 255);
        EXPECT_GL_NO_ERROR();
    }

    glDeleteFramebuffers(1, &fbo);
    glDeleteTextures(1, &tex);

    EXPECT_GL_NO_ERROR();
}

void CubeMapTextureTest::runSampleCoordinateTransformTest(const char *shader, const bool useES3)
{
    // Fails to compile the shader.  anglebug.com/3776
    ANGLE_SKIP_TEST_IF(IsOpenGL() && IsIntel() && IsWindows());

    constexpr GLsizei kCubeFaceCount            = 6;
    constexpr GLsizei kCubeFaceSectionCount     = 4;
    constexpr GLsizei kCubeFaceSectionCountSqrt = 2;

    constexpr GLColor faceColors[kCubeFaceCount][kCubeFaceSectionCount] = {
        {GLColor(255, 0, 0, 255), GLColor(191, 0, 0, 255), GLColor(127, 0, 0, 255),
         GLColor(63, 0, 0, 255)},
        {GLColor(0, 255, 0, 255), GLColor(0, 191, 0, 255), GLColor(0, 127, 0, 255),
         GLColor(0, 63, 0, 255)},
        {GLColor(0, 0, 255, 255), GLColor(0, 0, 191, 255), GLColor(0, 0, 127, 255),
         GLColor(0, 0, 63, 255)},
        {GLColor(255, 63, 0, 255), GLColor(191, 127, 0, 255), GLColor(127, 191, 0, 255),
         GLColor(63, 255, 0, 255)},
        {GLColor(0, 255, 63, 255), GLColor(0, 191, 127, 255), GLColor(0, 127, 191, 255),
         GLColor(0, 63, 255, 255)},
        {GLColor(63, 0, 255, 255), GLColor(127, 0, 191, 255), GLColor(191, 0, 127, 255),
         GLColor(255, 0, 63, 255)},
    };

    constexpr GLsizei kTextureSize = 32;

    GLTexture tex;
    glBindTexture(GL_TEXTURE_CUBE_MAP, tex);
    for (GLenum face = 0; face < kCubeFaceCount; face++)
    {
        std::vector<GLColor> faceData(kTextureSize * kTextureSize);

        // Create the face with four sections, each with a solid color from |faceColors|.
        for (size_t row = 0; row < kTextureSize / kCubeFaceSectionCountSqrt; ++row)
        {
            for (size_t col = 0; col < kTextureSize / kCubeFaceSectionCountSqrt; ++col)
            {
                for (size_t srow = 0; srow < kCubeFaceSectionCountSqrt; ++srow)
                {
                    for (size_t scol = 0; scol < kCubeFaceSectionCountSqrt; ++scol)
                    {
                        size_t r = row + srow * kTextureSize / kCubeFaceSectionCountSqrt;
                        size_t c = col + scol * kTextureSize / kCubeFaceSectionCountSqrt;
                        size_t s = srow * kCubeFaceSectionCountSqrt + scol;
                        faceData[r * kTextureSize + c] = faceColors[face][s];
                    }
                }
            }
        }

        glTexImage2D(GL_TEXTURE_CUBE_MAP_POSITIVE_X + face, 0, GL_RGBA, kTextureSize, kTextureSize,
                     0, GL_RGBA, GL_UNSIGNED_BYTE, faceData.data());
    }
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    glTexParameteri(GL_TEXTURE_CUBE_MAP, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    EXPECT_GL_NO_ERROR();

    GLTexture fboTex;
    glBindTexture(GL_TEXTURE_2D, fboTex);
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, kCubeFaceCount, kCubeFaceSectionCount, 0, GL_RGBA,
                 GL_UNSIGNED_BYTE, nullptr);

    GLFramebuffer fbo;
    glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, fboTex, 0);
    EXPECT_GL_NO_ERROR();

    ANGLE_GL_PROGRAM(program, useES3 ? essl3_shaders::vs::Simple() : essl1_shaders::vs::Simple(),
                     shader);
    glUseProgram(program);

    GLint texCubeLocation = glGetUniformLocation(program, "texCube");
    ASSERT_NE(-1, texCubeLocation);
    glUniform1i(texCubeLocation, 0);

    drawQuad(program, useES3 ? essl3_shaders::PositionAttrib() : essl1_shaders::PositionAttrib(),
             0.5f);
    EXPECT_GL_NO_ERROR();

    for (GLenum face = 0; face < kCubeFaceCount; face++)
    {
        // The following table defines the translation from textureCube coordinates to coordinates
        // in each face.  The framebuffer has width 6 and height 4.  Every column corresponding to
        // an x value represents one cube face.  The values in rows are samples from the four
        // sections of the face.
        //
        // Major    Axis Direction Target    sc  tc  ma
        //  +rx  TEXTURE_CUBE_MAP_POSITIVE_X −rz −ry rx
        //  −rx  TEXTURE_CUBE_MAP_NEGATIVE_X  rz −ry rx
        //  +ry  TEXTURE_CUBE_MAP_POSITIVE_Y  rx  rz ry
        //  −ry  TEXTURE_CUBE_MAP_NEGATIVE_Y  rx −rz ry
        //  +rz  TEXTURE_CUBE_MAP_POSITIVE_Z  rx −ry rz
        //  −rz  TEXTURE_CUBE_MAP_NEGATIVE_Z −rx −ry rz
        //
        // This table is used only to determine the direction of growth for s and t.  The shader
        // always generates (row,col) coordinates (0, 0), (0, 1), (1, 0), (1, 1) which is the order
        // the data is uploaded to the faces, but based on the table above, the sample order would
        // be different.
        constexpr size_t faceSampledSections[kCubeFaceCount][kCubeFaceSectionCount] = {
            {3, 2, 1, 0}, {2, 3, 0, 1}, {0, 1, 2, 3}, {2, 3, 0, 1}, {2, 3, 0, 1}, {3, 2, 1, 0},
        };

        for (size_t section = 0; section < kCubeFaceSectionCount; ++section)
        {
            const GLColor sectionColor = faceColors[face][faceSampledSections[face][section]];

            EXPECT_PIXEL_COLOR_EQ(face, section, sectionColor)
                << "face " << face << ", section " << section;
        }
    }
    EXPECT_GL_NO_ERROR();
}

// Verify that cube map sampling follows the rules that map cubemap coordinates to coordinates
// within each face.  See section 3.7.5 of GLES2.0 (Cube Map Texture Selection).
TEST_P(CubeMapTextureTest, SampleCoordinateTransform)
{
    // http://anglebug.com/4092
    ANGLE_SKIP_TEST_IF(IsWindows() && IsD3D9());
    // Create a program that samples from 6x4 directions of the cubemap, draw and verify that the
    // colors match the right color from |faceColors|.
    constexpr char kFS[] = R"(precision mediump float;

uniform samplerCube texCube;

const mat4 coordInSection = mat4(
    vec4(-0.5, -0.5, 0, 0),
    vec4( 0.5, -0.5, 0, 0),
    vec4(-0.5,  0.5, 0, 0),
    vec4( 0.5,  0.5, 0, 0)
);

void main()
{
    vec3 coord;
    if (gl_FragCoord.x < 2.0)
    {
        coord.x = gl_FragCoord.x < 1.0 ? 1.0 : -1.0;
        coord.zy = coordInSection[int(gl_FragCoord.y)].xy;
    }
    else if (gl_FragCoord.x < 4.0)
    {
        coord.y = gl_FragCoord.x < 3.0 ? 1.0 : -1.0;
        coord.xz = coordInSection[int(gl_FragCoord.y)].xy;
    }
    else
    {
        coord.z = gl_FragCoord.x < 5.0 ? 1.0 : -1.0;
        coord.xy = coordInSection[int(gl_FragCoord.y)].xy;
    }

    gl_FragColor = textureCube(texCube, coord);
})";

    runSampleCoordinateTransformTest(kFS, false);
}

// On Android Vulkan, unequal x and y derivatives cause this test to fail.
TEST_P(CubeMapTextureTest, SampleCoordinateTransformGrad)
{
    ANGLE_SKIP_TEST_IF(!IsGLExtensionEnabled("GL_EXT_shader_texture_lod"));

    constexpr char kFS[] = R"(#extension GL_EXT_shader_texture_lod : require
precision mediump float;

uniform samplerCube texCube;

const mat4 coordInSection = mat4(
    vec4(-0.5, -0.5, 0, 0),
    vec4( 0.5, -0.5, 0, 0),
    vec4(-0.5,  0.5, 0, 0),
    vec4( 0.5,  0.5, 0, 0)
);

void main()
{
    vec3 coord;
    if (gl_FragCoord.x < 2.0)
    {
        coord.x = gl_FragCoord.x < 1.0 ? 1.0 : -1.0;
        coord.zy = coordInSection[int(gl_FragCoord.y)].xy;
    }
    else if (gl_FragCoord.x < 4.0)
    {
        coord.y = gl_FragCoord.x < 3.0 ? 1.0 : -1.0;
        coord.xz = coordInSection[int(gl_FragCoord.y)].xy;
    }
    else
    {
        coord.z = gl_FragCoord.x < 5.0 ? 1.0 : -1.0;
        coord.xy = coordInSection[int(gl_FragCoord.y)].xy;
    }

    gl_FragColor = textureCubeGradEXT(texCube, coord,
                                      vec3(10.0, 10.0, 0.0), vec3(0.0, 10.0, 10.0));
})";

    runSampleCoordinateTransformTest(kFS, false);
}

// Same as the previous but uses the ES 3.0 explicit gradient function.
TEST_P(CubeMapTextureTest, SampleCoordinateTransformGrad_ES3)
{
    ANGLE_SKIP_TEST_IF(getClientMajorVersion() < 3);

    constexpr char kFS[] = R"(#version 300 es
precision mediump float;

uniform samplerCube texCube;
out vec4 my_FragColor;

const mat4 coordInSection = mat4(
    vec4(-0.5, -0.5, 0, 0),
    vec4( 0.5, -0.5, 0, 0),
    vec4(-0.5,  0.5, 0, 0),
    vec4( 0.5,  0.5, 0, 0)
);

void main()
{
    vec3 coord;
    if (gl_FragCoord.x < 2.0)
    {
        coord.x = gl_FragCoord.x < 1.0 ? 1.0 : -1.0;
        coord.zy = coordInSection[int(gl_FragCoord.y)].xy;
    }
    else if (gl_FragCoord.x < 4.0)
    {
        coord.y = gl_FragCoord.x < 3.0 ? 1.0 : -1.0;
        coord.xz = coordInSection[int(gl_FragCoord.y)].xy;
    }
    else
    {
        coord.z = gl_FragCoord.x < 5.0 ? 1.0 : -1.0;
        coord.xy = coordInSection[int(gl_FragCoord.y)].xy;
    }

    my_FragColor = textureGrad(texCube, coord,
                               vec3(10.0, 10.0, 0.0), vec3(0.0, 10.0, 10.0));
})";

    runSampleCoordinateTransformTest(kFS, true);
}

// Use this to select which configurations (e.g. which renderer, which GLES major version) these
// tests should be run against.
ANGLE_INSTANTIATE_TEST_ES2_AND_ES3(CubeMapTextureTest);
