/*-------------------------------------------------------------------------
 * drawElements Quality Program OpenGL (ES) Module
 * -----------------------------------------------
 *
 * Copyright 2014 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 Common object lifetime tests.
 *//*--------------------------------------------------------------------*/

#include "glsLifetimeTests.hpp"

#include "deString.h"
#include "deRandom.hpp"
#include "deSTLUtil.hpp"
#include "deStringUtil.hpp"
#include "tcuRGBA.hpp"
#include "tcuImageCompare.hpp"
#include "tcuRenderTarget.hpp"
#include "tcuStringTemplate.hpp"
#include "tcuTestLog.hpp"
#include "gluDrawUtil.hpp"
#include "gluObjectWrapper.hpp"
#include "gluPixelTransfer.hpp"
#include "gluShaderProgram.hpp"
#include "gluDefs.hpp"
#include "gluTextureUtil.hpp"
#include "gluStrUtil.hpp"
#include "glwFunctions.hpp"

#include <vector>
#include <map>
#include <algorithm>
#include <sstream>

namespace deqp
{
namespace gls
{
namespace LifetimeTests
{
namespace details
{

using de::Random;
using std::map;
using std::ostringstream;
using std::string;
using tcu::RenderTarget;
using tcu::RGBA;
using tcu::StringTemplate;
using tcu::TestCase;
typedef TestCase::IterateResult IterateResult;
using glu::Framebuffer;
using glu::Program;
using glu::Shader;
using glu::SHADERTYPE_FRAGMENT;
using glu::SHADERTYPE_VERTEX;
using tcu::ScopedLogSection;
using tcu::TestLog;
using namespace glw;

enum
{
    VIEWPORT_SIZE    = 128,
    FRAMEBUFFER_SIZE = 128
};

GLint getInteger(ContextWrapper &gl, GLenum queryParam)
{
    GLint ret = 0;
    GLU_CHECK_CALL_ERROR(gl.glGetIntegerv(queryParam, &ret), gl.glGetError());
    gl.log() << TestLog::Message << "// Single integer output: " << ret << TestLog::EndMessage;
    return ret;
}

#define GLSL100_SRC(BODY) ("#version 100\n" #BODY "\n")

static const char *const s_vertexShaderSrc =
    GLSL100_SRC(attribute vec2 pos; void main() { gl_Position = vec4(pos.xy, 0.0, 1.0); });

static const char *const s_fragmentShaderSrc = GLSL100_SRC(void main() { gl_FragColor = vec4(1.0); });

class CheckedShader : public Shader
{
public:
    CheckedShader(const RenderContext &renderCtx, glu::ShaderType type, const string &src) : Shader(renderCtx, type)
    {
        const char *const srcStr = src.c_str();
        setSources(1, &srcStr, DE_NULL);
        compile();
        TCU_CHECK(getCompileStatus());
    }
};

class CheckedProgram : public Program
{
public:
    CheckedProgram(const RenderContext &renderCtx, GLuint vtxShader, GLuint fragShader) : Program(renderCtx)
    {
        attachShader(vtxShader);
        attachShader(fragShader);
        link();
        TCU_CHECK(getLinkStatus());
    }
};

ContextWrapper::ContextWrapper(const Context &ctx) : CallLogWrapper(ctx.gl(), ctx.log()), m_ctx(ctx)
{
    enableLogging(true);
}

void SimpleBinder::bind(GLuint name)
{
    (this->*m_bindFunc)(m_bindTarget, name);
}

GLuint SimpleBinder::getBinding(void)
{
    return getInteger(*this, m_bindingParam);
}

GLuint SimpleType::gen(void)
{
    GLuint ret;
    (this->*m_genFunc)(1, &ret);
    return ret;
}

class VertexArrayBinder : public SimpleBinder
{
public:
    VertexArrayBinder(Context &ctx) : SimpleBinder(ctx, 0, GL_NONE, GL_VERTEX_ARRAY_BINDING, true)
    {
    }
    void bind(GLuint name)
    {
        glBindVertexArray(name);
    }
};

class QueryBinder : public Binder
{
public:
    QueryBinder(Context &ctx) : Binder(ctx)
    {
    }
    void bind(GLuint name)
    {
        if (name != 0)
            glBeginQuery(GL_ANY_SAMPLES_PASSED, name);
        else
            glEndQuery(GL_ANY_SAMPLES_PASSED);
    }
    GLuint getBinding(void)
    {
        return 0;
    }
};

bool ProgramType::isDeleteFlagged(GLuint name)
{
    GLint deleteFlagged = 0;
    glGetProgramiv(name, GL_DELETE_STATUS, &deleteFlagged);
    return deleteFlagged != 0;
}

bool ShaderType::isDeleteFlagged(GLuint name)
{
    GLint deleteFlagged = 0;
    glGetShaderiv(name, GL_DELETE_STATUS, &deleteFlagged);
    return deleteFlagged != 0;
}

void setupFbo(const Context &ctx, GLuint seed, GLuint fbo)
{
    const Functions &gl = ctx.getRenderContext().getFunctions();

    GLU_CHECK_CALL_ERROR(gl.bindFramebuffer(GL_FRAMEBUFFER, fbo), gl.getError());

    if (seed == 0)
    {
        gl.clearColor(0.0, 0.0, 0.0, 1.0);
        GLU_CHECK_CALL_ERROR(gl.clear(GL_COLOR_BUFFER_BIT), gl.getError());
    }
    else
    {
        Random rnd(seed);
        const GLsizei width  = rnd.getInt(0, FRAMEBUFFER_SIZE);
        const GLsizei height = rnd.getInt(0, FRAMEBUFFER_SIZE);
        const GLint x        = rnd.getInt(0, FRAMEBUFFER_SIZE - width);
        const GLint y        = rnd.getInt(0, FRAMEBUFFER_SIZE - height);
        const GLfloat r1     = rnd.getFloat();
        const GLfloat g1     = rnd.getFloat();
        const GLfloat b1     = rnd.getFloat();
        const GLfloat a1     = rnd.getFloat();
        const GLfloat r2     = rnd.getFloat();
        const GLfloat g2     = rnd.getFloat();
        const GLfloat b2     = rnd.getFloat();
        const GLfloat a2     = rnd.getFloat();

        GLU_CHECK_CALL_ERROR(gl.clearColor(r1, g1, b1, a1), gl.getError());
        GLU_CHECK_CALL_ERROR(gl.clear(GL_COLOR_BUFFER_BIT), gl.getError());
        gl.scissor(x, y, width, height);
        gl.enable(GL_SCISSOR_TEST);
        gl.clearColor(r2, g2, b2, a2);
        gl.clear(GL_COLOR_BUFFER_BIT);
        gl.disable(GL_SCISSOR_TEST);
    }

    gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
    GLU_CHECK_ERROR(gl.getError());
}

void drawFbo(const Context &ctx, GLuint fbo, Surface &dst)
{
    const RenderContext &renderCtx = ctx.getRenderContext();
    const Functions &gl            = renderCtx.getFunctions();

    GLU_CHECK_CALL_ERROR(gl.bindFramebuffer(GL_FRAMEBUFFER, fbo), gl.getError());

    dst.setSize(FRAMEBUFFER_SIZE, FRAMEBUFFER_SIZE);
    glu::readPixels(renderCtx, 0, 0, dst.getAccess());
    GLU_EXPECT_NO_ERROR(gl.getError(), "Read pixels from framebuffer");

    GLU_CHECK_CALL_ERROR(gl.bindFramebuffer(GL_FRAMEBUFFER, 0), gl.getError());
}

GLuint getFboAttachment(const Functions &gl, GLuint fbo, GLenum requiredType)
{
    GLint type = 0, name = 0;
    gl.bindFramebuffer(GL_FRAMEBUFFER, fbo);
    GLU_CHECK_CALL_ERROR(gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                                                GL_FRAMEBUFFER_ATTACHMENT_OBJECT_TYPE, &type),
                         gl.getError());

