/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtQuick 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 <private/qquickopenglshadereffectnode_p.h>

#include "qquickopenglshadereffect_p.h"
#include <QtQuick/qsgtextureprovider.h>
#include <QtQuick/private/qsgrenderer_p.h>
#include <QtQuick/private/qsgshadersourcebuilder_p.h>
#include <QtQuick/private/qsgtexture_p.h>
#include <QtCore/qmutex.h>
#include <QtGui/qopenglfunctions.h>

#ifndef GL_TEXTURE_EXTERNAL_OES
#define GL_TEXTURE_EXTERNAL_OES 0x8D65
#endif

QT_BEGIN_NAMESPACE

static bool hasAtlasTexture(const QVector<QSGTextureProvider *> &textureProviders)
{
    for (int i = 0; i < textureProviders.size(); ++i) {
        QSGTextureProvider *t = textureProviders.at(i);
        if (t && t->texture() && t->texture()->isAtlasTexture())
            return true;
    }
    return false;
}

class QQuickCustomMaterialShader : public QSGMaterialShader
{
public:
    QQuickCustomMaterialShader(const QQuickOpenGLShaderEffectMaterialKey &key, const QVector<QByteArray> &attributes);
    void deactivate() override;
    void updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect) override;
    char const *const *attributeNames() const override;

protected:
    friend class QQuickOpenGLShaderEffectNode;

    void compile() override;
    const char *vertexShader() const override;
    const char *fragmentShader() const override;

    const QQuickOpenGLShaderEffectMaterialKey m_key;
    QVector<QByteArray> m_attributes;
    QVector<const char *> m_attributeNames;
    QString m_log;
    bool m_compiled;

    QVector<int> m_uniformLocs[QQuickOpenGLShaderEffectMaterialKey::ShaderTypeCount];
    uint m_initialized : 1;
};

QQuickCustomMaterialShader::QQuickCustomMaterialShader(const QQuickOpenGLShaderEffectMaterialKey &key, const QVector<QByteArray> &attributes)
    : m_key(key)
    , m_attributes(attributes)
    , m_compiled(false)
    , m_initialized(false)
{
    const int attributesCount = m_attributes.count();
    m_attributeNames.reserve(attributesCount + 1);
    for (int i = 0; i < attributesCount; ++i)
        m_attributeNames.append(m_attributes.at(i).constData());
    m_attributeNames.append(0);
}

void QQuickCustomMaterialShader::deactivate()
{
    QSGMaterialShader::deactivate();
    QOpenGLContext::currentContext()->functions()->glDisable(GL_CULL_FACE);
}

