/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtGui 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 "qopenglshaderprogram.h"
#include "qopenglprogrambinarycache_p.h"
#include "qopenglextrafunctions.h"
#include "private/qopenglcontext_p.h"
#include <QtCore/private/qobject_p.h>
#include <QtCore/qdebug.h>
#include <QtCore/qfile.h>
#include <QtCore/qvarlengtharray.h>
#include <QtCore/qvector.h>
#include <QtCore/qloggingcategory.h>
#include <QtGui/qtransform.h>
#include <QtGui/QColor>
#include <QtGui/QSurfaceFormat>

#if !defined(QT_OPENGL_ES_2)
#include <QtGui/qopenglfunctions_4_0_core.h>
#endif

#include <algorithm>

QT_BEGIN_NAMESPACE

/*!
    \class QOpenGLShaderProgram
    \brief The QOpenGLShaderProgram class allows OpenGL shader programs to be linked and used.
    \since 5.0
    \ingroup painting-3D
    \inmodule QtGui

    \section1 Introduction

    This class supports shader programs written in the OpenGL Shading
    Language (GLSL) and in the OpenGL/ES Shading Language (GLSL/ES).

    QOpenGLShader and QOpenGLShaderProgram shelter the programmer from the details of
    compiling and linking vertex and fragment shaders.

    The following example creates a vertex shader program using the
    supplied source \c{code}.  Once compiled and linked, the shader
    program is activated in the current QOpenGLContext by calling
    QOpenGLShaderProgram::bind():

    \snippet code/src_gui_qopenglshaderprogram.cpp 0

    \section1 Writing Portable Shaders

    Shader programs can be difficult to reuse across OpenGL implementations
    because of varying levels of support for standard vertex attributes and
    uniform variables.  In particular, GLSL/ES lacks all of the
    standard variables that are present on desktop OpenGL systems:
    \c{gl_Vertex}, \c{gl_Normal}, \c{gl_Color}, and so on.  Desktop OpenGL
    lacks the variable qualifiers \c{highp}, \c{mediump}, and \c{lowp}.

    The QOpenGLShaderProgram class makes the process of writing portable shaders
    easier by prefixing all shader programs with the following lines on
    desktop OpenGL:

    \code
    #define highp
    #define mediump
    #define lowp
    \endcode

    This makes it possible to run most GLSL/ES shader programs
    on desktop systems.  The programmer should restrict themselves
    to just features that are present in GLSL/ES, and avoid
    standard variable names that only work on the desktop.

    \section1 Simple Shader Example

    \snippet code/src_gui_qopenglshaderprogram.cpp 1

    With the above shader program active, we can draw a green triangle
    as follows:

    \snippet code/src_gui_qopenglshaderprogram.cpp 2

    \section1 Binary Shaders and Programs

    Binary shaders may be specified using \c{glShaderBinary()} on
    the return value from QOpenGLShader::shaderId().  The QOpenGLShader instance
    containing the binary can then be added to the shader program with
    addShader() and linked in the usual fashion with link().

    Binary programs may be specified using \c{glProgramBinaryOES()}
    on the return value from programId().  Then the application should
    call link(), which will notice that the program has already been
    specified and linked, allowing other operations to be performed
    on the shader program. The shader program's id can be explicitly
    created using the create() function.

    \section2 Caching Program Binaries

    As of Qt 5.9, support for caching program binaries on disk is built in. To
    enable this, switch to using addCacheableShaderFromSourceCode() and
    addCacheableShaderFromSourceFile(). With an OpenGL ES 3.x context or support
    for \c{GL_ARB_get_program_binary}, this will transparently cache program
    binaries under QStandardPaths::GenericCacheLocation or
    QStandardPaths::CacheLocation. When support is not available, calling the
    cacheable function variants is equivalent to the normal ones.

    \note Some drivers do not have any binary formats available, even though
    they advertise the extension or offer OpenGL ES 3.0. In this case program
    binary support will be disabled.

    \sa QOpenGLShader
*/

/*!
    \class QOpenGLShader
    \brief The QOpenGLShader class allows OpenGL shaders to be compiled.
    \since 5.0
    \ingroup painting-3D
    \inmodule QtGui

    This class supports shaders written in the OpenGL Shading Language (GLSL)
    and in the OpenGL/ES Shading Language (GLSL/ES).

    QOpenGLShader and QOpenGLShaderProgram shelter the programmer from the details of
    compiling and linking vertex and fragment shaders.

    \sa QOpenGLShaderProgram
*/

/*!
    \enum QOpenGLShader::ShaderTypeBit
    This enum specifies the type of QOpenGLShader that is being created.

    \value Vertex Vertex shader written in the OpenGL Shading Language (GLSL).
    \value Fragment Fragment shader written in the OpenGL Shading Language (GLSL).
    \value Geometry Geometry shaders written in the OpenGL Shading Language (GLSL)
           (requires OpenGL >= 3.2 or OpenGL ES >= 3.2).
    \value TessellationControl Tessellation control shaders written in the OpenGL
           shading language (GLSL) (requires OpenGL >= 4.0 or OpenGL ES >= 3.2).
    \value TessellationEvaluation Tessellation evaluation shaders written in the OpenGL
           shading language (GLSL) (requires OpenGL >= 4.0 or OpenGL ES >= 3.2).
    \value Compute Compute shaders written in the OpenGL shading language (GLSL)
           (requires OpenGL >= 4.3 or OpenGL ES >= 3.1).
*/

Q_DECLARE_LOGGING_CATEGORY(lcOpenGLProgramDiskCache)

// For GLES 3.1/3.2
#ifndef GL_GEOMETRY_SHADER
#define GL_GEOMETRY_SHADER         0x8DD9
#endif
#ifndef GL_TESS_CONTROL_SHADER
#define GL_TESS_CONTROL_SHADER     0x8E88
#endif
#ifndef GL_TESS_EVALUATION_SHADER
#define GL_TESS_EVALUATION_SHADER  0x8E87
#endif
#ifndef GL_COMPUTE_SHADER
#define GL_COMPUTE_SHADER          0x91B9
#endif
#ifndef GL_MAX_GEOMETRY_OUTPUT_VERTICES
#define GL_MAX_GEOMETRY_OUTPUT_VERTICES          0x8DE0
#endif
#ifndef GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS
#define GL_MAX_GEOMETRY_TOTAL_OUTPUT_COMPONENTS  0x8DE1
#endif
#ifndef GL_PATCH_VERTICES
#define GL_PATCH_VERTICES  0x8E72
#endif
#ifndef GL_PATCH_DEFAULT_OUTER_LEVEL
#define GL_PATCH_DEFAULT_OUTER_LEVEL  0x8E74
#endif
#ifndef GL_PATCH_DEFAULT_INNER_LEVEL
#define GL_PATCH_DEFAULT_INNER_LEVEL  0x8E73
#endif

#ifndef QT_OPENGL_ES_2
static inline bool isFormatGLES(const QSurfaceFormat &f)
{
    return (f.renderableType() == QSurfaceFormat::OpenGLES);
}
#endif

static inline bool supportsGeometry(const QSurfaceFormat &f)
{
    return f.version() >= qMakePair(3, 2);
}

static inline bool supportsCompute(const QSurfaceFormat &f)
{
#ifndef QT_OPENGL_ES_2
    if (!isFormatGLES(f))
        return f.version() >= qMakePair(4, 3);
    else
        return f.version() >= qMakePair(3, 1);
#else
    return f.version() >= qMakePair(3, 1);
#endif
}

static inline bool supportsTessellation(const QSurfaceFormat &f)
{
#ifndef QT_OPENGL_ES_2
    if (!isFormatGLES(f))
        return f.version() >= qMakePair(4, 0);
    else
        return f.version() >= qMakePair(3, 2);
#else
    return f.version() >= qMakePair(3, 2);
#endif
}

class QOpenGLShaderPrivate : public QObjectPrivate
{
    Q_DECLARE_PUBLIC(QOpenGLShader)
public:
    QOpenGLShaderPrivate(QOpenGLContext *ctx, QOpenGLShader::ShaderType type)
        : shaderGuard(0)
        , shaderType(type)
        , compiled(false)
        , glfuncs(new QOpenGLExtraFunctions(ctx))
        , supportsGeometryShaders(false)
        , supportsTessellationShaders(false)
        , supportsComputeShaders(false)
    {
        if (shaderType & QOpenGLShader::Geometry)
            supportsGeometryShaders = supportsGeometry(ctx->format());
        else if (shaderType & (QOpenGLShader::TessellationControl | QOpenGLShader::TessellationEvaluation))
            supportsTessellationShaders = supportsTessellation(ctx->format());
        else if (shaderType & QOpenGLShader::Compute)
            supportsComputeShaders = supportsCompute(ctx->format());
    }
    ~QOpenGLShaderPrivate();

    QOpenGLSharedResourceGuard *shaderGuard;
    QOpenGLShader::ShaderType shaderType;
    bool compiled;
    QString log;

    QOpenGLExtraFunctions *glfuncs;

    // Support for geometry shaders
    bool supportsGeometryShaders;
    // Support for tessellation shaders
    bool supportsTessellationShaders;
    // Support for compute shaders
    bool supportsComputeShaders;


    bool create();
    bool compile(QOpenGLShader *q);
    void deleteShader();
};

namespace {
    void freeShaderFunc(QOpenGLFunctions *funcs, GLuint id)
    {
        funcs->glDeleteShader(id);
    }
}

QOpenGLShaderPrivate::~QOpenGLShaderPrivate()
{
    delete glfuncs;
    if (shaderGuard)
        shaderGuard->free();
}

bool QOpenGLShaderPrivate::create()
{
    QOpenGLContext *context = const_cast<QOpenGLContext *>(QOpenGLContext::currentContext());
    if (!context)
        return false;
    GLuint shader = 0;
    if (shaderType == QOpenGLShader::Vertex) {
        shader = glfuncs->glCreateShader(GL_VERTEX_SHADER);
    } else if (shaderType == QOpenGLShader::Geometry && supportsGeometryShaders) {
        shader = glfuncs->glCreateShader(GL_GEOMETRY_SHADER);
    } else if (shaderType == QOpenGLShader::TessellationControl && supportsTessellationShaders) {
        shader = glfuncs->glCreateShader(GL_TESS_CONTROL_SHADER);
    } else if (shaderType == QOpenGLShader::TessellationEvaluation && supportsTessellationShaders) {
        shader = glfuncs->glCreateShader(GL_TESS_EVALUATION_SHADER);
    } else if (shaderType == QOpenGLShader::Compute && supportsComputeShaders) {
        shader = glfuncs->glCreateShader(GL_COMPUTE_SHADER);
    } else if (shaderType == QOpenGLShader::Fragment) {
        shader = glfuncs->glCreateShader(GL_FRAGMENT_SHADER);
    }
    if (!shader) {
        qWarning("QOpenGLShader: could not create shader");
        return false;
    }
    shaderGuard = new QOpenGLSharedResourceGuard(context, shader, freeShaderFunc);
    return true;
}

bool QOpenGLShaderPrivate::compile(QOpenGLShader *q)
{
    GLuint shader = shaderGuard ? shaderGuard->id() : 0;
    if (!shader)
        return false;

    // Try to compile shader
    glfuncs->glCompileShader(shader);
    GLint value = 0;

    // Get compilation status
    glfuncs->glGetShaderiv(shader, GL_COMPILE_STATUS, &value);
    compiled = (value != 0);

    if (!compiled) {
        // Compilation failed, try to provide some information about the failure
        QString name = q->objectName();

        const char *types[] = {
            "Fragment",
            "Vertex",
            "Geometry",
            "Tessellation Control",
            "Tessellation Evaluation",
            "Compute",
            ""
        };

        const char *type = types[6];
        switch (shaderType) {
        case QOpenGLShader::Fragment:
            type = types[0]; break;
        case QOpenGLShader::Vertex:
            type = types[1]; break;
        case QOpenGLShader::Geometry:
            type = types[2]; break;
        case QOpenGLShader::TessellationControl:
            type = types[3]; break;
        case QOpenGLShader::TessellationEvaluation:
            type = types[4]; break;
        case QOpenGLShader::Compute:
            type = types[5]; break;
        }

        // Get info and source code lengths
        GLint infoLogLength = 0;
        GLint sourceCodeLength = 0;
        char *logBuffer = 0;
        char *sourceCodeBuffer = 0;

        // Get the compilation info log
        glfuncs->glGetShaderiv(shader, GL_INFO_LOG_LENGTH, &infoLogLength);

        if (infoLogLength > 1) {
            GLint temp;
            logBuffer = new char [infoLogLength];
            glfuncs->glGetShaderInfoLog(shader, infoLogLength, &temp, logBuffer);
        }

        // Get the source code
        glfuncs->glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &sourceCodeLength);

        if (sourceCodeLength > 1) {
            GLint temp;
            sourceCodeBuffer = new char [sourceCodeLength];
            glfuncs->glGetShaderSource(shader, sourceCodeLength, &temp, sourceCodeBuffer);
        }

        if (logBuffer)
            log = QString::fromLatin1(logBuffer);
        else
            log = QLatin1String("failed");

        if (name.isEmpty())
            qWarning("QOpenGLShader::compile(%s): %s", type, qPrintable(log));
        else
            qWarning("QOpenGLShader::compile(%s)[%s]: %s", type, qPrintable(name), qPrintable(log));

        // Dump the source code if we got it
        if (sourceCodeBuffer) {
            qWarning("*** Problematic %s shader source code ***\n"
                     "%ls\n"
                     "***",
                     type, qUtf16Printable(QString::fromLatin1(sourceCodeBuffer)));
        }

        // Cleanup
        delete [] logBuffer;
        delete [] sourceCodeBuffer;
    }

    return compiled;
}

