/*-------------------------------------------------------------------------
 * 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 Parametrized, long-running stress case.
 *
 * \todo [2013-06-27 nuutti] Do certain things in a cleaner and less
 *                             confusing way, such as the "redundant buffer
 *                             factor" thing in LongStressCase.
 *//*--------------------------------------------------------------------*/

#include "glsLongStressCase.hpp"
#include "tcuTestLog.hpp"
#include "tcuCommandLine.hpp"
#include "tcuTextureUtil.hpp"
#include "tcuVector.hpp"
#include "tcuVectorUtil.hpp"
#include "glsTextureTestUtil.hpp"
#include "gluPixelTransfer.hpp"
#include "gluTextureUtil.hpp"
#include "tcuStringTemplate.hpp"
#include "gluStrUtil.hpp"
#include "gluShaderProgram.hpp"
#include "deRandom.hpp"
#include "deStringUtil.hpp"
#include "deString.h"
#include "deSharedPtr.hpp"
#include "deClock.h"

#include "glw.h"

#include <limits>
#include <vector>
#include <iomanip>
#include <map>
#include <iomanip>

using de::Random;
using de::SharedPtr;
using de::toString;
using tcu::ConstPixelBufferAccess;
using tcu::CubeFace;
using tcu::IVec2;
using tcu::IVec3;
using tcu::IVec4;
using tcu::TestLog;
using tcu::TextureFormat;
using tcu::TextureLevel;
using tcu::Vec2;
using tcu::Vec3;
using tcu::Vec4;

using std::map;
using std::string;
using std::vector;

namespace deqp
{
namespace gls
{

using glu::TextureTestUtil::TextureType;
using glu::TextureTestUtil::TEXTURETYPE_2D;
using glu::TextureTestUtil::TEXTURETYPE_CUBE;

static const float Mi = (float)(1 << 20);

static const uint32_t bufferUsages[] = {GL_STATIC_DRAW, GL_STREAM_DRAW, GL_DYNAMIC_DRAW,

                                        GL_STATIC_READ, GL_STREAM_READ, GL_DYNAMIC_READ,

                                        GL_STATIC_COPY, GL_STREAM_COPY, GL_DYNAMIC_COPY};

static const uint32_t bufferUsagesGLES2[] = {GL_STATIC_DRAW, GL_DYNAMIC_DRAW, GL_STREAM_DRAW};

static const uint32_t bufferTargets[] = {GL_ARRAY_BUFFER,        GL_ELEMENT_ARRAY_BUFFER,

                                         GL_COPY_READ_BUFFER,    GL_COPY_WRITE_BUFFER,         GL_PIXEL_PACK_BUFFER,
                                         GL_PIXEL_UNPACK_BUFFER, GL_TRANSFORM_FEEDBACK_BUFFER, GL_UNIFORM_BUFFER};

static const uint32_t bufferTargetsGLES2[] = {GL_ARRAY_BUFFER, GL_ELEMENT_ARRAY_BUFFER};

static inline int computePixelStore(const TextureFormat &format)
{
    const int pixelSize = format.getPixelSize();
    if (deIsPowerOfTwo32(pixelSize))
        return de::min(pixelSize, 8);
    else
        return 1;
}

static inline int getNumIterations(const tcu::TestContext &testCtx, const int defaultNumIterations)
{
    const int cmdLineVal = testCtx.getCommandLine().getTestIterationCount();
    return cmdLineVal == 0 ? defaultNumIterations : cmdLineVal;
}

static inline float triangleArea(const Vec2 &a, const Vec2 &b, const Vec2 &c)
{
    const Vec2 ab = b - a;
    const Vec2 ac = c - a;
    return 0.5f * tcu::length(ab.x() * ac.y() - ab.y() * ac.x());
}

static inline string mangleShaderNames(const string &source, const string &manglingSuffix)
{
    map<string, string> m;
    m["NS"] = manglingSuffix;
    return tcu::StringTemplate(source.c_str()).specialize(m);
}

template <typename T, int N>
static inline T randomChoose(Random &rnd, const T (&arr)[N])
{
    return rnd.choose<T>(DE_ARRAY_BEGIN(arr), DE_ARRAY_END(arr));
}

static inline int nextDivisible(const int x, const int div)
{
    DE_ASSERT(x >= 0);
    DE_ASSERT(div >= 1);
    return x == 0 ? 0 : x - 1 + div - (x - 1) % div;
}

static inline string getTimeStr(const uint64_t seconds)
{
    const uint64_t m = seconds / 60;
    const uint64_t h = m / 60;
    const uint64_t d = h / 24;
    std::ostringstream res;

    res << d << "d " << h % 24 << "h " << m % 60 << "m " << seconds % 60 << "s";
    return res.str();
}

static inline string probabilityStr(const float prob)
{
    return prob == 0.0f ? "never" : prob == 1.0f ? "ALWAYS" : de::floatToString(prob * 100.0f, 0) + "%";
}

static inline uint32_t randomBufferTarget(Random &rnd, const bool isGLES3)
{
    return isGLES3 ? randomChoose(rnd, bufferTargets) : randomChoose(rnd, bufferTargetsGLES2);
}

static inline uint32_t randomBufferUsage(Random &rnd, const bool isGLES3)
{
    return isGLES3 ? randomChoose(rnd, bufferUsages) : randomChoose(rnd, bufferUsagesGLES2);
}

static inline uint32_t cubeFaceToGLFace(tcu::CubeFace face)
{
    switch (face)
    {
    case tcu::CUBEFACE_NEGATIVE_X:
        return GL_TEXTURE_CUBE_MAP_NEGATIVE_X;
    case tcu::CUBEFACE_POSITIVE_X:
        return GL_TEXTURE_CUBE_MAP_POSITIVE_X;
    case tcu::CUBEFACE_NEGATIVE_Y:
        return GL_TEXTURE_CUBE_MAP_NEGATIVE_Y;
    case tcu::CUBEFACE_POSITIVE_Y:
        return GL_TEXTURE_CUBE_MAP_POSITIVE_Y;
    case tcu::CUBEFACE_NEGATIVE_Z:
        return GL_TEXTURE_CUBE_MAP_NEGATIVE_Z;
    case tcu::CUBEFACE_POSITIVE_Z:
        return GL_TEXTURE_CUBE_MAP_POSITIVE_Z;
    default:
        DE_ASSERT(false);
        return GL_NONE;
    }
}

#if defined(DE_DEBUG)
static inline bool isMatchingGLInternalFormat(const uint32_t internalFormat, const TextureFormat &texFormat)
{
    switch (internalFormat)
    {
        // Unsized formats.

    case GL_RGBA:
        return texFormat.order == TextureFormat::RGBA &&
               (texFormat.type == TextureFormat::UNORM_INT8 || texFormat.type == TextureFormat::UNORM_SHORT_4444 ||
                texFormat.type == TextureFormat::UNORM_SHORT_5551);

    case GL_RGB:
        return texFormat.order == TextureFormat::RGB &&
               (texFormat.type == TextureFormat::UNORM_INT8 || texFormat.type == TextureFormat::UNORM_SHORT_565);

    case GL_LUMINANCE_ALPHA:
        return texFormat.order == TextureFormat::LA && texFormat.type == TextureFormat::UNORM_INT8;
    case GL_LUMINANCE:
        return texFormat.order == TextureFormat::L && texFormat.type == TextureFormat::UNORM_INT8;
    case GL_ALPHA:
        return texFormat.order == TextureFormat::A && texFormat.type == TextureFormat::UNORM_INT8;

        // Sized formats.

    default:
        return glu::mapGLInternalFormat(internalFormat) == texFormat;
    }
}
#endif // DE_DEBUG

static inline bool compileShader(const uint32_t shaderGL)
{
    glCompileShader(shaderGL);

    int success = GL_FALSE;
    glGetShaderiv(shaderGL, GL_COMPILE_STATUS, &success);

    return success == GL_TRUE;
}

static inline bool linkProgram(const uint32_t programGL)
{
    glLinkProgram(programGL);

    int success = GL_FALSE;
    glGetProgramiv(programGL, GL_LINK_STATUS, &success);

    return success == GL_TRUE;
}

static inline string getShaderInfoLog(const uint32_t shaderGL)
{
    int infoLogLen = 0;
    vector<char> infoLog;
    glGetShaderiv(shaderGL, GL_INFO_LOG_LENGTH, &infoLogLen);
    infoLog.resize(infoLogLen + 1);
    glGetShaderInfoLog(shaderGL, (int)infoLog.size(), DE_NULL, &infoLog[0]);
    return &infoLog[0];
}

static inline string getProgramInfoLog(const uint32_t programGL)
{
    int infoLogLen = 0;
    vector<char> infoLog;
    glGetProgramiv(programGL, GL_INFO_LOG_LENGTH, &infoLogLen);
    infoLog.resize(infoLogLen + 1);
    glGetProgramInfoLog(programGL, (int)infoLog.size(), DE_NULL, &infoLog[0]);
    return &infoLog[0];
}

namespace LongStressCaseInternal
{

// A hacky-ish class for drawing text on screen as GL quads.
class DebugInfoRenderer
{
public:
    DebugInfoRenderer(const glu::RenderContext &ctx);
    ~DebugInfoRenderer(void)
    {
        delete m_prog;
    }