void QQuickCustomMaterialShader::updateState(const RenderState &state, QSGMaterial *newEffect, QSGMaterial *oldEffect)
{
    typedef QQuickOpenGLShaderEffectMaterial::UniformData UniformData;

    Q_ASSERT(newEffect != nullptr);

    QQuickOpenGLShaderEffectMaterial *material = static_cast<QQuickOpenGLShaderEffectMaterial *>(newEffect);
    if (!material->m_emittedLogChanged && material->m_node) {
        material->m_emittedLogChanged = true;
        emit material->m_node->logAndStatusChanged(m_log, m_compiled ? QQuickShaderEffect::Compiled
                                                                     : QQuickShaderEffect::Error);
    }

    int textureProviderIndex = 0;
    if (!m_initialized) {
        for (int shaderType = 0; shaderType < QQuickOpenGLShaderEffectMaterialKey::ShaderTypeCount; ++shaderType) {
            Q_ASSERT(m_uniformLocs[shaderType].isEmpty());
            m_uniformLocs[shaderType].reserve(material->uniforms[shaderType].size());
            for (int i = 0; i < material->uniforms[shaderType].size(); ++i) {
                const UniformData &d = material->uniforms[shaderType].at(i);
                QByteArray name = d.name;
                if (d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) {
                    program()->setUniformValue(d.name.constData(), textureProviderIndex++);
                    // We don't need to store the sampler uniform locations, since their values
                    // only need to be set once. Look for the "qt_SubRect_" uniforms instead.
                    // These locations are used when binding the textures later.
                    name = "qt_SubRect_" + name;
                }
                m_uniformLocs[shaderType].append(program()->uniformLocation(name.constData()));
            }
        }
        m_initialized = true;
        textureProviderIndex = 0;
    }

    QOpenGLFunctions *functions = state.context()->functions();
    for (int shaderType = 0; shaderType < QQuickOpenGLShaderEffectMaterialKey::ShaderTypeCount; ++shaderType) {
        for (int i = 0; i < material->uniforms[shaderType].size(); ++i) {
            const UniformData &d = material->uniforms[shaderType].at(i);
            int loc = m_uniformLocs[shaderType].at(i);
            if (d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) {
                int idx = textureProviderIndex++;
                functions->glActiveTexture(GL_TEXTURE0 + idx);
                if (QSGTextureProvider *provider = material->textureProviders.at(idx)) {
                    if (QSGTexture *texture = provider->texture()) {

#ifndef QT_NO_DEBUG
                        if (!qsg_safeguard_texture(texture))
                            continue;
#endif

                        if (loc >= 0) {
                            QRectF r = texture->normalizedTextureSubRect();
                            program()->setUniformValue(loc, r.x(), r.y(), r.width(), r.height());
                        } else if (texture->isAtlasTexture() && !material->geometryUsesTextureSubRect) {
                            texture = texture->removedFromAtlas();
                        }
                        texture->bind();
                        continue;
                    }
                }
                if (d.specialType == UniformData::Sampler)
                    functions->glBindTexture(GL_TEXTURE_2D, 0);
                else if (d.specialType == UniformData::SamplerExternal)
                    functions->glBindTexture(GL_TEXTURE_EXTERNAL_OES, 0);
            } else if (d.specialType == UniformData::Opacity) {
                program()->setUniformValue(loc, state.opacity());
            } else if (d.specialType == UniformData::Matrix) {
                if (state.isMatrixDirty())
                    program()->setUniformValue(loc, state.combinedMatrix());
            } else if (d.specialType == UniformData::None) {
                switch (int(d.value.type())) {
                case QMetaType::QColor:
                    program()->setUniformValue(loc, qt_premultiply_color(qvariant_cast<QColor>(d.value)));
                    break;
                case QMetaType::Float:
                    program()->setUniformValue(loc, qvariant_cast<float>(d.value));
                    break;
                case QMetaType::Double:
                    program()->setUniformValue(loc, (float) qvariant_cast<double>(d.value));
                    break;
                case QMetaType::QTransform:
                    program()->setUniformValue(loc, qvariant_cast<QTransform>(d.value));
                    break;
                case QMetaType::Int:
                    program()->setUniformValue(loc, d.value.toInt());
                    break;
                case QMetaType::Bool:
                    program()->setUniformValue(loc, GLint(d.value.toBool()));
                    break;
                case QMetaType::QSize:
                case QMetaType::QSizeF:
                    program()->setUniformValue(loc, d.value.toSizeF());
                    break;
                case QMetaType::QPoint:
                case QMetaType::QPointF:
                    program()->setUniformValue(loc, d.value.toPointF());
                    break;
                case QMetaType::QRect:
                case QMetaType::QRectF:
                    {
                        QRectF r = d.value.toRectF();
                        program()->setUniformValue(loc, r.x(), r.y(), r.width(), r.height());
                    }
                    break;
                case QMetaType::QVector2D:
                    program()->setUniformValue(loc, qvariant_cast<QVector2D>(d.value));
                    break;
                case QMetaType::QVector3D:
                    program()->setUniformValue(loc, qvariant_cast<QVector3D>(d.value));
                    break;
                case QMetaType::QVector4D:
                    program()->setUniformValue(loc, qvariant_cast<QVector4D>(d.value));
                    break;
                case QMetaType::QQuaternion:
                    {
                        QQuaternion q = qvariant_cast<QQuaternion>(d.value);
                        program()->setUniformValue(loc, q.x(), q.y(), q.z(), q.scalar());
                    }
                    break;
                case QMetaType::QMatrix4x4:
                    program()->setUniformValue(loc, qvariant_cast<QMatrix4x4>(d.value));
                    break;
                default:
                    break;
                }
            }
        }
    }
    functions->glActiveTexture(GL_TEXTURE0);

    const QQuickOpenGLShaderEffectMaterial *oldMaterial = static_cast<const QQuickOpenGLShaderEffectMaterial *>(oldEffect);
    if (oldEffect == nullptr || material->cullMode != oldMaterial->cullMode) {
        switch (material->cullMode) {
        case QQuickShaderEffect::FrontFaceCulling:
            functions->glEnable(GL_CULL_FACE);
            functions->glCullFace(GL_FRONT);
            break;
        case QQuickShaderEffect::BackFaceCulling:
            functions->glEnable(GL_CULL_FACE);
            functions->glCullFace(GL_BACK);
            break;
        default:
            functions->glDisable(GL_CULL_FACE);
            break;
        }
    }
}

char const *const *QQuickCustomMaterialShader::attributeNames() const
{
    return m_attributeNames.constData();
}