void QOpenGLShaderPrivate::deleteShader()
{
    if (shaderGuard) {
        shaderGuard->free();
        shaderGuard = 0;
    }
}

/*!
    Constructs a new QOpenGLShader object of the specified \a type
    and attaches it to \a parent.  If shader programs are not supported,
    QOpenGLShaderProgram::hasOpenGLShaderPrograms() will return false.

    This constructor is normally followed by a call to compileSourceCode()
    or compileSourceFile().

    The shader will be associated with the current QOpenGLContext.

    \sa compileSourceCode(), compileSourceFile()
*/
QOpenGLShader::QOpenGLShader(QOpenGLShader::ShaderType type, QObject *parent)
    : QObject(*new QOpenGLShaderPrivate(QOpenGLContext::currentContext(), type), parent)
{
    Q_D(QOpenGLShader);
    d->create();
}

/*!
    Deletes this shader.  If the shader has been attached to a
    QOpenGLShaderProgram object, then the actual shader will stay around
    until the QOpenGLShaderProgram is destroyed.
*/
QOpenGLShader::~QOpenGLShader()
{
}

/*!
    Returns the type of this shader.
*/
QOpenGLShader::ShaderType QOpenGLShader::shaderType() const
{
    Q_D(const QOpenGLShader);
    return d->shaderType;
}

static const char qualifierDefines[] =
    "#define lowp\n"
    "#define mediump\n"
    "#define highp\n";

#if defined(QT_OPENGL_ES) && !defined(QT_OPENGL_FORCE_SHADER_DEFINES)
// The "highp" qualifier doesn't exist in fragment shaders
// on all ES platforms.  When it doesn't exist, use "mediump".
#define QOpenGL_REDEFINE_HIGHP 1
static const char redefineHighp[] =
    "#ifndef GL_FRAGMENT_PRECISION_HIGH\n"
    "#define highp mediump\n"
    "#endif\n";
#endif

// Boiler-plate header to have the layout attributes available we need later
static const char blendEquationAdvancedHeader[] =
    "#ifdef GL_KHR_blend_equation_advanced\n"
    "#extension GL_ARB_fragment_coord_conventions : enable\n"
    "#extension GL_KHR_blend_equation_advanced : enable\n"
    "#endif\n";

struct QVersionDirectivePosition
{
    Q_DECL_CONSTEXPR QVersionDirectivePosition(int position = 0, int line = -1)
        : position(position)
        , line(line)
    {
    }

    Q_DECL_CONSTEXPR bool hasPosition() const
    {
        return position > 0;
    }

    const int position;
    const int line;
};

static QVersionDirectivePosition findVersionDirectivePosition(const char *source)
{
    Q_ASSERT(source);

    // According to the GLSL spec the #version directive must not be
    // preceded by anything but whitespace and comments.
    // In order to not get confused by #version directives within a
    // multiline comment, we need to do some minimal comment parsing
    // while searching for the directive.
    enum {
        Normal,
        StartOfLine,
        PreprocessorDirective,
        CommentStarting,
        MultiLineComment,
        SingleLineComment,
        CommentEnding
    } state = StartOfLine;

    const char *c = source;
    while (*c) {
        switch (state) {
        case PreprocessorDirective:
            if (*c == ' ' || *c == '\t')
                break;
            if (!strncmp(c, "version", strlen("version"))) {
                // Found version directive
                c += strlen("version");
                while (*c && *c != '\n')
                    ++c;
                int splitPosition = c - source + 1;
                int linePosition = int(std::count(source, c, '\n')) + 1;
                return QVersionDirectivePosition(splitPosition, linePosition);
            } else if (*c == '/')
                state = CommentStarting;
            else if (*c == '\n')
                state = StartOfLine;
            else
                state = Normal;
            break;
        case StartOfLine:
            if (*c == ' ' || *c == '\t')
                break;
            else if (*c == '#') {
                state = PreprocessorDirective;
                break;
            }
            state = Normal;
            Q_FALLTHROUGH();
        case Normal:
            if (*c == '/')
                state = CommentStarting;
            else if (*c == '\n')
                state = StartOfLine;
            break;
        case CommentStarting:
            if (*c == '*')
                state = MultiLineComment;
            else if (*c == '/')
                state = SingleLineComment;
            else
                state = Normal;
            break;
        case MultiLineComment:
            if (*c == '*')
                state = CommentEnding;
            break;
        case SingleLineComment:
            if (*c == '\n')
                state = Normal;
            break;
        case CommentEnding:
            if (*c == '/')
                state = Normal;
            else if (*c != QLatin1Char('*'))
                state = MultiLineComment;
            break;
        }
        ++c;
    }

    return QVersionDirectivePosition(0, 1);
}

/*!
    Sets the \a source code for this shader and compiles it.
    Returns \c true if the source was successfully compiled, false otherwise.

    \sa compileSourceFile()
*/
bool QOpenGLShader::compileSourceCode(const char *source)
{
    Q_D(QOpenGLShader);
    // This method breaks the shader code into two parts:
    // 1. Up to and including an optional #version directive.
    // 2. The rest.
    // If a #version directive exists, qualifierDefines and redefineHighp
    // are inserted after. Otherwise they are inserted right at the start.
    // In both cases a #line directive is appended in order to compensate
    // for line number changes in case of compiler errors.

    if (d->shaderGuard && d->shaderGuard->id() && source) {
        const QVersionDirectivePosition versionDirectivePosition = findVersionDirectivePosition(source);

        QVarLengthArray<const char *, 5> sourceChunks;
        QVarLengthArray<GLint, 5> sourceChunkLengths;
        QOpenGLContext *ctx = QOpenGLContext::currentContext();

        if (versionDirectivePosition.hasPosition()) {
            // Append source up to and including the #version directive
            sourceChunks.append(source);
            sourceChunkLengths.append(GLint(versionDirectivePosition.position));
        } else {
            // QTBUG-55733: Intel on Windows with Compatibility profile requires a #version always
            if (ctx->format().profile() == QSurfaceFormat::CompatibilityProfile) {
                const char *vendor = reinterpret_cast<const char *>(ctx->functions()->glGetString(GL_VENDOR));
                if (vendor && !strcmp(vendor, "Intel")) {
                    static const char version110[] = "#version 110\n";
                    sourceChunks.append(version110);
                    sourceChunkLengths.append(GLint(sizeof(version110)) - 1);
                }
            }
        }
        if (d->shaderType == Fragment) {
            sourceChunks.append(blendEquationAdvancedHeader);
            sourceChunkLengths.append(GLint(sizeof(blendEquationAdvancedHeader) - 1));
        }

        // The precision qualifiers are useful on OpenGL/ES systems,
        // but usually not present on desktop systems.
        const QSurfaceFormat currentSurfaceFormat = ctx->format();
        QOpenGLContextPrivate *ctx_d = QOpenGLContextPrivate::get(QOpenGLContext::currentContext());
        if (currentSurfaceFormat.renderableType() == QSurfaceFormat::OpenGL
                || ctx_d->workaround_missingPrecisionQualifiers
#ifdef QT_OPENGL_FORCE_SHADER_DEFINES
                || true
#endif
                ) {
            sourceChunks.append(qualifierDefines);
            sourceChunkLengths.append(GLint(sizeof(qualifierDefines) - 1));
        }

#ifdef QOpenGL_REDEFINE_HIGHP
        if (d->shaderType == Fragment && !ctx_d->workaround_missingPrecisionQualifiers
            && QOpenGLContext::currentContext()->isOpenGLES()) {
            sourceChunks.append(redefineHighp);
            sourceChunkLengths.append(GLint(sizeof(redefineHighp) - 1));
        }
#endif

        QByteArray lineDirective;
        // #line is rejected by some drivers:
        // "2.1 Mesa 8.1-devel (git-48a3d4e)" or "MESA 2.1 Mesa 8.1-devel"
        const char *version = reinterpret_cast<const char *>(ctx->functions()->glGetString(GL_VERSION));
        if (!version || !strstr(version, "2.1 Mesa 8")) {
            // Append #line directive in order to compensate for text insertion
            lineDirective = QStringLiteral("#line %1\n").arg(versionDirectivePosition.line).toUtf8();
            sourceChunks.append(lineDirective.constData());
            sourceChunkLengths.append(GLint(lineDirective.length()));
        }

        // Append rest of shader code
        sourceChunks.append(source + versionDirectivePosition.position);
        sourceChunkLengths.append(GLint(qstrlen(source + versionDirectivePosition.position)));

        d->glfuncs->glShaderSource(d->shaderGuard->id(), sourceChunks.size(), sourceChunks.data(), sourceChunkLengths.data());
        return d->compile(this);
    } else {
        return false;
    }
}

/*!
    \overload

    Sets the \a source code for this shader and compiles it.
    Returns \c true if the source was successfully compiled, false otherwise.

    \sa compileSourceFile()
*/
bool QOpenGLShader::compileSourceCode(const QByteArray& source)
{
    return compileSourceCode(source.constData());
}

/*!
    \overload

    Sets the \a source code for this shader and compiles it.
    Returns \c true if the source was successfully compiled, false otherwise.

    \sa compileSourceFile()
*/
bool QOpenGLShader::compileSourceCode(const QString& source)
{
    return compileSourceCode(source.toLatin1().constData());
}

/*!
    Sets the source code for this shader to the contents of \a fileName
    and compiles it.  Returns \c true if the file could be opened and the
    source compiled, false otherwise.

    \sa compileSourceCode()
*/
bool QOpenGLShader::compileSourceFile(const QString& fileName)
{
    QFile file(fileName);
    if (!file.open(QFile::ReadOnly)) {
        qWarning() << "QOpenGLShader: Unable to open file" << fileName;
        return false;
    }

    QByteArray contents = file.readAll();
    return compileSourceCode(contents.constData());
}

/*!
    Returns the source code for this shader.

    \sa compileSourceCode()
*/
QByteArray QOpenGLShader::sourceCode() const
{
    Q_D(const QOpenGLShader);
    GLuint shader = d->shaderGuard ? d->shaderGuard->id() : 0;
    if (!shader)
        return QByteArray();
    GLint size = 0;
    d->glfuncs->glGetShaderiv(shader, GL_SHADER_SOURCE_LENGTH, &size);
    if (size <= 0)
        return QByteArray();
    GLint len = 0;
    char *source = new char [size];
    d->glfuncs->glGetShaderSource(shader, size, &len, source);
    QByteArray src(source);
    delete [] source;
    return src;
}

/*!
    Returns \c true if this shader has been compiled; false otherwise.

    \sa compileSourceCode(), compileSourceFile()
*/
bool QOpenGLShader::isCompiled() const
{
    Q_D(const QOpenGLShader);
    return d->compiled;
}

/*!
    Returns the errors and warnings that occurred during the last compile.

    \sa compileSourceCode(), compileSourceFile()
*/
QString QOpenGLShader::log() const
{
    Q_D(const QOpenGLShader);
    return d->log;
}

/*!
    Returns the OpenGL identifier associated with this shader.

    \sa QOpenGLShaderProgram::programId()
*/
GLuint QOpenGLShader::shaderId() const
{
    Q_D(const QOpenGLShader);
    return d->shaderGuard ? d->shaderGuard->id() : 0;
}

class QOpenGLShaderProgramPrivate : public QObjectPrivate
{
    Q_DECLARE_PUBLIC(QOpenGLShaderProgram)
public:
    QOpenGLShaderProgramPrivate()
        : programGuard(0)
        , linked(false)
        , inited(false)
        , removingShaders(false)
        , glfuncs(new QOpenGLExtraFunctions)
#ifndef QT_OPENGL_ES_2
        , tessellationFuncs(0)
#endif
        , linkBinaryRecursion(false)
    {
    }
    ~QOpenGLShaderProgramPrivate();

    QOpenGLSharedResourceGuard *programGuard;
    bool linked;
    bool inited;
    bool removingShaders;

    QString log;
    QList<QOpenGLShader *> shaders;
    QList<QOpenGLShader *> anonShaders;

    QOpenGLExtraFunctions *glfuncs;
#ifndef QT_OPENGL_ES_2
    // for tessellation features not in GLES 3.2
    QOpenGLFunctions_4_0_Core *tessellationFuncs;
#endif

    bool hasShader(QOpenGLShader::ShaderType type) const;

    QOpenGLProgramBinaryCache::ProgramDesc binaryProgram;
    bool isCacheDisabled() const;
    bool compileCacheable();
    bool linkBinary();

    bool linkBinaryRecursion;
};

namespace {
    void freeProgramFunc(QOpenGLFunctions *funcs, GLuint id)
    {
        funcs->glDeleteProgram(id);
    }
}


QOpenGLShaderProgramPrivate::~QOpenGLShaderProgramPrivate()
{
    delete glfuncs;
    if (programGuard)
        programGuard->free();
}

