/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL ES 3.1 Module
 * -------------------------------------------------
 *
 * Copyright 2016 The Android Open Source Project
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *      http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 *
 *//*!
 * \file
 * \brief Negative Advanced Blend Equation Tests
 *//*--------------------------------------------------------------------*/

#include "es31fNegativeAdvancedBlendEquationTests.hpp"

#include "gluShaderProgram.hpp"
#include "glwEnums.hpp"

namespace deqp
{
namespace gles31
{
namespace Functional
{
namespace NegativeTestShared
{
namespace
{

enum BlendEquation
{
    BLEND_EQUATION_MULTIPLY = 0,
    BLEND_EQUATION_SCREEN,
    BLEND_EQUATION_OVERLAY,
    BLEND_EQUATION_DARKEN,
    BLEND_EQUATION_LIGHTEN,
    BLEND_EQUATION_COLORDODGE,
    BLEND_EQUATION_COLORBURN,
    BLEND_EQUATION_HARDLIGHT,
    BLEND_EQUATION_SOFTLIGHT,
    BLEND_EQUATION_DIFFERENCE,
    BLEND_EQUATION_EXCLUSION,
    BLEND_EQUATION_HSL_HUE,
    BLEND_EQUATION_HSL_SATURATION,
    BLEND_EQUATION_HSL_COLOR,
    BLEND_EQUATION_HSL_LUMINOSITY,
    BLEND_EQUATION_ALL_EQUATIONS,

    BLEND_EQUATION_LAST
};

static const BlendEquation s_equations[] = {
    BLEND_EQUATION_MULTIPLY,       BLEND_EQUATION_SCREEN,     BLEND_EQUATION_OVERLAY,       BLEND_EQUATION_DARKEN,
    BLEND_EQUATION_LIGHTEN,        BLEND_EQUATION_COLORDODGE, BLEND_EQUATION_COLORBURN,     BLEND_EQUATION_HARDLIGHT,
    BLEND_EQUATION_SOFTLIGHT,      BLEND_EQUATION_DIFFERENCE, BLEND_EQUATION_EXCLUSION,     BLEND_EQUATION_HSL_HUE,
    BLEND_EQUATION_HSL_SATURATION, BLEND_EQUATION_HSL_COLOR,  BLEND_EQUATION_HSL_LUMINOSITY};

std::string getShaderLayoutEquation(BlendEquation equation)
{
    switch (equation)
    {
    case BLEND_EQUATION_MULTIPLY:
        return "blend_support_multiply";
    case BLEND_EQUATION_SCREEN:
        return "blend_support_screen";
    case BLEND_EQUATION_OVERLAY:
        return "blend_support_overlay";
    case BLEND_EQUATION_DARKEN:
        return "blend_support_darken";
    case BLEND_EQUATION_LIGHTEN:
        return "blend_support_lighten";
    case BLEND_EQUATION_COLORDODGE:
        return "blend_support_colordodge";
    case BLEND_EQUATION_COLORBURN:
        return "blend_support_colorburn";
    case BLEND_EQUATION_HARDLIGHT:
        return "blend_support_hardlight";
    case BLEND_EQUATION_SOFTLIGHT:
        return "blend_support_softlight";
    case BLEND_EQUATION_DIFFERENCE:
        return "blend_support_difference";
    case BLEND_EQUATION_EXCLUSION:
        return "blend_support_exclusion";
    case BLEND_EQUATION_HSL_HUE:
        return "blend_support_hsl_hue";
    case BLEND_EQUATION_HSL_SATURATION:
        return "blend_support_hsl_saturation";
    case BLEND_EQUATION_HSL_COLOR:
        return "blend_support_hsl_color";
    case BLEND_EQUATION_HSL_LUMINOSITY:
        return "blend_support_hsl_luminosity";
    case BLEND_EQUATION_ALL_EQUATIONS:
        return "blend_support_all_equations";
    default:
        DE_FATAL("Equation not supported.");
    }
    return DE_NULL;
}

glw::GLenum getEquation(BlendEquation equation)
{
    switch (equation)
    {
    case BLEND_EQUATION_MULTIPLY:
        return GL_MULTIPLY;
    case BLEND_EQUATION_SCREEN:
        return GL_SCREEN;
    case BLEND_EQUATION_OVERLAY:
        return GL_OVERLAY;
    case BLEND_EQUATION_DARKEN:
        return GL_DARKEN;
    case BLEND_EQUATION_LIGHTEN:
        return GL_LIGHTEN;
    case BLEND_EQUATION_COLORDODGE:
        return GL_COLORDODGE;
    case BLEND_EQUATION_COLORBURN:
        return GL_COLORBURN;
    case BLEND_EQUATION_HARDLIGHT:
        return GL_HARDLIGHT;
    case BLEND_EQUATION_SOFTLIGHT:
        return GL_SOFTLIGHT;
    case BLEND_EQUATION_DIFFERENCE:
        return GL_DIFFERENCE;
    case BLEND_EQUATION_EXCLUSION:
        return GL_EXCLUSION;
    case BLEND_EQUATION_HSL_HUE:
        return GL_HSL_HUE;
    case BLEND_EQUATION_HSL_SATURATION:
        return GL_HSL_SATURATION;
    case BLEND_EQUATION_HSL_COLOR:
        return GL_HSL_COLOR;
    case BLEND_EQUATION_HSL_LUMINOSITY:
        return GL_HSL_LUMINOSITY;
    default:
        DE_FATAL("Equation not supported.");
    }
    return DE_NULL;
}

std::string generateVertexShaderSource(NegativeTestContext &ctx)
{
    const bool supportsES32        = contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
    const glu::GLSLVersion version = supportsES32 ? glu::GLSL_VERSION_320_ES : glu::GLSL_VERSION_310_ES;
    std::ostringstream source;

    source << glu::getGLSLVersionDeclaration(version) << "\n"
           << "void main ()\n"
           << "{\n"
           << "    gl_Position = vec4(0.0);\n"
           << "}\n";

    return source.str();
}

std::string generateFragmentShaderSource(NegativeTestContext &ctx, BlendEquation equation)
{
    const bool supportsES32        = contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2));
    const glu::GLSLVersion version = supportsES32 ? glu::GLSL_VERSION_320_ES : glu::GLSL_VERSION_310_ES;
    std::ostringstream source;