    if (GLenum(type) != requiredType || GLenum(type) == GL_NONE)
        return 0;

    GLU_CHECK_CALL_ERROR(gl.getFramebufferAttachmentParameteriv(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                                                GL_FRAMEBUFFER_ATTACHMENT_OBJECT_NAME, &name),
                         gl.getError());
    gl.bindFramebuffer(GL_FRAMEBUFFER, 0);
    GLU_CHECK_ERROR(gl.getError());

    return name;
}

void FboAttacher::initAttachment(GLuint seed, GLuint element)
{
    Binder &binder = *getElementType().binder();
    Framebuffer fbo(getRenderContext());

    enableLogging(false);

    binder.enableLogging(false);
    binder.bind(element);
    initStorage();
    binder.bind(0);
    binder.enableLogging(true);

    attach(element, *fbo);
    setupFbo(getContext(), seed, *fbo);
    detach(element, *fbo);

    enableLogging(true);

    log() << TestLog::Message << "// Drew to " << getElementType().getName() << " " << element << " with seed " << seed
          << "." << TestLog::EndMessage;
}

void FboInputAttacher::drawContainer(GLuint fbo, Surface &dst)
{
    drawFbo(getContext(), fbo, dst);
    log() << TestLog::Message << "// Read pixels from framebuffer " << fbo << " to output image."
          << TestLog::EndMessage;
}

void FboOutputAttacher::setupContainer(GLuint seed, GLuint fbo)
{
    setupFbo(getContext(), seed, fbo);
    log() << TestLog::Message << "// Drew to framebuffer " << fbo << " with seed " << seed << "."
          << TestLog::EndMessage;
}

void FboOutputAttacher::drawAttachment(GLuint element, Surface &dst)
{
    Framebuffer fbo(getRenderContext());
    m_attacher.enableLogging(false);
    m_attacher.attach(element, *fbo);
    drawFbo(getContext(), *fbo, dst);
    m_attacher.detach(element, *fbo);
    m_attacher.enableLogging(true);
    log() << TestLog::Message << "// Read pixels from " << m_attacher.getElementType().getName() << " " << element
          << " to output image." << TestLog::EndMessage;
    GLU_CHECK_ERROR(gl().getError());
}

void TextureFboAttacher::attach(GLuint texture, GLuint fbo)
{
    GLU_CHECK_CALL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, fbo), gl().getError());
    GLU_CHECK_CALL_ERROR(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, texture, 0),
                         gl().getError());
    GLU_CHECK_CALL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, 0), gl().getError());
}

void TextureFboAttacher::detach(GLuint texture, GLuint fbo)
{
    DE_UNREF(texture);
    GLU_CHECK_CALL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, fbo), gl().getError());
    GLU_CHECK_CALL_ERROR(glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, 0, 0),
                         gl().getError());
    GLU_CHECK_CALL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, 0), gl().getError());
}

GLuint TextureFboAttacher::getAttachment(GLuint fbo)
{
    return getFboAttachment(gl(), fbo, GL_TEXTURE);
}