    void drawInfo(uint64_t secondsElapsed, int texMem, int maxTexMem, int bufMem, int maxBufMem, int iterNdx);

private:
    DebugInfoRenderer(const DebugInfoRenderer &);
    DebugInfoRenderer &operator=(const DebugInfoRenderer &);

    void render(void);
    void addTextToBuffer(const string &text, int yOffset);

    const glu::RenderContext &m_ctx;
    const glu::ShaderProgram *m_prog;
    vector<float> m_posBuf;
    vector<uint16_t> m_ndxBuf;
};

void DebugInfoRenderer::drawInfo(const uint64_t secondsElapsed, const int texMem, const int maxTexMem, const int bufMem,
                                 const int maxBufMem, const int iterNdx)
{
    const uint64_t m = secondsElapsed / 60;
    const uint64_t h = m / 60;
    const uint64_t d = h / 24;

    {
        std::ostringstream text;

        text << std::setw(2) << std::setfill('0') << d << ":" << std::setw(2) << std::setfill('0') << h % 24 << ":"
             << std::setw(2) << std::setfill('0') << m % 60 << ":" << std::setw(2) << std::setfill('0')
             << secondsElapsed % 60;
        addTextToBuffer(text.str(), 0);
        text.str("");

        text << std::fixed << std::setprecision(2) << (float)texMem / Mi << "/" << (float)maxTexMem / Mi;
        addTextToBuffer(text.str(), 1);
        text.str("");

        text << std::fixed << std::setprecision(2) << (float)bufMem / Mi << "/" << (float)maxBufMem / Mi;
        addTextToBuffer(text.str(), 2);
        text.str("");

        text << std::setw(0) << iterNdx;
        addTextToBuffer(text.str(), 3);
    }

    render();
}

DebugInfoRenderer::DebugInfoRenderer(const glu::RenderContext &ctx) : m_ctx(ctx), m_prog(DE_NULL)
{
    DE_ASSERT(!m_prog);
    m_prog = new glu::ShaderProgram(ctx, glu::makeVtxFragSources("attribute highp vec2 a_pos;\n"
                                                                 "void main (void)\n"
                                                                 "{\n"
                                                                 "    gl_Position = vec4(a_pos, -1.0, 1.0);\n"
                                                                 "}\n",

                                                                 "void main(void)\n"
                                                                 "{\n"
                                                                 "    gl_FragColor = vec4(1.0, 0.0, 0.0, 1.0);\n"
                                                                 "}\n"));
}

void DebugInfoRenderer::addTextToBuffer(const string &text, const int yOffset)
{
    static const char characters[] = "0123456789.:/";
    const int numCharacters        = DE_LENGTH_OF_ARRAY(characters) - 1; // \note -1 for null byte.
    const int charWid              = 6;
    const int charHei              = 6;
    static const string charsStr(characters);

    static const char font[numCharacters * charWid * charHei + 1] = " #### "
                                                                    "   #  "
                                                                    " #### "
                                                                    "##### "
                                                                    "   #  "
                                                                    "######"
                                                                    " #####"
                                                                    "######"
                                                                    " #### "
                                                                    " #### "
                                                                    "      "
                                                                    "  ##  "
                                                                    "     #"
                                                                    "#    #"
                                                                    "  ##  "
                                                                    "#    #"
                                                                    "     #"
                                                                    "  #   "
                                                                    "#     "
                                                                    "#     "
                                                                    "    # "
                                                                    "#    #"
                                                                    "#    #"
                                                                    "      "
                                                                    "  ##  "
                                                                    "    # "
                                                                    "#    #"
                                                                    "   #  "
                                                                    "    # "
                                                                    "  ### "
                                                                    " #  # "
                                                                    " #### "
                                                                    "# ### "
                                                                    "   #  "
                                                                    " #### "
                                                                    " #####"
                                                                    "      "
                                                                    "      "
                                                                    "   #  "
                                                                    "#    #"
                                                                    "   #  "
                                                                    "   #  "
                                                                    "     #"
                                                                    "######"
                                                                    "     #"
                                                                    "##   #"
                                                                    "  #   "
                                                                    "#    #"
                                                                    "     #"
                                                                    "      "
                                                                    "  ##  "
                                                                    "  #   "
                                                                    "#    #"
                                                                    "   #  "
                                                                    "  #   "
                                                                    "#    #"
                                                                    "    # "
                                                                    "#    #"
                                                                    "#    #"
                                                                    " #    "
                                                                    "#    #"
                                                                    "   ## "
                                                                    "  ##  "
                                                                    "  ##  "
                                                                    " #    "
                                                                    " #### "
                                                                    "  ### "
                                                                    "######"
                                                                    " #### "
                                                                    "    # "
                                                                    " #### "
                                                                    " #### "
                                                                    "#     "
                                                                    " #### "
                                                                    "###   "
                                                                    "  ##  "
                                                                    "      "
                                                                    "#     ";

    for (int ndxInText = 0; ndxInText < (int)text.size(); ndxInText++)
    {
        const int ndxInCharset = (int)charsStr.find(text[ndxInText]);
        DE_ASSERT(ndxInCharset < numCharacters);
        const int fontXStart = ndxInCharset * charWid;

        for (int y = 0; y < charHei; y++)
        {
            float ay = -1.0f + (float)(y + 0 + yOffset * (charHei + 2)) * 0.1f / (float)(charHei + 2);
            float by = -1.0f + (float)(y + 1 + yOffset * (charHei + 2)) * 0.1f / (float)(charHei + 2);
            for (int x = 0; x < charWid; x++)
            {
                // \note Text is mirrored in x direction since on most(?) mobile devices the image is mirrored(?).
                float ax = 1.0f - (float)(x + 0 + ndxInText * (charWid + 2)) * 0.1f / (float)(charWid + 2);
                float bx = 1.0f - (float)(x + 1 + ndxInText * (charWid + 2)) * 0.1f / (float)(charWid + 2);

                if (font[y * numCharacters * charWid + fontXStart + x] != ' ')
                {
                    const int vtxNdx = (int)m_posBuf.size() / 2;

                    m_ndxBuf.push_back(uint16_t(vtxNdx + 0));
                    m_ndxBuf.push_back(uint16_t(vtxNdx + 1));
                    m_ndxBuf.push_back(uint16_t(vtxNdx + 2));

                    m_ndxBuf.push_back(uint16_t(vtxNdx + 2));
                    m_ndxBuf.push_back(uint16_t(vtxNdx + 1));
                    m_ndxBuf.push_back(uint16_t(vtxNdx + 3));

                    m_posBuf.push_back(ax);
                    m_posBuf.push_back(ay);

                    m_posBuf.push_back(bx);
                    m_posBuf.push_back(ay);

                    m_posBuf.push_back(ax);
                    m_posBuf.push_back(by);

                    m_posBuf.push_back(bx);
                    m_posBuf.push_back(by);
                }
            }
        }
    }
}

void DebugInfoRenderer::render(void)
{
    const int prog   = m_prog->getProgram();
    const int posloc = glGetAttribLocation(prog, "a_pos");

    glUseProgram(prog);
    glBindBuffer(GL_ARRAY_BUFFER, 0);
    glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
    glEnableVertexAttribArray(posloc);
    glVertexAttribPointer(posloc, 2, GL_FLOAT, 0, 0, &m_posBuf[0]);
    glDrawElements(GL_TRIANGLES, (int)m_ndxBuf.size(), GL_UNSIGNED_SHORT, &m_ndxBuf[0]);
    glDisableVertexAttribArray(posloc);

    m_posBuf.clear();
    m_ndxBuf.clear();
}

/*--------------------------------------------------------------------*//*!
 * \brief Texture object helper class
 *
 * Each Texture owns a GL texture object that is created when the Texture
 * is constructed and deleted when it's destructed. The class provides some
 * convenience interface functions to e.g. upload texture data to the GL.
 *
 * In addition, the class tracks the approximate amount of GL memory likely
 * used by the corresponding GL texture object; get this with
 * getApproxMemUsage(). Also, getApproxMemUsageDiff() returns N-M, where N
 * is the value that getApproxMemUsage() would return after a call to
 * setData() with arguments corresponding to those given to
 * getApproxMemUsageDiff(), and M is the value currently returned by
 * getApproxMemUsage(). This can be used to check if we need to free some
 * other memory before performing the setData() call, in case we have an
 * upper limit on the amount of memory we want to use.
 *//*--------------------------------------------------------------------*/
class Texture
{
public:
    Texture(TextureType type);
    ~Texture(void);

    // Functions that may change the value returned by getApproxMemUsage().
    void setData(const ConstPixelBufferAccess &src, int width, int height, uint32_t internalFormat, bool useMipmap);

    // Functions that don't change the value returned by getApproxMemUsage().
    void setSubData(const ConstPixelBufferAccess &src, int xOff, int yOff, int width, int height) const;
    void toUnit(int unit) const;
    void setFilter(uint32_t min, uint32_t mag) const;
    void setWrap(uint32_t s, uint32_t t) const;

    int getApproxMemUsage(void) const
    {
        return m_dataSizeApprox;
    }
    int getApproxMemUsageDiff(int width, int height, uint32_t internalFormat, bool useMipmap) const;

private:
    Texture(const Texture &);            // Not allowed.
    Texture &operator=(const Texture &); // Not allowed.