bool QOpenGLShaderProgramPrivate::hasShader(QOpenGLShader::ShaderType type) const
{
    for (QOpenGLShader *shader : shaders) {
        if (shader->shaderType() == type)
            return true;
    }
    return false;
}

/*!
    Constructs a new shader program and attaches it to \a parent.
    The program will be invalid until addShader() is called.

    The shader program will be associated with the current QOpenGLContext.

    \sa addShader()
*/
QOpenGLShaderProgram::QOpenGLShaderProgram(QObject *parent)
    : QObject(*new QOpenGLShaderProgramPrivate, parent)
{
}

/*!
    Deletes this shader program.
*/
QOpenGLShaderProgram::~QOpenGLShaderProgram()
{
}

/*!
    Requests the shader program's id to be created immediately. Returns \c true
    if successful; \c false otherwise.

    This function is primarily useful when combining QOpenGLShaderProgram
    with other OpenGL functions that operate directly on the shader
    program id, like \c {GL_OES_get_program_binary}.

    When the shader program is used normally, the shader program's id will
    be created on demand.

    \sa programId()

    \since 5.3
 */
bool QOpenGLShaderProgram::create()
{
    return init();
}

bool QOpenGLShaderProgram::init()
{
    Q_D(QOpenGLShaderProgram);
    if ((d->programGuard && d->programGuard->id()) || d->inited)
        return true;
    d->inited = true;
    QOpenGLContext *context = const_cast<QOpenGLContext *>(QOpenGLContext::currentContext());
    if (!context)
        return false;
    d->glfuncs->initializeOpenGLFunctions();

#ifndef QT_OPENGL_ES_2
    if (!context->isOpenGLES() && context->format().version() >= qMakePair(4, 0)) {
        d->tessellationFuncs = context->versionFunctions<QOpenGLFunctions_4_0_Core>();
        d->tessellationFuncs->initializeOpenGLFunctions();
    }
#endif

    GLuint program = d->glfuncs->glCreateProgram();
    if (!program) {
        qWarning("QOpenGLShaderProgram: could not create shader program");
        return false;
    }
    if (d->programGuard)
        delete d->programGuard;
    d->programGuard = new QOpenGLSharedResourceGuard(context, program, freeProgramFunc);
    return true;
}

/*!
    Adds a compiled \a shader to this shader program.  Returns \c true
    if the shader could be added, or false otherwise.

    Ownership of the \a shader object remains with the caller.
    It will not be deleted when this QOpenGLShaderProgram instance
    is deleted.  This allows the caller to add the same shader
    to multiple shader programs.

    \sa addShaderFromSourceCode(), addShaderFromSourceFile()
    \sa removeShader(), link(), removeAllShaders()
*/
bool QOpenGLShaderProgram::addShader(QOpenGLShader *shader)
{
    Q_D(QOpenGLShaderProgram);
    if (!init())
        return false;
    if (d->shaders.contains(shader))
        return true;    // Already added to this shader program.
    if (d->programGuard && d->programGuard->id() && shader) {
        if (!shader->d_func()->shaderGuard || !shader->d_func()->shaderGuard->id())
            return false;
        if (d->programGuard->group() != shader->d_func()->shaderGuard->group()) {
            qWarning("QOpenGLShaderProgram::addShader: Program and shader are not associated with same context.");
            return false;
        }
        d->glfuncs->glAttachShader(d->programGuard->id(), shader->d_func()->shaderGuard->id());
        d->linked = false;  // Program needs to be relinked.
        d->shaders.append(shader);
        connect(shader, SIGNAL(destroyed()), this, SLOT(shaderDestroyed()));
        return true;
    } else {
        return false;
    }
}

/*!
    Compiles \a source as a shader of the specified \a type and
    adds it to this shader program.  Returns \c true if compilation
    was successful, false otherwise.  The compilation errors
    and warnings will be made available via log().

    This function is intended to be a short-cut for quickly
    adding vertex and fragment shaders to a shader program without
    creating an instance of QOpenGLShader first.

    \sa addShader(), addShaderFromSourceFile()
    \sa removeShader(), link(), log(), removeAllShaders()
*/
bool QOpenGLShaderProgram::addShaderFromSourceCode(QOpenGLShader::ShaderType type, const char *source)
{
    Q_D(QOpenGLShaderProgram);
    if (!init())
        return false;
    QOpenGLShader *shader = new QOpenGLShader(type, this);
    if (!shader->compileSourceCode(source)) {
        d->log = shader->log();
        delete shader;
        return false;
    }
    d->anonShaders.append(shader);
    return addShader(shader);
}

/*!
    \overload

    Compiles \a source as a shader of the specified \a type and
    adds it to this shader program.  Returns \c true if compilation
    was successful, false otherwise.  The compilation errors
    and warnings will be made available via log().

    This function is intended to be a short-cut for quickly
    adding vertex and fragment shaders to a shader program without
    creating an instance of QOpenGLShader first.

    \sa addShader(), addShaderFromSourceFile()
    \sa removeShader(), link(), log(), removeAllShaders()
*/
bool QOpenGLShaderProgram::addShaderFromSourceCode(QOpenGLShader::ShaderType type, const QByteArray& source)
{
    return addShaderFromSourceCode(type, source.constData());
}

/*!
    \overload

    Compiles \a source as a shader of the specified \a type and
    adds it to this shader program.  Returns \c true if compilation
    was successful, false otherwise.  The compilation errors
    and warnings will be made available via log().

    This function is intended to be a short-cut for quickly
    adding vertex and fragment shaders to a shader program without
    creating an instance of QOpenGLShader first.

    \sa addShader(), addShaderFromSourceFile()
    \sa removeShader(), link(), log(), removeAllShaders()
*/
bool QOpenGLShaderProgram::addShaderFromSourceCode(QOpenGLShader::ShaderType type, const QString& source)
{
    return addShaderFromSourceCode(type, source.toLatin1().constData());
}

/*!
    Compiles the contents of \a fileName as a shader of the specified
    \a type and adds it to this shader program.  Returns \c true if
    compilation was successful, false otherwise.  The compilation errors
    and warnings will be made available via log().

    This function is intended to be a short-cut for quickly
    adding vertex and fragment shaders to a shader program without
    creating an instance of QOpenGLShader first.

    \sa addShader(), addShaderFromSourceCode()
*/
bool QOpenGLShaderProgram::addShaderFromSourceFile
    (QOpenGLShader::ShaderType type, const QString& fileName)
{
    Q_D(QOpenGLShaderProgram);
    if (!init())
        return false;
    QOpenGLShader *shader = new QOpenGLShader(type, this);
    if (!shader->compileSourceFile(fileName)) {
        d->log = shader->log();
        delete shader;
        return false;
    }
    d->anonShaders.append(shader);
    return addShader(shader);
}

/*!
    Registers the shader of the specified \a type and \a source to this
    program. Unlike addShaderFromSourceCode(), this function does not perform
    compilation. Compilation is deferred to link(), and may not happen at all,
    because link() may potentially use a program binary from Qt's shader disk
    cache. This will typically lead to a significant increase in performance.

    \return true if the shader has been registered or, in the non-cached case,
    compiled successfully; false if there was an error. The compilation error
    messages can be retrieved via log().

    When the disk cache is disabled, via Qt::AA_DisableShaderDiskCache for
    example, or the OpenGL context has no support for context binaries, calling
    this function is equivalent to addShaderFromSourceCode().

    \since 5.9
    \sa addShaderFromSourceCode(), addCacheableShaderFromSourceFile()
 */
bool QOpenGLShaderProgram::addCacheableShaderFromSourceCode(QOpenGLShader::ShaderType type, const char *source)
{
    Q_D(QOpenGLShaderProgram);
    if (!init())
        return false;
    if (d->isCacheDisabled())
        return addShaderFromSourceCode(type, source);

    return addCacheableShaderFromSourceCode(type, QByteArray(source));
}

static inline QShader::Stage qt_shaderTypeToStage(QOpenGLShader::ShaderType type)
{
    switch (type) {
    case QOpenGLShader::Vertex:
        return QShader::VertexStage;
    case QOpenGLShader::Fragment:
        return QShader::FragmentStage;
    case QOpenGLShader::Geometry:
        return QShader::GeometryStage;
    case QOpenGLShader::TessellationControl:
        return QShader::TessellationControlStage;
    case QOpenGLShader::TessellationEvaluation:
        return QShader::TessellationEvaluationStage;
    case QOpenGLShader::Compute:
        return QShader::ComputeStage;
    }
    return QShader::VertexStage;
}

static inline QOpenGLShader::ShaderType qt_shaderStageToType(QShader::Stage stage)
{
    switch (stage) {
    case QShader::VertexStage:
        return QOpenGLShader::Vertex;
    case QShader::TessellationControlStage:
        return QOpenGLShader::TessellationControl;
    case QShader::TessellationEvaluationStage:
        return QOpenGLShader::TessellationEvaluation;
    case QShader::GeometryStage:
        return QOpenGLShader::Geometry;
    case QShader::FragmentStage:
        return QOpenGLShader::Fragment;
    case QShader::ComputeStage:
        return QOpenGLShader::Compute;
    }
    return QOpenGLShader::Vertex;
}

/*!
    \overload

    Registers the shader of the specified \a type and \a source to this
    program. Unlike addShaderFromSourceCode(), this function does not perform
    compilation. Compilation is deferred to link(), and may not happen at all,
    because link() may potentially use a program binary from Qt's shader disk
    cache. This will typically lead to a significant increase in performance.

    \return true if the shader has been registered or, in the non-cached case,
    compiled successfully; false if there was an error. The compilation error
    messages can be retrieved via log().

    When the disk cache is disabled, via Qt::AA_DisableShaderDiskCache for
    example, or the OpenGL context has no support for context binaries, calling
    this function is equivalent to addShaderFromSourceCode().

    \since 5.9
    \sa addShaderFromSourceCode(), addCacheableShaderFromSourceFile()
 */
bool QOpenGLShaderProgram::addCacheableShaderFromSourceCode(QOpenGLShader::ShaderType type, const QByteArray &source)
{
    Q_D(QOpenGLShaderProgram);
    if (!init())
        return false;
    if (d->isCacheDisabled())
        return addShaderFromSourceCode(type, source);

    d->binaryProgram.shaders.append(QOpenGLProgramBinaryCache::ShaderDesc(qt_shaderTypeToStage(type), source));
    return true;
}

/*!
    \overload

    Registers the shader of the specified \a type and \a source to this
    program. Unlike addShaderFromSourceCode(), this function does not perform
    compilation. Compilation is deferred to link(), and may not happen at all,
    because link() may potentially use a program binary from Qt's shader disk
    cache. This will typically lead to a significant increase in performance.

    When the disk cache is disabled, via Qt::AA_DisableShaderDiskCache for
    example, or the OpenGL context has no support for context binaries, calling
    this function is equivalent to addShaderFromSourceCode().

    \since 5.9
    \sa addShaderFromSourceCode(), addCacheableShaderFromSourceFile()
 */
bool QOpenGLShaderProgram::addCacheableShaderFromSourceCode(QOpenGLShader::ShaderType type, const QString &source)
{
    Q_D(QOpenGLShaderProgram);
    if (!init())
        return false;
    if (d->isCacheDisabled())
        return addShaderFromSourceCode(type, source);

    return addCacheableShaderFromSourceCode(type, source.toUtf8().constData());
}

/*!
    Registers the shader of the specified \a type and \a fileName to this
    program. Unlike addShaderFromSourceFile(), this function does not perform
    compilation. Compilation is deferred to link(), and may not happen at all,
    because link() may potentially use a program binary from Qt's shader disk
    cache. This will typically lead to a significant increase in performance.

    \return true if the file has been read successfully, false if the file could
    not be opened or the normal, non-cached compilation of the shader has
    failed. The compilation error messages can be retrieved via log().

    When the disk cache is disabled, via Qt::AA_DisableShaderDiskCache for
    example, or the OpenGL context has no support for context binaries, calling
    this function is equivalent to addShaderFromSourceFile().

    \since 5.9
    \sa addShaderFromSourceFile(), addCacheableShaderFromSourceCode()
 */
bool QOpenGLShaderProgram::addCacheableShaderFromSourceFile(QOpenGLShader::ShaderType type, const QString &fileName)
{
    Q_D(QOpenGLShaderProgram);
    if (!init())
        return false;
    if (d->isCacheDisabled())
        return addShaderFromSourceFile(type, fileName);

    QOpenGLProgramBinaryCache::ShaderDesc shader(qt_shaderTypeToStage(type));
    // NB! It could be tempting to defer reading the file contents and just
    // hash the filename as the cache key, perhaps combined with last-modified
    // timestamp checks. However, this would raise a number of issues (no
    // timestamps for files in the resource system; preference for global, not
    // per-application cache items (where filenames may clash); resource-based
    // shaders from libraries like Qt Quick; etc.), so just avoid it.
    QFile f(fileName);
    if (f.open(QIODevice::ReadOnly | QIODevice::Text)) {
        shader.source = f.readAll();
        f.close();
    } else {
        qWarning("QOpenGLShaderProgram: Unable to open file %s", qPrintable(fileName));
        return false;
    }
    d->binaryProgram.shaders.append(shader);
    return true;
}