static bool isTextureFormatColorRenderable(const glu::RenderContext &renderCtx, const glu::TransferFormat &format)
{
    const glw::Functions &gl = renderCtx.getFunctions();
    uint32_t curFbo          = ~0u;
    uint32_t curTex          = ~0u;
    uint32_t testFbo         = 0u;
    uint32_t testTex         = 0u;
    GLenum status            = GL_NONE;

    GLU_CHECK_GLW_CALL(gl, getIntegerv(GL_FRAMEBUFFER_BINDING, (int32_t *)&curFbo));
    GLU_CHECK_GLW_CALL(gl, getIntegerv(GL_TEXTURE_BINDING_2D, (int32_t *)&curTex));

    try
    {
        GLU_CHECK_GLW_CALL(gl, genTextures(1, &testTex));
        GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, testTex));
        GLU_CHECK_GLW_CALL(gl, texImage2D(GL_TEXTURE_2D, 0, format.format, FRAMEBUFFER_SIZE, FRAMEBUFFER_SIZE, 0,
                                          format.format, format.dataType, DE_NULL));

        GLU_CHECK_GLW_CALL(gl, genFramebuffers(1, &testFbo));
        GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, testFbo));
        GLU_CHECK_GLW_CALL(gl, framebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_TEXTURE_2D, testTex, 0));

        status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
        GLU_CHECK_GLW_MSG(gl, "glCheckFramebufferStatus(GL_FRAMEBUFFER)");

        GLU_CHECK_GLW_CALL(gl, bindTexture(GL_TEXTURE_2D, curTex));
        GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, curFbo));

        GLU_CHECK_GLW_CALL(gl, deleteTextures(1, &testTex));
        GLU_CHECK_GLW_CALL(gl, deleteFramebuffers(1, &testFbo));
    }
    catch (...)
    {
        if (testTex != 0)
            gl.deleteTextures(1, &testTex);

        if (testFbo != 0)
            gl.deleteFramebuffers(1, &testFbo);

        throw;
    }

    if (status == GL_FRAMEBUFFER_COMPLETE)
        return true;
    else if (status == GL_FRAMEBUFFER_UNSUPPORTED)
        return false;
    else
        TCU_THROW(TestError, (std::string("glCheckFramebufferStatus() returned invalid result code ") +
                              de::toString(glu::getFramebufferStatusStr(status)))
                                 .c_str());
}

static glu::TransferFormat getRenderableColorTextureFormat(const glu::RenderContext &renderCtx)
{
    if (glu::contextSupports(renderCtx.getType(), glu::ApiType::es(3, 0)))
        return glu::TransferFormat(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4);

    {
        const glu::TransferFormat candidates[] = {
            glu::TransferFormat(GL_RGBA, GL_UNSIGNED_SHORT_4_4_4_4),
            glu::TransferFormat(GL_RGBA, GL_UNSIGNED_SHORT_5_5_5_1),
            glu::TransferFormat(GL_RGB, GL_UNSIGNED_SHORT_5_6_5),
            glu::TransferFormat(GL_RGBA, GL_UNSIGNED_BYTE),
        };

        for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(candidates); ++ndx)
        {
            if (isTextureFormatColorRenderable(renderCtx, candidates[ndx]))
                return candidates[ndx];
        }
    }

    return glu::TransferFormat(GL_NONE, GL_NONE);
}

void TextureFboAttacher::initStorage(void)
{
    const glu::TransferFormat format = getRenderableColorTextureFormat(getRenderContext());

    if (format.format == GL_NONE)
        TCU_THROW(NotSupportedError, "No renderable texture format found");

    GLU_CHECK_CALL_ERROR(glTexImage2D(GL_TEXTURE_2D, 0, format.format, FRAMEBUFFER_SIZE, FRAMEBUFFER_SIZE, 0,
                                      format.format, format.dataType, DE_NULL),
                         gl().getError());
}

static bool isRenderbufferFormatColorRenderable(const glu::RenderContext &renderCtx, const uint32_t format)
{
    const glw::Functions &gl = renderCtx.getFunctions();
    uint32_t curFbo          = ~0u;
    uint32_t curRbo          = ~0u;
    uint32_t testFbo         = 0u;
    uint32_t testRbo         = 0u;
    GLenum status            = GL_NONE;

    GLU_CHECK_GLW_CALL(gl, getIntegerv(GL_FRAMEBUFFER_BINDING, (int32_t *)&curFbo));
    GLU_CHECK_GLW_CALL(gl, getIntegerv(GL_RENDERBUFFER_BINDING, (int32_t *)&curRbo));

    try
    {
        GLU_CHECK_GLW_CALL(gl, genRenderbuffers(1, &testRbo));
        GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, testRbo));
        GLU_CHECK_GLW_CALL(gl, renderbufferStorage(GL_RENDERBUFFER, format, FRAMEBUFFER_SIZE, FRAMEBUFFER_SIZE));

        GLU_CHECK_GLW_CALL(gl, genFramebuffers(1, &testFbo));
        GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, testFbo));
        GLU_CHECK_GLW_CALL(gl, framebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, testRbo));

        status = gl.checkFramebufferStatus(GL_FRAMEBUFFER);
        GLU_CHECK_GLW_MSG(gl, "glCheckFramebufferStatus(GL_FRAMEBUFFER)");

        GLU_CHECK_GLW_CALL(gl, bindRenderbuffer(GL_RENDERBUFFER, curRbo));
        GLU_CHECK_GLW_CALL(gl, bindFramebuffer(GL_FRAMEBUFFER, curFbo));

        GLU_CHECK_GLW_CALL(gl, deleteRenderbuffers(1, &testRbo));
        GLU_CHECK_GLW_CALL(gl, deleteFramebuffers(1, &testFbo));
    }
    catch (...)
    {
        if (testRbo != 0)
            gl.deleteRenderbuffers(1, &testRbo);

        if (testFbo != 0)
            gl.deleteFramebuffers(1, &testFbo);

        throw;
    }

    if (status == GL_FRAMEBUFFER_COMPLETE)
        return true;
    else if (status == GL_FRAMEBUFFER_UNSUPPORTED)
        return false;
    else
        TCU_THROW(TestError, (std::string("glCheckFramebufferStatus() returned invalid result code ") +
                              de::toString(glu::getFramebufferStatusStr(status)))
                                 .c_str());
}

static uint32_t getRenderableColorRenderbufferFormat(const glu::RenderContext &renderCtx)
{
    if (glu::contextSupports(renderCtx.getType(), glu::ApiType::es(3, 0)))
        return GL_RGBA4;

    {
        const uint32_t candidates[] = {
            GL_RGBA4,
            GL_RGB5_A1,
            GL_RGB565,
        };

        for (int ndx = 0; ndx < DE_LENGTH_OF_ARRAY(candidates); ++ndx)
        {
            if (isRenderbufferFormatColorRenderable(renderCtx, candidates[ndx]))
                return candidates[ndx];
        }
    }

    return GL_NONE;
}