    static uint32_t genTexture(void)
    {
        uint32_t tex = 0;
        glGenTextures(1, &tex);
        return tex;
    }

    uint32_t getGLBindTarget(void) const
    {
        DE_ASSERT(m_type == TEXTURETYPE_2D || m_type == TEXTURETYPE_CUBE);
        return m_type == TEXTURETYPE_2D ? GL_TEXTURE_2D : GL_TEXTURE_CUBE_MAP;
    }

    const TextureType m_type;
    const uint32_t m_textureGL;

    int m_numMipLevels;
    uint32_t m_internalFormat;
    int m_dataSizeApprox;
};

Texture::Texture(const TextureType type)
    : m_type(type)
    , m_textureGL(genTexture())
    , m_numMipLevels(0)
    , m_internalFormat(0)
    , m_dataSizeApprox(0)
{
}

Texture::~Texture(void)
{
    glDeleteTextures(1, &m_textureGL);
}

int Texture::getApproxMemUsageDiff(const int width, const int height, const uint32_t internalFormat,
                                   const bool useMipmap) const
{
    const int numLevels     = useMipmap ? deLog2Floor32(de::max(width, height)) + 1 : 1;
    const int pixelSize     = internalFormat == GL_RGBA  ? 4 :
                              internalFormat == GL_RGB   ? 3 :
                              internalFormat == GL_ALPHA ? 1 :
                                                           glu::mapGLInternalFormat(internalFormat).getPixelSize();
    int memUsageApproxAfter = 0;

    for (int level = 0; level < numLevels; level++)
        memUsageApproxAfter +=
            de::max(1, width >> level) * de::max(1, height >> level) * pixelSize * (m_type == TEXTURETYPE_CUBE ? 6 : 1);

    return memUsageApproxAfter - getApproxMemUsage();
}

void Texture::setData(const ConstPixelBufferAccess &src, const int width, const int height,
                      const uint32_t internalFormat, const bool useMipmap)
{
    DE_ASSERT(m_type != TEXTURETYPE_CUBE || width == height);
    DE_ASSERT(!useMipmap || (deIsPowerOfTwo32(width) && deIsPowerOfTwo32(height)));

    const TextureFormat &format        = src.getFormat();
    const glu::TransferFormat transfer = glu::getTransferFormat(format);

    m_numMipLevels = useMipmap ? deLog2Floor32(de::max(width, height)) + 1 : 1;

    m_internalFormat = internalFormat;
    m_dataSizeApprox = width * height * format.getPixelSize() * (m_type == TEXTURETYPE_CUBE ? 6 : 1);

    DE_ASSERT(src.getRowPitch() == format.getPixelSize() * src.getWidth());
    DE_ASSERT(isMatchingGLInternalFormat(internalFormat, format));
    DE_ASSERT(width <= src.getWidth() && height <= src.getHeight());

    glPixelStorei(GL_UNPACK_ALIGNMENT, computePixelStore(format));

    if (m_type == TEXTURETYPE_2D)
    {
        m_dataSizeApprox = 0;

        glBindTexture(GL_TEXTURE_2D, m_textureGL);
        for (int level = 0; level < m_numMipLevels; level++)
        {
            const int levelWid = de::max(1, width >> level);
            const int levelHei = de::max(1, height >> level);
            m_dataSizeApprox += levelWid * levelHei * format.getPixelSize();
            glTexImage2D(GL_TEXTURE_2D, level, internalFormat, levelWid, levelHei, 0, transfer.format,
                         transfer.dataType, src.getDataPtr());
        }
    }
    else if (m_type == TEXTURETYPE_CUBE)
    {
        m_dataSizeApprox = 0;

        glBindTexture(GL_TEXTURE_CUBE_MAP, m_textureGL);
        for (int level = 0; level < m_numMipLevels; level++)
        {
            const int levelWid = de::max(1, width >> level);
            const int levelHei = de::max(1, height >> level);
            m_dataSizeApprox += 6 * levelWid * levelHei * format.getPixelSize();
            for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
                glTexImage2D(cubeFaceToGLFace((CubeFace)face), level, internalFormat, levelWid, levelHei, 0,
                             transfer.format, transfer.dataType, src.getDataPtr());
        }
    }
    else
        DE_ASSERT(false);
}

void Texture::setSubData(const ConstPixelBufferAccess &src, const int xOff, const int yOff, const int width,
                         const int height) const
{
    const TextureFormat &format        = src.getFormat();
    const glu::TransferFormat transfer = glu::getTransferFormat(format);

    DE_ASSERT(src.getRowPitch() == format.getPixelSize() * src.getWidth());
    DE_ASSERT(isMatchingGLInternalFormat(m_internalFormat, format));
    DE_ASSERT(width <= src.getWidth() && height <= src.getHeight());

    glPixelStorei(GL_UNPACK_ALIGNMENT, computePixelStore(format));

    if (m_type == TEXTURETYPE_2D)
    {
        glBindTexture(GL_TEXTURE_2D, m_textureGL);
        for (int level = 0; level < m_numMipLevels; level++)
            glTexSubImage2D(GL_TEXTURE_2D, level, xOff >> level, yOff >> level, de::max(1, width >> level),
                            de::max(1, height >> level), transfer.format, transfer.dataType, src.getDataPtr());
    }
    else if (m_type == TEXTURETYPE_CUBE)
    {
        glBindTexture(GL_TEXTURE_CUBE_MAP, m_textureGL);
        for (int level = 0; level < m_numMipLevels; level++)
        {
            for (int face = 0; face < tcu::CUBEFACE_LAST; face++)
                glTexSubImage2D(cubeFaceToGLFace((CubeFace)face), level, xOff >> level, yOff >> level,
                                de::max(1, width >> level), de::max(1, height >> level), transfer.format,
                                transfer.dataType, src.getDataPtr());
        }
    }
    else
        DE_ASSERT(false);
}

void Texture::setFilter(const uint32_t min, const uint32_t mag) const
{
    glBindTexture(getGLBindTarget(), m_textureGL);
    glTexParameteri(getGLBindTarget(), GL_TEXTURE_MIN_FILTER, min);
    glTexParameteri(getGLBindTarget(), GL_TEXTURE_MAG_FILTER, mag);
}

void Texture::setWrap(const uint32_t s, const uint32_t t) const
{
    glBindTexture(getGLBindTarget(), m_textureGL);
    glTexParameteri(getGLBindTarget(), GL_TEXTURE_WRAP_S, s);
    glTexParameteri(getGLBindTarget(), GL_TEXTURE_WRAP_T, t);
}

void Texture::toUnit(const int unit) const
{
    glActiveTexture(GL_TEXTURE0 + unit);
    glBindTexture(getGLBindTarget(), m_textureGL);
}

/*--------------------------------------------------------------------*//*!
 * \brief Buffer object helper class
 *
 * Each Buffer owns a GL buffer object that is created when the Buffer
 * is constructed and deleted when it's destructed. The class provides some
 * convenience interface functions to e.g. upload buffer data to the GL.
 *
 * In addition, the class tracks the approximate amount of GL memory,
 * similarly to the Texture class (see above). The getApproxMemUsageDiff()
 * is also analoguous.
 *//*--------------------------------------------------------------------*/
class Buffer
{
public:
    Buffer(void);
    ~Buffer(void);

    // Functions that may change the value returned by getApproxMemUsage().
    template <typename T>
    void setData(const vector<T> &src, const uint32_t target, const uint32_t usage)
    {
        setData(&src[0], (int)(src.size() * sizeof(T)), target, usage);
    }
    void setData(const void *src, int size, uint32_t target, uint32_t usage);

    // Functions that don't change the value returned by getApproxMemUsage().
    template <typename T>
    void setSubData(const vector<T> &src, const int offsetElems, const int numElems, const uint32_t target)
    {
        setSubData(&src[offsetElems], offsetElems * (int)sizeof(T), numElems * (int)sizeof(T), target);
    }
    void setSubData(const void *src, int offsetBytes, int sizeBytes, uint32_t target) const;
    void bind(const uint32_t target) const
    {
        glBindBuffer(target, m_bufferGL);
    }

    int getApproxMemUsage(void) const
    {
        return m_dataSizeApprox;
    }
    template <typename T>
    int getApproxMemUsageDiff(const vector<T> &src) const
    {
        return getApproxMemUsageDiff((int)(src.size() * sizeof(T)));
    }
    int getApproxMemUsageDiff(const int sizeBytes) const
    {
        return sizeBytes - getApproxMemUsage();
    }

private:
    Buffer(const Buffer &);            // Not allowed.
    Buffer &operator=(const Buffer &); // Not allowed.

    static uint32_t genBuffer(void)
    {
        uint32_t buf = 0;
        glGenBuffers(1, &buf);
        return buf;
    }

    const uint32_t m_bufferGL;
    int m_dataSizeApprox;
};

Buffer::Buffer(void) : m_bufferGL(genBuffer()), m_dataSizeApprox(0)
{
}

Buffer::~Buffer(void)
{
    glDeleteBuffers(1, &m_bufferGL);
}

void Buffer::setData(const void *const src, const int size, const uint32_t target, const uint32_t usage)
{
    bind(target);
    glBufferData(target, size, src, usage);
    glBindBuffer(target, 0);

    m_dataSizeApprox = size;
}

void Buffer::setSubData(const void *const src, const int offsetBytes, const int sizeBytes, const uint32_t target) const
{
    bind(target);
    glBufferSubData(target, offsetBytes, sizeBytes, src);
    glBindBuffer(target, 0);
}

class Program
{
public:
    Program(void);
    ~Program(void);