/*!
    Removes \a shader from this shader program.  The object is not deleted.

    The shader program must be valid in the current QOpenGLContext.

    \sa addShader(), link(), removeAllShaders()
*/
void QOpenGLShaderProgram::removeShader(QOpenGLShader *shader)
{
    Q_D(QOpenGLShaderProgram);
    if (d->programGuard && d->programGuard->id()
        && shader && shader->d_func()->shaderGuard)
    {
        d->glfuncs->glDetachShader(d->programGuard->id(), shader->d_func()->shaderGuard->id());
    }
    d->linked = false;  // Program needs to be relinked.
    if (shader) {
        d->shaders.removeAll(shader);
        d->anonShaders.removeAll(shader);
        disconnect(shader, SIGNAL(destroyed()), this, SLOT(shaderDestroyed()));
    }
}

/*!
    Returns a list of all shaders that have been added to this shader
    program using addShader().

    \sa addShader(), removeShader()
*/
QList<QOpenGLShader *> QOpenGLShaderProgram::shaders() const
{
    Q_D(const QOpenGLShaderProgram);
    return d->shaders;
}

/*!
    Removes all of the shaders that were added to this program previously.
    The QOpenGLShader objects for the shaders will not be deleted if they
    were constructed externally.  QOpenGLShader objects that are constructed
    internally by QOpenGLShaderProgram will be deleted.

    \sa addShader(), removeShader()
*/
void QOpenGLShaderProgram::removeAllShaders()
{
    Q_D(QOpenGLShaderProgram);
    d->removingShaders = true;
    for (QOpenGLShader *shader : qAsConst(d->shaders)) {
        if (d->programGuard && d->programGuard->id()
            && shader && shader->d_func()->shaderGuard)
        {
            d->glfuncs->glDetachShader(d->programGuard->id(), shader->d_func()->shaderGuard->id());
        }
    }
    // Delete shader objects that were created anonymously.
    qDeleteAll(d->anonShaders);
    d->shaders.clear();
    d->anonShaders.clear();
    d->binaryProgram = QOpenGLProgramBinaryCache::ProgramDesc();
    d->linked = false;  // Program needs to be relinked.
    d->removingShaders = false;
}

/*!
    Links together the shaders that were added to this program with
    addShader().  Returns \c true if the link was successful or
    false otherwise.  If the link failed, the error messages can
    be retrieved with log().

    Subclasses can override this function to initialize attributes
    and uniform variables for use in specific shader programs.

    If the shader program was already linked, calling this
    function again will force it to be re-linked.

    When shaders were added to this program via
    addCacheableShaderFromSourceCode() or addCacheableShaderFromSourceFile(),
    program binaries are supported, and a cached binary is available on disk,
    actual compilation and linking are skipped. Instead, link() will initialize
    the program with the binary blob via glProgramBinary(). If there is no
    cached version of the program or it was generated with a different driver
    version, the shaders will be compiled from source and the program will get
    linked normally. This allows seamless upgrading of the graphics drivers,
    without having to worry about potentially incompatible binary formats.

    \sa addShader(), log()
*/
bool QOpenGLShaderProgram::link()
{
    Q_D(QOpenGLShaderProgram);
    GLuint program = d->programGuard ? d->programGuard->id() : 0;
    if (!program)
        return false;

    if (!d->linkBinaryRecursion && d->shaders.isEmpty() && !d->binaryProgram.shaders.isEmpty())
        return d->linkBinary();

    GLint value;
    if (d->shaders.isEmpty()) {
        // If there are no explicit shaders, then it is possible that the
        // application added a program binary with glProgramBinaryOES(), or
        // otherwise populated the shaders itself. This is also the case when
        // we are recursively called back from linkBinary() after a successful
        // glProgramBinary(). Check to see if the program is already linked and
        // bail out if so.
        value = 0;
        d->glfuncs->glGetProgramiv(program, GL_LINK_STATUS, &value);
        d->linked = (value != 0);
        if (d->linked)
            return true;
    }

    d->glfuncs->glLinkProgram(program);
    value = 0;
    d->glfuncs->glGetProgramiv(program, GL_LINK_STATUS, &value);
    d->linked = (value != 0);
    value = 0;
    d->glfuncs->glGetProgramiv(program, GL_INFO_LOG_LENGTH, &value);
    d->log = QString();
    if (value > 1) {
        char *logbuf = new char [value];
        GLint len;
        d->glfuncs->glGetProgramInfoLog(program, value, &len, logbuf);
        d->log = QString::fromLatin1(logbuf);
        if (!d->linked && !d->linkBinaryRecursion) {
            QString name = objectName();
            if (name.isEmpty())
                qWarning("QOpenGLShader::link: %ls", qUtf16Printable(d->log));
            else
                qWarning("QOpenGLShader::link[%ls]: %ls", qUtf16Printable(name), qUtf16Printable(d->log));
        }
        delete [] logbuf;
    }
    return d->linked;
}

/*!
    Returns \c true if this shader program has been linked; false otherwise.

    \sa link()
*/
bool QOpenGLShaderProgram::isLinked() const
{
    Q_D(const QOpenGLShaderProgram);
    return d->linked;
}

/*!
    Returns the errors and warnings that occurred during the last link()
    or addShader() with explicitly specified source code.

    \sa link()
*/
QString QOpenGLShaderProgram::log() const
{
    Q_D(const QOpenGLShaderProgram);
    return d->log;
}

/*!
    Binds this shader program to the active QOpenGLContext and makes
    it the current shader program.  Any previously bound shader program
    is released.  This is equivalent to calling \c{glUseProgram()} on
    programId().  Returns \c true if the program was successfully bound;
    false otherwise.  If the shader program has not yet been linked,
    or it needs to be re-linked, this function will call link().

    \sa link(), release()
*/
bool QOpenGLShaderProgram::bind()
{
    Q_D(QOpenGLShaderProgram);
    GLuint program = d->programGuard ? d->programGuard->id() : 0;
    if (!program)
        return false;
    if (!d->linked && !link())
        return false;
#ifndef QT_NO_DEBUG
    if (d->programGuard->group() != QOpenGLContextGroup::currentContextGroup()) {
        qWarning("QOpenGLShaderProgram::bind: program is not valid in the current context.");
        return false;
    }
#endif
    d->glfuncs->glUseProgram(program);
    return true;
}

/*!
    Releases the active shader program from the current QOpenGLContext.
    This is equivalent to calling \c{glUseProgram(0)}.

    \sa bind()
*/
void QOpenGLShaderProgram::release()
{
    Q_D(QOpenGLShaderProgram);
#ifndef QT_NO_DEBUG
    if (d->programGuard && d->programGuard->group() != QOpenGLContextGroup::currentContextGroup())
        qWarning("QOpenGLShaderProgram::release: program is not valid in the current context.");
#endif
    d->glfuncs->glUseProgram(0);
}

/*!
    Returns the OpenGL identifier associated with this shader program.

    \sa QOpenGLShader::shaderId()
*/
GLuint QOpenGLShaderProgram::programId() const
{
    Q_D(const QOpenGLShaderProgram);
    GLuint id = d->programGuard ? d->programGuard->id() : 0;
    if (id)
        return id;

    // Create the identifier if we don't have one yet.  This is for
    // applications that want to create the attached shader configuration
    // themselves, particularly those using program binaries.
    if (!const_cast<QOpenGLShaderProgram *>(this)->init())
        return 0;
    return d->programGuard ? d->programGuard->id() : 0;
}

/*!
    Binds the attribute \a name to the specified \a location.  This
    function can be called before or after the program has been linked.
    Any attributes that have not been explicitly bound when the program
    is linked will be assigned locations automatically.

    When this function is called after the program has been linked,
    the program will need to be relinked for the change to take effect.

    \sa attributeLocation()
*/
void QOpenGLShaderProgram::bindAttributeLocation(const char *name, int location)
{
    Q_D(QOpenGLShaderProgram);
    if (!init() || !d->programGuard || !d->programGuard->id())
        return;
    d->glfuncs->glBindAttribLocation(d->programGuard->id(), location, name);
    d->linked = false;  // Program needs to be relinked.
}

/*!
    \overload

    Binds the attribute \a name to the specified \a location.  This
    function can be called before or after the program has been linked.
    Any attributes that have not been explicitly bound when the program
    is linked will be assigned locations automatically.

    When this function is called after the program has been linked,
    the program will need to be relinked for the change to take effect.

    \sa attributeLocation()
*/
void QOpenGLShaderProgram::bindAttributeLocation(const QByteArray& name, int location)
{
    bindAttributeLocation(name.constData(), location);
}

/*!
    \overload

    Binds the attribute \a name to the specified \a location.  This
    function can be called before or after the program has been linked.
    Any attributes that have not been explicitly bound when the program
    is linked will be assigned locations automatically.

    When this function is called after the program has been linked,
    the program will need to be relinked for the change to take effect.

    \sa attributeLocation()
*/
void QOpenGLShaderProgram::bindAttributeLocation(const QString& name, int location)
{
    bindAttributeLocation(name.toLatin1().constData(), location);
}

/*!
    Returns the location of the attribute \a name within this shader
    program's parameter list.  Returns -1 if \a name is not a valid
    attribute for this shader program.

    \sa uniformLocation(), bindAttributeLocation()
*/
int QOpenGLShaderProgram::attributeLocation(const char *name) const
{
    Q_D(const QOpenGLShaderProgram);
    if (d->linked && d->programGuard && d->programGuard->id()) {
        return d->glfuncs->glGetAttribLocation(d->programGuard->id(), name);
    } else {
        qWarning("QOpenGLShaderProgram::attributeLocation(%s): shader program is not linked", name);
        return -1;
    }
}

/*!
    \overload

    Returns the location of the attribute \a name within this shader
    program's parameter list.  Returns -1 if \a name is not a valid
    attribute for this shader program.

    \sa uniformLocation(), bindAttributeLocation()
*/
int QOpenGLShaderProgram::attributeLocation(const QByteArray& name) const
{
    return attributeLocation(name.constData());
}

/*!
    \overload

    Returns the location of the attribute \a name within this shader
    program's parameter list.  Returns -1 if \a name is not a valid
    attribute for this shader program.

    \sa uniformLocation(), bindAttributeLocation()
*/
int QOpenGLShaderProgram::attributeLocation(const QString& name) const
{
    return attributeLocation(name.toLatin1().constData());
}

/*!
    Sets the attribute at \a location in the current context to \a value.

    \sa setUniformValue()
*/
void QOpenGLShaderProgram::setAttributeValue(int location, GLfloat value)
{
    Q_D(QOpenGLShaderProgram);
    if (location != -1)
        d->glfuncs->glVertexAttrib1fv(location, &value);
}

/*!
    \overload

    Sets the attribute called \a name in the current context to \a value.

    \sa setUniformValue()
*/
void QOpenGLShaderProgram::setAttributeValue(const char *name, GLfloat value)
{
    setAttributeValue(attributeLocation(name), value);
}

/*!
    Sets the attribute at \a location in the current context to
    the 2D vector (\a x, \a y).

    \sa setUniformValue()
*/
void QOpenGLShaderProgram::setAttributeValue(int location, GLfloat x, GLfloat y)
{
    Q_D(QOpenGLShaderProgram);
    if (location != -1) {
        GLfloat values[2] = {x, y};
        d->glfuncs->glVertexAttrib2fv(location, values);
    }
}

/*!
    \overload

    Sets the attribute called \a name in the current context to
    the 2D vector (\a x, \a y).

    \sa setUniformValue()
*/
void QOpenGLShaderProgram::setAttributeValue(const char *name, GLfloat x, GLfloat y)
{
    setAttributeValue(attributeLocation(name), x, y);
}

/*!
    Sets the attribute at \a location in the current context to
    the 3D vector (\a x, \a y, \a z).

    \sa setUniformValue()
*/
void QOpenGLShaderProgram::setAttributeValue
        (int location, GLfloat x, GLfloat y, GLfloat z)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1) {
        GLfloat values[3] = {x, y, z};
        d->glfuncs->glVertexAttrib3fv(location, values);
    }
}

/*!
    \overload

    Sets the attribute called \a name in the current context to
    the 3D vector (\a x, \a y, \a z).

    \sa setUniformValue()
*/
void QOpenGLShaderProgram::setAttributeValue
        (const char *name, GLfloat x, GLfloat y, GLfloat z)
{
    setAttributeValue(attributeLocation(name), x, y, z);
}

/*!
    Sets the attribute at \a location in the current context to
    the 4D vector (\a x, \a y, \a z, \a w).

    \sa setUniformValue()
*/
void QOpenGLShaderProgram::setAttributeValue
        (int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
    Q_D(QOpenGLShaderProgram);
    if (location != -1) {
        GLfloat values[4] = {x, y, z, w};
        d->glfuncs->glVertexAttrib4fv(location, values);
    }
}

/*!
    \overload

    Sets the attribute called \a name in the current context to
    the 4D vector (\a x, \a y, \a z, \a w).

    \sa setUniformValue()
*/
void QOpenGLShaderProgram::setAttributeValue
        (const char *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
    setAttributeValue(attributeLocation(name), x, y, z, w);
}

/*!
    Sets the attribute at \a location in the current context to \a value.

    \sa setUniformValue()
*/
void QOpenGLShaderProgram::setAttributeValue(int location, const QVector2D& value)
{
    Q_D(QOpenGLShaderProgram);
    if (location != -1)
        d->glfuncs->glVertexAttrib2fv(location, reinterpret_cast<const GLfloat *>(&value));
}

