/****************************************************************************
**
** Copyright (C) 2014 Klaralvdalens Datakonsult AB (KDAB).
** Contact: https://www.qt.io/licensing/
**
** This file is part of the Qt3D module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "graphicshelperes2_p.h"
#include <private/attachmentpack_p.h>
#include <qgraphicsutils_p.h>
#include <renderbuffer_p.h>
#include <logging_p.h>
#include <QtGui/private/qopenglextensions_p.h>


QT_BEGIN_NAMESPACE

// ES 3.0+
#ifndef GL_SAMPLER_3D
#define GL_SAMPLER_3D                     0x8B5F
#endif
#ifndef GL_SAMPLER_2D_SHADOW
#define GL_SAMPLER_2D_SHADOW              0x8B62
#endif
#ifndef GL_SAMPLER_CUBE_SHADOW
#define GL_SAMPLER_CUBE_SHADOW            0x8DC5
#endif
#ifndef GL_SAMPLER_2D_ARRAY
#define GL_SAMPLER_2D_ARRAY               0x8DC1
#endif
#ifndef GL_SAMPLER_2D_ARRAY_SHADOW
#define GL_SAMPLER_2D_ARRAY_SHADOW        0x8DC4
#endif

namespace Qt3DRender {
namespace Render {
namespace OpenGL {

GraphicsHelperES2::GraphicsHelperES2()
    : m_funcs(0)
    , m_supportFramebufferBlit(false)
{
}

GraphicsHelperES2::~GraphicsHelperES2()
{
}

void GraphicsHelperES2::initializeHelper(QOpenGLContext *context,
                                          QAbstractOpenGLFunctions *)
{
    Q_ASSERT(context);
    m_funcs = context->functions();
    Q_ASSERT(m_funcs);
    m_ext.reset(new QOpenGLExtensions(context));
    if (m_ext->hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit))
        m_supportFramebufferBlit = true;
}

void GraphicsHelperES2::drawElementsInstancedBaseVertexBaseInstance(GLenum primitiveType,
                                                                    GLsizei primitiveCount,
                                                                    GLint indexType,
                                                                    void *indices,
                                                                    GLsizei instances,
                                                                    GLint baseVertex,
                                                                    GLint baseInstance)
{
    if (baseInstance != 0)
        qWarning() << "glDrawElementsInstancedBaseVertexBaseInstance is not supported with OpenGL ES 2";

    if (baseVertex != 0)
        qWarning() << "glDrawElementsInstancedBaseVertex is not supported with OpenGL ES 2";

    for (GLint i = 0; i < instances; i++)
        drawElements(primitiveType,
                     primitiveCount,
                     indexType,
                     indices);
}

void GraphicsHelperES2::drawArraysInstanced(GLenum primitiveType,
                                             GLint first,
                                             GLsizei count,
                                             GLsizei instances)
{
    for (GLint i = 0; i < instances; i++)
        drawArrays(primitiveType,
                   first,
                   count);
}

void GraphicsHelperES2::drawArraysInstancedBaseInstance(GLenum primitiveType, GLint first, GLsizei count, GLsizei instances, GLsizei baseInstance)
{
    if (baseInstance != 0)
        qWarning() << "glDrawArraysInstancedBaseInstance is not supported with OpenGL ES 2";
    for (GLint i = 0; i < instances; i++)
        drawArrays(primitiveType,
                   first,
                   count);
}

void GraphicsHelperES2::drawElements(GLenum primitiveType,
                                      GLsizei primitiveCount,
                                      GLint indexType,
                                      void *indices,
                                      GLint baseVertex)
{
    if (baseVertex != 0)
        qWarning() << "glDrawElementsBaseVertex is not supported with OpenGL ES 2";
    QOpenGLExtensions *xfuncs = static_cast<QOpenGLExtensions *>(m_funcs);
    if (indexType == GL_UNSIGNED_INT && !xfuncs->hasOpenGLExtension(QOpenGLExtensions::ElementIndexUint)) {
        static bool warnShown = false;
        if (!warnShown) {
            warnShown = true;
            qWarning("GL_UNSIGNED_INT index type not supported on this system, skipping draw call.");
        }
        return;
    }
    m_funcs->glDrawElements(primitiveType,
                            primitiveCount,
                            indexType,
                            indices);
}

void GraphicsHelperES2::drawArrays(GLenum primitiveType,
                                    GLint first,
                                    GLsizei count)
{
    m_funcs->glDrawArrays(primitiveType,
                          first,
                          count);
}

void GraphicsHelperES2::drawElementsIndirect(GLenum, GLenum, void *)
{
    static bool showWarning = true;
    if (!showWarning)
        return;
    showWarning = false;
    qWarning() << "Indirect Drawing is not supported with OpenGL ES 2";
}

void GraphicsHelperES2::drawArraysIndirect(GLenum , void *)
{
    static bool showWarning = true;
    if (!showWarning)
        return;
    showWarning = false;
    qWarning() << "Indirect Drawing is not supported with OpenGL ES 2";
}

void GraphicsHelperES2::setVerticesPerPatch(GLint verticesPerPatch)
{
    Q_UNUSED(verticesPerPatch);
    static bool showWarning = true;
    if (!showWarning)
        return;
    showWarning = false;
    qWarning() << "Tessellation not supported with OpenGL ES 2";
}

void GraphicsHelperES2::useProgram(GLuint programId)
{
    m_funcs->glUseProgram(programId);
}

QVector<ShaderUniform> GraphicsHelperES2::programUniformsAndLocations(GLuint programId)
{
    QVector<ShaderUniform> uniforms;

    GLint nbrActiveUniforms = 0;
    m_funcs->glGetProgramiv(programId, GL_ACTIVE_UNIFORMS, &nbrActiveUniforms);
    uniforms.reserve(nbrActiveUniforms);
    char uniformName[256];
    for (GLint i = 0; i < nbrActiveUniforms; i++) {
        ShaderUniform uniform;
        GLsizei uniformNameLength = 0;
        // Size is 1 for scalar and more for struct or arrays
        // Type is the GL Type
        m_funcs->glGetActiveUniform(programId, i, sizeof(uniformName) - 1, &uniformNameLength,
                                    &uniform.m_size, &uniform.m_type, uniformName);
        uniformName[sizeof(uniformName) - 1] = '\0';
        uniform.m_location = m_funcs->glGetUniformLocation(programId, uniformName);
        uniform.m_name = QString::fromUtf8(uniformName, uniformNameLength);
        // Work around for uniform array names that aren't returned with [0] by some drivers
        if (uniform.m_size > 1 && !uniform.m_name.endsWith(QLatin1String("[0]")))
            uniform.m_name.append(QLatin1String("[0]"));
        uniform.m_rawByteSize = uniformByteSize(uniform);
        uniforms.append(uniform);
    }
    return uniforms;
}

QVector<ShaderAttribute> GraphicsHelperES2::programAttributesAndLocations(GLuint programId)
{
    QVector<ShaderAttribute> attributes;
    GLint nbrActiveAttributes = 0;
    m_funcs->glGetProgramiv(programId, GL_ACTIVE_ATTRIBUTES, &nbrActiveAttributes);
    attributes.reserve(nbrActiveAttributes);
    char attributeName[256];
    for (GLint i = 0; i < nbrActiveAttributes; i++) {
        ShaderAttribute attribute;
        GLsizei attributeNameLength = 0;
        // Size is 1 for scalar and more for struct or arrays
        // Type is the GL Type
        m_funcs->glGetActiveAttrib(programId, i, sizeof(attributeName) - 1, &attributeNameLength,
                                   &attribute.m_size, &attribute.m_type, attributeName);
        attributeName[sizeof(attributeName) - 1] = '\0';
        attribute.m_location = m_funcs->glGetAttribLocation(programId, attributeName);
        attribute.m_name = QString::fromUtf8(attributeName, attributeNameLength);
        attributes.append(attribute);
    }
    return attributes;
}

QVector<ShaderUniformBlock> GraphicsHelperES2::programUniformBlocks(GLuint programId)
{
    Q_UNUSED(programId);
    QVector<ShaderUniformBlock> blocks;
    static bool showWarning = true;
    if (!showWarning)
        return blocks;
    showWarning = false;
    qWarning() << "UBO are not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)";
    return blocks;
}

QVector<ShaderStorageBlock> GraphicsHelperES2::programShaderStorageBlocks(GLuint programId)
{
    Q_UNUSED(programId);
    QVector<ShaderStorageBlock> blocks;
    static bool showWarning = true;
    if (!showWarning)
        return blocks;
    showWarning = false;
    qWarning() << "SSBO are not supported by OpenGL ES 2.0 (since OpenGL ES 3.1)";
    return blocks;
}

void GraphicsHelperES2::vertexAttribDivisor(GLuint index, GLuint divisor)
{
    Q_UNUSED(index);
    Q_UNUSED(divisor);
}

void GraphicsHelperES2::vertexAttributePointer(GLenum shaderDataType,
                                               GLuint index,
                                               GLint size,
                                               GLenum type,
                                               GLboolean normalized,
                                               GLsizei stride,
                                               const GLvoid *pointer)
{
    switch (shaderDataType) {
    case GL_FLOAT:
    case GL_FLOAT_VEC2:
    case GL_FLOAT_VEC3:
    case GL_FLOAT_VEC4:
    case GL_FLOAT_MAT2:
    case GL_FLOAT_MAT3:
    case GL_FLOAT_MAT4:
        m_funcs->glVertexAttribPointer(index, size, type, normalized, stride, pointer);
        break;

    default:
        qCWarning(Rendering) << "vertexAttribPointer: Unhandled type";
        Q_UNREACHABLE();
    }
}

void GraphicsHelperES2::readBuffer(GLenum mode)
{
    Q_UNUSED(mode)
    static bool showWarning = true;
    if (!showWarning)
        return;
    showWarning = false;
    qWarning() << "glReadBuffer not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)";
}

void GraphicsHelperES2::drawBuffer(GLenum mode)
{
    Q_UNUSED(mode);
    static bool showWarning = true;
    if (!showWarning)
        return;
    showWarning = false;
    qWarning() << "glDrawBuffer is not supported with OpenGL ES 2";
}

void *GraphicsHelperES2::fenceSync()
{
    qWarning() << "Fences are not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)";
    return nullptr;
}

void GraphicsHelperES2::clientWaitSync(void *, GLuint64 )
{
    qWarning() << "Fences are not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)";
}

void GraphicsHelperES2::waitSync(void *)
{
    qWarning() << "Fences are not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)";
}

bool GraphicsHelperES2::wasSyncSignaled(void *)
{
    qWarning() << "Fences are not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)";
    return false;
}

void GraphicsHelperES2::deleteSync(void *)
{
    qWarning() << "Fences are not supported by OpenGL ES 2.0 (since OpenGL ES 3.0)";
}

void GraphicsHelperES2::rasterMode(GLenum faceMode, GLenum rasterMode)
{
    Q_UNUSED(faceMode);
    Q_UNUSED(rasterMode);
    qWarning() << "glPolyonMode is not supported with OpenGL ES";
}

void GraphicsHelperES2::blendEquation(GLenum mode)
{
    m_funcs->glBlendEquation(mode);
}

void GraphicsHelperES2::blendFunci(GLuint buf, GLenum sfactor, GLenum dfactor)
{
    Q_UNUSED(buf);
    Q_UNUSED(sfactor);
    Q_UNUSED(dfactor);

    static bool showWarning = true;
    if (!showWarning)
        return;
    showWarning = false;
    qWarning() << "glBlendFunci() not supported by OpenGL ES 2.0";
}

void GraphicsHelperES2::blendFuncSeparatei(GLuint buf, GLenum sRGB, GLenum dRGB, GLenum sAlpha, GLenum dAlpha)
{
    Q_UNUSED(buf);
    Q_UNUSED(sRGB);
    Q_UNUSED(dRGB);
    Q_UNUSED(sAlpha);
    Q_UNUSED(dAlpha);

    static bool showWarning = true;
    if (!showWarning)
        return;
    showWarning = false;
    qWarning() << "glBlendFuncSeparatei() not supported by OpenGL ES 2.0";
}

void GraphicsHelperES2::alphaTest(GLenum, GLenum)
{
    qCWarning(Rendering) << Q_FUNC_INFO << "AlphaTest not available with OpenGL ES 2.0";
}

void GraphicsHelperES2::depthTest(GLenum mode)
{
    m_funcs->glEnable(GL_DEPTH_TEST);
    m_funcs->glDepthFunc(mode);
}

void GraphicsHelperES2::depthMask(GLenum mode)
{
    m_funcs->glDepthMask(mode);
}

void GraphicsHelperES2::depthRange(GLdouble nearValue, GLdouble farValue)
{
    m_funcs->glDepthRangef(static_cast<float>(nearValue), static_cast<float>(farValue));
}

void GraphicsHelperES2::frontFace(GLenum mode)
{
    m_funcs->glFrontFace(mode);
}

void GraphicsHelperES2::setMSAAEnabled(bool enabled)
{
    Q_UNUSED(enabled);
    static bool showWarning = true;
    if (!showWarning)
        return;
    if (!enabled) {
        showWarning = false;
        qWarning() << "MSAA cannot be disabled with OpenGL ES 2.0";
    }
}

void GraphicsHelperES2::setAlphaCoverageEnabled(bool enabled)
{
    enabled ? m_funcs->glEnable(GL_SAMPLE_ALPHA_TO_COVERAGE)
            : m_funcs->glDisable(GL_SAMPLE_ALPHA_TO_COVERAGE);
}

GLuint GraphicsHelperES2::createFrameBufferObject()
{
    GLuint id;
    m_funcs->glGenFramebuffers(1, &id);
    return id;
}

void GraphicsHelperES2::releaseFrameBufferObject(GLuint frameBufferId)
{
    m_funcs->glDeleteFramebuffers(1, &frameBufferId);
}

void GraphicsHelperES2::bindFrameBufferObject(GLuint frameBufferId, FBOBindMode mode)
{
    Q_UNUSED(mode)
    // For ES2 the spec states for target: The symbolic constant must be GL_FRAMEBUFFER
    // so mode is ignored and is always set to GL_FRAMEBUFFER
    m_funcs->glBindFramebuffer(GL_FRAMEBUFFER, frameBufferId);
}

void GraphicsHelperES2::bindImageTexture(GLuint imageUnit, GLuint texture,
                                         GLint mipLevel, GLboolean layered,
                                         GLint layer, GLenum access, GLenum format)
{
    Q_UNUSED(imageUnit)
    Q_UNUSED(texture)
    Q_UNUSED(mipLevel)
    Q_UNUSED(layered)
    Q_UNUSED(layer)
    Q_UNUSED(access)
    Q_UNUSED(format)
    qWarning() << "Shader Images are not supported by ES 2.0 (since ES 3.1)";

}

GLuint GraphicsHelperES2::boundFrameBufferObject()
{
    GLint id = 0;
    m_funcs->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &id);
    return id;
}

bool GraphicsHelperES2::checkFrameBufferComplete()
{
    return (m_funcs->glCheckFramebufferStatus(GL_FRAMEBUFFER) == GL_FRAMEBUFFER_COMPLETE);
}

bool GraphicsHelperES2::frameBufferNeedsRenderBuffer(const Attachment &attachment)
{
    // Use a renderbuffer for depth or stencil attachments since this is
    // problematic before GLES 3.2. Keep using textures for everything else.
    // For ES2 individual Depth and Stencil buffers need to be an option because
    // DepthStencil is an extension.
    return attachment.m_point == QRenderTargetOutput::DepthStencil ||
           attachment.m_point == QRenderTargetOutput::Depth ||
           attachment.m_point == QRenderTargetOutput::Stencil;
}

void GraphicsHelperES2::bindFrameBufferAttachment(QOpenGLTexture *texture, const Attachment &attachment)
{
    GLenum attr = GL_COLOR_ATTACHMENT0;

    if (attachment.m_point == QRenderTargetOutput::Color0)
        attr = GL_COLOR_ATTACHMENT0;
    else if (attachment.m_point == QRenderTargetOutput::Depth)
        attr = GL_DEPTH_ATTACHMENT;
    else if (attachment.m_point == QRenderTargetOutput::Stencil)
        attr = GL_STENCIL_ATTACHMENT;
    else
        qCritical() << "Unsupported FBO attachment OpenGL ES 2.0";

    const QOpenGLTexture::Target target = texture->target();

    if (target == QOpenGLTexture::TargetCubeMap && attachment.m_face == QAbstractTexture::AllFaces) {
        qWarning() << "OpenGL ES 2.0 doesn't handle attaching all the faces of a cube map texture at once to an FBO";
        return;
    }

    texture->bind();
    if (target == QOpenGLTexture::Target2D)
        m_funcs->glFramebufferTexture2D(GL_FRAMEBUFFER, attr, target, texture->textureId(), attachment.m_mipLevel);
    else if (target == QOpenGLTexture::TargetCubeMap)
        m_funcs->glFramebufferTexture2D(GL_FRAMEBUFFER, attr, attachment.m_face, texture->textureId(), attachment.m_mipLevel);
    else
        qCritical() << "Unsupported Texture FBO attachment format";
    texture->release();
}

void GraphicsHelperES2::bindFrameBufferAttachment(RenderBuffer *renderBuffer, const Attachment &attachment)
{
    if (attachment.m_point != QRenderTargetOutput::DepthStencil &&
        attachment.m_point != QRenderTargetOutput::Depth &&
        attachment.m_point != QRenderTargetOutput::Stencil) {
        qCritical() << "Renderbuffers only supported for combined depth-stencil, depth, or stencil, but got attachment point"
                    << attachment.m_point;
        return;
    }

    renderBuffer->bind();
    if (attachment.m_point == QRenderTargetOutput::DepthStencil ||
        attachment.m_point == QRenderTargetOutput::Depth)
        m_funcs->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT, GL_RENDERBUFFER, renderBuffer->renderBufferId());
    if (attachment.m_point == QRenderTargetOutput::DepthStencil ||
        attachment.m_point == QRenderTargetOutput::Stencil)
        m_funcs->glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT, GL_RENDERBUFFER, renderBuffer->renderBufferId());
    renderBuffer->release();
}

bool GraphicsHelperES2::supportsFeature(GraphicsHelperInterface::Feature feature) const
{
    switch (feature) {
    case RenderBufferDimensionRetrieval:
        return true;
    case BlitFramebuffer:
        return m_supportFramebufferBlit;
    default:
        return false;
    }
}

void GraphicsHelperES2::drawBuffers(GLsizei, const int *)
{
    static bool showWarning = true;
    if (!showWarning)
        return;
    showWarning = false;
    qWarning() << "drawBuffers is not supported by ES 2.0";
}

void GraphicsHelperES2::bindFragDataLocation(GLuint , const QHash<QString, int> &)
{
    qCritical() << "bindFragDataLocation is not supported by ES 2.0";
}

void GraphicsHelperES2::bindUniformBlock(GLuint programId, GLuint uniformBlockIndex, GLuint uniformBlockBinding)
{
    Q_UNUSED(programId);
    Q_UNUSED(uniformBlockIndex);
    Q_UNUSED(uniformBlockBinding);
    static bool showWarning = true;
    if (!showWarning)
        return;
    showWarning = false;
    qWarning() << "UBO are not supported by ES 2.0 (since ES 3.0)";
}

void GraphicsHelperES2::bindShaderStorageBlock(GLuint programId, GLuint shaderStorageBlockIndex, GLuint shaderStorageBlockBinding)
{
    Q_UNUSED(programId);
    Q_UNUSED(shaderStorageBlockIndex);
    Q_UNUSED(shaderStorageBlockBinding);
    static bool showWarning = true;
    if (!showWarning)
        return;
    showWarning = false;
    qWarning() << "SSBO are not supported by ES 2.0 (since ES 3.1)";
}

void GraphicsHelperES2::bindBufferBase(GLenum target, GLuint index, GLuint buffer)
{
    Q_UNUSED(target);
    Q_UNUSED(index);
    Q_UNUSED(buffer);
    static bool showWarning = true;
    if (!showWarning)
        return;
    showWarning = false;
    qWarning() << "bindBufferBase is not supported by ES 2.0 (since ES 3.0)";
}

void GraphicsHelperES2::buildUniformBuffer(const QVariant &v, const ShaderUniform &description, QByteArray &buffer)
{
    Q_UNUSED(v);
    Q_UNUSED(description);
    Q_UNUSED(buffer);
    static bool showWarning = true;
    if (!showWarning)
        return;
    showWarning = false;
    qWarning() << "UBO are not supported by ES 2.0 (since ES 3.0)";
}

uint GraphicsHelperES2::uniformByteSize(const ShaderUniform &description)
{
    uint rawByteSize = 0;
    int arrayStride = qMax(description.m_arrayStride, 0);
    int matrixStride = qMax(description.m_matrixStride, 0);

    switch (description.m_type) {

    case GL_FLOAT_VEC2:
    case GL_INT_VEC2:
        rawByteSize = 8;
        break;

    case GL_FLOAT_VEC3:
    case GL_INT_VEC3:
        rawByteSize = 12;
        break;

    case GL_FLOAT_VEC4:
    case GL_INT_VEC4:
        rawByteSize = 16;
        break;

    case GL_FLOAT_MAT2:
        rawByteSize = matrixStride ? 2 * matrixStride : 16;
        break;

    case GL_FLOAT_MAT3:
        rawByteSize = matrixStride ? 3 * matrixStride : 36;
        break;

    case GL_FLOAT_MAT4:
        rawByteSize = matrixStride ? 4 * matrixStride : 64;
        break;

    case GL_BOOL:
        rawByteSize = 1;
        break;

    case GL_BOOL_VEC2:
        rawByteSize = 2;
        break;

    case GL_BOOL_VEC3:
        rawByteSize = 3;
        break;

    case GL_BOOL_VEC4:
        rawByteSize = 4;
        break;

    case GL_INT:
    case GL_FLOAT:
    case GL_SAMPLER_2D:
    case GL_SAMPLER_CUBE:
        rawByteSize = 4;
        break;
    }

    return arrayStride ? rawByteSize * arrayStride : rawByteSize;
}

void GraphicsHelperES2::enableClipPlane(int)
{
}

void GraphicsHelperES2::disableClipPlane(int)
{
}

void GraphicsHelperES2::setClipPlane(int, const QVector3D &, float)
{
    static bool showWarning = true;
    if (!showWarning)
        return;
    showWarning = false;
    qWarning() << "Clip planes not supported by OpenGL ES 2.0";
}

GLint GraphicsHelperES2::maxClipPlaneCount()
{
    return 0;
}

void GraphicsHelperES2::memoryBarrier(QMemoryBarrier::Operations barriers)
{
    Q_UNUSED(barriers);
    static bool showWarning = true;
    if (!showWarning)
        return;
    showWarning = false;
    qWarning() << "memory barrier is not supported by OpenGL ES 2.0 (since 4.3)";
}

void GraphicsHelperES2::enablePrimitiveRestart(int)
{
}

void GraphicsHelperES2::enableVertexAttributeArray(int location)
{
    m_funcs->glEnableVertexAttribArray(location);
}

void GraphicsHelperES2::disablePrimitiveRestart()
{
}

void GraphicsHelperES2::clearBufferf(GLint drawbuffer, const QVector4D &values)
{
    Q_UNUSED(drawbuffer);
    Q_UNUSED(values);
    static bool showWarning = true;
    if (!showWarning)
        return;
    showWarning = false;
    qWarning() << "glClearBuffer*() not supported by OpenGL ES 2.0";
}

void GraphicsHelperES2::pointSize(bool programmable, GLfloat value)
{
    // If this is not a reset to default values, print a warning
    if (programmable || !qFuzzyCompare(value, 1.0f)) {
        static bool warned = false;
        if (!warned) {
            qWarning() << "glPointSize() and GL_PROGRAM_POINT_SIZE are not supported by ES 2.0";
            warned = true;
        }
    }
}

void GraphicsHelperES2::enablei(GLenum cap, GLuint index)
{
    Q_UNUSED(cap);
    Q_UNUSED(index);
    static bool showWarning = true;
    if (!showWarning)
        return;
    showWarning = false;
    qWarning() << "glEnablei() not supported by OpenGL ES 2.0";
}

void GraphicsHelperES2::disablei(GLenum cap, GLuint index)
{
    Q_UNUSED(cap);
    Q_UNUSED(index);
    static bool showWarning = true;
    if (!showWarning)
        return;
    showWarning = false;
    qWarning() << "glDisablei() not supported by OpenGL ES 2.0";
}

void GraphicsHelperES2::setSeamlessCubemap(bool enable)
{
    Q_UNUSED(enable);
    static bool showWarning = true;
    if (!showWarning)
        return;
    showWarning = false;
    qWarning() << "GL_TEXTURE_CUBE_MAP_SEAMLESS not supported by OpenGL ES 2.0";
}

QSize GraphicsHelperES2::getRenderBufferDimensions(GLuint renderBufferId)
{
    GLint width = 0;
    GLint height = 0;

    m_funcs->glBindRenderbuffer(GL_RENDERBUFFER, renderBufferId);
    m_funcs->glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_WIDTH, &width);
    m_funcs->glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_HEIGHT, &height);
    m_funcs->glBindRenderbuffer(GL_RENDERBUFFER, 0);

    return QSize(width, height);
}

QSize GraphicsHelperES2::getTextureDimensions(GLuint textureId, GLenum target, uint level)
{
    Q_UNUSED(textureId);
    Q_UNUSED(target);
    Q_UNUSED(level);
    qCritical() << "getTextureDimensions is not supported by ES 2.0";
    return QSize(0, 0);
}

void GraphicsHelperES2::dispatchCompute(GLuint wx, GLuint wy, GLuint wz)
{
    Q_UNUSED(wx);
    Q_UNUSED(wy);
    Q_UNUSED(wz);
    static bool showWarning = true;
    if (!showWarning)
        return;
    showWarning = false;
    qWarning() << "Compute Shaders are not supported by ES 2.0 (since ES 3.1)";
}

char *GraphicsHelperES2::mapBuffer(GLenum target, GLsizeiptr size)
{
    Q_UNUSED(target);
    Q_UNUSED(size);
    static bool showWarning = true;
    if (!showWarning)
        return nullptr;
    showWarning = false;
    qWarning() << "Map buffer is not a core requirement for ES 2.0";
    return nullptr;
}

GLboolean GraphicsHelperES2::unmapBuffer(GLenum target)
{
    Q_UNUSED(target);
    static bool showWarning = true;
    if (!showWarning)
        return false;
    showWarning = false;
    qWarning() << "unMap buffer is not a core requirement for ES 2.0";
    return false;
}

void GraphicsHelperES2::glUniform1fv(GLint location, GLsizei count, const GLfloat *values)
{
    m_funcs->glUniform1fv(location, count, values);
}

void GraphicsHelperES2::glUniform2fv(GLint location, GLsizei count, const GLfloat *values)
{
    m_funcs->glUniform2fv(location, count, values);
}

void GraphicsHelperES2::glUniform3fv(GLint location, GLsizei count, const GLfloat *values)
{
    m_funcs->glUniform3fv(location, count, values);
}

void GraphicsHelperES2::glUniform4fv(GLint location, GLsizei count, const GLfloat *values)
{
    m_funcs->glUniform4fv(location, count, values);
}

void GraphicsHelperES2::glUniform1iv(GLint location, GLsizei count, const GLint *values)
{
    m_funcs->glUniform1iv(location, count, values);
}

void GraphicsHelperES2::glUniform2iv(GLint location, GLsizei count, const GLint *values)
{
    m_funcs->glUniform2iv(location, count, values);
}

void GraphicsHelperES2::glUniform3iv(GLint location, GLsizei count, const GLint *values)
{
    m_funcs->glUniform3iv(location, count, values);
}

void GraphicsHelperES2::glUniform4iv(GLint location, GLsizei count, const GLint *values)
{
    m_funcs->glUniform4iv(location, count, values);
}

void GraphicsHelperES2::glUniform1uiv(GLint , GLsizei , const GLuint *)
{
    static bool showWarning = true;
    if (!showWarning)
        return;
    showWarning = false;
    qWarning() << "glUniform1uiv not supported by ES 2";
}

void GraphicsHelperES2::glUniform2uiv(GLint , GLsizei , const GLuint *)
{
    static bool showWarning = true;
    if (!showWarning)
        return;
    showWarning = false;
    qWarning() << "glUniform2uiv not supported by ES 2";
}

void GraphicsHelperES2::glUniform3uiv(GLint , GLsizei , const GLuint *)
{
    static bool showWarning = true;
    if (!showWarning)
        return;
    showWarning = false;
    qWarning() << "glUniform3uiv not supported by ES 2";
}

void GraphicsHelperES2::glUniform4uiv(GLint , GLsizei , const GLuint *)
{
    static bool showWarning = true;
    if (!showWarning)
        return;
    showWarning = false;
    qWarning() << "glUniform4uiv not supported by ES 2";
}

void GraphicsHelperES2::glUniformMatrix2fv(GLint location, GLsizei count, const GLfloat *values)
{
    m_funcs->glUniformMatrix2fv(location, count, false, values);
}

void GraphicsHelperES2::glUniformMatrix3fv(GLint location, GLsizei count, const GLfloat *values)
{
    m_funcs->glUniformMatrix3fv(location, count, false, values);
}

void GraphicsHelperES2::glUniformMatrix4fv(GLint location, GLsizei count, const GLfloat *values)
{
    m_funcs->glUniformMatrix4fv(location, count, false, values);
}

void GraphicsHelperES2::glUniformMatrix2x3fv(GLint , GLsizei , const GLfloat *)
{
    static bool showWarning = true;
    if (!showWarning)
        return;
    showWarning = false;
    qWarning() << "glUniformMatrix2x3fv not supported by ES 2";
}

void GraphicsHelperES2::glUniformMatrix3x2fv(GLint , GLsizei , const GLfloat *)
{
    static bool showWarning = true;
    if (!showWarning)
        return;
    showWarning = false;
    qWarning() << "glUniformMatrix3x2fv not supported by ES 2";
}

void GraphicsHelperES2::glUniformMatrix2x4fv(GLint , GLsizei , const GLfloat *)
{
    static bool showWarning = true;
    if (!showWarning)
        return;
    showWarning = false;
    qWarning() << "glUniformMatrix2x4fv not supported by ES 2";
}

void GraphicsHelperES2::glUniformMatrix4x2fv(GLint , GLsizei , const GLfloat *)
{
    static bool showWarning = true;
    if (!showWarning)
        return;
    showWarning = false;
    qWarning() << "glUniformMatrix4x2fv not supported by ES 2";
}

void GraphicsHelperES2::glUniformMatrix3x4fv(GLint , GLsizei , const GLfloat *)
{
    static bool showWarning = true;
    if (!showWarning)
        return;
    showWarning = false;
    qWarning() << "glUniformMatrix3x4fv not supported by ES 2";
}

void GraphicsHelperES2::glUniformMatrix4x3fv(GLint , GLsizei , const GLfloat *)
{
    static bool showWarning = true;
    if (!showWarning)
        return;
    showWarning = false;
    qWarning() << "glUniformMatrix4x3fv not supported by ES 2";
}

UniformType GraphicsHelperES2::uniformTypeFromGLType(GLenum type)
{
    switch (type) {
    case GL_FLOAT:
        return UniformType::Float;
    case GL_FLOAT_VEC2:
        return UniformType::Vec2;
    case GL_FLOAT_VEC3:
        return UniformType::Vec3;
    case GL_FLOAT_VEC4:
        return UniformType::Vec4;
    case GL_FLOAT_MAT2:
        return UniformType::Mat2;
    case GL_FLOAT_MAT3:
        return UniformType::Mat3;
    case GL_FLOAT_MAT4:
        return UniformType::Mat4;
    case GL_INT:
        return UniformType::Int;
    case GL_INT_VEC2:
        return UniformType::IVec2;
    case GL_INT_VEC3:
        return UniformType::IVec3;
    case GL_INT_VEC4:
        return UniformType::IVec4;
    case GL_BOOL:
        return UniformType::Bool;
    case GL_BOOL_VEC2:
        return UniformType::BVec2;
    case GL_BOOL_VEC3:
        return UniformType::BVec3;
    case GL_BOOL_VEC4:
        return UniformType::BVec4;

    case GL_SAMPLER_2D:
    case GL_SAMPLER_CUBE:
        return UniformType::Sampler;
    default:
        Q_UNREACHABLE();
        return UniformType::Float;
    }
}

void GraphicsHelperES2::blitFramebuffer(GLint srcX0, GLint srcY0, GLint srcX1, GLint srcY1, GLint dstX0, GLint dstY0, GLint dstX1, GLint dstY1, GLbitfield mask, GLenum filter)
{
    if (!m_supportFramebufferBlit) {
        static bool showWarning = true;
        if (!showWarning)
            return;
        showWarning = false;
        qWarning() << "Framebuffer blits are not supported by ES 2.0 (since ES 3.1)";
    } else
        m_ext->glBlitFramebuffer(srcX0, srcY0, srcX1, srcY1, dstX0, dstY0, dstX1, dstY1, mask, filter);
}

} // namespace OpenGL
} // namespace Render
} // namespace Qt3DRender

QT_END_NAMESPACE