void RboFboAttacher::initStorage(void)
{
    const uint32_t format = getRenderableColorRenderbufferFormat(getRenderContext());

    if (format == GL_NONE)
        TCU_THROW(TestError, "No color-renderable renderbuffer format found");

    GLU_CHECK_CALL_ERROR(glRenderbufferStorage(GL_RENDERBUFFER, format, FRAMEBUFFER_SIZE, FRAMEBUFFER_SIZE),
                         gl().getError());
}

void RboFboAttacher::attach(GLuint rbo, GLuint fbo)
{
    GLU_CHECK_CALL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, fbo), gl().getError());
    GLU_CHECK_CALL_ERROR(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, rbo),
                         gl().getError());
    GLU_CHECK_CALL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, 0), gl().getError());
}

void RboFboAttacher::detach(GLuint rbo, GLuint fbo)
{
    DE_UNREF(rbo);
    GLU_CHECK_CALL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, fbo), gl().getError());
    GLU_CHECK_CALL_ERROR(glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, GL_RENDERBUFFER, 0),
                         gl().getError());
    GLU_CHECK_CALL_ERROR(glBindFramebuffer(GL_FRAMEBUFFER, 0), gl().getError());
}

GLuint RboFboAttacher::getAttachment(GLuint fbo)
{
    return getFboAttachment(gl(), fbo, GL_RENDERBUFFER);
}

static const char *const s_fragmentShaderTemplate =
    GLSL100_SRC(void main() { gl_FragColor = vec4(${RED}, ${GREEN}, ${BLUE}, 1.0); });

void ShaderProgramAttacher::initAttachment(GLuint seed, GLuint shader)
{
    using de::floatToString;
    using de::insert;

    Random rnd(seed);
    map<string, string> params;
    const StringTemplate sourceTmpl(s_fragmentShaderTemplate);

    insert(params, "RED", floatToString(rnd.getFloat(), 4));
    insert(params, "GREEN", floatToString(rnd.getFloat(), 4));
    insert(params, "BLUE", floatToString(rnd.getFloat(), 4));

    {
        const string source         = sourceTmpl.specialize(params);
        const char *const sourceStr = source.c_str();

        GLU_CHECK_CALL_ERROR(glShaderSource(shader, 1, &sourceStr, DE_NULL), gl().getError());
        GLU_CHECK_CALL_ERROR(glCompileShader(shader), gl().getError());

        {
            GLint compileStatus = 0;
            gl().getShaderiv(shader, GL_COMPILE_STATUS, &compileStatus);
            TCU_CHECK_MSG(compileStatus != 0, sourceStr);
        }
    }
}

void ShaderProgramAttacher::attach(GLuint shader, GLuint program)
{
    GLU_CHECK_CALL_ERROR(glAttachShader(program, shader), gl().getError());
}

void ShaderProgramAttacher::detach(GLuint shader, GLuint program)
{
    GLU_CHECK_CALL_ERROR(glDetachShader(program, shader), gl().getError());
}

GLuint ShaderProgramAttacher::getAttachment(GLuint program)
{
    GLuint shaders[2]        = {0, 0};
    const GLsizei shadersLen = DE_LENGTH_OF_ARRAY(shaders);
    GLsizei numShaders       = 0;
    GLuint ret               = 0;

    gl().getAttachedShaders(program, shadersLen, &numShaders, shaders);

    // There should ever be at most one attached shader in normal use, but if
    // something is wrong, the temporary vertex shader might not have been
    // detached properly, so let's find the fragment shader explicitly.
    for (int ndx = 0; ndx < de::min<GLsizei>(shadersLen, numShaders); ++ndx)
    {
        GLint shaderType = GL_NONE;
        gl().getShaderiv(shaders[ndx], GL_SHADER_TYPE, &shaderType);

        if (shaderType == GL_FRAGMENT_SHADER)
        {
            ret = shaders[ndx];
            break;
        }
    }

    return ret;
}

void setViewport(const RenderContext &renderCtx, const Rectangle &rect)
{
    renderCtx.getFunctions().viewport(rect.x, rect.y, rect.width, rect.height);
}

void readRectangle(const RenderContext &renderCtx, const Rectangle &rect, Surface &dst)
{
    dst.setSize(rect.width, rect.height);
    glu::readPixels(renderCtx, rect.x, rect.y, dst.getAccess());
}

Rectangle randomViewport(const RenderContext &ctx, GLint maxWidth, GLint maxHeight, Random &rnd)
{
    const RenderTarget &target = ctx.getRenderTarget();
    const GLint width          = de::min(target.getWidth(), maxWidth);
    const GLint xOff           = rnd.getInt(0, target.getWidth() - width);
    const GLint height         = de::min(target.getHeight(), maxHeight);
    const GLint yOff           = rnd.getInt(0, target.getHeight() - height);

    return Rectangle(xOff, yOff, width, height);
}