/*!
    \overload

    Sets the attribute called \a name in the current context to \a value.

    \sa setUniformValue()
*/
void QOpenGLShaderProgram::setAttributeValue(const char *name, const QVector2D& value)
{
    setAttributeValue(attributeLocation(name), value);
}

/*!
    Sets the attribute at \a location in the current context to \a value.

    \sa setUniformValue()
*/
void QOpenGLShaderProgram::setAttributeValue(int location, const QVector3D& value)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1)
        d->glfuncs->glVertexAttrib3fv(location, reinterpret_cast<const GLfloat *>(&value));
}

/*!
    \overload

    Sets the attribute called \a name in the current context to \a value.

    \sa setUniformValue()
*/
void QOpenGLShaderProgram::setAttributeValue(const char *name, const QVector3D& value)
{
    setAttributeValue(attributeLocation(name), value);
}

/*!
    Sets the attribute at \a location in the current context to \a value.

    \sa setUniformValue()
*/
void QOpenGLShaderProgram::setAttributeValue(int location, const QVector4D& value)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1)
        d->glfuncs->glVertexAttrib4fv(location, reinterpret_cast<const GLfloat *>(&value));
}

/*!
    \overload

    Sets the attribute called \a name in the current context to \a value.

    \sa setUniformValue()
*/
void QOpenGLShaderProgram::setAttributeValue(const char *name, const QVector4D& value)
{
    setAttributeValue(attributeLocation(name), value);
}

/*!
    Sets the attribute at \a location in the current context to \a value.

    \sa setUniformValue()
*/
void QOpenGLShaderProgram::setAttributeValue(int location, const QColor& value)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1) {
        GLfloat values[4] = {GLfloat(value.redF()), GLfloat(value.greenF()),
                             GLfloat(value.blueF()), GLfloat(value.alphaF())};
        d->glfuncs->glVertexAttrib4fv(location, values);
    }
}

/*!
    \overload

    Sets the attribute called \a name in the current context to \a value.

    \sa setUniformValue()
*/
void QOpenGLShaderProgram::setAttributeValue(const char *name, const QColor& value)
{
    setAttributeValue(attributeLocation(name), value);
}

/*!
    Sets the attribute at \a location in the current context to the
    contents of \a values, which contains \a columns elements, each
    consisting of \a rows elements.  The \a rows value should be
    1, 2, 3, or 4.  This function is typically used to set matrix
    values and column vectors.

    \sa setUniformValue()
*/
void QOpenGLShaderProgram::setAttributeValue
    (int location, const GLfloat *values, int columns, int rows)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (rows < 1 || rows > 4) {
        qWarning("QOpenGLShaderProgram::setAttributeValue: rows %d not supported", rows);
        return;
    }
    if (location != -1) {
        while (columns-- > 0) {
            if (rows == 1)
                d->glfuncs->glVertexAttrib1fv(location, values);
            else if (rows == 2)
                d->glfuncs->glVertexAttrib2fv(location, values);
            else if (rows == 3)
                d->glfuncs->glVertexAttrib3fv(location, values);
            else
                d->glfuncs->glVertexAttrib4fv(location, values);
            values += rows;
            ++location;
        }
    }
}

/*!
    \overload

    Sets the attribute called \a name in the current context to the
    contents of \a values, which contains \a columns elements, each
    consisting of \a rows elements.  The \a rows value should be
    1, 2, 3, or 4.  This function is typically used to set matrix
    values and column vectors.

    \sa setUniformValue()
*/
void QOpenGLShaderProgram::setAttributeValue
    (const char *name, const GLfloat *values, int columns, int rows)
{
    setAttributeValue(attributeLocation(name), values, columns, rows);
}

/*!
    Sets an array of vertex \a values on the attribute at \a location
    in this shader program.  The \a tupleSize indicates the number of
    components per vertex (1, 2, 3, or 4), and the \a stride indicates
    the number of bytes between vertices.  A default \a stride value
    of zero indicates that the vertices are densely packed in \a values.

    The array will become active when enableAttributeArray() is called
    on the \a location.  Otherwise the value specified with
    setAttributeValue() for \a location will be used.

    \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
    \sa disableAttributeArray()
*/
void QOpenGLShaderProgram::setAttributeArray
    (int location, const GLfloat *values, int tupleSize, int stride)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1) {
        d->glfuncs->glVertexAttribPointer(location, tupleSize, GL_FLOAT, GL_FALSE,
                              stride, values);
    }
}

/*!
    Sets an array of 2D vertex \a values on the attribute at \a location
    in this shader program.  The \a stride indicates the number of bytes
    between vertices.  A default \a stride value of zero indicates that
    the vertices are densely packed in \a values.

    The array will become active when enableAttributeArray() is called
    on the \a location.  Otherwise the value specified with
    setAttributeValue() for \a location will be used.

    \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
    \sa disableAttributeArray()
*/
void QOpenGLShaderProgram::setAttributeArray
        (int location, const QVector2D *values, int stride)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1) {
        d->glfuncs->glVertexAttribPointer(location, 2, GL_FLOAT, GL_FALSE,
                              stride, values);
    }
}

/*!
    Sets an array of 3D vertex \a values on the attribute at \a location
    in this shader program.  The \a stride indicates the number of bytes
    between vertices.  A default \a stride value of zero indicates that
    the vertices are densely packed in \a values.

    The array will become active when enableAttributeArray() is called
    on the \a location.  Otherwise the value specified with
    setAttributeValue() for \a location will be used.

    \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
    \sa disableAttributeArray()
*/
void QOpenGLShaderProgram::setAttributeArray
        (int location, const QVector3D *values, int stride)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1) {
        d->glfuncs->glVertexAttribPointer(location, 3, GL_FLOAT, GL_FALSE,
                              stride, values);
    }
}

/*!
    Sets an array of 4D vertex \a values on the attribute at \a location
    in this shader program.  The \a stride indicates the number of bytes
    between vertices.  A default \a stride value of zero indicates that
    the vertices are densely packed in \a values.

    The array will become active when enableAttributeArray() is called
    on the \a location.  Otherwise the value specified with
    setAttributeValue() for \a location will be used.

    \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
    \sa disableAttributeArray()
*/
void QOpenGLShaderProgram::setAttributeArray
        (int location, const QVector4D *values, int stride)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1) {
        d->glfuncs->glVertexAttribPointer(location, 4, GL_FLOAT, GL_FALSE,
                              stride, values);
    }
}

/*!
    Sets an array of vertex \a values on the attribute at \a location
    in this shader program.  The \a stride indicates the number of bytes
    between vertices.  A default \a stride value of zero indicates that
    the vertices are densely packed in \a values.

    The \a type indicates the type of elements in the \a values array,
    usually \c{GL_FLOAT}, \c{GL_UNSIGNED_BYTE}, etc.  The \a tupleSize
    indicates the number of components per vertex: 1, 2, 3, or 4.

    The array will become active when enableAttributeArray() is called
    on the \a location.  Otherwise the value specified with
    setAttributeValue() for \a location will be used.

    The setAttributeBuffer() function can be used to set the attribute
    array to an offset within a vertex buffer.

    \note Normalization will be enabled. If this is not desired, call
    glVertexAttribPointer directly through QOpenGLFunctions.

    \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
    \sa disableAttributeArray(), setAttributeBuffer()
*/
void QOpenGLShaderProgram::setAttributeArray
    (int location, GLenum type, const void *values, int tupleSize, int stride)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1) {
        d->glfuncs->glVertexAttribPointer(location, tupleSize, type, GL_TRUE,
                              stride, values);
    }
}

/*!
    \overload

    Sets an array of vertex \a values on the attribute called \a name
    in this shader program.  The \a tupleSize indicates the number of
    components per vertex (1, 2, 3, or 4), and the \a stride indicates
    the number of bytes between vertices.  A default \a stride value
    of zero indicates that the vertices are densely packed in \a values.

    The array will become active when enableAttributeArray() is called
    on \a name.  Otherwise the value specified with setAttributeValue()
    for \a name will be used.

    \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
    \sa disableAttributeArray()
*/
void QOpenGLShaderProgram::setAttributeArray
    (const char *name, const GLfloat *values, int tupleSize, int stride)
{
    setAttributeArray(attributeLocation(name), values, tupleSize, stride);
}

/*!
    \overload

    Sets an array of 2D vertex \a values on the attribute called \a name
    in this shader program.  The \a stride indicates the number of bytes
    between vertices.  A default \a stride value of zero indicates that
    the vertices are densely packed in \a values.

    The array will become active when enableAttributeArray() is called
    on \a name.  Otherwise the value specified with setAttributeValue()
    for \a name will be used.

    \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
    \sa disableAttributeArray()
*/
void QOpenGLShaderProgram::setAttributeArray
        (const char *name, const QVector2D *values, int stride)
{
    setAttributeArray(attributeLocation(name), values, stride);
}

/*!
    \overload

    Sets an array of 3D vertex \a values on the attribute called \a name
    in this shader program.  The \a stride indicates the number of bytes
    between vertices.  A default \a stride value of zero indicates that
    the vertices are densely packed in \a values.

    The array will become active when enableAttributeArray() is called
    on \a name.  Otherwise the value specified with setAttributeValue()
    for \a name will be used.

    \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
    \sa disableAttributeArray()
*/
void QOpenGLShaderProgram::setAttributeArray
        (const char *name, const QVector3D *values, int stride)
{
    setAttributeArray(attributeLocation(name), values, stride);
}

/*!
    \overload

    Sets an array of 4D vertex \a values on the attribute called \a name
    in this shader program.  The \a stride indicates the number of bytes
    between vertices.  A default \a stride value of zero indicates that
    the vertices are densely packed in \a values.

    The array will become active when enableAttributeArray() is called
    on \a name.  Otherwise the value specified with setAttributeValue()
    for \a name will be used.

    \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
    \sa disableAttributeArray()
*/
void QOpenGLShaderProgram::setAttributeArray
        (const char *name, const QVector4D *values, int stride)
{
    setAttributeArray(attributeLocation(name), values, stride);
}

/*!
    \overload

    Sets an array of vertex \a values on the attribute called \a name
    in this shader program.  The \a stride indicates the number of bytes
    between vertices.  A default \a stride value of zero indicates that
    the vertices are densely packed in \a values.

    The \a type indicates the type of elements in the \a values array,
    usually \c{GL_FLOAT}, \c{GL_UNSIGNED_BYTE}, etc.  The \a tupleSize
    indicates the number of components per vertex: 1, 2, 3, or 4.

    The array will become active when enableAttributeArray() is called
    on the \a name.  Otherwise the value specified with
    setAttributeValue() for \a name will be used.

    The setAttributeBuffer() function can be used to set the attribute
    array to an offset within a vertex buffer.

    \sa setAttributeValue(), setUniformValue(), enableAttributeArray()
    \sa disableAttributeArray(), setAttributeBuffer()
*/
void QOpenGLShaderProgram::setAttributeArray
    (const char *name, GLenum type, const void *values, int tupleSize, int stride)
{
    setAttributeArray(attributeLocation(name), type, values, tupleSize, stride);
}

/*!
    Sets an array of vertex values on the attribute at \a location in
    this shader program, starting at a specific \a offset in the
    currently bound vertex buffer.  The \a stride indicates the number
    of bytes between vertices.  A default \a stride value of zero
    indicates that the vertices are densely packed in the value array.

    The \a type indicates the type of elements in the vertex value
    array, usually \c{GL_FLOAT}, \c{GL_UNSIGNED_BYTE}, etc.  The \a
    tupleSize indicates the number of components per vertex: 1, 2, 3,
    or 4.

    The array will become active when enableAttributeArray() is called
    on the \a location.  Otherwise the value specified with
    setAttributeValue() for \a location will be used.

    \note Normalization will be enabled. If this is not desired, call
    glVertexAttribPointer directly through QOpenGLFunctions.

    \sa setAttributeArray()
*/
void QOpenGLShaderProgram::setAttributeBuffer
    (int location, GLenum type, int offset, int tupleSize, int stride)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1) {
        d->glfuncs->glVertexAttribPointer(location, tupleSize, type, GL_TRUE, stride,
                              reinterpret_cast<const void *>(qintptr(offset)));
    }
}

/*!
    \overload

    Sets an array of vertex values on the attribute called \a name
    in this shader program, starting at a specific \a offset in the
    currently bound vertex buffer.  The \a stride indicates the number
    of bytes between vertices.  A default \a stride value of zero
    indicates that the vertices are densely packed in the value array.

    The \a type indicates the type of elements in the vertex value
    array, usually \c{GL_FLOAT}, \c{GL_UNSIGNED_BYTE}, etc.  The \a
    tupleSize indicates the number of components per vertex: 1, 2, 3,
    or 4.

    The array will become active when enableAttributeArray() is called
    on the \a name.  Otherwise the value specified with
    setAttributeValue() for \a name will be used.

    \sa setAttributeArray()
*/
void QOpenGLShaderProgram::setAttributeBuffer
    (const char *name, GLenum type, int offset, int tupleSize, int stride)
{
    setAttributeBuffer(attributeLocation(name), type, offset, tupleSize, stride);
}

