//
// 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 "common/unsafe_buffers.h"
#include "test_utils/ANGLETest.h"

using namespace angle;

namespace
{

class UnpackAlignmentTest : public ANGLETest<>
{
  protected:
    UnpackAlignmentTest()
    {
        setWindowWidth(128);
        setWindowHeight(128);
        setConfigRedBits(8);
        setConfigGreenBits(8);
        setConfigBlueBits(8);
        setConfigAlphaBits(8);
        setConfigDepthBits(24);

        mProgram = 0;
    }

    void testSetUp() override
    {
        constexpr char kFS[] = R"(uniform sampler2D tex;
void main()
{
    gl_FragColor = texture2D(tex, vec2(0.0, 1.0));
})";

        mProgram = CompileProgram(essl1_shaders::vs::Simple(), kFS);
        if (mProgram == 0)
        {
            FAIL() << "shader compilation failed.";
        }
    }

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

    void getPixelSize(GLenum format, GLenum type, unsigned int *size)
    {
        switch (type)
        {
            case GL_UNSIGNED_SHORT_5_5_5_1:
            case GL_UNSIGNED_SHORT_5_6_5:
            case GL_UNSIGNED_SHORT_4_4_4_4:
                *size = sizeof(GLushort);
                break;

            case GL_UNSIGNED_BYTE:
            {
                unsigned int compCount = 0;
                switch (format)
                {
                    case GL_RGBA:
                        compCount = 4;
                        break;
                    case GL_RGB:
                        compCount = 3;
                        break;
                    case GL_LUMINANCE_ALPHA:
                        compCount = 2;
                        break;
                    case GL_LUMINANCE:
                        compCount = 1;
                        break;
                    case GL_ALPHA:
                        compCount = 1;
                        break;
                    default:
                        FAIL() << "unknown pixel format.";
                }
                *size = sizeof(GLubyte) * compCount;
            }
            break;
            default:
                FAIL() << "unknown pixel type.";
        }
    }

    bool formatHasRGB(GLenum format) { return (format != GL_ALPHA); }

    void testAlignment(int alignment, unsigned int offset, GLenum format, GLenum type)
    {
        static const unsigned int width  = 7;
        static const unsigned int height = 2;

        glPixelStorei(GL_UNPACK_ALIGNMENT, alignment);

        GLint readbackAlignment;
        glGetIntegerv(GL_UNPACK_ALIGNMENT, &readbackAlignment);
        EXPECT_EQ(alignment, readbackAlignment);

        GLubyte buf[1024];
        ANGLE_UNSAFE_TODO(memset(buf, 0, sizeof(buf)));

        unsigned int pixelSize;
        getPixelSize(format, type, &pixelSize);
        for (unsigned int i = 0; i < pixelSize; i++)
        {
            ANGLE_UNSAFE_TODO(buf[offset + i]) = 0xFF;
        }

        GLuint tex;
        glGenTextures(1, &tex);
        glBindTexture(GL_TEXTURE_2D, tex);

        glTexImage2D(GL_TEXTURE_2D, 0, format, width, height, 0, format, type, &buf[0]);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);

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

        GLubyte expectedRGB = formatHasRGB(format) ? 255 : 0;
        EXPECT_PIXEL_EQ(0, 0, expectedRGB, expectedRGB, expectedRGB, 255);

        glDeleteTextures(1, &tex);
    }

    GLuint mProgram;
};

TEST_P(UnpackAlignmentTest, DefaultAlignment)
{
    GLint defaultAlignment;
    glGetIntegerv(GL_UNPACK_ALIGNMENT, &defaultAlignment);
    EXPECT_EQ(defaultAlignment, 4);
}

TEST_P(UnpackAlignmentTest, Alignment1RGBAUByte)
{
    testAlignment(1, 7 * 4, GL_RGBA, GL_UNSIGNED_BYTE);
}

TEST_P(UnpackAlignmentTest, Alignment1RGBUByte)
{
    testAlignment(1, 7 * 3, GL_RGB, GL_UNSIGNED_BYTE);
}