void ShaderProgramInputAttacher::drawContainer(GLuint program, Surface &dst)
{
    static const float s_vertices[6] = {-1.0, 0.0, 1.0, 1.0, 0.0, -1.0};
    Random rnd(program);
    CheckedShader vtxShader(getRenderContext(), SHADERTYPE_VERTEX, s_vertexShaderSrc);
    const Rectangle viewport = randomViewport(getRenderContext(), VIEWPORT_SIZE, VIEWPORT_SIZE, rnd);

    gl().attachShader(program, vtxShader.getShader());
    gl().linkProgram(program);

    {
        GLint linkStatus = 0;
        gl().getProgramiv(program, GL_LINK_STATUS, &linkStatus);
        TCU_CHECK(linkStatus != 0);
    }

    log() << TestLog::Message << "// Attached a temporary vertex shader and linked program " << program
          << TestLog::EndMessage;

    setViewport(getRenderContext(), viewport);
    log() << TestLog::Message << "// Positioned viewport randomly" << TestLog::EndMessage;

    glUseProgram(program);
    {
        GLint posLoc = gl().getAttribLocation(program, "pos");
        TCU_CHECK(posLoc >= 0);

        gl().enableVertexAttribArray(posLoc);

        gl().clearColor(0, 0, 0, 1);
        gl().clear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
        gl().vertexAttribPointer(posLoc, 2, GL_FLOAT, GL_FALSE, 0, s_vertices);
        gl().drawArrays(GL_TRIANGLES, 0, 3);

        gl().disableVertexAttribArray(posLoc);
        log() << TestLog::Message << "// Drew a fixed triangle" << TestLog::EndMessage;
    }
    glUseProgram(0);

    readRectangle(getRenderContext(), viewport, dst);
    log() << TestLog::Message << "// Copied viewport to output image" << TestLog::EndMessage;

    gl().detachShader(program, vtxShader.getShader());
    log() << TestLog::Message << "// Removed temporary vertex shader" << TestLog::EndMessage;
}

ES2Types::ES2Types(const Context &ctx)
    : Types(ctx)
    , m_bufferBind(ctx, &CallLogWrapper::glBindBuffer, GL_ARRAY_BUFFER, GL_ARRAY_BUFFER_BINDING)
    , m_bufferType(ctx, "buffer", &CallLogWrapper::glGenBuffers, &CallLogWrapper::glDeleteBuffers,
                   &CallLogWrapper::glIsBuffer, &m_bufferBind)
    , m_textureBind(ctx, &CallLogWrapper::glBindTexture, GL_TEXTURE_2D, GL_TEXTURE_BINDING_2D)
    , m_textureType(ctx, "texture", &CallLogWrapper::glGenTextures, &CallLogWrapper::glDeleteTextures,
                    &CallLogWrapper::glIsTexture, &m_textureBind)
    , m_rboBind(ctx, &CallLogWrapper::glBindRenderbuffer, GL_RENDERBUFFER, GL_RENDERBUFFER_BINDING)
    , m_rboType(ctx, "renderbuffer", &CallLogWrapper::glGenRenderbuffers, &CallLogWrapper::glDeleteRenderbuffers,
                &CallLogWrapper::glIsRenderbuffer, &m_rboBind)
    , m_fboBind(ctx, &CallLogWrapper::glBindFramebuffer, GL_FRAMEBUFFER, GL_FRAMEBUFFER_BINDING)
    , m_fboType(ctx, "framebuffer", &CallLogWrapper::glGenFramebuffers, &CallLogWrapper::glDeleteFramebuffers,
                &CallLogWrapper::glIsFramebuffer, &m_fboBind)
    , m_shaderType(ctx)
    , m_programType(ctx)
    , m_texFboAtt(ctx, m_textureType, m_fboType)
    , m_texFboInAtt(m_texFboAtt)
    , m_texFboOutAtt(m_texFboAtt)
    , m_rboFboAtt(ctx, m_rboType, m_fboType)
    , m_rboFboInAtt(m_rboFboAtt)
    , m_rboFboOutAtt(m_rboFboAtt)
    , m_shaderAtt(ctx, m_shaderType, m_programType)
    , m_shaderInAtt(m_shaderAtt)
{
    Type *const types[] = {&m_bufferType, &m_textureType, &m_rboType, &m_fboType, &m_shaderType, &m_programType};
    m_types.insert(m_types.end(), DE_ARRAY_BEGIN(types), DE_ARRAY_END(types));

    m_attachers.push_back(&m_texFboAtt);
    m_attachers.push_back(&m_rboFboAtt);
    m_attachers.push_back(&m_shaderAtt);

    m_inAttachers.push_back(&m_texFboInAtt);
    m_inAttachers.push_back(&m_rboFboInAtt);
    m_inAttachers.push_back(&m_shaderInAtt);

    m_outAttachers.push_back(&m_texFboOutAtt);
    m_outAttachers.push_back(&m_rboFboOutAtt);
}

class Name
{
public:
    Name(Type &type) : m_type(type), m_name(type.gen())
    {
    }
    Name(Type &type, GLuint name) : m_type(type), m_name(name)
    {
    }
    ~Name(void)
    {
        m_type.release(m_name);
    }
    GLuint operator*(void) const
    {
        return m_name;
    }

private:
    Type &m_type;
    const GLuint m_name;
};

class ResultCollector
{
public:
    ResultCollector(TestContext &testCtx);
    bool check(bool cond, const char *msg);
    void fail(const char *msg);
    void warn(const char *msg);
    ~ResultCollector(void);

private:
    void addResult(qpTestResult result, const char *msg);

    TestContext &m_testCtx;
    TestLog &m_log;
    qpTestResult m_result;
    const char *m_message;
};

ResultCollector::ResultCollector(TestContext &testCtx)
    : m_testCtx(testCtx)
    , m_log(testCtx.getLog())
    , m_result(QP_TEST_RESULT_PASS)
    , m_message("Pass")
{
}

bool ResultCollector::check(bool cond, const char *msg)
{
    if (!cond)
        fail(msg);
    return cond;
}

void ResultCollector::addResult(qpTestResult result, const char *msg)
{
    m_log << TestLog::Message << "// Fail: " << msg << TestLog::EndMessage;
    if (m_result == QP_TEST_RESULT_PASS)
    {
        m_result  = result;
        m_message = msg;
    }
    else
    {
        if (result == QP_TEST_RESULT_FAIL)
            m_result = result;
        m_message = "Multiple problems, see log for details";
    }
}

void ResultCollector::fail(const char *msg)
{
    addResult(QP_TEST_RESULT_FAIL, msg);
}

void ResultCollector::warn(const char *msg)
{
    addResult(QP_TEST_RESULT_QUALITY_WARNING, msg);
}

ResultCollector::~ResultCollector(void)
{
    m_testCtx.setTestResult(m_result, m_message);
}