    void setSources(const string &vertSource, const string &fragSource);
    void build(TestLog &log);
    void use(void) const
    {
        DE_ASSERT(m_isBuilt);
        glUseProgram(m_programGL);
    }
    void setRandomUniforms(const vector<VarSpec> &uniforms, const string &shaderNameManglingSuffix, Random &rnd) const;
    void setAttribute(const Buffer &attrBuf, int attrBufOffset, const VarSpec &attrSpec,
                      const string &shaderNameManglingSuffix) const;
    void setAttributeClientMem(const void *attrData, const VarSpec &attrSpec,
                               const string &shaderNameManglingSuffix) const;
    void disableAttributeArray(const VarSpec &attrSpec, const string &shaderNameManglingSuffix) const;

private:
    Program(const Program &);            // Not allowed.
    Program &operator=(const Program &); // Not allowed.

    string m_vertSource;
    string m_fragSource;

    const uint32_t m_vertShaderGL;
    const uint32_t m_fragShaderGL;
    const uint32_t m_programGL;
    bool m_hasSources;
    bool m_isBuilt;
};

Program::Program(void)
    : m_vertShaderGL(glCreateShader(GL_VERTEX_SHADER))
    , m_fragShaderGL(glCreateShader(GL_FRAGMENT_SHADER))
    , m_programGL(glCreateProgram())
    , m_hasSources(false)
    , m_isBuilt(false)
{
    glAttachShader(m_programGL, m_vertShaderGL);
    glAttachShader(m_programGL, m_fragShaderGL);
}

Program::~Program(void)
{
    glDeleteShader(m_vertShaderGL);
    glDeleteShader(m_fragShaderGL);
    glDeleteProgram(m_programGL);
}

void Program::setSources(const string &vertSource, const string &fragSource)
{
    const char *const vertSourceCstr = vertSource.c_str();
    const char *const fragSourceCstr = fragSource.c_str();

    m_vertSource = vertSource;
    m_fragSource = fragSource;

    // \note In GLES2 api the source parameter type lacks one const.
    glShaderSource(m_vertShaderGL, 1, (const char **)&vertSourceCstr, DE_NULL);
    glShaderSource(m_fragShaderGL, 1, (const char **)&fragSourceCstr, DE_NULL);

    m_hasSources = true;
}

void Program::build(TestLog &log)
{
    DE_ASSERT(m_hasSources);

    const bool vertCompileOk = compileShader(m_vertShaderGL);
    const bool fragCompileOk = compileShader(m_fragShaderGL);
    const bool attemptLink   = vertCompileOk && fragCompileOk;
    const bool linkOk        = attemptLink && linkProgram(m_programGL);

    if (!(vertCompileOk && fragCompileOk && linkOk))
    {
        log << TestLog::ShaderProgram(linkOk, attemptLink ? getProgramInfoLog(m_programGL) : string(""))
            << TestLog::Shader(QP_SHADER_TYPE_VERTEX, m_vertSource, vertCompileOk, getShaderInfoLog(m_vertShaderGL))
            << TestLog::Shader(QP_SHADER_TYPE_FRAGMENT, m_fragSource, fragCompileOk, getShaderInfoLog(m_fragShaderGL))
            << TestLog::EndShaderProgram;

        throw tcu::TestError("Program build failed");
    }

    m_isBuilt = true;
}

void Program::setRandomUniforms(const vector<VarSpec> &uniforms, const string &shaderNameManglingSuffix,
                                Random &rnd) const
{
    use();

    for (int unifNdx = 0; unifNdx < (int)uniforms.size(); unifNdx++)
    {
        const VarSpec &spec      = uniforms[unifNdx];
        const int typeScalarSize = glu::getDataTypeScalarSize(spec.type);
        const int location =
            glGetUniformLocation(m_programGL, mangleShaderNames(spec.name, shaderNameManglingSuffix).c_str());
        if (location < 0)
            continue;

        if (glu::isDataTypeFloatOrVec(spec.type))
        {
            float val[4];
            for (int i = 0; i < typeScalarSize; i++)
                val[i] = rnd.getFloat(spec.minValue.f[i], spec.maxValue.f[i]);

            switch (spec.type)
            {
            case glu::TYPE_FLOAT:
                glUniform1f(location, val[0]);
                break;
            case glu::TYPE_FLOAT_VEC2:
                glUniform2f(location, val[0], val[1]);
                break;
            case glu::TYPE_FLOAT_VEC3:
                glUniform3f(location, val[0], val[1], val[2]);
                break;
            case glu::TYPE_FLOAT_VEC4:
                glUniform4f(location, val[0], val[1], val[2], val[3]);
                break;
            default:
                DE_ASSERT(false);
            }
        }
        else if (glu::isDataTypeMatrix(spec.type))
        {
            float val[4 * 4];
            for (int i = 0; i < typeScalarSize; i++)
                val[i] = rnd.getFloat(spec.minValue.f[i], spec.maxValue.f[i]);

            switch (spec.type)
            {
            case glu::TYPE_FLOAT_MAT2:
                glUniformMatrix2fv(location, 1, GL_FALSE, &val[0]);
                break;
            case glu::TYPE_FLOAT_MAT3:
                glUniformMatrix3fv(location, 1, GL_FALSE, &val[0]);
                break;
            case glu::TYPE_FLOAT_MAT4:
                glUniformMatrix4fv(location, 1, GL_FALSE, &val[0]);
                break;
            case glu::TYPE_FLOAT_MAT2X3:
                glUniformMatrix2x3fv(location, 1, GL_FALSE, &val[0]);
                break;
            case glu::TYPE_FLOAT_MAT2X4:
                glUniformMatrix2x4fv(location, 1, GL_FALSE, &val[0]);
                break;
            case glu::TYPE_FLOAT_MAT3X2:
                glUniformMatrix3x2fv(location, 1, GL_FALSE, &val[0]);
                break;
            case glu::TYPE_FLOAT_MAT3X4:
                glUniformMatrix3x4fv(location, 1, GL_FALSE, &val[0]);
                break;
            case glu::TYPE_FLOAT_MAT4X2:
                glUniformMatrix4x2fv(location, 1, GL_FALSE, &val[0]);
                break;
            case glu::TYPE_FLOAT_MAT4X3:
                glUniformMatrix4x3fv(location, 1, GL_FALSE, &val[0]);
                break;
            default:
                DE_ASSERT(false);
            }
        }
        else if (glu::isDataTypeIntOrIVec(spec.type))
        {
            int val[4];
            for (int i = 0; i < typeScalarSize; i++)
                val[i] = rnd.getInt(spec.minValue.i[i], spec.maxValue.i[i]);

            switch (spec.type)
            {
            case glu::TYPE_INT:
                glUniform1i(location, val[0]);
                break;
            case glu::TYPE_INT_VEC2:
                glUniform2i(location, val[0], val[1]);
                break;
            case glu::TYPE_INT_VEC3:
                glUniform3i(location, val[0], val[1], val[2]);
                break;
            case glu::TYPE_INT_VEC4:
                glUniform4i(location, val[0], val[1], val[2], val[3]);
                break;
            default:
                DE_ASSERT(false);
            }
        }
        else if (glu::isDataTypeUintOrUVec(spec.type))
        {
            uint32_t val[4];
            for (int i = 0; i < typeScalarSize; i++)
            {
                DE_ASSERT(spec.minValue.i[i] >= 0 && spec.maxValue.i[i] >= 0);
                val[i] = (uint32_t)rnd.getInt(spec.minValue.i[i], spec.maxValue.i[i]);
            }

            switch (spec.type)
            {
            case glu::TYPE_UINT:
                glUniform1ui(location, val[0]);
                break;
            case glu::TYPE_UINT_VEC2:
                glUniform2ui(location, val[0], val[1]);
                break;
            case glu::TYPE_UINT_VEC3:
                glUniform3ui(location, val[0], val[1], val[2]);
                break;
            case glu::TYPE_UINT_VEC4:
                glUniform4ui(location, val[0], val[1], val[2], val[3]);
                break;
            default:
                DE_ASSERT(false);
            }
        }
        else
            DE_ASSERT(false);
    }
}

void Program::setAttribute(const Buffer &attrBuf, const int attrBufOffset, const VarSpec &attrSpec,
                           const string &shaderNameManglingSuffix) const
{
    const int attrLoc =
        glGetAttribLocation(m_programGL, mangleShaderNames(attrSpec.name, shaderNameManglingSuffix).c_str());

    glEnableVertexAttribArray(attrLoc);
    attrBuf.bind(GL_ARRAY_BUFFER);

    if (glu::isDataTypeFloatOrVec(attrSpec.type))
        glVertexAttribPointer(attrLoc, glu::getDataTypeScalarSize(attrSpec.type), GL_FLOAT, GL_FALSE, 0,
                              (GLvoid *)(intptr_t)attrBufOffset);
    else
        DE_ASSERT(false);
}

void Program::setAttributeClientMem(const void *const attrData, const VarSpec &attrSpec,
                                    const string &shaderNameManglingSuffix) const
{
    const int attrLoc =
        glGetAttribLocation(m_programGL, mangleShaderNames(attrSpec.name, shaderNameManglingSuffix).c_str());

    glEnableVertexAttribArray(attrLoc);
    glBindBuffer(GL_ARRAY_BUFFER, 0);

    if (glu::isDataTypeFloatOrVec(attrSpec.type))
        glVertexAttribPointer(attrLoc, glu::getDataTypeScalarSize(attrSpec.type), GL_FLOAT, GL_FALSE, 0, attrData);
    else
        DE_ASSERT(false);
}

void Program::disableAttributeArray(const VarSpec &attrSpec, const string &shaderNameManglingSuffix) const
{
    const int attrLoc =
        glGetAttribLocation(m_programGL, mangleShaderNames(attrSpec.name, shaderNameManglingSuffix).c_str());

    glDisableVertexAttribArray(attrLoc);
}

/*--------------------------------------------------------------------*//*!
 * \brief Container class for managing GL objects
 *
 * GLObjectManager can be used for objects of class Program, Buffer or
 * Texture. In the manager, each such object is associated with a name that
 * is used to access it.
 *
 * In addition to the making, getting and removing functions, the manager
 * supports marking objects as "garbage", meaning they're not yet
 * destroyed, but can be later destroyed with removeRandomGarbage(). The
 * idea is that if we want to stress test with high memory usage, we can
 * continuously move objects to garbage after using them, and when a memory
 * limit is reached, we can call removeGarbageUntilUnder(limit, rnd). This
 * way we can approximately keep our memory usage at just under the wanted
 * limit.
 *
 * The manager also supports querying the approximate amount of GL memory
 * used by its objects.
 *
 * \note The memory usage related functions are not currently supported
 *         for Program objects.
 *//*--------------------------------------------------------------------*/
template <typename T>
class GLObjectManager
{
public:
    void make(const string &name)
    {
        DE_ASSERT(!has(name));
        m_objects[name] = SharedPtr<T>(new T);
    }
    void make(const string &name, gls::TextureType texType)
    {
        DE_ASSERT(!has(name));
        m_objects[name] = SharedPtr<T>(new T(texType));
    }
    bool has(const string &name) const
    {
        return m_objects.find(name) != m_objects.end();
    }
    const T &get(const string &name) const;
    T &get(const string &name)
    {
        return const_cast<T &>(((const GLObjectManager<T> *)this)->get(name));
    }
    void remove(const string &name)
    {
        const int removed = (int)m_objects.erase(name);
        DE_ASSERT(removed);
        DE_UNREF(removed);
    }
    int computeApproxMemUsage(void) const;
    void markAsGarbage(const string &name);
    int removeRandomGarbage(Random &rnd);
    void removeGarbageUntilUnder(int limit, Random &rnd);

private:
    static const char *objTypeName(void);

