/****************************************************************************
**
** 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/qquickopenglshadereffect_p.h>

#include <QtQuick/qsgmaterial.h>
#include <QtQuick/private/qsgshadersourcebuilder_p.h>
#include "qquickitem_p.h"

#include <QtQuick/private/qsgcontext_p.h>
#include <QtQuick/qsgtextureprovider.h>
#include "qquickwindow.h"

#include "qquickimage_p.h"
#include "qquickshadereffectsource_p.h"
#include "qquickshadereffectmesh_p.h"

#include <QtQml/qqmlfile.h>
#include <QtCore/qsignalmapper.h>
#include <QtCore/qfileselector.h>

QT_BEGIN_NAMESPACE

// Note: this legacy ShaderEffect implementation is used only when running
// directly with OpenGL. This is going to go away in the future (Qt 6?), since
// the RHI path uses QQuickGenericShaderEffect always.

namespace {

    enum VariableQualifier {
        AttributeQualifier,
        UniformQualifier
    };

    inline bool qt_isalpha(char c)
    {
        char ch = c | 0x20;
        return (ch >= 'a' && ch <= 'z') || c == '_';
    }

    inline bool qt_isalnum(char c)
    {
        return qt_isalpha(c) || (c >= '0' && c <= '9');
    }

    inline bool qt_isspace(char c)
    {
        return c == ' ' || (c >= 0x09 && c <= 0x0d);
    }

    // Returns -1 if not found, returns index to first character after the name if found.
    int qt_search_for_variable(const char *s, int length, int index, VariableQualifier &decl,
                               int &typeIndex, int &typeLength,
                               int &nameIndex, int &nameLength,
                               QQuickOpenGLShaderEffectCommon::Key::ShaderType shaderType)
    {
        enum Identifier {
            QualifierIdentifier, // Base state
            PrecisionIdentifier,
            TypeIdentifier,
            NameIdentifier
        };
        Identifier expected = QualifierIdentifier;
        bool compilerDirectiveExpected = index == 0;

        while (index < length) {
            // Skip whitespace.
            while (qt_isspace(s[index])) {
                compilerDirectiveExpected |= s[index] == '\n';
                ++index;
            }

            if (qt_isalpha(s[index])) {
                // Read identifier.
                int idIndex = index;
                ++index;
                while (qt_isalnum(s[index]))
                    ++index;
                int idLength = index - idIndex;

                const int attrLen = sizeof("attribute") - 1;
                const int inLen = sizeof("in") - 1;
                const int uniLen = sizeof("uniform") - 1;
                const int loLen = sizeof("lowp") - 1;
                const int medLen = sizeof("mediump") - 1;
                const int hiLen = sizeof("highp") - 1;

                switch (expected) {
                case QualifierIdentifier:
                    if (idLength == attrLen && qstrncmp("attribute", s + idIndex, attrLen) == 0) {
                        decl = AttributeQualifier;
                        expected = PrecisionIdentifier;
                    } else if (shaderType == QQuickOpenGLShaderEffectCommon::Key::VertexShader
                               && idLength == inLen && qstrncmp("in", s + idIndex, inLen) == 0) {
                        decl = AttributeQualifier;
                        expected = PrecisionIdentifier;
                    } else if (idLength == uniLen && qstrncmp("uniform", s + idIndex, uniLen) == 0) {
                        decl = UniformQualifier;
                        expected = PrecisionIdentifier;
                    }
                    break;
                case PrecisionIdentifier:
                    if ((idLength == loLen && qstrncmp("lowp", s + idIndex, loLen) == 0)
                            || (idLength == medLen && qstrncmp("mediump", s + idIndex, medLen) == 0)
                            || (idLength == hiLen && qstrncmp("highp", s + idIndex, hiLen) == 0))
                    {
                        expected = TypeIdentifier;
                        break;
                    }
                    Q_FALLTHROUGH();
                case TypeIdentifier:
                    typeIndex = idIndex;
                    typeLength = idLength;
                    expected = NameIdentifier;
                    break;
                case NameIdentifier:
                    nameIndex = idIndex;
                    nameLength = idLength;
                    return index; // Attribute or uniform declaration found. Return result.
                default:
                    break;
                }
            } else if (s[index] == '#' && compilerDirectiveExpected) {
                // Skip compiler directives.
                ++index;
                while (index < length && (s[index] != '\n' || s[index - 1] == '\\'))
                    ++index;
            } else if (s[index] == '/' && s[index + 1] == '/') {
                // Skip comments.
                index += 2;
                while (index < length && s[index] != '\n')
                    ++index;
            } else if (s[index] == '/' && s[index + 1] == '*') {
                // Skip comments.
                index += 2;
                while (index < length && (s[index] != '*' || s[index + 1] != '/'))
                    ++index;
                if (index < length)
                    index += 2; // Skip star-slash.
            } else {
                expected = QualifierIdentifier;
                ++index;
            }
            compilerDirectiveExpected = false;
        }
        return -1;
    }
}

namespace QtPrivate {
class MappedSlotObject: public QtPrivate::QSlotObjectBase
{
public:
    typedef std::function<void()> PropChangedFunc;

    explicit MappedSlotObject(PropChangedFunc f)
        : QSlotObjectBase(&impl), _signalIndex(-1), func(std::move(f))
    { ref(); }

    void setSignalIndex(int idx) { _signalIndex = idx; }
    int signalIndex() const { return _signalIndex; }

private:
    int _signalIndex;
    PropChangedFunc func;

    static void impl(int which, QSlotObjectBase *this_, QObject *, void **a, bool *ret)
    {
        auto thiz = static_cast<MappedSlotObject*>(this_);
        switch (which) {
        case Destroy:
            delete thiz;
            break;
        case Call:
            thiz->func();
            break;
        case Compare:
            *ret = thiz == reinterpret_cast<MappedSlotObject *>(a[0]);
            break;
        case NumOperations: ;
        }
    }
};
}

QQuickOpenGLShaderEffectCommon::~QQuickOpenGLShaderEffectCommon()
{
    for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType)
        clearSignalMappers(shaderType);
}

void QQuickOpenGLShaderEffectCommon::disconnectPropertySignals(QQuickItem *item, Key::ShaderType shaderType)
{
    for (int i = 0; i < uniformData[shaderType].size(); ++i) {
        if (signalMappers[shaderType].at(i) == 0)
            continue;
        const UniformData &d = uniformData[shaderType].at(i);
        auto mapper = signalMappers[shaderType].at(i);
        void *a = mapper;
        QObjectPrivate::disconnect(item, mapper->signalIndex(), &a);
        if (d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) {
            QQuickItem *source = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(d.value));
            if (source) {
                if (item->window())
                    QQuickItemPrivate::get(source)->derefWindow();
                QObject::disconnect(source, SIGNAL(destroyed(QObject*)), host, SLOT(sourceDestroyed(QObject*)));
            }
        }
    }
}

void QQuickOpenGLShaderEffectCommon::connectPropertySignals(QQuickItem *item,
                                                            const QMetaObject *itemMetaObject,
                                                            Key::ShaderType shaderType)
{
    auto engine = qmlEngine(item);
    if (!engine)
        return;

    QQmlPropertyCache *propCache = QQmlData::ensurePropertyCache(engine, item);
    for (int i = 0; i < uniformData[shaderType].size(); ++i) {
        if (signalMappers[shaderType].at(i) == 0)
            continue;
        const UniformData &d = uniformData[shaderType].at(i);
        QQmlPropertyData *pd = propCache->property(QString::fromUtf8(d.name), nullptr, nullptr);
        if (pd && !pd->isFunction()) {
            if (pd->notifyIndex() == -1) {
                qWarning("QQuickOpenGLShaderEffect: property '%s' does not have notification method!", d.name.constData());
            } else {
                auto *mapper = signalMappers[shaderType].at(i);
                mapper->setSignalIndex(itemMetaObject->property(d.propertyIndex).notifySignal().methodIndex());
                Q_ASSERT(item->metaObject() == itemMetaObject);
                bool ok = QObjectPrivate::connectImpl(item, pd->notifyIndex(), item, nullptr, mapper,
                                                      Qt::AutoConnection, nullptr, itemMetaObject);
                if (!ok)
                    qWarning() << "Failed to connect to property" << itemMetaObject->property(d.propertyIndex).name()
                               << "(" << d.propertyIndex << ", signal index" << pd->notifyIndex()
                               << ") of item" << item;
            }
        } else {
            // If the source is set via a dynamic property, like the layer is, then we need this
            // check to disable the warning.
            if (!item->property(d.name).isValid())
                qWarning("QQuickOpenGLShaderEffect: '%s' does not have a matching property!", d.name.constData());
        }

        if (d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) {
            QQuickItem *source = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(d.value));
            if (source) {
                if (item->window())
                    QQuickItemPrivate::get(source)->refWindow(item->window());
                QObject::connect(source, SIGNAL(destroyed(QObject*)), host, SLOT(sourceDestroyed(QObject*)));
            }
        }
    }
}

void QQuickOpenGLShaderEffectCommon::updateParseLog(bool ignoreAttributes)
{
    parseLog.clear();
    if (!ignoreAttributes) {
        if (!attributes.contains(qtPositionAttributeName())) {
            parseLog += QLatin1String("Warning: Missing reference to \'")
                        + QLatin1String(qtPositionAttributeName())
                        + QLatin1String("\'.\n");
        }
        if (!attributes.contains(qtTexCoordAttributeName())) {
            parseLog += QLatin1String("Warning: Missing reference to \'")
                        + QLatin1String(qtTexCoordAttributeName())
                        + QLatin1String("\'.\n");
        }
    }
    bool respectsMatrix = false;
    bool respectsOpacity = false;
    for (int i = 0; i < uniformData[Key::VertexShader].size(); ++i)
        respectsMatrix |= uniformData[Key::VertexShader].at(i).specialType == UniformData::Matrix;
    for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) {
        for (int i = 0; i < uniformData[shaderType].size(); ++i)
            respectsOpacity |= uniformData[shaderType].at(i).specialType == UniformData::Opacity;
    }
    if (!respectsMatrix)
        parseLog += QLatin1String("Warning: Vertex shader is missing reference to \'qt_Matrix\'.\n");
    if (!respectsOpacity)
        parseLog += QLatin1String("Warning: Shaders are missing reference to \'qt_Opacity\'.\n");
}

void QQuickOpenGLShaderEffectCommon::lookThroughShaderCode(QQuickItem *item,
                                                           const QMetaObject *itemMetaObject,
                                                           Key::ShaderType shaderType,
                                                           const QByteArray &code)
{
    auto engine = qmlEngine(item);
    QQmlPropertyCache *propCache = (engine) ? QQmlData::ensurePropertyCache(engine, item) : nullptr;
    int index = 0;
    int typeIndex = -1;
    int typeLength = 0;
    int nameIndex = -1;
    int nameLength = 0;
    const char *s = code.constData();
    VariableQualifier decl = AttributeQualifier;
    while ((index = qt_search_for_variable(s, code.size(), index, decl, typeIndex, typeLength,
                                           nameIndex, nameLength, shaderType)) != -1)
    {
        if (decl == AttributeQualifier) {
            if (shaderType == Key::VertexShader)
                attributes.append(QByteArray(s + nameIndex, nameLength));
        } else {
            Q_ASSERT(decl == UniformQualifier);

            const int sampLen = sizeof("sampler2D") - 1;
            const int sampExtLen = sizeof("samplerExternalOES") - 1;
            const int opLen = sizeof("qt_Opacity") - 1;
            const int matLen = sizeof("qt_Matrix") - 1;
            const int srLen = sizeof("qt_SubRect_") - 1;

            UniformData d;
            QtPrivate::MappedSlotObject *mapper = nullptr;
            d.name = QByteArray(s + nameIndex, nameLength);
            if (nameLength == opLen && qstrncmp("qt_Opacity", s + nameIndex, opLen) == 0) {
                d.specialType = UniformData::Opacity;
            } else if (nameLength == matLen && qstrncmp("qt_Matrix", s + nameIndex, matLen) == 0) {
                d.specialType = UniformData::Matrix;
            } else if (nameLength > srLen && qstrncmp("qt_SubRect_", s + nameIndex, srLen) == 0) {
                d.specialType = UniformData::SubRect;
            } else {
                if (propCache) {
                    if (QQmlPropertyData *pd = propCache->property(QString::fromUtf8(d.name), nullptr, nullptr)) {
                        if (!pd->isFunction())
                            d.propertyIndex = pd->coreIndex();
                    }
                }
                const int mappedId = uniformData[shaderType].size() | (shaderType << 16);
                mapper = new QtPrivate::MappedSlotObject([this, mappedId](){
                    this->mappedPropertyChanged(mappedId);
                });
                if (typeLength == sampLen && qstrncmp("sampler2D", s + typeIndex, sampLen) == 0)
                    d.specialType = UniformData::Sampler;
                else if (typeLength == sampExtLen && qstrncmp("samplerExternalOES", s + typeIndex, sampExtLen) == 0)
                    d.specialType = UniformData::SamplerExternal;
                else
                    d.specialType = UniformData::None;
                d.setValueFromProperty(item, itemMetaObject);
            }
            uniformData[shaderType].append(d);
            signalMappers[shaderType].append(mapper);
        }
    }
}

void QQuickOpenGLShaderEffectCommon::updateShader(QQuickItem *item,
                                                  const QMetaObject *itemMetaObject,
                                                  Key::ShaderType shaderType)
{
    disconnectPropertySignals(item, shaderType);
    uniformData[shaderType].clear();
    clearSignalMappers(shaderType);
    if (shaderType == Key::VertexShader)
        attributes.clear();

    // A qrc or file URL means the shader source is to be read from the specified file.
    QUrl srcUrl(QString::fromUtf8(source.sourceCode[shaderType]));
    if (!srcUrl.scheme().compare(QLatin1String("qrc"), Qt::CaseInsensitive) || srcUrl.isLocalFile()) {
        if (!fileSelector) {
            fileSelector = new QFileSelector(item);
            // There may not be an OpenGL context accessible here. So rely on
            // the window's requestedFormat().
            if (item->window()
                    && item->window()->requestedFormat().profile() == QSurfaceFormat::CoreProfile) {
                fileSelector->setExtraSelectors(QStringList() << QStringLiteral("glslcore"));
            }
        }
        const QString fn = fileSelector->select(QQmlFile::urlToLocalFileOrQrc(srcUrl));
        QFile f(fn);
        if (f.open(QIODevice::ReadOnly | QIODevice::Text)) {
            source.sourceCode[shaderType] = f.readAll();
            f.close();
        } else {
            qWarning("ShaderEffect: Failed to read %s", qPrintable(fn));
            source.sourceCode[shaderType] = QByteArray();
        }
    }

    const QByteArray &code = source.sourceCode[shaderType];
    if (code.isEmpty()) {
        // Optimize for default code.
        if (shaderType == Key::VertexShader) {
            attributes.append(QByteArray(qtPositionAttributeName()));
            attributes.append(QByteArray(qtTexCoordAttributeName()));
            UniformData d;
            d.name = "qt_Matrix";
            d.specialType = UniformData::Matrix;
            uniformData[Key::VertexShader].append(d);
            signalMappers[Key::VertexShader].append(0);
        } else if (shaderType == Key::FragmentShader) {
            UniformData d;
            d.name = "qt_Opacity";
            d.specialType = UniformData::Opacity;
            uniformData[Key::FragmentShader].append(d);
            signalMappers[Key::FragmentShader].append(0);
            auto mapper = new QtPrivate::MappedSlotObject([this](){
                mappedPropertyChanged(1 | (Key::FragmentShader << 16));
            });
            const char *sourceName = "source";
            d.name = sourceName;
            d.setValueFromProperty(item, itemMetaObject);
            d.specialType = UniformData::Sampler;
            uniformData[Key::FragmentShader].append(d);
            signalMappers[Key::FragmentShader].append(mapper);
        }
    } else {
        lookThroughShaderCode(item, itemMetaObject, shaderType, code);
    }

    connectPropertySignals(item, itemMetaObject, shaderType);
}

void QQuickOpenGLShaderEffectCommon::updateMaterial(QQuickOpenGLShaderEffectNode *node,
                                              QQuickOpenGLShaderEffectMaterial *material,
                                              bool updateUniforms, bool updateUniformValues,
                                              bool updateTextureProviders)
{
    if (updateUniforms) {
        for (int i = 0; i < material->textureProviders.size(); ++i) {
            QSGTextureProvider *t = material->textureProviders.at(i);
            if (t) {
                QObject::disconnect(t, SIGNAL(textureChanged()), node, SLOT(markDirtyTexture()));
                QObject::disconnect(t, SIGNAL(destroyed(QObject*)), node, SLOT(textureProviderDestroyed(QObject*)));
            }
        }

        // First make room in the textureProviders array. Set to proper value further down.
        int textureProviderCount = 0;
        for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) {
            for (int i = 0; i < uniformData[shaderType].size(); ++i) {
                if (uniformData[shaderType].at(i).specialType == UniformData::Sampler ||
                        uniformData[shaderType].at(i).specialType == UniformData::SamplerExternal)
                    ++textureProviderCount;
            }
            material->uniforms[shaderType] = uniformData[shaderType];
        }
        material->textureProviders.fill(0, textureProviderCount);
        updateUniformValues = false;
        updateTextureProviders = true;
    }

    if (updateUniformValues) {
        for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) {
            Q_ASSERT(uniformData[shaderType].size() == material->uniforms[shaderType].size());
            for (int i = 0; i < uniformData[shaderType].size(); ++i)
                material->uniforms[shaderType][i].value = uniformData[shaderType].at(i).value;
        }
    }

    if (updateTextureProviders) {
        int index = 0;
        for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) {
            for (int i = 0; i < uniformData[shaderType].size(); ++i) {
                const UniformData &d = uniformData[shaderType].at(i);
                if (d.specialType != UniformData::Sampler && d.specialType != UniformData::SamplerExternal)
                    continue;
                QSGTextureProvider *oldProvider = material->textureProviders.at(index);
                QSGTextureProvider *newProvider = nullptr;
                QQuickItem *source = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(d.value));
                if (source && source->isTextureProvider())
                    newProvider = source->textureProvider();
                if (newProvider != oldProvider) {
                    if (oldProvider) {
                        QObject::disconnect(oldProvider, SIGNAL(textureChanged()), node, SLOT(markDirtyTexture()));
                        QObject::disconnect(oldProvider, SIGNAL(destroyed(QObject*)), node, SLOT(textureProviderDestroyed(QObject*)));
                    }
                    if (newProvider) {
                        Q_ASSERT_X(newProvider->thread() == QThread::currentThread(),
                                   "QQuickOpenGLShaderEffect::updatePaintNode",
                                   "Texture provider must belong to the rendering thread");
                        QObject::connect(newProvider, SIGNAL(textureChanged()), node, SLOT(markDirtyTexture()));
                        QObject::connect(newProvider, SIGNAL(destroyed(QObject*)), node, SLOT(textureProviderDestroyed(QObject*)));
                    } else {
                        const char *typeName = source ? source->metaObject()->className() : d.value.typeName();
                        qWarning("ShaderEffect: Property '%s' is not assigned a valid texture provider (%s).",
                                 d.name.constData(), typeName);
                    }
                    material->textureProviders[index] = newProvider;
                }
                ++index;
            }
        }
        Q_ASSERT(index == material->textureProviders.size());
    }
}

void QQuickOpenGLShaderEffectCommon::updateWindow(QQuickWindow *window)
{
    // See comment in QQuickOpenGLShaderEffectCommon::propertyChanged().
    if (window) {
        for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) {
            for (int i = 0; i < uniformData[shaderType].size(); ++i) {
                const UniformData &d = uniformData[shaderType].at(i);
                if (d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) {
                    QQuickItem *source = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(d.value));
                    if (source)
                        QQuickItemPrivate::get(source)->refWindow(window);
                }
            }
        }
    } else {
        for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) {
            for (int i = 0; i < uniformData[shaderType].size(); ++i) {
                const UniformData &d = uniformData[shaderType].at(i);
                if (d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) {
                    QQuickItem *source = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(d.value));
                    if (source)
                        QQuickItemPrivate::get(source)->derefWindow();
                }
            }
        }
    }
}

void QQuickOpenGLShaderEffectCommon::sourceDestroyed(QObject *object)
{
    for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) {
        for (int i = 0; i < uniformData[shaderType].size(); ++i) {
            UniformData &d = uniformData[shaderType][i];
            if ((d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) && d.value.canConvert<QObject *>()) {
                if (qvariant_cast<QObject *>(d.value) == object)
                    d.value = QVariant();
            }
        }
    }
}

static bool qquick_uniqueInUniformData(QQuickItem *source, const QVector<QQuickOpenGLShaderEffectMaterial::UniformData> *uniformData, int typeToSkip, int indexToSkip)
{
    for (int s=0; s<QQuickOpenGLShaderEffectMaterialKey::ShaderTypeCount; ++s) {
        for (int i=0; i<uniformData[s].size(); ++i) {
            if (s == typeToSkip && i == indexToSkip)
                continue;
            const QQuickOpenGLShaderEffectMaterial::UniformData &d = uniformData[s][i];
            if ((d.specialType == QQuickOpenGLShaderEffectMaterial::UniformData::Sampler || d.specialType == QQuickOpenGLShaderEffectMaterial::UniformData::SamplerExternal) && qvariant_cast<QObject *>(d.value) == source)
                return false;
        }
    }
    return true;
}

void QQuickOpenGLShaderEffectCommon::propertyChanged(QQuickItem *item,
                                                     const QMetaObject *itemMetaObject,
                                                     int mappedId, bool *textureProviderChanged)
{
    Key::ShaderType shaderType = Key::ShaderType(mappedId >> 16);
    int index = mappedId & 0xffff;
    UniformData &d = uniformData[shaderType][index];
    if (d.specialType == UniformData::Sampler || d.specialType == UniformData::SamplerExternal) {
        QQuickItem *source = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(d.value));
        if (source) {
            if (item->window())
                QQuickItemPrivate::get(source)->derefWindow();

            // QObject::disconnect() will disconnect all matching connections. If the same
            // source has been attached to two separate samplers, then changing one of them
            // would trigger both to be disconnected. Without the connection we'll end up
            // with a dangling pointer in the uniformData.
            if (qquick_uniqueInUniformData(source, uniformData, shaderType, index))
                QObject::disconnect(source, SIGNAL(destroyed(QObject*)), host, SLOT(sourceDestroyed(QObject*)));
        }

        d.setValueFromProperty(item, itemMetaObject);

        source = qobject_cast<QQuickItem *>(qvariant_cast<QObject *>(d.value));
        if (source) {
            // 'source' needs a window to get a scene graph node. It usually gets one through its
            // parent, but if the source item is "inline" rather than a reference -- i.e.
            // "property variant source: Image { }" instead of "property variant source: foo" -- it
            // will not get a parent. In those cases, 'source' should get the window from 'item'.
            if (item->window())
                QQuickItemPrivate::get(source)->refWindow(item->window());
            QObject::connect(source, SIGNAL(destroyed(QObject*)), host, SLOT(sourceDestroyed(QObject*)));
        }
        if (textureProviderChanged)
            *textureProviderChanged = true;
    } else {
        d.setValueFromProperty(item, itemMetaObject);
        if (textureProviderChanged)
            *textureProviderChanged = false;
    }
}

void QQuickOpenGLShaderEffectCommon::clearSignalMappers(int shader)
{
    for (auto mapper : qAsConst(signalMappers[shader])) {
        if (mapper)
            mapper->destroyIfLastRef();
    }
    signalMappers[shader].clear();
}

QQuickOpenGLShaderEffect::QQuickOpenGLShaderEffect(QQuickShaderEffect *item, QObject *parent)
    : QObject(parent)
    , m_item(item)
    , m_itemMetaObject(nullptr)
    , m_meshResolution(1, 1)
    , m_mesh(nullptr)
    , m_cullMode(QQuickShaderEffect::NoCulling)
    , m_status(QQuickShaderEffect::Uncompiled)
    , m_common(this, [this](int mappedId){this->propertyChanged(mappedId);})
    , m_blending(true)
    , m_dirtyUniforms(true)
    , m_dirtyUniformValues(true)
    , m_dirtyTextureProviders(true)
    , m_dirtyProgram(true)
    , m_dirtyParseLog(true)
    , m_dirtyMesh(true)
    , m_dirtyGeometry(true)
    , m_customVertexShader(false)
    , m_supportsAtlasTextures(false)
    , m_vertNeedsUpdate(true)
    , m_fragNeedsUpdate(true)
{
}

QQuickOpenGLShaderEffect::~QQuickOpenGLShaderEffect()
{
    for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType)
        m_common.disconnectPropertySignals(m_item, Key::ShaderType(shaderType));
}

void QQuickOpenGLShaderEffect::setFragmentShader(const QByteArray &code)
{
    if (m_common.source.sourceCode[Key::FragmentShader].constData() == code.constData())
        return;
    m_common.source.sourceCode[Key::FragmentShader] = code;
    m_dirtyProgram = true;
    m_dirtyParseLog = true;

    m_fragNeedsUpdate = true;
    if (m_item->isComponentComplete())
        maybeUpdateShaders();

    m_item->update();
    if (m_status != QQuickShaderEffect::Uncompiled) {
        m_status = QQuickShaderEffect::Uncompiled;
        emit m_item->statusChanged();
    }
    emit m_item->fragmentShaderChanged();
}

void QQuickOpenGLShaderEffect::setVertexShader(const QByteArray &code)
{
    if (m_common.source.sourceCode[Key::VertexShader].constData() == code.constData())
        return;
    m_common.source.sourceCode[Key::VertexShader] = code;
    m_dirtyProgram = true;
    m_dirtyParseLog = true;
    m_customVertexShader = true;

    m_vertNeedsUpdate = true;
    if (m_item->isComponentComplete())
        maybeUpdateShaders();

    m_item->update();
    if (m_status != QQuickShaderEffect::Uncompiled) {
        m_status = QQuickShaderEffect::Uncompiled;
        emit m_item->statusChanged();
    }
    emit m_item->vertexShaderChanged();
}

void QQuickOpenGLShaderEffect::setBlending(bool enable)
{
    if (blending() == enable)
        return;

    m_blending = enable;
    m_item->update();

    emit m_item->blendingChanged();
}

QVariant QQuickOpenGLShaderEffect::mesh() const
{
    return m_mesh ? QVariant::fromValue(static_cast<QObject *>(m_mesh))
                  : QVariant::fromValue(m_meshResolution);
}

void QQuickOpenGLShaderEffect::setMesh(const QVariant &mesh)
{
    QQuickShaderEffectMesh *newMesh = qobject_cast<QQuickShaderEffectMesh *>(qvariant_cast<QObject *>(mesh));
    if (newMesh && newMesh == m_mesh)
        return;
    if (m_mesh)
        disconnect(m_mesh, SIGNAL(geometryChanged()), this, nullptr);
    m_mesh = newMesh;
    if (m_mesh) {
        connect(m_mesh, SIGNAL(geometryChanged()), this, SLOT(updateGeometry()));
    } else {
        if (mesh.canConvert<QSize>()) {
            m_meshResolution = mesh.toSize();
        } else {
            QList<QByteArray> res = mesh.toByteArray().split('x');
            bool ok = res.size() == 2;
            if (ok) {
                int w = res.at(0).toInt(&ok);
                if (ok) {
                    int h = res.at(1).toInt(&ok);
                    if (ok)
                        m_meshResolution = QSize(w, h);
                }
            }
            if (!ok)
                qWarning("ShaderEffect: mesh property must be size or object deriving from QQuickShaderEffectMesh.");
        }
        m_defaultMesh.setResolution(m_meshResolution);
    }

    m_dirtyMesh = true;
    m_dirtyParseLog = true;
    m_item->update();
    emit m_item->meshChanged();
}

void QQuickOpenGLShaderEffect::setCullMode(QQuickShaderEffect::CullMode face)
{
    if (face == m_cullMode)
        return;
    m_cullMode = face;
    m_item->update();
    emit m_item->cullModeChanged();
}

void QQuickOpenGLShaderEffect::setSupportsAtlasTextures(bool supports)
{
    if (supports == m_supportsAtlasTextures)
        return;
    m_supportsAtlasTextures = supports;
    updateGeometry();
    emit m_item->supportsAtlasTexturesChanged();
}

QString QQuickOpenGLShaderEffect::parseLog()
{
    maybeUpdateShaders(true);

    if (m_dirtyParseLog) {
        m_common.updateParseLog(m_mesh != nullptr);
        m_dirtyParseLog = false;
    }
    return m_common.parseLog;
}

void QQuickOpenGLShaderEffect::handleEvent(QEvent *event)
{
    if (event->type() == QEvent::DynamicPropertyChange) {
        QDynamicPropertyChangeEvent *e = static_cast<QDynamicPropertyChangeEvent *>(event);
        for (int shaderType = 0; shaderType < Key::ShaderTypeCount; ++shaderType) {
            for (int i = 0; i < m_common.uniformData[shaderType].size(); ++i) {
                if (m_common.uniformData[shaderType].at(i).name == e->propertyName()) {
                    bool textureProviderChanged;
                    m_common.propertyChanged(m_item, m_itemMetaObject,
                                             (shaderType << 16) | i, &textureProviderChanged);
                    m_dirtyTextureProviders |= textureProviderChanged;
                    m_dirtyUniformValues = true;
                    m_item->update();
                }
            }
        }
    }
}

void QQuickOpenGLShaderEffect::updateGeometry()
{
    m_dirtyGeometry = true;
    m_item->update();
}

void QQuickOpenGLShaderEffect::updateGeometryIfAtlased()
{
    if (m_supportsAtlasTextures)
        updateGeometry();
}

void QQuickOpenGLShaderEffect::updateLogAndStatus(const QString &log, int status)
{
    m_log = parseLog() + log;
    m_status = QQuickShaderEffect::Status(status);
    emit m_item->logChanged();
    emit m_item->statusChanged();
}

void QQuickOpenGLShaderEffect::sourceDestroyed(QObject *object)
{
    m_common.sourceDestroyed(object);
}

void QQuickOpenGLShaderEffect::propertyChanged(int mappedId)
{
    bool textureProviderChanged;
    m_common.propertyChanged(m_item, m_itemMetaObject, mappedId, &textureProviderChanged);
    m_dirtyTextureProviders |= textureProviderChanged;
    m_dirtyUniformValues = true;
    m_item->update();
}

void QQuickOpenGLShaderEffect::handleGeometryChanged(const QRectF &, const QRectF &)
{
    m_dirtyGeometry = true;
}

QSGNode *QQuickOpenGLShaderEffect::handleUpdatePaintNode(QSGNode *oldNode, QQuickItem::UpdatePaintNodeData *)
{
    QQuickOpenGLShaderEffectNode *node = static_cast<QQuickOpenGLShaderEffectNode *>(oldNode);

    // In the case of zero-size or a bad vertex shader, don't try to create a node...
    if (m_common.attributes.isEmpty() || m_item->width() <= 0 || m_item->height() <= 0) {
        if (node)
            delete node;
        return nullptr;
    }

    if (!node) {
        node = new QQuickOpenGLShaderEffectNode;
        node->setMaterial(new QQuickOpenGLShaderEffectMaterial(node));
        node->setFlag(QSGNode::OwnsMaterial, true);
        m_dirtyProgram = true;
        m_dirtyUniforms = true;
        m_dirtyGeometry = true;
        connect(node, SIGNAL(logAndStatusChanged(QString,int)), this, SLOT(updateLogAndStatus(QString,int)));
        connect(node, &QQuickOpenGLShaderEffectNode::dirtyTexture,
                this, &QQuickOpenGLShaderEffect::updateGeometryIfAtlased);
    }

    QQuickOpenGLShaderEffectMaterial *material = static_cast<QQuickOpenGLShaderEffectMaterial *>(node->material());

    // Update blending
    if (bool(material->flags() & QSGMaterial::Blending) != m_blending) {
        material->setFlag(QSGMaterial::Blending, m_blending);
        node->markDirty(QSGNode::DirtyMaterial);
    }

    if (int(material->cullMode) != int(m_cullMode)) {
        material->cullMode = QQuickShaderEffect::CullMode(m_cullMode);
        node->markDirty(QSGNode::DirtyMaterial);
    }

    if (m_dirtyProgram) {
        Key s = m_common.source;
        QSGShaderSourceBuilder builder;
        if (s.sourceCode[Key::FragmentShader].isEmpty()) {
            builder.appendSourceFile(QStringLiteral(":/qt-project.org/items/shaders/shadereffect.frag"));
            s.sourceCode[Key::FragmentShader] = builder.source();
            builder.clear();
        }
        if (s.sourceCode[Key::VertexShader].isEmpty()) {
            builder.appendSourceFile(QStringLiteral(":/qt-project.org/items/shaders/shadereffect.vert"));
            s.sourceCode[Key::VertexShader] = builder.source();
        }

        material->setProgramSource(s);
        material->attributes = m_common.attributes;
        node->markDirty(QSGNode::DirtyMaterial);
        m_dirtyProgram = false;
        m_dirtyUniforms = true;
    }

    if (m_dirtyUniforms || m_dirtyUniformValues || m_dirtyTextureProviders) {
        m_common.updateMaterial(node, material, m_dirtyUniforms, m_dirtyUniformValues,
                                m_dirtyTextureProviders);
        node->markDirty(QSGNode::DirtyMaterial);
        m_dirtyUniforms = m_dirtyUniformValues = m_dirtyTextureProviders = false;
    }

    QRectF srcRect(0, 0, 1, 1);
    bool geometryUsesTextureSubRect = false;
    if (m_supportsAtlasTextures && material->textureProviders.size() == 1) {
        QSGTextureProvider *provider = material->textureProviders.at(0);
        if (provider && provider->texture()) {
            srcRect = provider->texture()->normalizedTextureSubRect();
            geometryUsesTextureSubRect = true;
        }
    }

    if (bool(material->flags() & QSGMaterial::RequiresFullMatrix) != m_customVertexShader) {
        material->setFlag(QSGMaterial::RequiresFullMatrix, m_customVertexShader);
        node->markDirty(QSGNode::DirtyMaterial);
    }

    if (material->geometryUsesTextureSubRect != geometryUsesTextureSubRect) {
        material->geometryUsesTextureSubRect = geometryUsesTextureSubRect;
        node->markDirty(QSGNode::DirtyMaterial);
    }

    if (m_dirtyMesh) {
        node->setGeometry(nullptr);
        m_dirtyMesh = false;
        m_dirtyGeometry = true;
    }

    if (m_dirtyGeometry) {
        node->setFlag(QSGNode::OwnsGeometry, false);
        QSGGeometry *geometry = node->geometry();
        QRectF rect(0, 0, m_item->width(), m_item->height());
        QQuickShaderEffectMesh *mesh = m_mesh ? m_mesh : &m_defaultMesh;

        int posIndex = 0;
        if (!mesh->validateAttributes(m_common.attributes, &posIndex)) {
            QString log = mesh->log();
            if (!log.isNull()) {
                m_log = parseLog() + QLatin1String("*** Mesh ***\n") + log;
                m_status = QQuickShaderEffect::Error;
                emit m_item->logChanged();
                emit m_item->statusChanged();
            }
            delete node;
            return nullptr;
        }

        geometry = mesh->updateGeometry(geometry, m_common.attributes.count(), posIndex, srcRect, rect);

        node->setGeometry(geometry);
        node->setFlag(QSGNode::OwnsGeometry, true);

        m_dirtyGeometry = false;
    }

    return node;
}

void QQuickOpenGLShaderEffect::maybeUpdateShaders(bool force)
{
    if (!m_itemMetaObject)
        m_itemMetaObject = m_item->metaObject();

    // Defer processing if a window is not yet associated with the item. This
    // is because the actual scenegraph backend is not known so conditions
    // based on GraphicsInfo.shaderType and similar evaluate to wrong results.
    if (!m_item->window() && !force) {
        m_item->polish();
        return;
    }

    if (m_vertNeedsUpdate) {
        m_vertNeedsUpdate = false;
        m_common.updateShader(m_item, m_itemMetaObject, Key::VertexShader);
    }

    if (m_fragNeedsUpdate) {
        m_fragNeedsUpdate = false;
        m_common.updateShader(m_item, m_itemMetaObject, Key::FragmentShader);
    }
}

void QQuickOpenGLShaderEffect::handleItemChange(QQuickItem::ItemChange change, const QQuickItem::ItemChangeData &value)
{
    if (change == QQuickItem::ItemSceneChange)
        m_common.updateWindow(value.window);
}

QT_END_NAMESPACE

#include "moc_qquickopenglshadereffect_p.cpp"