class TestBase : public TestCase, protected CallLogWrapper
{
protected:
    TestBase(const char *name, const char *description, const Context &ctx);

    // Copy ContextWrapper since MI (except for CallLogWrapper) is a no-no.
    const Context &getContext(void) const
    {
        return m_ctx;
    }
    const RenderContext &getRenderContext(void) const
    {
        return m_ctx.getRenderContext();
    }
    const Functions &gl(void) const
    {
        return m_ctx.gl();
    }
    TestLog &log(void) const
    {
        return m_ctx.log();
    }
    void init(void);

    Context m_ctx;
    Random m_rnd;
};

TestBase::TestBase(const char *name, const char *description, const Context &ctx)
    : TestCase(ctx.getTestContext(), name, description)
    , CallLogWrapper(ctx.gl(), ctx.log())
    , m_ctx(ctx)
    , m_rnd(deStringHash(name))
{
    enableLogging(true);
}

void TestBase::init(void)
{
    m_rnd = Random(deStringHash(getName()));
}

class LifeTest : public TestBase
{
public:
    typedef void (LifeTest::*TestFunction)(void);

    LifeTest(const char *name, const char *description, Type &type, TestFunction test)
        : TestBase(name, description, type.getContext())
        , m_type(type)
        , m_test(test)
    {
    }

    IterateResult iterate(void);

    void testGen(void);
    void testDelete(void);
    void testBind(void);
    void testDeleteBound(void);
    void testBindNoGen(void);
    void testDeleteUsed(void);

private:
    Binder &binder(void)
    {
        return *m_type.binder();
    }

    Type &m_type;
    TestFunction m_test;
};

IterateResult LifeTest::iterate(void)
{
    (this->*m_test)();
    return STOP;
}

void LifeTest::testGen(void)
{
    ResultCollector errors(getTestContext());
    Name name(m_type);

    if (m_type.genCreates())
        errors.check(m_type.exists(*name), "Gen* should have created an object, but didn't");
    else
        errors.check(!m_type.exists(*name), "Gen* should not have created an object, but did");
}

void LifeTest::testDelete(void)
{
    ResultCollector errors(getTestContext());
    GLuint name = m_type.gen();

    m_type.release(name);
    errors.check(!m_type.exists(name), "Object still exists after deletion");
}

void LifeTest::testBind(void)
{
    ResultCollector errors(getTestContext());
    Name name(m_type);

    binder().bind(*name);
    GLU_EXPECT_NO_ERROR(gl().getError(), "Bind failed");
    errors.check(m_type.exists(*name), "Object does not exist after binding");
    binder().bind(0);
}

void LifeTest::testDeleteBound(void)
{
    const GLuint id = m_type.gen();
    ResultCollector errors(getTestContext());

    binder().bind(id);
    m_type.release(id);

    if (m_type.nameLingers())
    {
        errors.check(gl().getError() == GL_NO_ERROR, "Deleting bound object failed");
        errors.check(binder().getBinding() == id, "Deleting bound object did not retain binding");
        errors.check(m_type.exists(id), "Deleting bound object made its name invalid");
        errors.check(m_type.isDeleteFlagged(id), "Deleting bound object did not flag the object for deletion");
        binder().bind(0);
    }
    else
    {
        errors.check(gl().getError() == GL_NO_ERROR, "Deleting bound object failed");
        errors.check(binder().getBinding() == 0, "Deleting bound object did not remove binding");
        errors.check(!m_type.exists(id), "Deleting bound object did not make its name invalid");
        binder().bind(0);
    }

    errors.check(binder().getBinding() == 0, "Unbinding didn't remove binding");
    errors.check(!m_type.exists(id), "Name is still valid after deleting and unbinding");
}

void LifeTest::testBindNoGen(void)
{
    ResultCollector errors(getTestContext());
    const GLuint id = m_rnd.getUint32();

    if (!errors.check(!m_type.exists(id), "Randomly chosen identifier already exists"))
        return;

    Name name(m_type, id);
    binder().bind(*name);

    if (binder().genRequired())
    {
        errors.check(glGetError() == GL_INVALID_OPERATION,
                     "Did not fail when binding a name not generated by Gen* call");
        errors.check(!m_type.exists(*name), "Bind* created an object for a name not generated by a Gen* call");
    }
    else
    {
        errors.check(glGetError() == GL_NO_ERROR, "Failed when binding a name not generated by Gen* call");
        errors.check(m_type.exists(*name), "Object was not created by the Bind* call");
    }
}

void LifeTest::testDeleteUsed(void)
{
    ResultCollector errors(getTestContext());
    GLuint programId = 0;

    {
        CheckedShader vtxShader(getRenderContext(), SHADERTYPE_VERTEX, s_vertexShaderSrc);
        CheckedShader fragShader(getRenderContext(), SHADERTYPE_FRAGMENT, s_fragmentShaderSrc);
        CheckedProgram program(getRenderContext(), vtxShader.getShader(), fragShader.getShader());

        programId = program.getProgram();

        log() << TestLog::Message << "// Created and linked program " << programId << TestLog::EndMessage;
        GLU_CHECK_CALL_ERROR(glUseProgram(programId), gl().getError());

        log() << TestLog::Message << "// Deleted program " << programId << TestLog::EndMessage;
    }
    TCU_CHECK(glIsProgram(programId));
    {
        GLint deleteFlagged = 0;
        glGetProgramiv(programId, GL_DELETE_STATUS, &deleteFlagged);
        errors.check(deleteFlagged != 0, "Program object was not flagged as deleted");
    }
    GLU_CHECK_CALL_ERROR(glUseProgram(0), gl().getError());
    errors.check(!gl().isProgram(programId), "Deleted program name still valid after being made non-current");
}

class AttachmentTest : public TestBase
{
public:
    typedef void (AttachmentTest::*TestFunction)(void);
    AttachmentTest(const char *name, const char *description, Attacher &attacher, TestFunction test)
        : TestBase(name, description, attacher.getContext())
        , m_attacher(attacher)
        , m_test(test)
    {
    }
    IterateResult iterate(void);