/*!
    Enables the vertex array at \a location in this shader program
    so that the value set by setAttributeArray() on \a location
    will be used by the shader program.

    \sa disableAttributeArray(), setAttributeArray(), setAttributeValue()
    \sa setUniformValue()
*/
void QOpenGLShaderProgram::enableAttributeArray(int location)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1)
        d->glfuncs->glEnableVertexAttribArray(location);
}

/*!
    \overload

    Enables the vertex array called \a name in this shader program
    so that the value set by setAttributeArray() on \a name
    will be used by the shader program.

    \sa disableAttributeArray(), setAttributeArray(), setAttributeValue()
    \sa setUniformValue()
*/
void QOpenGLShaderProgram::enableAttributeArray(const char *name)
{
    enableAttributeArray(attributeLocation(name));
}

/*!
    Disables the vertex array at \a location in this shader program
    that was enabled by a previous call to enableAttributeArray().

    \sa enableAttributeArray(), setAttributeArray(), setAttributeValue()
    \sa setUniformValue()
*/
void QOpenGLShaderProgram::disableAttributeArray(int location)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1)
        d->glfuncs->glDisableVertexAttribArray(location);
}

/*!
    \overload

    Disables the vertex array called \a name in this shader program
    that was enabled by a previous call to enableAttributeArray().

    \sa enableAttributeArray(), setAttributeArray(), setAttributeValue()
    \sa setUniformValue()
*/
void QOpenGLShaderProgram::disableAttributeArray(const char *name)
{
    disableAttributeArray(attributeLocation(name));
}

/*!
    Returns the location of the uniform variable \a name within this shader
    program's parameter list.  Returns -1 if \a name is not a valid
    uniform variable for this shader program.

    \sa attributeLocation()
*/
int QOpenGLShaderProgram::uniformLocation(const char *name) const
{
    Q_D(const QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (d->linked && d->programGuard && d->programGuard->id()) {
        return d->glfuncs->glGetUniformLocation(d->programGuard->id(), name);
    } else {
        qWarning("QOpenGLShaderProgram::uniformLocation(%s): shader program is not linked", name);
        return -1;
    }
}

/*!
    \overload

    Returns the location of the uniform variable \a name within this shader
    program's parameter list.  Returns -1 if \a name is not a valid
    uniform variable for this shader program.

    \sa attributeLocation()
*/
int QOpenGLShaderProgram::uniformLocation(const QByteArray& name) const
{
    return uniformLocation(name.constData());
}

/*!
    \overload

    Returns the location of the uniform variable \a name within this shader
    program's parameter list.  Returns -1 if \a name is not a valid
    uniform variable for this shader program.

    \sa attributeLocation()
*/
int QOpenGLShaderProgram::uniformLocation(const QString& name) const
{
    return uniformLocation(name.toLatin1().constData());
}

/*!
    Sets the uniform variable at \a location in the current context to \a value.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, GLfloat value)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1)
        d->glfuncs->glUniform1fv(location, 1, &value);
}

/*!
    \overload

    Sets the uniform variable called \a name in the current context
    to \a value.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, GLfloat value)
{
    setUniformValue(uniformLocation(name), value);
}

/*!
    Sets the uniform variable at \a location in the current context to \a value.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, GLint value)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1)
        d->glfuncs->glUniform1i(location, value);
}

/*!
    \overload

    Sets the uniform variable called \a name in the current context
    to \a value.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, GLint value)
{
    setUniformValue(uniformLocation(name), value);
}

/*!
    Sets the uniform variable at \a location in the current context to \a value.
    This function should be used when setting sampler values.

    \note This function is not aware of unsigned int support in modern OpenGL
    versions and therefore treats \a value as a GLint and calls glUniform1i.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, GLuint value)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1)
        d->glfuncs->glUniform1i(location, value);
}

/*!
    \overload

    Sets the uniform variable called \a name in the current context
    to \a value.  This function should be used when setting sampler values.

    \note This function is not aware of unsigned int support in modern OpenGL
    versions and therefore treats \a value as a GLint and calls glUniform1i.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, GLuint value)
{
    setUniformValue(uniformLocation(name), value);
}

/*!
    Sets the uniform variable at \a location in the current context to
    the 2D vector (\a x, \a y).

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, GLfloat x, GLfloat y)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1) {
        GLfloat values[2] = {x, y};
        d->glfuncs->glUniform2fv(location, 1, values);
    }
}

/*!
    \overload

    Sets the uniform variable called \a name in the current context to
    the 2D vector (\a x, \a y).

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, GLfloat x, GLfloat y)
{
    setUniformValue(uniformLocation(name), x, y);
}

/*!
    Sets the uniform variable at \a location in the current context to
    the 3D vector (\a x, \a y, \a z).

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue
        (int location, GLfloat x, GLfloat y, GLfloat z)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1) {
        GLfloat values[3] = {x, y, z};
        d->glfuncs->glUniform3fv(location, 1, values);
    }
}

/*!
    \overload

    Sets the uniform variable called \a name in the current context to
    the 3D vector (\a x, \a y, \a z).

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue
        (const char *name, GLfloat x, GLfloat y, GLfloat z)
{
    setUniformValue(uniformLocation(name), x, y, z);
}

/*!
    Sets the uniform variable at \a location in the current context to
    the 4D vector (\a x, \a y, \a z, \a w).

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue
        (int location, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1) {
        GLfloat values[4] = {x, y, z, w};
        d->glfuncs->glUniform4fv(location, 1, values);
    }
}

/*!
    \overload

    Sets the uniform variable called \a name in the current context to
    the 4D vector (\a x, \a y, \a z, \a w).

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue
        (const char *name, GLfloat x, GLfloat y, GLfloat z, GLfloat w)
{
    setUniformValue(uniformLocation(name), x, y, z, w);
}

/*!
    Sets the uniform variable at \a location in the current context to \a value.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const QVector2D& value)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1)
        d->glfuncs->glUniform2fv(location, 1, reinterpret_cast<const GLfloat *>(&value));
}

/*!
    \overload

    Sets the uniform variable called \a name in the current context
    to \a value.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const QVector2D& value)
{
    setUniformValue(uniformLocation(name), value);
}

/*!
    Sets the uniform variable at \a location in the current context to \a value.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const QVector3D& value)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1)
        d->glfuncs->glUniform3fv(location, 1, reinterpret_cast<const GLfloat *>(&value));
}

/*!
    \overload

    Sets the uniform variable called \a name in the current context
    to \a value.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const QVector3D& value)
{
    setUniformValue(uniformLocation(name), value);
}

/*!
    Sets the uniform variable at \a location in the current context to \a value.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const QVector4D& value)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1)
        d->glfuncs->glUniform4fv(location, 1, reinterpret_cast<const GLfloat *>(&value));
}

/*!
    \overload

    Sets the uniform variable called \a name in the current context
    to \a value.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const QVector4D& value)
{
    setUniformValue(uniformLocation(name), value);
}

/*!
    Sets the uniform variable at \a location in the current context to
    the red, green, blue, and alpha components of \a color.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const QColor& color)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1) {
        GLfloat values[4] = {GLfloat(color.redF()), GLfloat(color.greenF()),
                             GLfloat(color.blueF()), GLfloat(color.alphaF())};
        d->glfuncs->glUniform4fv(location, 1, values);
    }
}

/*!
    \overload

    Sets the uniform variable called \a name in the current context to
    the red, green, blue, and alpha components of \a color.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const QColor& color)
{
    setUniformValue(uniformLocation(name), color);
}

/*!
    Sets the uniform variable at \a location in the current context to
    the x and y coordinates of \a point.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const QPoint& point)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1) {
        GLfloat values[4] = {GLfloat(point.x()), GLfloat(point.y())};
        d->glfuncs->glUniform2fv(location, 1, values);
    }
}

/*!
    \overload

    Sets the uniform variable associated with \a name in the current
    context to the x and y coordinates of \a point.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const QPoint& point)
{
    setUniformValue(uniformLocation(name), point);
}

/*!
    Sets the uniform variable at \a location in the current context to
    the x and y coordinates of \a point.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const QPointF& point)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1) {
        GLfloat values[4] = {GLfloat(point.x()), GLfloat(point.y())};
        d->glfuncs->glUniform2fv(location, 1, values);
    }
}

/*!
    \overload

    Sets the uniform variable associated with \a name in the current
    context to the x and y coordinates of \a point.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const QPointF& point)
{
    setUniformValue(uniformLocation(name), point);
}

/*!
    Sets the uniform variable at \a location in the current context to
    the width and height of the given \a size.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const QSize& size)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1) {
        GLfloat values[4] = {GLfloat(size.width()), GLfloat(size.height())};
        d->glfuncs->glUniform2fv(location, 1, values);
    }
}

/*!
    \overload

    Sets the uniform variable associated with \a name in the current
    context to the width and height of the given \a size.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const QSize& size)
{
    setUniformValue(uniformLocation(name), size);
}

/*!
    Sets the uniform variable at \a location in the current context to
    the width and height of the given \a size.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const QSizeF& size)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1) {
        GLfloat values[4] = {GLfloat(size.width()), GLfloat(size.height())};
        d->glfuncs->glUniform2fv(location, 1, values);
    }
}

/*!
    \overload

    Sets the uniform variable associated with \a name in the current
    context to the width and height of the given \a size.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const QSizeF& size)
{
    setUniformValue(uniformLocation(name), size);
}

/*!
    Sets the uniform variable at \a location in the current context
    to a 2x2 matrix \a value.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix2x2& value)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    d->glfuncs->glUniformMatrix2fv(location, 1, GL_FALSE, value.constData());
}

/*!
    \overload

    Sets the uniform variable called \a name in the current context
    to a 2x2 matrix \a value.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix2x2& value)
{
    setUniformValue(uniformLocation(name), value);
}

/*!
    Sets the uniform variable at \a location in the current context
    to a 2x3 matrix \a value.

    \note This function is not aware of non square matrix support,
    that is, GLSL types like mat2x3, that is present in modern OpenGL
    versions. Instead, it treats the uniform as an array of vec3.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix2x3& value)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    d->glfuncs->glUniform3fv(location, 2, value.constData());
}

/*!
    \overload

    Sets the uniform variable called \a name in the current context
    to a 2x3 matrix \a value.

    \note This function is not aware of non square matrix support,
    that is, GLSL types like mat2x3, that is present in modern OpenGL
    versions. Instead, it treats the uniform as an array of vec3.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix2x3& value)
{
    setUniformValue(uniformLocation(name), value);
}

/*!
    Sets the uniform variable at \a location in the current context
    to a 2x4 matrix \a value.

    \note This function is not aware of non square matrix support,
    that is, GLSL types like mat2x4, that is present in modern OpenGL
    versions. Instead, it treats the uniform as an array of vec4.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix2x4& value)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    d->glfuncs->glUniform4fv(location, 2, value.constData());
}

/*!
    \overload

    Sets the uniform variable called \a name in the current context
    to a 2x4 matrix \a value.

    \note This function is not aware of non square matrix support,
    that is, GLSL types like mat2x4, that is present in modern OpenGL
    versions. Instead, it treats the uniform as an array of vec4.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix2x4& value)
{
    setUniformValue(uniformLocation(name), value);
}

/*!
    Sets the uniform variable at \a location in the current context
    to a 3x2 matrix \a value.

    \note This function is not aware of non square matrix support,
    that is, GLSL types like mat3x2, that is present in modern OpenGL
    versions. Instead, it treats the uniform as an array of vec2.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix3x2& value)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    d->glfuncs->glUniform2fv(location, 3, value.constData());
}

/*!
    \overload

    Sets the uniform variable called \a name in the current context
    to a 3x2 matrix \a value.

    \note This function is not aware of non square matrix support,
    that is, GLSL types like mat3x2, that is present in modern OpenGL
    versions. Instead, it treats the uniform as an array of vec2.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix3x2& value)
{
    setUniformValue(uniformLocation(name), value);
}

/*!
    Sets the uniform variable at \a location in the current context
    to a 3x3 matrix \a value.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix3x3& value)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    d->glfuncs->glUniformMatrix3fv(location, 1, GL_FALSE, value.constData());
}

/*!
    \overload

    Sets the uniform variable called \a name in the current context
    to a 3x3 matrix \a value.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix3x3& value)
{
    setUniformValue(uniformLocation(name), value);
}

/*!
    Sets the uniform variable at \a location in the current context
    to a 3x4 matrix \a value.

    \note This function is not aware of non square matrix support,
    that is, GLSL types like mat3x4, that is present in modern OpenGL
    versions. Instead, it treats the uniform as an array of vec4.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix3x4& value)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    d->glfuncs->glUniform4fv(location, 3, value.constData());
}

/*!
    \overload

    Sets the uniform variable called \a name in the current context
    to a 3x4 matrix \a value.

    \note This function is not aware of non square matrix support,
    that is, GLSL types like mat3x4, that is present in modern OpenGL
    versions. Instead, it treats the uniform as an array of vec4.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix3x4& value)
{
    setUniformValue(uniformLocation(name), value);
}

/*!
    Sets the uniform variable at \a location in the current context
    to a 4x2 matrix \a value.

    \note This function is not aware of non square matrix support,
    that is, GLSL types like mat4x2, that is present in modern OpenGL
    versions. Instead, it treats the uniform as an array of vec2.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix4x2& value)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    d->glfuncs->glUniform2fv(location, 4, value.constData());
}

/*!
    \overload

    Sets the uniform variable called \a name in the current context
    to a 4x2 matrix \a value.

    \note This function is not aware of non square matrix support,
    that is, GLSL types like mat4x2, that is present in modern OpenGL
    versions. Instead, it treats the uniform as an array of vec2.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix4x2& value)
{
    setUniformValue(uniformLocation(name), value);
}

/*!
    Sets the uniform variable at \a location in the current context
    to a 4x3 matrix \a value.

    \note This function is not aware of non square matrix support,
    that is, GLSL types like mat4x3, that is present in modern OpenGL
    versions. Instead, it treats the uniform as an array of vec3.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix4x3& value)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    d->glfuncs->glUniform3fv(location, 4, value.constData());
}

/*!
    \overload

    Sets the uniform variable called \a name in the current context
    to a 4x3 matrix \a value.

    \note This function is not aware of non square matrix support,
    that is, GLSL types like mat4x3, that is present in modern OpenGL
    versions. Instead, it treats the uniform as an array of vec3.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix4x3& value)
{
    setUniformValue(uniformLocation(name), value);
}

/*!
    Sets the uniform variable at \a location in the current context
    to a 4x4 matrix \a value.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const QMatrix4x4& value)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    d->glfuncs->glUniformMatrix4fv(location, 1, GL_FALSE, value.constData());
}

/*!
    \overload

    Sets the uniform variable called \a name in the current context
    to a 4x4 matrix \a value.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const QMatrix4x4& value)
{
    setUniformValue(uniformLocation(name), value);
}

/*!
    \overload

    Sets the uniform variable at \a location in the current context
    to a 2x2 matrix \a value.  The matrix elements must be specified
    in column-major order.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const GLfloat value[2][2])
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1)
        d->glfuncs->glUniformMatrix2fv(location, 1, GL_FALSE, value[0]);
}

/*!
    \overload

    Sets the uniform variable at \a location in the current context
    to a 3x3 matrix \a value.  The matrix elements must be specified
    in column-major order.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const GLfloat value[3][3])
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1)
        d->glfuncs->glUniformMatrix3fv(location, 1, GL_FALSE, value[0]);
}

/*!
    \overload

    Sets the uniform variable at \a location in the current context
    to a 4x4 matrix \a value.  The matrix elements must be specified
    in column-major order.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(int location, const GLfloat value[4][4])
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1)
        d->glfuncs->glUniformMatrix4fv(location, 1, GL_FALSE, value[0]);
}


/*!
    \overload

    Sets the uniform variable called \a name in the current context
    to a 2x2 matrix \a value.  The matrix elements must be specified
    in column-major order.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const GLfloat value[2][2])
{
    setUniformValue(uniformLocation(name), value);
}

/*!
    \overload

    Sets the uniform variable called \a name in the current context
    to a 3x3 matrix \a value.  The matrix elements must be specified
    in column-major order.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const GLfloat value[3][3])
{
    setUniformValue(uniformLocation(name), value);
}

/*!
    \overload

    Sets the uniform variable called \a name in the current context
    to a 4x4 matrix \a value.  The matrix elements must be specified
    in column-major order.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValue(const char *name, const GLfloat value[4][4])
{
    setUniformValue(uniformLocation(name), value);
}

/*!
    Sets the uniform variable at \a location in the current context to a
    3x3 transformation matrix \a value that is specified as a QTransform value.

    To set a QTransform value as a 4x4 matrix in a shader, use
    \c{setUniformValue(location, QMatrix4x4(value))}.
*/
void QOpenGLShaderProgram::setUniformValue(int location, const QTransform& value)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1) {
        GLfloat mat[3][3] = {
            {GLfloat(value.m11()), GLfloat(value.m12()), GLfloat(value.m13())},
            {GLfloat(value.m21()), GLfloat(value.m22()), GLfloat(value.m23())},
            {GLfloat(value.m31()), GLfloat(value.m32()), GLfloat(value.m33())}
        };
        d->glfuncs->glUniformMatrix3fv(location, 1, GL_FALSE, mat[0]);
    }
}