void QQuickCustomMaterialShader::compile()
{
    Q_ASSERT_X(!program()->isLinked(), "QQuickCustomMaterialShader::compile()", "Compile called multiple times!");

    m_log.clear();
    m_compiled = true;
    if (!program()->addCacheableShaderFromSourceCode(QOpenGLShader::Vertex, vertexShader())) {
        m_log += QLatin1String("*** Vertex shader ***\n") + program()->log();
        m_compiled = false;
    }
    if (!program()->addCacheableShaderFromSourceCode(QOpenGLShader::Fragment, fragmentShader())) {
        m_log += QLatin1String("*** Fragment shader ***\n") + program()->log();
        m_compiled = false;
    }

    char const *const *attr = attributeNames();
#ifndef QT_NO_DEBUG
    int maxVertexAttribs = 0;
    QOpenGLContext::currentContext()->functions()->glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
    int attrCount = 0;
    while (attrCount < maxVertexAttribs && attr[attrCount])
        ++attrCount;
    if (attr[attrCount]) {
        qWarning("List of attribute names is too long.\n"
                 "Maximum number of attributes on this hardware is %i.\n"
                 "Vertex shader:\n%s\n"
                 "Fragment shader:\n%s\n",
                 maxVertexAttribs, vertexShader(), fragmentShader());
    }
#endif

    if (m_compiled) {
#ifndef QT_NO_DEBUG
        for (int i = 0; i < attrCount; ++i) {
#else
        for (int i = 0; attr[i]; ++i) {
#endif
            if (*attr[i])
                program()->bindAttributeLocation(attr[i], i);
        }
        m_compiled = program()->link();
        m_log += program()->log();
    }

    if (!m_compiled) {
        qWarning("QQuickCustomMaterialShader: Shader compilation failed:");
        qWarning() << program()->log();

        QSGShaderSourceBuilder::initializeProgramFromFiles(
            program(),
            QStringLiteral(":/qt-project.org/items/shaders/shadereffectfallback.vert"),
            QStringLiteral(":/qt-project.org/items/shaders/shadereffectfallback.frag"));

#ifndef QT_NO_DEBUG
        for (int i = 0; i < attrCount; ++i) {
#else
        for (int i = 0; attr[i]; ++i) {
#endif
            if (qstrcmp(attr[i], qtPositionAttributeName()) == 0)
                program()->bindAttributeLocation("v", i);
        }
        program()->link();
    }
}

const char *QQuickCustomMaterialShader::vertexShader() const
{
    return m_key.sourceCode[QQuickOpenGLShaderEffectMaterialKey::VertexShader].constData();
}

const char *QQuickCustomMaterialShader::fragmentShader() const
{
    return m_key.sourceCode[QQuickOpenGLShaderEffectMaterialKey::FragmentShader].constData();
}


bool QQuickOpenGLShaderEffectMaterialKey::operator == (const QQuickOpenGLShaderEffectMaterialKey &other) const
{
    for (int shaderType = 0; shaderType < ShaderTypeCount; ++shaderType) {
        if (sourceCode[shaderType] != other.sourceCode[shaderType])
            return false;
    }
    return true;
}

bool QQuickOpenGLShaderEffectMaterialKey::operator != (const QQuickOpenGLShaderEffectMaterialKey &other) const
{
    return !(*this == other);
}

uint qHash(const QQuickOpenGLShaderEffectMaterialKey &key)
{
    uint hash = 1;
    typedef QQuickOpenGLShaderEffectMaterialKey Key;
    for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType)
        hash = hash * 31337 + qHash(key.sourceCode[shaderType]);
    return hash;
}

class QQuickOpenGLShaderEffectMaterialCache : public QObject
{
    Q_OBJECT
public:
    static QQuickOpenGLShaderEffectMaterialCache *get(bool create = true) {
        QOpenGLContext *ctx = QOpenGLContext::currentContext();
        QQuickOpenGLShaderEffectMaterialCache *me = ctx->findChild<QQuickOpenGLShaderEffectMaterialCache *>(QStringLiteral("__qt_ShaderEffectCache"), Qt::FindDirectChildrenOnly);
        if (!me && create) {
            me = new QQuickOpenGLShaderEffectMaterialCache();
            me->setObjectName(QStringLiteral("__qt_ShaderEffectCache"));
            me->setParent(ctx);
        }
        return me;
    }
    QHash<QQuickOpenGLShaderEffectMaterialKey, QSGMaterialType *> cache;
};

QQuickOpenGLShaderEffectMaterial::QQuickOpenGLShaderEffectMaterial(QQuickOpenGLShaderEffectNode *node)
    : cullMode(QQuickShaderEffect::NoCulling)
    , geometryUsesTextureSubRect(false)
    , m_node(node)
    , m_emittedLogChanged(false)
{
    setFlag(Blending | RequiresFullMatrix, true);
}

QSGMaterialType *QQuickOpenGLShaderEffectMaterial::type() const
{
    return m_type;
}

QSGMaterialShader *QQuickOpenGLShaderEffectMaterial::createShader() const
{
    return new QQuickCustomMaterialShader(m_source, attributes);
}

bool QQuickOpenGLShaderEffectMaterial::UniformData::operator == (const UniformData &other) const
{
    if (specialType != other.specialType)
        return false;
    if (name != other.name)
        return false;

    if (specialType == UniformData::Sampler || specialType == UniformData::SamplerExternal) {
        // We can't check the source objects as these live in the GUI thread,
        // so return true here and rely on the textureProvider check for
        // equality of these..
        return true;
    } else {
        return value == other.value;
    }
}

int QQuickOpenGLShaderEffectMaterial::compare(const QSGMaterial *o) const
{
    const QQuickOpenGLShaderEffectMaterial *other = static_cast<const QQuickOpenGLShaderEffectMaterial *>(o);
    if ((hasAtlasTexture(textureProviders) && !geometryUsesTextureSubRect) || (hasAtlasTexture(other->textureProviders) && !other->geometryUsesTextureSubRect))
        return 1;
    if (cullMode != other->cullMode)
        return 1;
    for (int shaderType = 0; shaderType < QQuickOpenGLShaderEffectMaterialKey::ShaderTypeCount; ++shaderType) {
        if (uniforms[shaderType] != other->uniforms[shaderType])
            return 1;
    }

    // Check the texture providers..
    if (textureProviders.size() != other->textureProviders.size())
        return 1;
    for (int i=0; i<textureProviders.size(); ++i) {
        QSGTextureProvider *tp1 = textureProviders.at(i);
        QSGTextureProvider *tp2 = other->textureProviders.at(i);
        if (!tp1 || !tp2)
            return tp1 == tp2 ? 0 : 1;
        QSGTexture *t1 = tp1->texture();
        QSGTexture *t2 = tp2->texture();
        if (!t1 || !t2)
            return t1 == t2 ? 0 : 1;
        // Check texture id's as textures may be in the same atlas.
        if (t1->textureId() != t2->textureId())
            return 1;
    }
    return 0;
}

void QQuickOpenGLShaderEffectMaterial::setProgramSource(const QQuickOpenGLShaderEffectMaterialKey &source)
{
    m_source = source;
    m_emittedLogChanged = false;

    QQuickOpenGLShaderEffectMaterialCache *cache = QQuickOpenGLShaderEffectMaterialCache::get();
    m_type = cache->cache.value(m_source);
    if (!m_type) {
        m_type = new QSGMaterialType();
        cache->cache.insert(source, m_type);
    }
}

void QQuickOpenGLShaderEffectMaterial::cleanupMaterialCache()
{
    QQuickOpenGLShaderEffectMaterialCache *cache = QQuickOpenGLShaderEffectMaterialCache::get(false);
    if (cache) {
        qDeleteAll(cache->cache);
        delete cache;
    }
}

void QQuickOpenGLShaderEffectMaterial::updateTextures() const
{
    for (int i = 0; i < textureProviders.size(); ++i) {
        if (QSGTextureProvider *provider = textureProviders.at(i)) {
            if (QSGDynamicTexture *texture = qobject_cast<QSGDynamicTexture *>(provider->texture()))
                texture->updateTexture();
        }
    }
}

void QQuickOpenGLShaderEffectMaterial::invalidateTextureProvider(const QObject *provider)
{
    for (int i = 0; i < textureProviders.size(); ++i) {
        if (provider == textureProviders.at(i))
            textureProviders[i] = nullptr;
    }
}


QQuickOpenGLShaderEffectNode::QQuickOpenGLShaderEffectNode()
{
    QSGNode::setFlag(UsePreprocess, true);

#ifdef QSG_RUNTIME_DESCRIPTION
    qsgnode_set_description(this, QLatin1String("shadereffect"));
#endif
}

QQuickOpenGLShaderEffectNode::~QQuickOpenGLShaderEffectNode()
{
}

void QQuickOpenGLShaderEffectNode::markDirtyTexture()
{
    markDirty(DirtyMaterial);
    Q_EMIT dirtyTexture();
}

void QQuickOpenGLShaderEffectNode::textureProviderDestroyed(QObject *object)
{
    Q_ASSERT(material());
    static_cast<QQuickOpenGLShaderEffectMaterial *>(material())->invalidateTextureProvider(object);
}

void QQuickOpenGLShaderEffectNode::preprocess()
{
    Q_ASSERT(material());
    static_cast<QQuickOpenGLShaderEffectMaterial *>(material())->updateTextures();
}

#include "qquickopenglshadereffectnode.moc"
#include "moc_qquickopenglshadereffectnode_p.cpp"

QT_END_NAMESPACE