    void testDeletedNames(void);
    void testDeletedBinding(void);
    void testDeletedReattach(void);

private:
    Attacher &m_attacher;
    const TestFunction m_test;
};

IterateResult AttachmentTest::iterate(void)
{
    (this->*m_test)();
    return STOP;
}

GLuint getAttachment(Attacher &attacher, GLuint container)
{
    const GLuint queriedAttachment = attacher.getAttachment(container);
    attacher.log() << TestLog::Message << "// Result of query for " << attacher.getElementType().getName()
                   << " attached to " << attacher.getContainerType().getName() << " " << container << ": "
                   << queriedAttachment << "." << TestLog::EndMessage;
    return queriedAttachment;
}

void AttachmentTest::testDeletedNames(void)
{
    Type &elemType      = m_attacher.getElementType();
    Type &containerType = m_attacher.getContainerType();
    Name container(containerType);
    ResultCollector errors(getTestContext());
    GLuint elementId = 0;

    {
        Name element(elemType);
        elementId = *element;
        m_attacher.initAttachment(0, *element);
        m_attacher.attach(*element, *container);
        errors.check(getAttachment(m_attacher, *container) == elementId,
                     "Attachment name not returned by query even before deletion.");
    }

    // "Such a container or other context may continue using the object, and
    // may still contain state identifying its name as being currently bound"
    //
    // We here interpret "may" to mean that whenever the container has a
    // deleted object attached to it, a query will return that object's former
    // name.
    errors.check(getAttachment(m_attacher, *container) == elementId,
                 "Attachment name not returned by query after attachment was deleted.");

    if (elemType.nameLingers())
        errors.check(elemType.exists(elementId), "Attached object name no longer valid after deletion.");
    else
        errors.check(!elemType.exists(elementId), "Attached object name still valid after deletion.");

    m_attacher.detach(elementId, *container);
    errors.check(getAttachment(m_attacher, *container) == 0,
                 "Attachment name returned by query even after detachment.");
    errors.check(!elemType.exists(elementId), "Deleted attached object name still usable after detachment.");
}

class InputAttachmentTest : public TestBase
{
public:
    InputAttachmentTest(const char *name, const char *description, InputAttacher &inputAttacher)
        : TestBase(name, description, inputAttacher.getContext())
        , m_inputAttacher(inputAttacher)
    {
    }

    IterateResult iterate(void);

private:
    InputAttacher &m_inputAttacher;
};

GLuint replaceName(Type &type, GLuint oldName, TestLog &log)
{
    const Binder *const binder = type.binder();
    const bool genRequired     = binder == DE_NULL || binder->genRequired();

    if (genRequired)
        return type.gen();

    log << TestLog::Message << "// Type does not require Gen* for binding, reusing old id " << oldName << "."
        << TestLog::EndMessage;

    return oldName;
}

IterateResult InputAttachmentTest::iterate(void)
{
    Attacher &attacher  = m_inputAttacher.getAttacher();
    Type &containerType = attacher.getContainerType();
    Type &elementType   = attacher.getElementType();
    Name container(containerType);
    GLuint elementId     = 0;
    const GLuint refSeed = m_rnd.getUint32();
    const GLuint newSeed = m_rnd.getUint32();
    ResultCollector errors(getTestContext());

    Surface refSurface; // Surface from drawing with refSeed-seeded attachment
    Surface delSurface; // Surface from drawing with deleted refSeed attachment
    Surface newSurface; // Surface from drawing with newSeed-seeded attachment

    log() << TestLog::Message << "Testing if writing to a newly created object modifies a deleted attachment"
          << TestLog::EndMessage;

    {
        ScopedLogSection section(log(), "Write to original", "Writing to an original attachment");
        const Name element(elementType);

        elementId = *element;
        attacher.initAttachment(refSeed, elementId);
        attacher.attach(elementId, *container);
        m_inputAttacher.drawContainer(*container, refSurface);
        // element gets deleted here
        log() << TestLog::Message << "// Deleting attachment";
    }
    {
        ScopedLogSection section(log(), "Write to new", "Writing to a new attachment after deleting the original");
        const GLuint newId = replaceName(elementType, elementId, log());
        const Name newElement(elementType, newId);

        attacher.initAttachment(newSeed, newId);

        m_inputAttacher.drawContainer(*container, delSurface);
        attacher.detach(elementId, *container);

        attacher.attach(newId, *container);
        m_inputAttacher.drawContainer(*container, newSurface);
        attacher.detach(newId, *container);
    }
    {
        const bool surfacesMatch =
            tcu::pixelThresholdCompare(log(), "Reading from deleted",
                                       "Comparison result from reading from a container with a deleted attachment "
                                       "before and after writing to a fresh object.",
                                       refSurface, delSurface, RGBA(0, 0, 0, 0), tcu::COMPARE_LOG_RESULT);

        errors.check(surfacesMatch, "Writing to a fresh object modified the container with a deleted attachment.");

        if (!surfacesMatch)
            log() << TestLog::Image("New attachment", "Container state after attached to the fresh object", newSurface);
    }

    return STOP;
}

class OutputAttachmentTest : public TestBase
{
public:
    OutputAttachmentTest(const char *name, const char *description, OutputAttacher &outputAttacher)
        : TestBase(name, description, outputAttacher.getContext())
        , m_outputAttacher(outputAttacher)
    {
    }
    IterateResult iterate(void);

private:
    OutputAttacher &m_outputAttacher;
};