    source << glu::getGLSLVersionDeclaration(version) << "\n"
           << (supportsES32 ? "" : "#extension GL_KHR_blend_equation_advanced : enable\n") << "layout("
           << getShaderLayoutEquation(equation) << ") out;\n"
           << "layout(location=0) out mediump vec4 o_color;\n"
           << "void main ()\n"
           << "{\n"
           << "    o_color = vec4(0);\n"
           << "}\n";

    return source.str();
}

glu::ProgramSources generateProgramSources(NegativeTestContext &ctx, BlendEquation equation)
{
    return glu::ProgramSources() << glu::VertexSource(generateVertexShaderSource(ctx))
                                 << glu::FragmentSource(generateFragmentShaderSource(ctx, equation));
}

void blend_qualifier_mismatch(NegativeTestContext &ctx)
{
    TCU_CHECK_AND_THROW(NotSupportedError,
                        ctx.isExtensionSupported("GL_KHR_blend_equation_advanced") ||
                            contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)),
                        "This test requires support for the extension GL_KHR_blend_equation_advanced or context "
                        "version 3.2 or higher.");

    glw::GLuint vao = 0;
    bool isES       = glu::isContextTypeES(ctx.getRenderContext().getType());
    if (!isES)
    {
        ctx.glGenVertexArrays(1, &vao);
        ctx.glBindVertexArray(vao);
    }

    ctx.beginSection("GL_INVALID_OPERATION is generated if blending is enabled, and the blend qualifier is different "
                     "from blend_support_all_equations and does not match the blend equation.");
    for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_equations); ++ndx)
    {
        glu::ShaderProgram program(ctx.getRenderContext(), generateProgramSources(ctx, s_equations[ndx]));

        ctx.getLog() << program;
        TCU_CHECK(program.isOk());

        ctx.glUseProgram(program.getProgram());
        ctx.expectError(GL_NO_ERROR);

        for (int ndx2 = 0; ndx2 < DE_LENGTH_OF_ARRAY(s_equations); ++ndx2)
        {
            if (s_equations[ndx] == s_equations[ndx2])
                continue;

            ctx.glEnable(GL_BLEND);
            ctx.glBlendEquation(getEquation(s_equations[ndx2]));
            ctx.expectError(GL_NO_ERROR);
            ctx.glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0);
            ctx.expectError(GL_INVALID_OPERATION);

            ctx.glDisable(GL_BLEND);
            ctx.glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0);
            ctx.expectError(GL_NO_ERROR);
        }
    }
    ctx.endSection();

    if (!isES)
        ctx.glDeleteVertexArrays(1, &vao);
}