    map<string, SharedPtr<T>> m_objects;
    vector<SharedPtr<T>> m_garbageObjects;
};

template <>
const char *GLObjectManager<Buffer>::objTypeName(void)
{
    return "buffer";
}
template <>
const char *GLObjectManager<Texture>::objTypeName(void)
{
    return "texture";
}
template <>
const char *GLObjectManager<Program>::objTypeName(void)
{
    return "program";
}

template <typename T>
const T &GLObjectManager<T>::get(const string &name) const
{
    const typename map<string, SharedPtr<T>>::const_iterator it = m_objects.find(name);
    DE_ASSERT(it != m_objects.end());
    return *it->second;
}

template <typename T>
int GLObjectManager<T>::computeApproxMemUsage(void) const
{
    int result = 0;

    for (typename map<string, SharedPtr<T>>::const_iterator it = m_objects.begin(); it != m_objects.end(); ++it)
        result += it->second->getApproxMemUsage();

    for (typename vector<SharedPtr<T>>::const_iterator it = m_garbageObjects.begin(); it != m_garbageObjects.end();
         ++it)
        result += (*it)->getApproxMemUsage();

    return result;
}

template <typename T>
void GLObjectManager<T>::markAsGarbage(const string &name)
{
    const typename map<string, SharedPtr<T>>::iterator it = m_objects.find(name);
    DE_ASSERT(it != m_objects.end());
    m_garbageObjects.push_back(it->second);
    m_objects.erase(it);
}

template <typename T>
int GLObjectManager<T>::removeRandomGarbage(Random &rnd)
{
    if (m_garbageObjects.empty())
        return -1;

    const int removeNdx   = rnd.getInt(0, (int)m_garbageObjects.size() - 1);
    const int memoryFreed = m_garbageObjects[removeNdx]->getApproxMemUsage();
    m_garbageObjects.erase(m_garbageObjects.begin() + removeNdx);
    return memoryFreed;
}

template <typename T>
void GLObjectManager<T>::removeGarbageUntilUnder(const int limit, Random &rnd)
{
    int memUsage = computeApproxMemUsage();

    while (memUsage > limit)
    {
        const int memReleased = removeRandomGarbage(rnd);
        if (memReleased < 0)
            throw tcu::InternalError(string("") + "Given " + objTypeName() +
                                     " memory usage limit exceeded, and no unneeded " + objTypeName() +
                                     " resources available to release");
        memUsage -= memReleased;
        DE_ASSERT(memUsage == computeApproxMemUsage());
    }
}

} // namespace LongStressCaseInternal

using namespace LongStressCaseInternal;

static int generateRandomAttribData(vector<uint8_t> &attrDataBuf, int &dataSizeBytesDst, const VarSpec &attrSpec,
                                    const int numVertices, Random &rnd)
{
    const bool isFloat      = glu::isDataTypeFloatOrVec(attrSpec.type);
    const int numComponents = glu::getDataTypeScalarSize(attrSpec.type);
    const int componentSize = (int)(isFloat ? sizeof(GLfloat) : sizeof(GLint));
    const int offsetInBuf   = nextDivisible((int)attrDataBuf.size(), componentSize); // Round up for alignment.

    DE_STATIC_ASSERT(sizeof(GLint) == sizeof(int));
    DE_STATIC_ASSERT(sizeof(GLfloat) == sizeof(float));

    dataSizeBytesDst = numComponents * componentSize * numVertices;

    attrDataBuf.resize(offsetInBuf + dataSizeBytesDst);

    if (isFloat)
    {
        float *const data = (float *)&attrDataBuf[offsetInBuf];

        for (int vtxNdx = 0; vtxNdx < numVertices; vtxNdx++)
            for (int compNdx = 0; compNdx < numComponents; compNdx++)
                data[vtxNdx * numComponents + compNdx] =
                    rnd.getFloat(attrSpec.minValue.f[compNdx], attrSpec.maxValue.f[compNdx]);
    }
    else
    {
        DE_ASSERT(glu::isDataTypeIntOrIVec(attrSpec.type));

        int *const data = (int *)&attrDataBuf[offsetInBuf];

        for (int vtxNdx = 0; vtxNdx < numVertices; vtxNdx++)
            for (int compNdx = 0; compNdx < numComponents; compNdx++)
                data[vtxNdx * numComponents + compNdx] =
                    rnd.getInt(attrSpec.minValue.i[compNdx], attrSpec.maxValue.i[compNdx]);
    }

    return offsetInBuf;
}

static int generateRandomPositionAttribData(vector<uint8_t> &attrDataBuf, int &dataSizeBytesDst,
                                            const VarSpec &attrSpec, const int numVertices, Random &rnd)
{
    DE_ASSERT(glu::isDataTypeFloatOrVec(attrSpec.type));

    const int numComponents = glu::getDataTypeScalarSize(attrSpec.type);
    DE_ASSERT(numComponents >= 2);
    const int offsetInBuf = generateRandomAttribData(attrDataBuf, dataSizeBytesDst, attrSpec, numVertices, rnd);

    if (numComponents > 2)
    {
        float *const data = (float *)&attrDataBuf[offsetInBuf];

        for (int vtxNdx = 0; vtxNdx < numVertices; vtxNdx++)
            data[vtxNdx * numComponents + 2] = -1.0f;

        for (int triNdx = 0; triNdx < numVertices - 2; triNdx++)
        {
            float *const vtxAComps = &data[(triNdx + 0) * numComponents];
            float *const vtxBComps = &data[(triNdx + 1) * numComponents];
            float *const vtxCComps = &data[(triNdx + 2) * numComponents];

            const float triArea = triangleArea(Vec2(vtxAComps[0], vtxAComps[1]), Vec2(vtxBComps[0], vtxBComps[1]),
                                               Vec2(vtxCComps[0], vtxCComps[1]));
            const float t       = triArea / (triArea + 1.0f);
            const float z       = (1.0f - t) * attrSpec.minValue.f[2] + t * attrSpec.maxValue.f[2];

            vtxAComps[2] = de::max(vtxAComps[2], z);
            vtxBComps[2] = de::max(vtxBComps[2], z);
            vtxCComps[2] = de::max(vtxCComps[2], z);
        }
    }

    return offsetInBuf;
}

static void generateAttribs(vector<uint8_t> &attrDataBuf, vector<int> &attrDataOffsets, vector<int> &attrDataSizes,
                            const vector<VarSpec> &attrSpecs, const string &posAttrName, const int numVertices,
                            Random &rnd)
{
    attrDataBuf.clear();
    attrDataOffsets.clear();
    attrDataSizes.resize(attrSpecs.size());

    for (int i = 0; i < (int)attrSpecs.size(); i++)
    {
        if (attrSpecs[i].name == posAttrName)
            attrDataOffsets.push_back(
                generateRandomPositionAttribData(attrDataBuf, attrDataSizes[i], attrSpecs[i], numVertices, rnd));
        else
            attrDataOffsets.push_back(
                generateRandomAttribData(attrDataBuf, attrDataSizes[i], attrSpecs[i], numVertices, rnd));
    }
}

LongStressCase::LongStressCase(tcu::TestContext &testCtx, const glu::RenderContext &renderCtx, const char *const name,
                               const char *const desc, const int maxTexMemoryUsageBytes,
                               const int maxBufMemoryUsageBytes, const int numDrawCallsPerIteration,
                               const int numTrianglesPerDrawCall, const vector<ProgramContext> &programContexts,
                               const FeatureProbabilities &probabilities, const uint32_t indexBufferUsage,
                               const uint32_t attrBufferUsage, const int redundantBufferFactor,
                               const bool showDebugInfo)
    : tcu::TestCase(testCtx, name, desc)
    , m_renderCtx(renderCtx)
    , m_maxTexMemoryUsageBytes(maxTexMemoryUsageBytes)
    , m_maxBufMemoryUsageBytes(maxBufMemoryUsageBytes)
    , m_numDrawCallsPerIteration(numDrawCallsPerIteration)
    , m_numTrianglesPerDrawCall(numTrianglesPerDrawCall)
    , m_numVerticesPerDrawCall(numTrianglesPerDrawCall + 2) // \note Triangle strips are used.
    , m_programContexts(programContexts)
    , m_probabilities(probabilities)
    , m_indexBufferUsage(indexBufferUsage)
    , m_attrBufferUsage(attrBufferUsage)
    , m_redundantBufferFactor(redundantBufferFactor)
    , m_showDebugInfo(showDebugInfo)
    , m_numIterations(getNumIterations(testCtx, 5))
    , m_isGLES3(contextSupports(renderCtx.getType(), glu::ApiType::es(3, 0)))
    , m_currentIteration(0)
    , m_startTimeSeconds((uint64_t)-1)
    , m_lastLogTime((uint64_t)-1)
    , m_lastLogIteration(0)
    , m_currentLogEntryNdx(0)
    , m_rnd(deStringHash(getName()) ^ testCtx.getCommandLine().getBaseSeed())
    , m_programs(DE_NULL)
    , m_buffers(DE_NULL)
    , m_textures(DE_NULL)
    , m_debugInfoRenderer(DE_NULL)
{
    DE_ASSERT(m_numVerticesPerDrawCall <=
              (int)std::numeric_limits<uint16_t>::max() + 1); // \note Vertices are referred to with 16-bit indices.
    DE_ASSERT(m_redundantBufferFactor > 0);
}

LongStressCase::~LongStressCase(void)
{
    LongStressCase::deinit();
}

void LongStressCase::init(void)
{
    // Generate dummy texture data for each texture spec in m_programContexts.

    DE_ASSERT(!m_programContexts.empty());
    DE_ASSERT(m_programResources.empty());
    m_programResources.resize(m_programContexts.size());

    for (int progCtxNdx = 0; progCtxNdx < (int)m_programContexts.size(); progCtxNdx++)
    {
        const ProgramContext &progCtx = m_programContexts[progCtxNdx];
        ProgramResources &progRes     = m_programResources[progCtxNdx];

        for (int texSpecNdx = 0; texSpecNdx < (int)progCtx.textureSpecs.size(); texSpecNdx++)
        {
            const TextureSpec &spec    = progCtx.textureSpecs[texSpecNdx];
            const TextureFormat format = glu::mapGLTransferFormat(spec.format, spec.dataType);

            // If texture data with the same format has already been generated, re-use that (don't care much about contents).

            SharedPtr<TextureLevel> dummyTex;

            for (int prevProgCtxNdx = 0; prevProgCtxNdx < (int)m_programResources.size(); prevProgCtxNdx++)
            {
                const vector<SharedPtr<TextureLevel>> &prevProgCtxTextures =
                    m_programResources[prevProgCtxNdx].dummyTextures;

                for (int texNdx = 0; texNdx < (int)prevProgCtxTextures.size(); texNdx++)
                {
                    if (prevProgCtxTextures[texNdx]->getFormat() == format)
                    {
                        dummyTex = prevProgCtxTextures[texNdx];
                        break;
                    }
                }
            }

            if (!dummyTex)
                dummyTex = SharedPtr<TextureLevel>(new TextureLevel(format));

            if (dummyTex->getWidth() < spec.width || dummyTex->getHeight() < spec.height)
            {
                dummyTex->setSize(spec.width, spec.height);
                tcu::fillWithComponentGradients(dummyTex->getAccess(), spec.minValue, spec.maxValue);
            }

            progRes.dummyTextures.push_back(dummyTex);
        }
    }

    m_vertexIndices.clear();
    for (int i = 0; i < m_numVerticesPerDrawCall; i++)
        m_vertexIndices.push_back((uint16_t)i);
    m_rnd.shuffle(m_vertexIndices.begin(), m_vertexIndices.end());

    DE_ASSERT(!m_programs && !m_buffers && !m_textures);
    m_programs = new GLObjectManager<Program>;
    m_buffers  = new GLObjectManager<Buffer>;
    m_textures = new GLObjectManager<Texture>;

    m_currentIteration = 0;

    {
        TestLog &log = m_testCtx.getLog();

        log << TestLog::Message
            << "Number of iterations: " << (m_numIterations > 0 ? toString(m_numIterations) : "infinite")
            << TestLog::EndMessage << TestLog::Message
            << "Number of draw calls per iteration: " << m_numDrawCallsPerIteration << TestLog::EndMessage
            << TestLog::Message << "Number of triangles per draw call: " << m_numTrianglesPerDrawCall
            << TestLog::EndMessage << TestLog::Message << "Using triangle strips" << TestLog::EndMessage
            << TestLog::Message
            << "Approximate texture memory usage limit: " << de::floatToString((float)m_maxTexMemoryUsageBytes / Mi, 2)
            << " MiB" << TestLog::EndMessage << TestLog::Message
            << "Approximate buffer memory usage limit: " << de::floatToString((float)m_maxBufMemoryUsageBytes / Mi, 2)
            << " MiB" << TestLog::EndMessage << TestLog::Message
            << "Default vertex attribute data buffer usage parameter: " << glu::getUsageName(m_attrBufferUsage)
            << TestLog::EndMessage << TestLog::Message
            << "Default vertex index data buffer usage parameter: " << glu::getUsageName(m_indexBufferUsage)
            << TestLog::EndMessage

            << TestLog::Section("ProbabilityParams", "Per-iteration probability parameters") << TestLog::Message
            << "Program re-build: " << probabilityStr(m_probabilities.rebuildProgram) << TestLog::EndMessage
            << TestLog::Message << "Texture re-upload: " << probabilityStr(m_probabilities.reuploadTexture)
            << TestLog::EndMessage << TestLog::Message
            << "Buffer re-upload: " << probabilityStr(m_probabilities.reuploadBuffer) << TestLog::EndMessage
            << TestLog::Message << "Use glTexImage* instead of glTexSubImage* when uploading texture: "
            << probabilityStr(m_probabilities.reuploadWithTexImage) << TestLog::EndMessage << TestLog::Message
            << "Use glBufferData* instead of glBufferSubData* when uploading buffer: "
            << probabilityStr(m_probabilities.reuploadWithBufferData) << TestLog::EndMessage << TestLog::Message
            << "Delete texture after using it, even if could re-use it: "
            << probabilityStr(m_probabilities.deleteTexture) << TestLog::EndMessage << TestLog::Message
            << "Delete buffer after using it, even if could re-use it: " << probabilityStr(m_probabilities.deleteBuffer)
            << TestLog::EndMessage << TestLog::Message
            << "Don't re-use texture, and only delete if memory limit is hit: "
            << probabilityStr(m_probabilities.wastefulTextureMemoryUsage) << TestLog::EndMessage << TestLog::Message
            << "Don't re-use buffer, and only delete if memory limit is hit: "
            << probabilityStr(m_probabilities.wastefulBufferMemoryUsage) << TestLog::EndMessage << TestLog::Message
            << "Use client memory (instead of GL buffers) for vertex attribute data: "
            << probabilityStr(m_probabilities.clientMemoryAttributeData) << TestLog::EndMessage << TestLog::Message
            << "Use client memory (instead of GL buffers) for vertex index data: "
            << probabilityStr(m_probabilities.clientMemoryIndexData) << TestLog::EndMessage << TestLog::Message
            << "Use random target parameter when uploading buffer data: "
            << probabilityStr(m_probabilities.randomBufferUploadTarget) << TestLog::EndMessage << TestLog::Message
            << "Use random usage parameter when uploading buffer data: "
            << probabilityStr(m_probabilities.randomBufferUsage) << TestLog::EndMessage << TestLog::Message
            << "Use glDrawArrays instead of glDrawElements: " << probabilityStr(m_probabilities.useDrawArrays)
            << TestLog::EndMessage << TestLog::Message
            << "Use separate buffers for each attribute, instead of one array for all: "
            << probabilityStr(m_probabilities.separateAttributeBuffers) << TestLog::EndMessage << TestLog::EndSection
            << TestLog::Message << "Using " << m_programContexts.size() << " program(s)" << TestLog::EndMessage;

        bool anyProgramsFailed = false;
        for (int progCtxNdx = 0; progCtxNdx < (int)m_programContexts.size(); progCtxNdx++)
        {
            const ProgramContext &progCtx = m_programContexts[progCtxNdx];
            glu::ShaderProgram prog(m_renderCtx,
                                    glu::makeVtxFragSources(mangleShaderNames(progCtx.vertexSource, ""),
                                                            mangleShaderNames(progCtx.fragmentSource, "")));
            log << TestLog::Section("ShaderProgram" + toString(progCtxNdx), "Shader program " + toString(progCtxNdx))
                << prog << TestLog::EndSection;
            if (!prog.isOk())
                anyProgramsFailed = true;
        }

        if (anyProgramsFailed)
            throw tcu::TestError("One or more shader programs failed to compile");
    }

    DE_ASSERT(!m_debugInfoRenderer);
    if (m_showDebugInfo)
        m_debugInfoRenderer = new DebugInfoRenderer(m_renderCtx);
}

void LongStressCase::deinit(void)
{
    m_programResources.clear();

    delete m_programs;
    m_programs = DE_NULL;

    delete m_buffers;
    m_buffers = DE_NULL;

    delete m_textures;
    m_textures = DE_NULL;

    delete m_debugInfoRenderer;
    m_debugInfoRenderer = DE_NULL;
}

LongStressCase::IterateResult LongStressCase::iterate(void)
{
    TestLog &log                            = m_testCtx.getLog();
    const int renderWidth                   = m_renderCtx.getRenderTarget().getWidth();
    const int renderHeight                  = m_renderCtx.getRenderTarget().getHeight();
    const bool useClientMemoryIndexData     = m_rnd.getFloat() < m_probabilities.clientMemoryIndexData;
    const bool useDrawArrays                = m_rnd.getFloat() < m_probabilities.useDrawArrays;
    const bool separateAttributeBuffers     = m_rnd.getFloat() < m_probabilities.separateAttributeBuffers;
    const int progContextNdx                = m_rnd.getInt(0, (int)m_programContexts.size() - 1);
    const ProgramContext &programContext    = m_programContexts[progContextNdx];
    ProgramResources &programResources      = m_programResources[progContextNdx];
    const string programName                = "prog" + toString(progContextNdx);
    const string textureNamePrefix          = "tex" + toString(progContextNdx) + "_";
    const string unitedAttrBufferNamePrefix = "attrBuf" + toString(progContextNdx) + "_";
    const string indexBufferName            = "indexBuf" + toString(progContextNdx);
    const string separateAttrBufNamePrefix  = "attrBuf" + toString(progContextNdx) + "_";

    if (m_currentIteration == 0)
        m_lastLogTime = m_startTimeSeconds = deGetTime();

    // Make or re-compile programs.
    {
        const bool hadProgram = m_programs->has(programName);

        if (!hadProgram)
            m_programs->make(programName);

        Program &prog = m_programs->get(programName);

        if (!hadProgram || m_rnd.getFloat() < m_probabilities.rebuildProgram)
        {
            programResources.shaderNameManglingSuffix =
                toString((uint16_t)deUint64Hash((uint64_t)m_currentIteration ^ deGetTime()));

            prog.setSources(
                mangleShaderNames(programContext.vertexSource, programResources.shaderNameManglingSuffix),
                mangleShaderNames(programContext.fragmentSource, programResources.shaderNameManglingSuffix));

            prog.build(log);
        }

        prog.use();
    }

    Program &program = m_programs->get(programName);

    // Make or re-upload textures.

    for (int texNdx = 0; texNdx < (int)programContext.textureSpecs.size(); texNdx++)
    {
        const string texName    = textureNamePrefix + toString(texNdx);
        const bool hadTexture   = m_textures->has(texName);
        const TextureSpec &spec = programContext.textureSpecs[texNdx];

        if (!hadTexture)
            m_textures->make(texName, spec.textureType);

        if (!hadTexture || m_rnd.getFloat() < m_probabilities.reuploadTexture)
        {
            Texture &texture = m_textures->get(texName);

            m_textures->removeGarbageUntilUnder(
                m_maxTexMemoryUsageBytes -
                    texture.getApproxMemUsageDiff(spec.width, spec.height, spec.internalFormat, spec.useMipmap),
                m_rnd);

            if (!hadTexture || m_rnd.getFloat() < m_probabilities.reuploadWithTexImage)
                texture.setData(programResources.dummyTextures[texNdx]->getAccess(), spec.width, spec.height,
                                spec.internalFormat, spec.useMipmap);
            else
                texture.setSubData(programResources.dummyTextures[texNdx]->getAccess(), 0, 0, spec.width, spec.height);

            texture.toUnit(0);
            texture.setWrap(spec.sWrap, spec.tWrap);
            texture.setFilter(spec.minFilter, spec.magFilter);
        }
    }

    // Bind textures to units, in random order (because when multiple texture specs have same unit, we want to pick one randomly).

    {
        vector<int> texSpecIndices(programContext.textureSpecs.size());
        for (int i = 0; i < (int)texSpecIndices.size(); i++)
            texSpecIndices[i] = i;
        m_rnd.shuffle(texSpecIndices.begin(), texSpecIndices.end());
        for (int i = 0; i < (int)texSpecIndices.size(); i++)
            m_textures->get(textureNamePrefix + toString(texSpecIndices[i]))
                .toUnit(programContext.textureSpecs[i].textureUnit);
    }

    // Make or re-upload index buffer.

    if (!useDrawArrays)
    {
        m_rnd.shuffle(m_vertexIndices.begin(), m_vertexIndices.end());

        if (!useClientMemoryIndexData)
        {
            const bool hadIndexBuffer = m_buffers->has(indexBufferName);

            if (!hadIndexBuffer)
                m_buffers->make(indexBufferName);

            Buffer &indexBuf = m_buffers->get(indexBufferName);

            if (!hadIndexBuffer || m_rnd.getFloat() < m_probabilities.reuploadBuffer)
            {
                m_buffers->removeGarbageUntilUnder(
                    m_maxBufMemoryUsageBytes - indexBuf.getApproxMemUsageDiff(m_vertexIndices), m_rnd);
                const uint32_t target = m_rnd.getFloat() < m_probabilities.randomBufferUploadTarget ?
                                            randomBufferTarget(m_rnd, m_isGLES3) :
                                            GL_ELEMENT_ARRAY_BUFFER;

                if (!hadIndexBuffer || m_rnd.getFloat() < m_probabilities.reuploadWithBufferData)
                    indexBuf.setData(m_vertexIndices, target,
                                     m_rnd.getFloat() < m_probabilities.randomBufferUsage ?
                                         randomBufferUsage(m_rnd, m_isGLES3) :
                                         m_indexBufferUsage);
                else
                    indexBuf.setSubData(m_vertexIndices, 0, m_numVerticesPerDrawCall, target);
            }
        }
    }

    // Set vertex attributes. If not using client-memory data, make or re-upload attribute buffers.

    generateAttribs(programResources.attrDataBuf, programResources.attrDataOffsets, programResources.attrDataSizes,
                    programContext.attributes, programContext.positionAttrName, m_numVerticesPerDrawCall, m_rnd);

    if (!(m_rnd.getFloat() < m_probabilities.clientMemoryAttributeData))
    {
        if (separateAttributeBuffers)
        {
            for (int attrNdx = 0; attrNdx < (int)programContext.attributes.size(); attrNdx++)
            {
                const int usedRedundantBufferNdx = m_rnd.getInt(0, m_redundantBufferFactor - 1);

                for (int redundantBufferNdx = 0; redundantBufferNdx < m_redundantBufferFactor; redundantBufferNdx++)
                {
                    const string curAttrBufName =
                        separateAttrBufNamePrefix + toString(attrNdx) + "_" + toString(redundantBufferNdx);
                    const bool hadCurAttrBuffer = m_buffers->has(curAttrBufName);

                    if (!hadCurAttrBuffer)
                        m_buffers->make(curAttrBufName);

                    Buffer &curAttrBuf = m_buffers->get(curAttrBufName);

                    if (!hadCurAttrBuffer || m_rnd.getFloat() < m_probabilities.reuploadBuffer)
                    {
                        m_buffers->removeGarbageUntilUnder(
                            m_maxBufMemoryUsageBytes -
                                curAttrBuf.getApproxMemUsageDiff(programResources.attrDataSizes[attrNdx]),
                            m_rnd);
                        const uint32_t target = m_rnd.getFloat() < m_probabilities.randomBufferUploadTarget ?
                                                    randomBufferTarget(m_rnd, m_isGLES3) :
                                                    GL_ARRAY_BUFFER;

                        if (!hadCurAttrBuffer || m_rnd.getFloat() < m_probabilities.reuploadWithBufferData)
                            curAttrBuf.setData(&programResources.attrDataBuf[programResources.attrDataOffsets[attrNdx]],
                                               programResources.attrDataSizes[attrNdx], target,
                                               m_rnd.getFloat() < m_probabilities.randomBufferUsage ?
                                                   randomBufferUsage(m_rnd, m_isGLES3) :
                                                   m_attrBufferUsage);
                        else
                            curAttrBuf.setSubData(
                                &programResources.attrDataBuf[programResources.attrDataOffsets[attrNdx]], 0,
                                programResources.attrDataSizes[attrNdx], target);
                    }

                    if (redundantBufferNdx == usedRedundantBufferNdx)
                        program.setAttribute(curAttrBuf, 0, programContext.attributes[attrNdx],
                                             programResources.shaderNameManglingSuffix);
                }
            }
        }
        else
        {
            const int usedRedundantBufferNdx = m_rnd.getInt(0, m_redundantBufferFactor - 1);

            for (int redundantBufferNdx = 0; redundantBufferNdx < m_redundantBufferFactor; redundantBufferNdx++)
            {
                const string attrBufName = unitedAttrBufferNamePrefix + toString(redundantBufferNdx);
                const bool hadAttrBuffer = m_buffers->has(attrBufName);

                if (!hadAttrBuffer)
                    m_buffers->make(attrBufName);

                Buffer &attrBuf = m_buffers->get(attrBufName);

                if (!hadAttrBuffer || m_rnd.getFloat() < m_probabilities.reuploadBuffer)
                {
                    m_buffers->removeGarbageUntilUnder(
                        m_maxBufMemoryUsageBytes - attrBuf.getApproxMemUsageDiff(programResources.attrDataBuf), m_rnd);
                    const uint32_t target = m_rnd.getFloat() < m_probabilities.randomBufferUploadTarget ?
                                                randomBufferTarget(m_rnd, m_isGLES3) :
                                                GL_ARRAY_BUFFER;

                    if (!hadAttrBuffer || m_rnd.getFloat() < m_probabilities.reuploadWithBufferData)
                        attrBuf.setData(programResources.attrDataBuf, target,
                                        m_rnd.getFloat() < m_probabilities.randomBufferUsage ?
                                            randomBufferUsage(m_rnd, m_isGLES3) :
                                            m_attrBufferUsage);
                    else
                        attrBuf.setSubData(programResources.attrDataBuf, 0, (int)programResources.attrDataBuf.size(),
                                           target);
                }

                if (redundantBufferNdx == usedRedundantBufferNdx)
                {
                    for (int i = 0; i < (int)programContext.attributes.size(); i++)
                        program.setAttribute(attrBuf, programResources.attrDataOffsets[i], programContext.attributes[i],
                                             programResources.shaderNameManglingSuffix);
                }
            }
        }
    }
    else
    {
        for (int i = 0; i < (int)programContext.attributes.size(); i++)
            program.setAttributeClientMem(&programResources.attrDataBuf[programResources.attrDataOffsets[i]],
                                          programContext.attributes[i], programResources.shaderNameManglingSuffix);
    }

    // Draw.

    glViewport(0, 0, renderWidth, renderHeight);

    glClearDepthf(1.0f);
    glClear(GL_DEPTH_BUFFER_BIT);
    glEnable(GL_DEPTH_TEST);

    for (int i = 0; i < m_numDrawCallsPerIteration; i++)
    {
        program.use();
        program.setRandomUniforms(programContext.uniforms, programResources.shaderNameManglingSuffix, m_rnd);

        if (useDrawArrays)
            glDrawArrays(GL_TRIANGLE_STRIP, 0, m_numVerticesPerDrawCall);
        else
        {
            if (useClientMemoryIndexData)
            {
                glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0);
                glDrawElements(GL_TRIANGLE_STRIP, m_numVerticesPerDrawCall, GL_UNSIGNED_SHORT, &m_vertexIndices[0]);
            }
            else
            {
                m_buffers->get(indexBufferName).bind(GL_ELEMENT_ARRAY_BUFFER);
                glDrawElements(GL_TRIANGLE_STRIP, m_numVerticesPerDrawCall, GL_UNSIGNED_SHORT, DE_NULL);
            }
        }
    }