/*!
    \overload

    Sets the uniform variable called \a name in the current context to a
    3x3 transformation matrix \a value that is specified as a QTransform value.

    To set a QTransform value as a 4x4 matrix in a shader, use
    \c{setUniformValue(name, QMatrix4x4(value))}.
*/
void QOpenGLShaderProgram::setUniformValue
        (const char *name, const QTransform& value)
{
    setUniformValue(uniformLocation(name), value);
}

/*!
    Sets the uniform variable array at \a location in the current
    context to the \a count elements of \a values.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValueArray(int location, const GLint *values, int count)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1)
        d->glfuncs->glUniform1iv(location, count, values);
}

/*!
    \overload

    Sets the uniform variable array called \a name in the current
    context to the \a count elements of \a values.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValueArray
        (const char *name, const GLint *values, int count)
{
    setUniformValueArray(uniformLocation(name), values, count);
}

/*!
    Sets the uniform variable array at \a location in the current
    context to the \a count elements of \a values.  This overload
    should be used when setting an array of sampler values.

    \note This function is not aware of unsigned int support in modern OpenGL
    versions and therefore treats \a values as a GLint and calls glUniform1iv.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValueArray(int location, const GLuint *values, int count)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1)
        d->glfuncs->glUniform1iv(location, count, reinterpret_cast<const GLint *>(values));
}

/*!
    \overload

    Sets the uniform variable array called \a name in the current
    context to the \a count elements of \a values.  This overload
    should be used when setting an array of sampler values.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValueArray
        (const char *name, const GLuint *values, int count)
{
    setUniformValueArray(uniformLocation(name), values, count);
}

/*!
    Sets the uniform variable array at \a location in the current
    context to the \a count elements of \a values.  Each element
    has \a tupleSize components.  The \a tupleSize must be 1, 2, 3, or 4.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValueArray(int location, const GLfloat *values, int count, int tupleSize)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1) {
        if (tupleSize == 1)
            d->glfuncs->glUniform1fv(location, count, values);
        else if (tupleSize == 2)
            d->glfuncs->glUniform2fv(location, count, values);
        else if (tupleSize == 3)
            d->glfuncs->glUniform3fv(location, count, values);
        else if (tupleSize == 4)
            d->glfuncs->glUniform4fv(location, count, values);
        else
            qWarning("QOpenGLShaderProgram::setUniformValue: size %d not supported", tupleSize);
    }
}

/*!
    \overload

    Sets the uniform variable array called \a name in the current
    context to the \a count elements of \a values.  Each element
    has \a tupleSize components.  The \a tupleSize must be 1, 2, 3, or 4.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValueArray
        (const char *name, const GLfloat *values, int count, int tupleSize)
{
    setUniformValueArray(uniformLocation(name), values, count, tupleSize);
}

/*!
    Sets the uniform variable array at \a location in the current
    context to the \a count 2D vector elements of \a values.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValueArray(int location, const QVector2D *values, int count)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1)
        d->glfuncs->glUniform2fv(location, count, reinterpret_cast<const GLfloat *>(values));
}

/*!
    \overload

    Sets the uniform variable array called \a name in the current
    context to the \a count 2D vector elements of \a values.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValueArray(const char *name, const QVector2D *values, int count)
{
    setUniformValueArray(uniformLocation(name), values, count);
}

/*!
    Sets the uniform variable array at \a location in the current
    context to the \a count 3D vector elements of \a values.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValueArray(int location, const QVector3D *values, int count)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1)
        d->glfuncs->glUniform3fv(location, count, reinterpret_cast<const GLfloat *>(values));
}

/*!
    \overload

    Sets the uniform variable array called \a name in the current
    context to the \a count 3D vector elements of \a values.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValueArray(const char *name, const QVector3D *values, int count)
{
    setUniformValueArray(uniformLocation(name), values, count);
}

/*!
    Sets the uniform variable array at \a location in the current
    context to the \a count 4D vector elements of \a values.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValueArray(int location, const QVector4D *values, int count)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    if (location != -1)
        d->glfuncs->glUniform4fv(location, count, reinterpret_cast<const GLfloat *>(values));
}

/*!
    \overload

    Sets the uniform variable array called \a name in the current
    context to the \a count 4D vector elements of \a values.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValueArray(const char *name, const QVector4D *values, int count)
{
    setUniformValueArray(uniformLocation(name), values, count);
}

// We have to repack matrix arrays from qreal to GLfloat.
#define setUniformMatrixArray(func,location,values,count,type,cols,rows) \
    if (location == -1 || count <= 0) \
        return; \
    if (sizeof(type) == sizeof(GLfloat) * cols * rows) { \
        func(location, count, GL_FALSE, \
             reinterpret_cast<const GLfloat *>(values[0].constData())); \
    } else { \
        QVarLengthArray<GLfloat> temp(cols * rows * count); \
        for (int index = 0; index < count; ++index) { \
            for (int index2 = 0; index2 < (cols * rows); ++index2) { \
                temp.data()[cols * rows * index + index2] = \
                    values[index].constData()[index2]; \
            } \
        } \
        func(location, count, GL_FALSE, temp.constData()); \
    }
#define setUniformGenericMatrixArray(colfunc,location,values,count,type,cols,rows) \
    if (location == -1 || count <= 0) \
        return; \
    if (sizeof(type) == sizeof(GLfloat) * cols * rows) { \
        const GLfloat *data = reinterpret_cast<const GLfloat *> \
            (values[0].constData());  \
        colfunc(location, count * cols, data); \
    } else { \
        QVarLengthArray<GLfloat> temp(cols * rows * count); \
        for (int index = 0; index < count; ++index) { \
            for (int index2 = 0; index2 < (cols * rows); ++index2) { \
                temp.data()[cols * rows * index + index2] = \
                    values[index].constData()[index2]; \
            } \
        } \
        colfunc(location, count * cols, temp.constData()); \
    }

/*!
    Sets the uniform variable array at \a location in the current
    context to the \a count 2x2 matrix elements of \a values.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValueArray(int location, const QMatrix2x2 *values, int count)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    setUniformMatrixArray
        (d->glfuncs->glUniformMatrix2fv, location, values, count, QMatrix2x2, 2, 2);
}

/*!
    \overload

    Sets the uniform variable array called \a name in the current
    context to the \a count 2x2 matrix elements of \a values.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValueArray(const char *name, const QMatrix2x2 *values, int count)
{
    setUniformValueArray(uniformLocation(name), values, count);
}

/*!
    Sets the uniform variable array at \a location in the current
    context to the \a count 2x3 matrix elements of \a values.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValueArray(int location, const QMatrix2x3 *values, int count)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    setUniformGenericMatrixArray
        (d->glfuncs->glUniform3fv, location, values, count,
         QMatrix2x3, 2, 3);
}

/*!
    \overload

    Sets the uniform variable array called \a name in the current
    context to the \a count 2x3 matrix elements of \a values.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValueArray(const char *name, const QMatrix2x3 *values, int count)
{
    setUniformValueArray(uniformLocation(name), values, count);
}

/*!
    Sets the uniform variable array at \a location in the current
    context to the \a count 2x4 matrix elements of \a values.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValueArray(int location, const QMatrix2x4 *values, int count)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    setUniformGenericMatrixArray
        (d->glfuncs->glUniform4fv, location, values, count,
         QMatrix2x4, 2, 4);
}

/*!
    \overload

    Sets the uniform variable array called \a name in the current
    context to the \a count 2x4 matrix elements of \a values.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValueArray(const char *name, const QMatrix2x4 *values, int count)
{
    setUniformValueArray(uniformLocation(name), values, count);
}

/*!
    Sets the uniform variable array at \a location in the current
    context to the \a count 3x2 matrix elements of \a values.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValueArray(int location, const QMatrix3x2 *values, int count)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    setUniformGenericMatrixArray
        (d->glfuncs->glUniform2fv, location, values, count,
         QMatrix3x2, 3, 2);
}

/*!
    \overload

    Sets the uniform variable array called \a name in the current
    context to the \a count 3x2 matrix elements of \a values.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValueArray(const char *name, const QMatrix3x2 *values, int count)
{
    setUniformValueArray(uniformLocation(name), values, count);
}

/*!
    Sets the uniform variable array at \a location in the current
    context to the \a count 3x3 matrix elements of \a values.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValueArray(int location, const QMatrix3x3 *values, int count)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    setUniformMatrixArray
        (d->glfuncs->glUniformMatrix3fv, location, values, count, QMatrix3x3, 3, 3);
}

/*!
    \overload

    Sets the uniform variable array called \a name in the current
    context to the \a count 3x3 matrix elements of \a values.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValueArray(const char *name, const QMatrix3x3 *values, int count)
{
    setUniformValueArray(uniformLocation(name), values, count);
}

/*!
    Sets the uniform variable array at \a location in the current
    context to the \a count 3x4 matrix elements of \a values.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValueArray(int location, const QMatrix3x4 *values, int count)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    setUniformGenericMatrixArray
        (d->glfuncs->glUniform4fv, location, values, count,
         QMatrix3x4, 3, 4);
}

/*!
    \overload

    Sets the uniform variable array called \a name in the current
    context to the \a count 3x4 matrix elements of \a values.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValueArray(const char *name, const QMatrix3x4 *values, int count)
{
    setUniformValueArray(uniformLocation(name), values, count);
}

/*!
    Sets the uniform variable array at \a location in the current
    context to the \a count 4x2 matrix elements of \a values.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValueArray(int location, const QMatrix4x2 *values, int count)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    setUniformGenericMatrixArray
        (d->glfuncs->glUniform2fv, location, values, count,
         QMatrix4x2, 4, 2);
}

/*!
    \overload

    Sets the uniform variable array called \a name in the current
    context to the \a count 4x2 matrix elements of \a values.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValueArray(const char *name, const QMatrix4x2 *values, int count)
{
    setUniformValueArray(uniformLocation(name), values, count);
}

/*!
    Sets the uniform variable array at \a location in the current
    context to the \a count 4x3 matrix elements of \a values.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValueArray(int location, const QMatrix4x3 *values, int count)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    setUniformGenericMatrixArray
        (d->glfuncs->glUniform3fv, location, values, count,
         QMatrix4x3, 4, 3);
}

/*!
    \overload

    Sets the uniform variable array called \a name in the current
    context to the \a count 4x3 matrix elements of \a values.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValueArray(const char *name, const QMatrix4x3 *values, int count)
{
    setUniformValueArray(uniformLocation(name), values, count);
}

/*!
    Sets the uniform variable array at \a location in the current
    context to the \a count 4x4 matrix elements of \a values.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValueArray(int location, const QMatrix4x4 *values, int count)
{
    Q_D(QOpenGLShaderProgram);
    Q_UNUSED(d);
    setUniformMatrixArray
        (d->glfuncs->glUniformMatrix4fv, location, values, count, QMatrix4x4, 4, 4);
}

/*!
    \overload

    Sets the uniform variable array called \a name in the current
    context to the \a count 4x4 matrix elements of \a values.

    \sa setAttributeValue()
*/
void QOpenGLShaderProgram::setUniformValueArray(const char *name, const QMatrix4x4 *values, int count)
{
    setUniformValueArray(uniformLocation(name), values, count);
}