TEST_P(UnpackAlignmentTest, Alignment1RGBAUShort4444)
{
    testAlignment(1, 7 * 2, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
}

TEST_P(UnpackAlignmentTest, Alignment1RGBAUShort5551)
{
    testAlignment(1, 7 * 2, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
}

TEST_P(UnpackAlignmentTest, Alignment1RGBAUShort565)
{
    testAlignment(1, 7 * 2, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
}

TEST_P(UnpackAlignmentTest, Alignment1LAUByte)
{
    testAlignment(1, 7 * 2, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE);
}

TEST_P(UnpackAlignmentTest, Alignment1LUByte)
{
    testAlignment(1, 7, GL_LUMINANCE, GL_UNSIGNED_BYTE);
}

TEST_P(UnpackAlignmentTest, Alignment1AUByte)
{
    testAlignment(1, 7, GL_ALPHA, GL_UNSIGNED_BYTE);
}

TEST_P(UnpackAlignmentTest, Alignment2RGBAUByte)
{
    testAlignment(2, 7 * 4, GL_RGBA, GL_UNSIGNED_BYTE);
}

TEST_P(UnpackAlignmentTest, Alignment2RGBUByte)
{
    testAlignment(2, 7 * 3 + 1, GL_RGB, GL_UNSIGNED_BYTE);
}

TEST_P(UnpackAlignmentTest, Alignment2RGBAUShort4444)
{
    testAlignment(2, 7 * 2, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
}

TEST_P(UnpackAlignmentTest, Alignment2RGBAUShort5551)
{
    testAlignment(2, 7 * 2, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
}

TEST_P(UnpackAlignmentTest, Alignment2RGBAUShort565)
{
    testAlignment(2, 7 * 2, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
}

TEST_P(UnpackAlignmentTest, Alignment2LAUByte)
{
    testAlignment(2, 7 * 2, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE);
}

TEST_P(UnpackAlignmentTest, Alignment2LAByte)
{
    testAlignment(2, 7 + 1, GL_LUMINANCE, GL_UNSIGNED_BYTE);
}

TEST_P(UnpackAlignmentTest, Alignment2AUByte)
{
    testAlignment(2, 7 + 1, GL_ALPHA, GL_UNSIGNED_BYTE);
}

TEST_P(UnpackAlignmentTest, Alignment4RGBAUByte)
{
    testAlignment(4, 7 * 4, GL_RGBA, GL_UNSIGNED_BYTE);
}

TEST_P(UnpackAlignmentTest, Alignment4RGBUByte)
{
    testAlignment(4, 7 * 3 + 3, GL_RGB, GL_UNSIGNED_BYTE);
}

TEST_P(UnpackAlignmentTest, Alignment4RGBAUShort4444)
{
    testAlignment(4, 7 * 2 + 2, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
}

TEST_P(UnpackAlignmentTest, Alignment4RGBAUShort5551)
{
    testAlignment(4, 7 * 2 + 2, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
}

TEST_P(UnpackAlignmentTest, Alignment4RGBAUShort565)
{
    testAlignment(4, 7 * 2 + 2, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
}

TEST_P(UnpackAlignmentTest, Alignment4LAUByte)
{
    testAlignment(4, 7 * 2 + 2, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE);
}

TEST_P(UnpackAlignmentTest, Alignment4LUByte)
{
    testAlignment(4, 7 + 1, GL_LUMINANCE, GL_UNSIGNED_BYTE);
}

TEST_P(UnpackAlignmentTest, Alignment4AUByte)
{
    testAlignment(4, 7 + 1, GL_ALPHA, GL_UNSIGNED_BYTE);
}

TEST_P(UnpackAlignmentTest, Alignment8RGBAUByte)
{
    testAlignment(8, 7 * 4 + 4, GL_RGBA, GL_UNSIGNED_BYTE);
}

TEST_P(UnpackAlignmentTest, Alignment8RGBUByte)
{
    testAlignment(8, 7 * 3 + 3, GL_RGB, GL_UNSIGNED_BYTE);
}

TEST_P(UnpackAlignmentTest, Alignment8RGBAUShort4444)
{
    testAlignment(8, 7 * 2 + 2, GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);
}

TEST_P(UnpackAlignmentTest, Alignment8RGBAUShort5551)
{
    testAlignment(8, 7 * 2 + 2, GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1);
}

TEST_P(UnpackAlignmentTest, Alignment8RGBAUShort565)
{
    testAlignment(8, 7 * 2 + 2, GL_RGB, GL_UNSIGNED_SHORT_5_6_5);
}

TEST_P(UnpackAlignmentTest, Alignment8LAUByte)
{
    testAlignment(8, 7 * 2 + 2, GL_LUMINANCE_ALPHA, GL_UNSIGNED_BYTE);
}

TEST_P(UnpackAlignmentTest, Alignment8LUByte)
{
    testAlignment(8, 7 + 1, GL_LUMINANCE, GL_UNSIGNED_BYTE);
}

TEST_P(UnpackAlignmentTest, Alignment8AUByte)
{
    testAlignment(8, 7 + 1, GL_ALPHA, GL_UNSIGNED_BYTE);
}

// 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(UnpackAlignmentTest);

}  // namespace