    for (int i = 0; i < (int)programContext.attributes.size(); i++)
        program.disableAttributeArray(programContext.attributes[i], programResources.shaderNameManglingSuffix);

    if (m_showDebugInfo)
        m_debugInfoRenderer->drawInfo(deGetTime() - m_startTimeSeconds, m_textures->computeApproxMemUsage(),
                                      m_maxTexMemoryUsageBytes, m_buffers->computeApproxMemUsage(),
                                      m_maxBufMemoryUsageBytes, m_currentIteration);

    if (m_currentIteration > 0)
    {
        // Log if a certain amount of time has passed since last log entry (or if this is the last iteration).

        const uint64_t loggingIntervalSeconds = 10;
        const uint64_t time                   = deGetTime();
        const uint64_t timeDiff               = time - m_lastLogTime;
        const int iterDiff                    = m_currentIteration - m_lastLogIteration;

        if (timeDiff >= loggingIntervalSeconds || m_currentIteration == m_numIterations - 1)
        {
            log << TestLog::Section("LogEntry" + toString(m_currentLogEntryNdx),
                                    "Log entry " + toString(m_currentLogEntryNdx))
                << TestLog::Message << "Time elapsed: " << getTimeStr(time - m_startTimeSeconds) << TestLog::EndMessage
                << TestLog::Message << "Frame number: " << m_currentIteration << TestLog::EndMessage << TestLog::Message
                << "Time since last log entry: " << timeDiff << "s" << TestLog::EndMessage << TestLog::Message
                << "Frames since last log entry: " << iterDiff << TestLog::EndMessage << TestLog::Message
                << "Average frame time since last log entry: "
                << de::floatToString((float)timeDiff / (float)iterDiff, 2) << "s" << TestLog::EndMessage
                << TestLog::Message << "Approximate texture memory usage: "
                << de::floatToString((float)m_textures->computeApproxMemUsage() / Mi, 2) << " MiB / "
                << de::floatToString((float)m_maxTexMemoryUsageBytes / Mi, 2) << " MiB" << TestLog::EndMessage
                << TestLog::Message << "Approximate buffer memory usage: "
                << de::floatToString((float)m_buffers->computeApproxMemUsage() / Mi, 2) << " MiB / "
                << de::floatToString((float)m_maxBufMemoryUsageBytes / Mi, 2) << " MiB" << TestLog::EndMessage
                << TestLog::EndSection;

            m_lastLogTime      = time;
            m_lastLogIteration = m_currentIteration;
            m_currentLogEntryNdx++;
        }
    }