/*!
    Returns the hardware limit for how many vertices a geometry shader
    can output.
*/
int QOpenGLShaderProgram::maxGeometryOutputVertices() const
{
    GLint n = 0;
    Q_D(const QOpenGLShaderProgram);
    d->glfuncs->glGetIntegerv(GL_MAX_GEOMETRY_OUTPUT_VERTICES, &n);
    return n;
}

/*!
    Use this function to specify to OpenGL the number of vertices in
    a patch to \a count. A patch is a custom OpenGL primitive whose interpretation
    is entirely defined by the tessellation shader stages. Therefore, calling
    this function only makes sense when using a QOpenGLShaderProgram
    containing tessellation stage shaders. When using OpenGL tessellation,
    the only primitive that can be rendered with \c{glDraw*()} functions is
    \c{GL_PATCHES}.

    This is equivalent to calling glPatchParameteri(GL_PATCH_VERTICES, count).

    \note This modifies global OpenGL state and is not specific to this
    QOpenGLShaderProgram instance. You should call this in your render
    function when needed, as QOpenGLShaderProgram will not apply this for
    you. This is purely a convenience function.

    \sa patchVertexCount()
*/
void QOpenGLShaderProgram::setPatchVertexCount(int count)
{
    Q_D(QOpenGLShaderProgram);
    d->glfuncs->glPatchParameteri(GL_PATCH_VERTICES, count);
}

/*!
    Returns the number of vertices per-patch to be used when rendering.

    \note This returns the global OpenGL state value. It is not specific to
    this QOpenGLShaderProgram instance.

    \sa setPatchVertexCount()
*/
int QOpenGLShaderProgram::patchVertexCount() const
{
    int patchVertices = 0;
    Q_D(const QOpenGLShaderProgram);
    d->glfuncs->glGetIntegerv(GL_PATCH_VERTICES, &patchVertices);
    return patchVertices;
}

/*!
    Sets the default outer tessellation levels to be used by the tessellation
    primitive generator in the event that the tessellation control shader
    does not output them to \a levels. For more details on OpenGL and Tessellation
    shaders see \l{OpenGL Tessellation Shaders}.

    The \a levels argument should be a QVector consisting of 4 floats. Not all
    of the values make sense for all tessellation modes. If you specify a vector with
    fewer than 4 elements, the remaining elements will be given a default value of 1.

    \note This modifies global OpenGL state and is not specific to this
    QOpenGLShaderProgram instance. You should call this in your render
    function when needed, as QOpenGLShaderProgram will not apply this for
    you. This is purely a convenience function.

    \note This function is only available with OpenGL >= 4.0 and is not supported
    with OpenGL ES 3.2.

    \sa defaultOuterTessellationLevels(), setDefaultInnerTessellationLevels()
*/
void QOpenGLShaderProgram::setDefaultOuterTessellationLevels(const QVector<float> &levels)
{
#ifndef QT_OPENGL_ES_2
    Q_D(QOpenGLShaderProgram);
    if (d->tessellationFuncs) {
        QVector<float> tessLevels = levels;

        // Ensure we have the required 4 outer tessellation levels
        // Use default of 1 for missing entries (same as spec)
        const int argCount = 4;
        if (tessLevels.size() < argCount) {
            tessLevels.reserve(argCount);
            for (int i = tessLevels.size(); i < argCount; ++i)
                tessLevels.append(1.0f);
        }
        d->tessellationFuncs->glPatchParameterfv(GL_PATCH_DEFAULT_OUTER_LEVEL, tessLevels.data());
    }
#else
    Q_UNUSED(levels);
#endif
}

/*!
    Returns the default outer tessellation levels to be used by the tessellation
    primitive generator in the event that the tessellation control shader
    does not output them. For more details on OpenGL and Tessellation shaders see
    \l{OpenGL Tessellation Shaders}.

    Returns a QVector of floats describing the outer tessellation levels. The vector
    will always have four elements but not all of them make sense for every mode
    of tessellation.

    \note This returns the global OpenGL state value. It is not specific to
    this QOpenGLShaderProgram instance.

    \note This function is only supported with OpenGL >= 4.0 and will not
    return valid results with OpenGL ES 3.2.

    \sa setDefaultOuterTessellationLevels(), defaultInnerTessellationLevels()
*/
QVector<float> QOpenGLShaderProgram::defaultOuterTessellationLevels() const
{
#ifndef QT_OPENGL_ES_2
    QVector<float> tessLevels(4, 1.0f);
    Q_D(const QOpenGLShaderProgram);
    if (d->tessellationFuncs)
        d->tessellationFuncs->glGetFloatv(GL_PATCH_DEFAULT_OUTER_LEVEL, tessLevels.data());
    return tessLevels;
#else
    return QVector<float>();
#endif
}

/*!
    Sets the default outer tessellation levels to be used by the tessellation
    primitive generator in the event that the tessellation control shader
    does not output them to \a levels. For more details on OpenGL and Tessellation shaders see
    \l{OpenGL Tessellation Shaders}.

    The \a levels argument should be a QVector consisting of 2 floats. Not all
    of the values make sense for all tessellation modes. If you specify a vector with
    fewer than 2 elements, the remaining elements will be given a default value of 1.

    \note This modifies global OpenGL state and is not specific to this
    QOpenGLShaderProgram instance. You should call this in your render
    function when needed, as QOpenGLShaderProgram will not apply this for
    you. This is purely a convenience function.

    \note This function is only available with OpenGL >= 4.0 and is not supported
    with OpenGL ES 3.2.

    \sa defaultInnerTessellationLevels(), setDefaultOuterTessellationLevels()
*/
void QOpenGLShaderProgram::setDefaultInnerTessellationLevels(const QVector<float> &levels)
{
#ifndef QT_OPENGL_ES_2
    Q_D(QOpenGLShaderProgram);
    if (d->tessellationFuncs) {
        QVector<float> tessLevels = levels;

        // Ensure we have the required 2 inner tessellation levels
        // Use default of 1 for missing entries (same as spec)
        const int argCount = 2;
        if (tessLevels.size() < argCount) {
            tessLevels.reserve(argCount);
            for (int i = tessLevels.size(); i < argCount; ++i)
                tessLevels.append(1.0f);
        }
        d->tessellationFuncs->glPatchParameterfv(GL_PATCH_DEFAULT_INNER_LEVEL, tessLevels.data());
    }
#else
    Q_UNUSED(levels);
#endif
}

/*!
    Returns the default inner tessellation levels to be used by the tessellation
    primitive generator in the event that the tessellation control shader
    does not output them. For more details on OpenGL and Tessellation shaders see
    \l{OpenGL Tessellation Shaders}.

    Returns a QVector of floats describing the inner tessellation levels. The vector
    will always have two elements but not all of them make sense for every mode
    of tessellation.

    \note This returns the global OpenGL state value. It is not specific to
    this QOpenGLShaderProgram instance.

    \note This function is only supported with OpenGL >= 4.0 and will not
    return valid results with OpenGL ES 3.2.

    \sa setDefaultInnerTessellationLevels(), defaultOuterTessellationLevels()
*/
QVector<float> QOpenGLShaderProgram::defaultInnerTessellationLevels() const
{
#ifndef QT_OPENGL_ES_2
    QVector<float> tessLevels(2, 1.0f);
    Q_D(const QOpenGLShaderProgram);
    if (d->tessellationFuncs)
        d->tessellationFuncs->glGetFloatv(GL_PATCH_DEFAULT_INNER_LEVEL, tessLevels.data());
    return tessLevels;
#else
    return QVector<float>();
#endif
}


/*!
    Returns \c true if shader programs written in the OpenGL Shading
    Language (GLSL) are supported on this system; false otherwise.

    The \a context is used to resolve the GLSL extensions.
    If \a context is \nullptr, then QOpenGLContext::currentContext()
    is used.
*/
bool QOpenGLShaderProgram::hasOpenGLShaderPrograms(QOpenGLContext *context)
{
    if (!context)
        context = QOpenGLContext::currentContext();
    if (!context)
        return false;
    return QOpenGLFunctions(context).hasOpenGLFeature(QOpenGLFunctions::Shaders);
}

/*!
    \internal
*/
void QOpenGLShaderProgram::shaderDestroyed()
{
    Q_D(QOpenGLShaderProgram);
    QOpenGLShader *shader = qobject_cast<QOpenGLShader *>(sender());
    if (shader && !d->removingShaders)
        removeShader(shader);
}

/*!
    Returns \c true if shader programs of type \a type are supported on
    this system; false otherwise.

    The \a context is used to resolve the GLSL extensions.
    If \a context is \nullptr, then QOpenGLContext::currentContext()
    is used.
*/
bool QOpenGLShader::hasOpenGLShaders(ShaderType type, QOpenGLContext *context)
{
    if (!context)
        context = QOpenGLContext::currentContext();
    if (!context)
        return false;

    if ((type & ~(Geometry | Vertex | Fragment | TessellationControl | TessellationEvaluation | Compute)) || type == 0)
        return false;

    if (type & QOpenGLShader::Geometry)
        return supportsGeometry(context->format());
    else if (type & (QOpenGLShader::TessellationControl | QOpenGLShader::TessellationEvaluation))
        return supportsTessellation(context->format());
    else if (type & QOpenGLShader::Compute)
        return supportsCompute(context->format());

    // Unconditional support of vertex and fragment shaders implicitly assumes
    // a minimum OpenGL version of 2.0
    return true;
}

bool QOpenGLShaderProgramPrivate::isCacheDisabled() const
{
    static QOpenGLProgramBinarySupportCheckWrapper binSupportCheck;
    return !binSupportCheck.get(QOpenGLContext::currentContext())->isSupported();
}

bool QOpenGLShaderProgramPrivate::compileCacheable()
{
    Q_Q(QOpenGLShaderProgram);
    for (const QOpenGLProgramBinaryCache::ShaderDesc &shader : qAsConst(binaryProgram.shaders)) {
        QScopedPointer<QOpenGLShader> s(new QOpenGLShader(qt_shaderStageToType(shader.stage), q));
        if (!s->compileSourceCode(shader.source)) {
            log = s->log();
            return false;
        }
        anonShaders.append(s.take());
        if (!q->addShader(anonShaders.last()))
            return false;
    }
    return true;
}

bool QOpenGLShaderProgramPrivate::linkBinary()
{
    static QOpenGLProgramBinaryCache binCache;

    Q_Q(QOpenGLShaderProgram);

    const QByteArray cacheKey = binaryProgram.cacheKey();
    if (lcOpenGLProgramDiskCache().isEnabled(QtDebugMsg))
        qCDebug(lcOpenGLProgramDiskCache, "program with %d shaders, cache key %s",
                binaryProgram.shaders.count(), cacheKey.constData());

    bool needsCompile = true;
    if (binCache.load(cacheKey, q->programId())) {
        qCDebug(lcOpenGLProgramDiskCache, "Program binary received from cache");
        needsCompile = false;
    }

    bool needsSave = false;
    if (needsCompile) {
        qCDebug(lcOpenGLProgramDiskCache, "Program binary not in cache, compiling");
        if (compileCacheable())
            needsSave = true;
        else
            return false;
    }

    linkBinaryRecursion = true;
    bool ok = q->link();
    linkBinaryRecursion = false;
    if (ok && needsSave)
        binCache.save(cacheKey, q->programId());

    return ok;
}

QT_END_NAMESPACE