void attachment_advanced_equation(NegativeTestContext &ctx)
{
    TCU_CHECK_AND_THROW(NotSupportedError,
                        ctx.isExtensionSupported("GL_KHR_blend_equation_advanced") ||
                            contextSupports(ctx.getRenderContext().getType(), glu::ApiType::es(3, 2)),
                        "This test requires support for the extension GL_KHR_blend_equation_advanced or context "
                        "version 3.2 or higher.");

    glw::GLuint vao                 = 0;
    glw::GLuint fbo                 = 0x1234;
    glw::GLuint texture             = 0x1234;
    const glw::GLenum attachments[] = {GL_COLOR_ATTACHMENT0, GL_COLOR_ATTACHMENT1};
    const bool isES                 = glu::isContextTypeES(ctx.getRenderContext().getType());

    if (!isES)
    {
        ctx.glGenVertexArrays(1, &vao);
        ctx.glBindVertexArray(vao);
    }

    ctx.glGenTextures(1, &texture);
    ctx.glBindTexture(GL_TEXTURE_2D, texture);
    ctx.glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA8, 32, 32, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    ctx.glGenFramebuffers(1, &fbo);
    ctx.glBindFramebuffer(GL_FRAMEBUFFER, fbo);
    ctx.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0);
    ctx.expectError(GL_NO_ERROR);
    ctx.glCheckFramebufferStatus(GL_FRAMEBUFFER);

    ctx.beginSection(
        "GL_INVALID_OPERATION is generated if blending is enabled, advanced equations are used, and the draw buffer "
        "for other color outputs is not NONE unless NVX_blend_equation_advanced_multi_draw_buffers is supported.");
    for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_equations); ++ndx)
    {
        glu::ShaderProgram program(ctx.getRenderContext(), generateProgramSources(ctx, s_equations[ndx]));
        ctx.getLog() << program;
        TCU_CHECK(program.isOk());

        ctx.glUseProgram(program.getProgram());
        ctx.glEnable(GL_BLEND);
        ctx.glDrawBuffers(2, attachments);
        ctx.expectError(GL_NO_ERROR);
        ctx.glBlendEquation(getEquation(s_equations[ndx]));
        ctx.glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0);
        if (ctx.isExtensionSupported("GL_NVX_blend_equation_advanced_multi_draw_buffers"))
            ctx.expectError(GL_NO_ERROR);
        else
            ctx.expectError(GL_INVALID_OPERATION);
    }
    ctx.endSection();

    ctx.beginSection("GL_NO_ERROR is generated if no advanced blend equations are used.");
    ctx.glBlendEquation(GL_FUNC_ADD);
    ctx.glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0);
    ctx.expectError(GL_NO_ERROR);
    ctx.endSection();

    ctx.beginSection("GL_NO_ERROR is generated if blending is disabled.");
    ctx.glDisable(GL_BLEND);
    for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(s_equations); ++ndx)
    {
        ctx.glBlendEquation(getEquation(s_equations[ndx]));
        ctx.glDrawElements(GL_TRIANGLES, 0, GL_UNSIGNED_INT, 0);
        ctx.expectError(GL_NO_ERROR);
    }
    ctx.endSection();

    if (!isES)
        ctx.glDeleteVertexArrays(1, &vao);

    ctx.glDeleteFramebuffers(1, &fbo);
    ctx.glDeleteTextures(1, &texture);
}

} // namespace

std::vector<FunctionContainer> getNegativeAdvancedBlendEquationTestFunctions(void)
{
    const FunctionContainer funcs[] = {
        {blend_qualifier_mismatch, "blend_qualifier_mismatch", "Test blend qualifier mismatch."},
        {attachment_advanced_equation, "attachment_advanced_equation", "Test draw buffer for other color outputs."},
    };

    return std::vector<FunctionContainer>(DE_ARRAY_BEGIN(funcs), DE_ARRAY_END(funcs));
}

} // namespace NegativeTestShared
} // namespace Functional
} // namespace gles31
} // namespace deqp