    // Possibly remove or set-as-garbage some objects, depending on given probabilities.

    for (int texNdx = 0; texNdx < (int)programContext.textureSpecs.size(); texNdx++)
    {
        const string texName = textureNamePrefix + toString(texNdx);
        if (m_rnd.getFloat() < m_probabilities.deleteTexture)
            m_textures->remove(texName);
        else if (m_rnd.getFloat() < m_probabilities.wastefulTextureMemoryUsage)
            m_textures->markAsGarbage(texName);
    }

    if (m_buffers->has(indexBufferName))
    {
        if (m_rnd.getFloat() < m_probabilities.deleteBuffer)
            m_buffers->remove(indexBufferName);
        else if (m_rnd.getFloat() < m_probabilities.wastefulBufferMemoryUsage)
            m_buffers->markAsGarbage(indexBufferName);
    }

    if (separateAttributeBuffers)
    {
        for (int attrNdx = 0; attrNdx < (int)programContext.attributes.size(); attrNdx++)
        {
            const string curAttrBufNamePrefix = separateAttrBufNamePrefix + toString(attrNdx) + "_";

            if (m_buffers->has(curAttrBufNamePrefix + "0"))
            {
                if (m_rnd.getFloat() < m_probabilities.deleteBuffer)
                {
                    for (int i = 0; i < m_redundantBufferFactor; i++)
                        m_buffers->remove(curAttrBufNamePrefix + toString(i));
                }
                else if (m_rnd.getFloat() < m_probabilities.wastefulBufferMemoryUsage)
                {
                    for (int i = 0; i < m_redundantBufferFactor; i++)
                        m_buffers->markAsGarbage(curAttrBufNamePrefix + toString(i));
                }
            }
        }
    }
    else
    {
        if (m_buffers->has(unitedAttrBufferNamePrefix + "0"))
        {
            if (m_rnd.getFloat() < m_probabilities.deleteBuffer)
            {
                for (int i = 0; i < m_redundantBufferFactor; i++)
                    m_buffers->remove(unitedAttrBufferNamePrefix + toString(i));
            }
            else if (m_rnd.getFloat() < m_probabilities.wastefulBufferMemoryUsage)
            {
                for (int i = 0; i < m_redundantBufferFactor; i++)
                    m_buffers->markAsGarbage(unitedAttrBufferNamePrefix + toString(i));
            }
        }
    }

    GLU_CHECK_MSG("End of LongStressCase::iterate()");

    m_currentIteration++;
    if (m_currentIteration == m_numIterations)
    {
        m_testCtx.setTestResult(QP_TEST_RESULT_PASS, "Passed");
        return STOP;
    }
    else
        return CONTINUE;
}

} // namespace gls
} // namespace deqp