IterateResult OutputAttachmentTest::iterate(void)
{
    Attacher &attacher  = m_outputAttacher.getAttacher();
    Type &containerType = attacher.getContainerType();
    Type &elementType   = attacher.getElementType();
    Name container(containerType);
    GLuint elementId     = 0;
    const GLuint refSeed = m_rnd.getUint32();
    const GLuint newSeed = m_rnd.getUint32();
    ResultCollector errors(getTestContext());
    Surface refSurface; // Surface drawn from attachment to refSeed container
    Surface newSurface; // Surface drawn from attachment to newSeed container
    Surface delSurface; // Like newSurface, after writing to a deleted attachment

    log() << TestLog::Message << "Testing if writing to a container with a deleted attachment "
          << "modifies a newly created object" << TestLog::EndMessage;

    {
        ScopedLogSection section(log(), "Write to existing", "Writing to a container with an existing attachment");
        const Name element(elementType);

        elementId = *element;
        attacher.initAttachment(0, elementId);
        attacher.attach(elementId, *container);

        // For reference purposes, make note of what refSeed looks like.
        m_outputAttacher.setupContainer(refSeed, *container);
        m_outputAttacher.drawAttachment(elementId, refSurface);
    }
    {
        ScopedLogSection section(log(), "Write to deleted", "Writing to a container after deletion of attachment");
        const GLuint newId = replaceName(elementType, elementId, log());
        const Name newElement(elementType, newId);

        log() << TestLog::Message << "Creating a new object " << newId << TestLog::EndMessage;

        log() << TestLog::Message << "Recording state of new object before writing to container" << TestLog::EndMessage;
        attacher.initAttachment(newSeed, newId);
        m_outputAttacher.drawAttachment(newId, newSurface);

        log() << TestLog::Message << "Writing to container" << TestLog::EndMessage;

        // Now re-write refSeed to the container.
        m_outputAttacher.setupContainer(refSeed, *container);
        // Does it affect the newly created attachment object?
        m_outputAttacher.drawAttachment(newId, delSurface);
    }
    attacher.detach(elementId, *container);

    const bool surfacesMatch =
        tcu::pixelThresholdCompare(log(), "Writing to deleted",
                                   "Comparison result from reading from a fresh object before and after "
                                   "writing to a container with a deleted attachment",
                                   newSurface, delSurface, RGBA(0, 0, 0, 0), tcu::COMPARE_LOG_RESULT);

    errors.check(surfacesMatch, "Writing to container with deleted attachment modified a new object.");

    if (!surfacesMatch)
        log() << TestLog::Image("Original attachment",
                                "Result of container modification on original attachment before deletion.", refSurface);
    return STOP;
}

struct LifeTestSpec
{
    const char *name;
    LifeTest::TestFunction func;
    bool needBind;
};

MovePtr<TestCaseGroup> createLifeTestGroup(TestContext &testCtx, const LifeTestSpec &spec, const vector<Type *> &types)
{
    MovePtr<TestCaseGroup> group(new TestCaseGroup(testCtx, spec.name, spec.name));

    for (vector<Type *>::const_iterator it = types.begin(); it != types.end(); ++it)
    {
        Type &type       = **it;
        const char *name = type.getName();
        if (!spec.needBind || type.binder() != DE_NULL)
            group->addChild(new LifeTest(name, name, type, spec.func));
    }

    return group;
}

static const LifeTestSpec s_lifeTests[] = {
    {"gen", &LifeTest::testGen, false},
    {"delete", &LifeTest::testDelete, false},
    {"bind", &LifeTest::testBind, true},
    {"delete_bound", &LifeTest::testDeleteBound, true},
    {"bind_no_gen", &LifeTest::testBindNoGen, true},
};

string attacherName(Attacher &attacher)
{
    ostringstream os;
    os << attacher.getElementType().getName() << "_" << attacher.getContainerType().getName();
    return os.str();
}

void addTestCases(TestCaseGroup &group, Types &types)
{
    TestContext &testCtx = types.getTestContext();

    for (const LifeTestSpec *it = DE_ARRAY_BEGIN(s_lifeTests); it != DE_ARRAY_END(s_lifeTests); ++it)
        group.addChild(createLifeTestGroup(testCtx, *it, types.getTypes()).release());

    {
        TestCaseGroup *const delUsedGroup = new TestCaseGroup(testCtx, "delete_used", "Delete current program");
        group.addChild(delUsedGroup);

        delUsedGroup->addChild(new LifeTest("program", "program", types.getProgramType(), &LifeTest::testDeleteUsed));
    }

    {
        TestCaseGroup *const attGroup = new TestCaseGroup(testCtx, "attach", "Attachment tests");
        group.addChild(attGroup);

        {
            TestCaseGroup *const nameGroup = new TestCaseGroup(testCtx, "deleted_name", "Name of deleted attachment");
            attGroup->addChild(nameGroup);

            const vector<Attacher *> &atts = types.getAttachers();
            for (vector<Attacher *>::const_iterator it = atts.begin(); it != atts.end(); ++it)
            {
                const string name = attacherName(**it);
                nameGroup->addChild(
                    new AttachmentTest(name.c_str(), name.c_str(), **it, &AttachmentTest::testDeletedNames));
            }
        }
        {
            TestCaseGroup *inputGroup = new TestCaseGroup(testCtx, "deleted_input", "Input from deleted attachment");
            attGroup->addChild(inputGroup);

            const vector<InputAttacher *> &inAtts = types.getInputAttachers();
            for (vector<InputAttacher *>::const_iterator it = inAtts.begin(); it != inAtts.end(); ++it)
            {
                const string name = attacherName((*it)->getAttacher());
                inputGroup->addChild(new InputAttachmentTest(name.c_str(), name.c_str(), **it));
            }
        }
        {
            TestCaseGroup *outputGroup = new TestCaseGroup(testCtx, "deleted_output", "Output to deleted attachment");
            attGroup->addChild(outputGroup);

            const vector<OutputAttacher *> &outAtts = types.getOutputAttachers();
            for (vector<OutputAttacher *>::const_iterator it = outAtts.begin(); it != outAtts.end(); ++it)
            {
                string name = attacherName((*it)->getAttacher());
                outputGroup->addChild(new OutputAttachmentTest(name.c_str(), name.c_str(), **it));
            }
        }
    }
}

} // namespace details
} // namespace LifetimeTests
} // namespace gls
} // namespace deqp
