/****************************************************************************
**
** Copyright (C) 2019 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of Qt Quick 3D.
**
** $QT_BEGIN_LICENSE:GPL$
** 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 General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 or (at your option) 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.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-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qquick3dcustommaterial_p.h"
#include <QtQuick3DRuntimeRender/private/qssgrendercustommaterial_p.h>
#include <QtQuick3DRuntimeRender/private/qssgrendercontextcore_p.h>
#include <QtQuick/QQuickWindow>

#include "qquick3dobject_p_p.h"
#include "qquick3dviewport_p.h"

Q_DECLARE_OPAQUE_POINTER(QQuick3DCustomMaterialTextureInput)

QT_BEGIN_NAMESPACE

/*!
    \qmltype CustomMaterial
    \inherits Material
    \inqmlmodule QtQuick3D.Materials
    \brief Base component for creating custom materials used to shade models.

    The custom material allows the user of QtQuick3D to access its material library and implement
    own materials. There are two types of custom materials, which differ on how they are using the
    material library. First one uses the custom material interface provided by the library to
    implement materials similarly to many of the materials in the material library without
    implementing it's own main function. This type of material must implement all the required
    functions of the material. The second type implements it's own main function, but can still
    use functionality from the material library. See \l {Qt Quick 3D Custom Material Reference}{reference}
    on how to implement the material using the material interface.

    \qml
    CustomMaterial {
        // These properties names need to match the ones in the shader code!
        property bool uEnvironmentMappingEnabled: false
        property bool uShadowMappingEnabled: false
        property real roughness: 0.0
        property vector3d metal_color: Qt.vector3d(0.805, 0.395, 0.305)

        shaderInfo: ShaderInfo {
            version: "330"
            type: "GLSL"
            shaderKey: ShaderInfo.Glossy
        }

        property TextureInput uEnvironmentTexture: TextureInput {
                enabled: uEnvironmentMappingEnabled
                texture: Texture {
                    id: envImage
                    source: "maps/spherical_checker.png"
                }
        }
        property TextureInput uBakedShadowTexture: TextureInput {
                enabled: uShadowMappingEnabled
                texture: Texture {
                    id: shadowImage
                    source: "maps/shadow.png"
                }
        }

        Shader {
            id: copperFragShader
            stage: Shader.Fragment
            shader: "shaders/copper.frag"
        }

        passes: [ Pass {
                shaders: copperFragShader
            }
        ]
    }
    \endqml

    The example here from CopperMaterial shows how the material is built. First, the shader
    parameters are specified as properties. The names and types must match the names in the shader
    code. Textures use TextureInput to assign \l{QtQuick3D::Texture}{texture} into the shader variable.
    The shaderInfo property specifies more information about the shader and also configures some of
    its features on or off when the custom material is built by QtQuick3D shader generator.
    Then the material can use Shader type to specify shader source and shader stage. These are used
    with \l {Pass}{passes} to create the resulting material. The passes can contain multiple
    rendering passes and also other commands. Normally only the fragment shader needs to be passed
    to a pass. The material library generates the vertex shader for the material. The material can
    also create \l {Buffer}{buffers} to store intermediate rendering results. Here is an example
    from GlassRefractiveMaterial:

    \qml
    Buffer {
        id: tempBuffer
        name: "temp_buffer"
        format: Buffer.Unknown
        textureFilterOperation: Buffer.Linear
        textureCoordOperation: Buffer.ClampToEdge
        sizeMultiplier: 1.0
        bufferFlags: Buffer.None // aka frame
    }

    passes: [ Pass {
            shaders: simpleGlassRefractiveFragShader
            commands: [ BufferBlit {
                    destination: tempBuffer
                }, BufferInput {
                    buffer: tempBuffer
                    param: "refractiveTexture"
                }, Blending {
                    srcBlending: Blending.SrcAlpha
                    destBlending: Blending.OneMinusSrcAlpha
                }
            ]
        }
    ]
    \endqml

    Multiple passes can also be specified to create advanced materials. Here is an example from
    FrostedGlassMaterial.

    \qml
    passes: [ Pass {
            shaders: noopShader
            output: dummyBuffer
            commands: [ BufferBlit {
                    destination: frameBuffer
                }
            ]
        }, Pass {
            shaders: preBlurShader
            output: tempBuffer
            commands: [ BufferInput {
                    buffer: frameBuffer
                    param: "OriginBuffer"
                }
            ]
        }, Pass {
            shaders: blurXShader
            output: blurXBuffer
            commands: [ BufferInput {
                    buffer: tempBuffer
                    param: "BlurBuffer"
                }
            ]
        }, Pass {
            shaders: blurYShader
            output: blurYBuffer
            commands: [ BufferInput {
                    buffer: blurXBuffer
                    param: "BlurBuffer"
                }, BufferInput {
                    buffer: tempBuffer
                    param: "OriginBuffer"
                }
            ]
        }, Pass {
            shaders: mainShader
            commands: [BufferInput {
                    buffer: blurYBuffer
                    param: "refractiveTexture"
                }, Blending {
                    srcBlending: Blending.SrcAlpha
                    destBlending: Blending.OneMinusSrcAlpha
                }
            ]
        }
    ]
    \endqml
*/
/*!
    \qmlproperty bool CustomMaterial::hasTransparency
    Specifies that the material has transparency.
*/
/*!
    \qmlproperty bool CustomMaterial::hasRefraction
    Specifies that the material has refraction.
*/
/*!
    \qmlproperty bool CustomMaterial::alwaysDirty
    Specifies that the material state is always dirty, which indicates that the material needs
    to be refreshed every time it is used by the QtQuick3D.
*/
/*!
    \qmlproperty ShaderInfo CustomMaterial::shaderInfo
    Specifies the ShaderInfo of the material.
*/
/*!
    \qmlproperty list CustomMaterial::passes
    Contains a list of render \l {Pass}{passes} implemented by the material.
*/

/*!
    \qmltype Shader
    \inherits Object
    \inqmlmodule QtQuick3D.Materials
    \brief Container component for defining shader code used by CustomMaterials.
*/
/*!
    \qmlproperty string Shader::shader
    Specifies the name of the shader source file.
*/
/*!
    \qmlproperty enumeration Shader::stage
    Specifies the shader stage.

    \value Shader.Shared The shader can be shared among different stages
    \value Shader.Vertex The shader is a vertex shader
    \value Shader.Fragment The shader is a fragment shader
    \value Shader.Geometry The shader is a geometry shader
    \value Shader.Compute The shader is a compute shader
*/

/*!
    \qmltype ShaderInfo
    \inherits Object
    \inqmlmodule QtQuick3D.Materials
    \brief Defines basic information about custom shader code for CustomMaterials.
*/
/*!
    \qmlproperty string ShaderInfo::version
    Specifies the shader code version.
*/
/*!
    \qmlproperty string ShaderInfo::type
    Specifies the shader code type.
*/
/*!
    \qmlproperty string ShaderInfo::shaderKey
    Specifies the options used by the shader using the combination of shader key values.

    \value ShaderInfo.Diffuse The shader uses diffuse lighting.
    \value ShaderInfo.Specular The shader uses specular lighting.
    \value ShaderInfo.Cutout The shader uses alpha cutout.
    \value ShaderInfo.Refraction The shader uses refraction.
    \value ShaderInfo.Transparent The shader uses transparency.
    \value ShaderInfo.Displace The shader uses displacement mapping.
    \value ShaderInfo.Transmissive The shader uses transmissiveness.
    \value ShaderInfo.Glossy The shader is default glossy. This is a combination of \c ShaderInfo.Diffuse and
        \c ShaderInfo.Specular.
*/

/*!
    \qmltype TextureInput
    \inherits Object
    \inqmlmodule QtQuick3D.Materials
    \brief Defines a texture channel for a Custom Material.
*/
/*!
    \qmlproperty Texture TextureInput::texture
    Specifies the Texture to input.
*/
/*!
    \qmlproperty bool TextureInput::enabled
    The property determines if this TextureInput is enabled.
*/

/*!
    \qmltype Pass
    \inherits Object
    \inqmlmodule QtQuick3D.Materials
    \brief Defines a render pass in the CustomMaterial.
*/
/*!
    \qmlproperty Buffer Pass::output
    Specifies the output \l {Buffer}{buffer} of the pass.
*/
/*!
    \qmlproperty list Pass::commands
    Specifies the list of render \l {Command}{commands} of the pass.
*/
/*!
    \qmlproperty list Pass::shaders
    Specifies the list of \l {Shader}{shaders} of the pass.
*/

/*!
    \qmltype Command
    \inherits Object
    \inqmlmodule QtQuick3D.Materials
    \brief Defines a command to be performed in a pass of a CustomMaterial.
*/

/*!
    \qmltype BufferInput
    \inherits Command
    \inqmlmodule QtQuick3D.Materials
    \brief Defines an input buffer to be used for a pass of a CustomMaterial.
*/
/*!
    \qmlproperty Buffer BufferInput::buffer
    Specifies the \l {Buffer}{buffer} used for the parameter.
*/
/*!
    \qmlproperty string BufferInput::param
    Specifies the name of the input parameter in the shader.
*/

/*!
    \qmltype BufferBlit
    \inherits Command
    \inqmlmodule QtQuick3D.Materials
    \brief Defines a copy operation between two buffers in a pass of a CustomMaterial.
*/
/*!
    \qmlproperty Buffer BufferBlit::source
    Specifies the source \l {Buffer}{buffer} of the copy operation.
*/
/*!
    \qmlproperty Buffer BufferBlit::destination
    Specifies the destination \l {Buffer}{buffer} of the copy operation.
*/

/*!
    \qmltype Blending
    \inherits Command
    \inqmlmodule QtQuick3D.Materials
    \brief Defines the blending state in a pass of a CustomMaterial.
*/
/*!
    \qmlproperty enumeration Blending::srcBlending
    Specifies the source blending function.

    \value Blending.Unknown
    \value Blending.Zero
    \value Blending.One
    \value Blending.SrcColor
    \value Blending.OneMinusSrcColor
    \value Blending.DstColor
    \value Blending.OneMinusDstColor
    \value Blending.SrcAlpha
    \value Blending.OneMinusSrcAlpha
    \value Blending.DstAlpha
    \value Blending.OneMinusDstAlpha
    \value Blending.ConstantColor
    \value Blending.OneMinusConstantColor
    \value Blending.ConstantAlpha
    \value Blending.OneMinusConstantAlpha
    \value Blending.SrcAlphaSaturate

*/
/*!
    \qmlproperty enumeration Blending::destBlending
    Specifies the destination blending function.

    \value Blending.Unknown
    \value Blending.Zero
    \value Blending.One
    \value Blending.SrcColor
    \value Blending.OneMinusSrcColor
    \value Blending.DstColor
    \value Blending.OneMinusDstColor
    \value Blending.SrcAlpha
    \value Blending.OneMinusSrcAlpha
    \value Blending.DstAlpha
    \value Blending.OneMinusDstAlpha
    \value Blending.ConstantColor
    \value Blending.OneMinusConstantColor
    \value Blending.ConstantAlpha
    \value Blending.OneMinusConstantAlpha
*/

/*!
    \qmltype Buffer
    \inherits Object
    \inqmlmodule QtQuick3D.Materials
    \brief Defines a buffer to be used for a pass of a CustomMaterial.
*/
/*!
    \qmlproperty enumeration Buffer::format
    Specifies the buffer format.

    \value Buffer.Unknown
    \value Buffer.R8
    \value Buffer.R16
    \value Buffer.R16F
    \value Buffer.R32I
    \value Buffer.R32UI
    \value Buffer.R32F
    \value Buffer.RG8
    \value Buffer.RGBA8
    \value Buffer.RGB8
    \value Buffer.SRGB8
    \value Buffer.SRGB8A8
    \value Buffer.RGB565
    \value Buffer.RGBA16F
    \value Buffer.RG16F
    \value Buffer.RG32F
    \value Buffer.RGB32F
    \value Buffer.RGBA32F
    \value Buffer.R11G11B10
    \value Buffer.RGB9E5
    \value Buffer.Depth16
    \value Buffer.Depth24
    \value Buffer.Depth32
    \value Buffer.Depth24Stencil8
*/
/*!
    \qmlproperty enumeration Buffer::textureFilterOperation
    Specifies the filter operation when a render \l {Pass}{pass} is reading the buffer that is
    different size as the current output buffer.

    \value Buffer.Unknown Value not set.
    \value Buffer.Nearest Use nearest-neighbor.
    \value Buffer.Linear Use linear filtering.
*/
/*!
    \qmlproperty enumeration Buffer::textureCoordOperation
    Specifies the texture coordinate operation for coordinates outside [0, 1] range.

    \value Buffer.Unknown Value not set.
    \value Buffer.ClampToEdge Clamp coordinate to edge.
    \value Buffer.MirroredRepeat Repeat the coordinate, but flip direction at the beginning and end.
    \value Buffer.Repeat Repeat the coordinate always from the beginning.
*/
/*!
    \qmlproperty real Buffer::sizeMultiplier
    Specifies the size multiplier of the buffer. \c 1.0 creates buffer with the same size while
    \c 0.5 creates buffer with width and height halved.
*/
/*!
    \qmlproperty enumeration Buffer::bufferFlags
    Specifies the buffer allocation flags.

    \value Buffer.None Value not set.
    \value Buffer.SceneLifetime The buffer is allocated for the whole lifetime of the scene.
*/
/*!
    \qmlproperty string Buffer::name
    Specifies the name of the buffer
*/

/*!
    \qmltype RenderState
    \inherits Command
    \inqmlmodule QtQuick3D.Materials
    \brief Defines the render state to be disabled in a pass of a CustomMaterial.
*/
/*!
    \qmlproperty enumeration RenderState::renderState
    Specifies the render state to enable/disable in a \l {Pass}{pass}.

    \value RenderState.Unknown
    \value RenderState.Blend
    \value RenderState.DepthTest
    \value RenderState.StencilTest
    \value RenderState.ScissorTest
    \value RenderState.DepthWrite
    \value RenderState.Multisample
*/
/*!
    \qmlproperty bool RenderState::enable
    Specifies if the state is enabled or disabled.
*/

template <QVariant::Type>
struct ShaderType
{
};

template<>
struct ShaderType<QVariant::Double>
{
    static constexpr QSSGRenderShaderDataType type() { return QSSGRenderShaderDataType::Float; }
    static QByteArray name() { return QByteArrayLiteral("float"); }
};

template<>
struct ShaderType<QVariant::Bool>
{
    static constexpr QSSGRenderShaderDataType type() { return QSSGRenderShaderDataType::Boolean; }
    static QByteArray name() { return QByteArrayLiteral("bool"); }
};

template<>
struct ShaderType<QVariant::Int>
{
    static constexpr QSSGRenderShaderDataType type() { return QSSGRenderShaderDataType::Integer; }
    static QByteArray name() { return QByteArrayLiteral("int"); }
};

template<>
struct ShaderType<QVariant::Vector2D>
{
    static constexpr QSSGRenderShaderDataType type() { return QSSGRenderShaderDataType::Vec2; }
    static QByteArray name() { return QByteArrayLiteral("vec2"); }
};

template<>
struct ShaderType<QVariant::Vector3D>
{
    static constexpr QSSGRenderShaderDataType type() { return QSSGRenderShaderDataType::Vec3; }
    static QByteArray name() { return QByteArrayLiteral("vec3"); }
};

template<>
struct ShaderType<QVariant::Vector4D>
{
    static constexpr QSSGRenderShaderDataType type() { return QSSGRenderShaderDataType::Vec4; }
    static QByteArray name() { return QByteArrayLiteral("vec4"); }
};

template<>
struct ShaderType<QVariant::Color>
{
    static constexpr QSSGRenderShaderDataType type() { return QSSGRenderShaderDataType::Rgba; }
    static QByteArray name() { return QByteArrayLiteral("vec4"); }
};

QQuick3DCustomMaterialBuffer::TextureFormat QQuick3DCustomMaterialBuffer::format() const
{
    return mapRenderTextureFormat(command.m_format.format);
}

void QQuick3DCustomMaterialBuffer::setFormat(TextureFormat format)
{
    command.m_format = mapTextureFormat(format);
}

QQuick3DCustomMaterialBuffer::TextureFormat QQuick3DCustomMaterialBuffer::mapRenderTextureFormat(
        QSSGRenderTextureFormat::Format fmt)
{
    switch (fmt) {
    case QSSGRenderTextureFormat::R8: return TextureFormat::R8;
    case QSSGRenderTextureFormat::R16: return TextureFormat::R16;
    case QSSGRenderTextureFormat::R16F: return TextureFormat::R16F;
    case QSSGRenderTextureFormat::R32I: return TextureFormat::R32I;
    case QSSGRenderTextureFormat::R32UI: return TextureFormat::R32UI;
    case QSSGRenderTextureFormat::R32F: return TextureFormat::R32F;
    case QSSGRenderTextureFormat::RG8: return TextureFormat::RG8;
    case QSSGRenderTextureFormat::RGBA8: return TextureFormat::RGBA8;
    case QSSGRenderTextureFormat::RGB8: return TextureFormat::RGB8;
    case QSSGRenderTextureFormat::SRGB8: return TextureFormat::SRGB8;
    case QSSGRenderTextureFormat::SRGB8A8: return TextureFormat::SRGB8A8;
    case QSSGRenderTextureFormat::RGB565: return TextureFormat::RGB565;
    case QSSGRenderTextureFormat::RGBA16F: return TextureFormat::RGBA16F;
    case QSSGRenderTextureFormat::RG16F: return TextureFormat::RG16F;
    case QSSGRenderTextureFormat::RG32F: return TextureFormat::RG32F;
    case QSSGRenderTextureFormat::RGB32F: return TextureFormat::RGB32F;
    case QSSGRenderTextureFormat::RGBA32F: return TextureFormat::RGBA32F;
    case QSSGRenderTextureFormat::R11G11B10: return TextureFormat::R11G11B10;
    case QSSGRenderTextureFormat::RGB9E5: return TextureFormat::RGB9E5;
    case QSSGRenderTextureFormat::Depth16: return TextureFormat::Depth16;
    case QSSGRenderTextureFormat::Depth24: return TextureFormat::Depth24;
    case QSSGRenderTextureFormat::Depth32: return TextureFormat::Depth32;
    case QSSGRenderTextureFormat::Depth24Stencil8: return TextureFormat::Depth24Stencil8;
    default:
        break;
    }
    return TextureFormat::Unknown;
}

QSSGRenderTextureFormat::Format QQuick3DCustomMaterialBuffer::mapTextureFormat(
        QQuick3DCustomMaterialBuffer::TextureFormat fmt)
{
    switch (fmt) {
    case TextureFormat::R8: return QSSGRenderTextureFormat::R8;
    case TextureFormat::R16: return QSSGRenderTextureFormat::R16;
    case TextureFormat::R16F: return QSSGRenderTextureFormat::R16F;
    case TextureFormat::R32I: return QSSGRenderTextureFormat::R32I;
    case TextureFormat::R32UI: return QSSGRenderTextureFormat::R32UI;
    case TextureFormat::R32F: return QSSGRenderTextureFormat::R32F;
    case TextureFormat::RG8: return QSSGRenderTextureFormat::RG8;
    case TextureFormat::RGBA8: return QSSGRenderTextureFormat::RGBA8;
    case TextureFormat::RGB8: return QSSGRenderTextureFormat::RGB8;
    case TextureFormat::SRGB8: return QSSGRenderTextureFormat::SRGB8;
    case TextureFormat::SRGB8A8: return QSSGRenderTextureFormat::SRGB8A8;
    case TextureFormat::RGB565: return QSSGRenderTextureFormat::RGB565;
    case TextureFormat::RGBA16F: return QSSGRenderTextureFormat::RGBA16F;
    case TextureFormat::RG16F: return QSSGRenderTextureFormat::RG16F;
    case TextureFormat::RG32F: return QSSGRenderTextureFormat::RG32F;
    case TextureFormat::RGB32F: return QSSGRenderTextureFormat::RGB32F;
    case TextureFormat::RGBA32F: return QSSGRenderTextureFormat::RGBA32F;
    case TextureFormat::R11G11B10: return QSSGRenderTextureFormat::R11G11B10;
    case TextureFormat::RGB9E5: return QSSGRenderTextureFormat::RGB9E5;
    case TextureFormat::Depth16: return QSSGRenderTextureFormat::Depth16;
    case TextureFormat::Depth24: return QSSGRenderTextureFormat::Depth24;
    case TextureFormat::Depth32: return QSSGRenderTextureFormat::Depth32;
    case TextureFormat::Depth24Stencil8: return QSSGRenderTextureFormat::Depth24Stencil8;
    default:
        break;
    }
    return QSSGRenderTextureFormat::Unknown;
}

QQuick3DCustomMaterial::QQuick3DCustomMaterial() {}

QQuick3DCustomMaterial::~QQuick3DCustomMaterial() {}

QQuick3DObject::Type QQuick3DCustomMaterial::type() const
{
    return QQuick3DObject::CustomMaterial;
}

bool QQuick3DCustomMaterial::hasTransparency() const
{
    return m_hasTransparency;
}

bool QQuick3DCustomMaterial::hasRefraction() const
{
    return m_hasRefraction;
}

QQuick3DCustomMaterialShaderInfo *QQuick3DCustomMaterial::shaderInfo() const
{
    return m_shaderInfo;
}

QQmlListProperty<QQuick3DCustomMaterialRenderPass> QQuick3DCustomMaterial::passes()
{
    return QQmlListProperty<QQuick3DCustomMaterialRenderPass>(this,
                                                            nullptr,
                                                            QQuick3DCustomMaterial::qmlAppendPass,
                                                            QQuick3DCustomMaterial::qmlPassCount,
                                                            QQuick3DCustomMaterial::qmlPassAt,
                                                            nullptr);
}

void QQuick3DCustomMaterial::markAllDirty()
{
    m_dirtyAttributes = 0xffffffff;
    QQuick3DMaterial::markAllDirty();
}

bool QQuick3DCustomMaterial::alwaysDirty() const
{
    return m_alwaysDirty;
}

void QQuick3DCustomMaterial::setHasTransparency(bool hasTransparency)
{
    if (m_hasTransparency == hasTransparency)
        return;

    m_hasTransparency = hasTransparency;
    emit hasTransparencyChanged(m_hasTransparency);
}

void QQuick3DCustomMaterial::setHasRefraction(bool hasRefraction)
{
    if (m_hasRefraction == hasRefraction)
        return;

    m_hasRefraction = hasRefraction;
    emit hasRefractionChanged(m_hasRefraction);
}

void QQuick3DCustomMaterial::setShaderInfo(QQuick3DCustomMaterialShaderInfo *shaderInfo)
{
    m_shaderInfo = shaderInfo;
}

void QQuick3DCustomMaterial::setAlwaysDirty(bool alwaysDirty)
{
    if (m_alwaysDirty == alwaysDirty)
        return;

    m_alwaysDirty = alwaysDirty;
    emit alwaysDirtyChanged(m_alwaysDirty);
}

QSSGRenderGraphObject *QQuick3DCustomMaterial::updateSpatialNode(QSSGRenderGraphObject *node)
{
    static const auto updateShaderPrefix = [](QByteArray &shaderPrefix, const QByteArray &name) {
        const char *filter = "linear";
        const char *clamp = "clamp";
        // Output macro so we can change the set of variables used for this
        // independent of the
        // meta data system.
        shaderPrefix.append("SNAPPER_SAMPLER2D(");
        shaderPrefix.append(name);
        shaderPrefix.append(", ");
        shaderPrefix.append(name);
        shaderPrefix.append(", ");
        shaderPrefix.append(filter);
        shaderPrefix.append(", ");
        shaderPrefix.append(clamp);
        shaderPrefix.append(", ");
        shaderPrefix.append("false )\n");
    };

    static const auto appendShaderUniform = [](const QByteArray &type, const QByteArray &name, QByteArray *shaderPrefix) {
        shaderPrefix->append(QByteArrayLiteral("uniform ") + type + " " + name + ";\n");
    };

    static const auto resolveShader = [](const QByteArray &shader) -> QByteArray {
        int offset = -1;
        if (shader.startsWith("qrc:/"))
            offset = 3;
        else if (shader.startsWith("file:/"))
            offset = 6;
        else if (shader.startsWith(":/"))
            offset = 0;

        QString path;
        if (offset == -1) {
            QUrl u(QString::fromUtf8(shader));
            if (u.isLocalFile())
                path = u.toLocalFile();
        }

        if (offset == -1 && path.isEmpty())
            path = QString::fromLatin1(":/") + QString::fromLocal8Bit(shader);
        else
            path = QString::fromLocal8Bit(shader.constData() + offset);

        QFile f(path);
        if (f.open(QIODevice::ReadOnly | QIODevice::Text))
            return f.readAll();

        return shader;
    };

    static const auto mergeShaderCode = [](const QByteArray &shared, const QByteArray &vertex, const QByteArray &geometry, const QByteArray &fragment) {
        QByteArray shaderCode;
            // Shared
            if (!shared.isEmpty())
                shaderCode.append(shared);

            // Vetex
            shaderCode.append(QByteArrayLiteral("\n#ifdef VERTEX_SHADER\n"));
            if (!vertex.isEmpty())
                shaderCode.append(vertex);
            else
                shaderCode.append(QByteArrayLiteral("void vert(){}"));
            shaderCode.append(QByteArrayLiteral("\n#endif\n"));

            // Geometry
            if (!geometry.isEmpty()) {
                shaderCode.append(QByteArrayLiteral("\n#ifdef USER_GEOMETRY_SHADER\n"));
                shaderCode.append(geometry);
                shaderCode.append(QByteArrayLiteral("\n#endif\n"));
            }

            // Fragment
            shaderCode.append(QByteArrayLiteral("\n#ifdef FRAGMENT_SHADER\n"));
            if (!fragment.isEmpty())
                shaderCode.append(fragment);
            else
                shaderCode.append(QByteArrayLiteral("void frag(){}"));
            shaderCode.append(QByteArrayLiteral("\n#endif\n"));

            return shaderCode;
    };


    // Sanity check(s)
    if (!m_shaderInfo || !m_shaderInfo->isValid()) {
        qWarning("ShaderInfo is not valid!");
        return node;
    }

    // Find the parent window
    QObject *p = this;
    QQuickWindow *window = nullptr;
    while (p != nullptr && window == nullptr) {
        p = p->parent();
        if ((window = qobject_cast<QQuickWindow *>(p)))
            break;
    }

    QSSGRenderContextInterface::QSSGRenderContextInterfacePtr renderContext
                = QSSGRenderContextInterface::getRenderContextInterface(quintptr(window));

    QSSGRenderCustomMaterial *customMaterial = static_cast<QSSGRenderCustomMaterial *>(node);
    if (!customMaterial) {
        markAllDirty();
        customMaterial = new QSSGRenderCustomMaterial;
        customMaterial->m_shaderKeyValues = static_cast<QSSGRenderCustomMaterial::MaterialShaderKeyFlags>(m_shaderInfo->shaderKey);
        customMaterial->className = metaObject()->className();
        customMaterial->m_alwaysDirty = m_alwaysDirty;
        customMaterial->m_hasTransparency = m_hasTransparency;
        customMaterial->m_hasRefraction = m_hasRefraction;

        // Shader info
        auto &shaderInfo = customMaterial->shaderInfo;
        shaderInfo.type = m_shaderInfo->type;
        shaderInfo.version = m_shaderInfo->version;
        shaderInfo.shaderPrefix = m_shaderInfo->shaderPrefix;

        QMetaMethod propertyDirtyMethod;
        const int idx = metaObject()->indexOfSlot("onPropertyDirty()");
        if (idx != -1)
            propertyDirtyMethod = metaObject()->method(idx);

        // Properties
        const int propCount = metaObject()->propertyCount();
        const int propOffset = metaObject()->propertyOffset();
        QVector<QMetaProperty> userProperties;
        for (int i = propOffset; i != propCount; ++i) {
            const auto property = metaObject()->property(i);
            if (Q_UNLIKELY(!property.isValid()))
                continue;

            // Track the property changes
            if (property.hasNotifySignal() && propertyDirtyMethod.isValid())
                connect(this, property.notifySignal(), this, propertyDirtyMethod);

            if (property.type() == QVariant::Double) {
                appendShaderUniform(ShaderType<QVariant::Double>::name(), property.name(), &shaderInfo.shaderPrefix);
                customMaterial->properties.push_back({ property.name(), property.read(this), ShaderType<QVariant::Double>::type(), i});
            } else if (property.type() == QVariant::Bool) {
                appendShaderUniform(ShaderType<QVariant::Bool>::name(), property.name(), &shaderInfo.shaderPrefix);
                customMaterial->properties.push_back({ property.name(), property.read(this), ShaderType<QVariant::Bool>::type(), i});
            } else if (property.type() == QVariant::Vector2D) {
                appendShaderUniform(ShaderType<QVariant::Vector2D>::name(), property.name(), &shaderInfo.shaderPrefix);
                customMaterial->properties.push_back({ property.name(), property.read(this), ShaderType<QVariant::Vector2D>::type(), i});
            } else if (property.type() == QVariant::Vector3D) {
                appendShaderUniform(ShaderType<QVariant::Vector3D>::name(), property.name(), &shaderInfo.shaderPrefix);
                customMaterial->properties.push_back({ property.name(), property.read(this), ShaderType<QVariant::Vector3D>::type(), i});
            } else if (property.type() == QVariant::Vector4D) {
                appendShaderUniform(ShaderType<QVariant::Vector4D>::name(), property.name(), &shaderInfo.shaderPrefix);
                customMaterial->properties.push_back({ property.name(), property.read(this), ShaderType<QVariant::Vector4D>::type(), i});
            } else if (property.type() == QVariant::Int) {
                appendShaderUniform(ShaderType<QVariant::Int>::name(), property.name(), &shaderInfo.shaderPrefix);
                customMaterial->properties.push_back({ property.name(), property.read(this), ShaderType<QVariant::Int>::type(), i});
            } else if (property.type() == QVariant::Color) {
                appendShaderUniform(ShaderType<QVariant::Color>::name(), property.name(), &shaderInfo.shaderPrefix);
                customMaterial->properties.push_back({ property.name(), property.read(this), ShaderType<QVariant::Color>::type(), i});
            } else if (property.type() == QVariant::UserType) {
                if (property.userType() == qMetaTypeId<QQuick3DCustomMaterialTextureInput *>())
                    userProperties.push_back(property);
            } else {
                Q_ASSERT(0);
            }
        }

        // Textures
        for (const auto &userProperty : qAsConst(userProperties)) {
            QSSGRenderCustomMaterial::TextureProperty textureData;
            QQuick3DCustomMaterialTextureInput *texture = userProperty.read(this).value<QQuick3DCustomMaterialTextureInput *>();
            const QByteArray &name = userProperty.name();
            if (name.isEmpty()) // Warnings here will just drown in the shader error messages
                continue;
            QQuick3DTexture *tex = texture->texture(); //
            connect(texture, &QQuick3DCustomMaterialTextureInput::textureDirty, this, &QQuick3DCustomMaterial::onTextureDirty);
            textureData.name = name;
            if (texture->enabled)
                textureData.texImage = tex->getRenderImage();
            textureData.shaderDataType = QSSGRenderShaderDataType::Texture2D;
            textureData.clampType = tex->horizontalTiling() == QQuick3DTexture::Repeat ? QSSGRenderTextureCoordOp::Repeat
                                                                                     : (tex->horizontalTiling() == QQuick3DTexture::ClampToEdge) ? QSSGRenderTextureCoordOp::ClampToEdge
                                                                                                                                               : QSSGRenderTextureCoordOp::MirroredRepeat;
            updateShaderPrefix(shaderInfo.shaderPrefix, textureData.name);
            customMaterial->textureProperties.push_back(textureData);
        }

        QByteArray &shared = shaderInfo.shaderPrefix;
        QByteArray vertex, geometry, fragment, shaderCode;
        if (!m_passes.isEmpty()) {
            for (const auto &pass : qAsConst(m_passes)) {
                QQuick3DCustomMaterialShader *sharedShader = pass->m_shaders.at(int(QQuick3DCustomMaterialShader::Stage::Shared));
                QQuick3DCustomMaterialShader *vertShader = pass->m_shaders.at(int(QQuick3DCustomMaterialShader::Stage::Vertex));
                QQuick3DCustomMaterialShader *fragShader = pass->m_shaders.at(int(QQuick3DCustomMaterialShader::Stage::Fragment));
                QQuick3DCustomMaterialShader *geomShader = pass->m_shaders.at(int(QQuick3DCustomMaterialShader::Stage::Geometry));
                if (!sharedShader && !vertShader && !fragShader && !geomShader) {
                    qWarning("Pass with no shader attatched!");
                    continue;
                }

                // Build up shader code
                const QByteArray &shaderName = fragShader ? fragShader->shader : vertShader->shader;
                Q_ASSERT(!shaderName.isEmpty());

                if (sharedShader)
                    shared += resolveShader(sharedShader->shader);
                if (vertShader)
                    vertex = resolveShader(vertShader->shader);
                if (fragShader)
                    fragment = resolveShader(fragShader->shader);
                if (geomShader)
                    geometry = resolveShader(geomShader->shader);

                shaderCode = mergeShaderCode(shared, vertex, geometry, fragment);

                // Bind shader
                customMaterial->commands.push_back(new dynamic::QSSGBindShader(shaderName));
                customMaterial->commands.push_back(new dynamic::QSSGApplyInstanceValue());

                // Buffers
                QQuick3DCustomMaterialBuffer *outputBuffer = pass->outputBuffer;
                if (outputBuffer) {
                    const QByteArray &outBufferName = outputBuffer->name;
                    Q_ASSERT(!outBufferName.isEmpty());
                    // Allocate buffer command
                    customMaterial->commands.push_back(outputBuffer->getCommand());
                    // bind buffer
                    customMaterial->commands.push_back(new dynamic::QSSGBindBuffer(outBufferName, true));
                } else {
                    customMaterial->commands.push_back(new dynamic::QSSGBindTarget(QSSGRenderTextureFormat::RGBA8));
                }

                // Other commands (BufferInput, Blending ... )
                const auto &extraCommands = pass->m_commands;
                for (const auto &command : extraCommands) {
                    const int bufferCount = command->bufferCount();
                    for (int i = 0; i != bufferCount; ++i)
                        customMaterial->commands.push_back(command->bufferAt(i)->getCommand());
                    customMaterial->commands.push_back(command->getCommand());
                }

                // ... and finaly the render command
                customMaterial->commands.push_back(new dynamic::QSSGRender);

                renderContext->customMaterialSystem()->setMaterialClassShader(shaderName, shaderInfo.type, shaderInfo.version, shaderCode, false, false);
            }
        }
    }

    QQuick3DMaterial::updateSpatialNode(customMaterial);

    if (m_dirtyAttributes & Dirty::PropertyDirty) {
        for (const auto &prop : qAsConst(customMaterial->properties)) {
            auto p = metaObject()->property(prop.pid);
            if (Q_LIKELY(p.isValid()))
                prop.value = p.read(this);
        }
    }

    if (m_dirtyAttributes & Dirty::TextureDirty) {
        // TODO:
    }

    return customMaterial;
}

void QQuick3DCustomMaterial::onPropertyDirty()
{
    markDirty(Dirty::PropertyDirty);
    update();
}

void QQuick3DCustomMaterial::onTextureDirty(QQuick3DCustomMaterialTextureInput *texture)
{
    Q_UNUSED(texture)
    markDirty(Dirty::TextureDirty);
    update();
}

void QQuick3DCustomMaterial::qmlAppendPass(QQmlListProperty<QQuick3DCustomMaterialRenderPass> *list, QQuick3DCustomMaterialRenderPass *pass)
{
    if (!pass)
        return;

    QQuick3DCustomMaterial *that = qobject_cast<QQuick3DCustomMaterial *>(list->object);
    that->m_passes.push_back(pass);
}

QQuick3DCustomMaterialRenderPass *QQuick3DCustomMaterial::qmlPassAt(QQmlListProperty<QQuick3DCustomMaterialRenderPass> *list, int index)
{
    QQuick3DCustomMaterial *that = qobject_cast<QQuick3DCustomMaterial *>(list->object);
    return that->m_passes.at(index);
}

int QQuick3DCustomMaterial::qmlPassCount(QQmlListProperty<QQuick3DCustomMaterialRenderPass> *list)
{
    QQuick3DCustomMaterial *that = qobject_cast<QQuick3DCustomMaterial *>(list->object);
    return that->m_passes.count();
}

void QQuick3DCustomMaterialRenderPass::qmlAppendCommand(QQmlListProperty<QQuick3DCustomMaterialRenderCommand> *list, QQuick3DCustomMaterialRenderCommand *command)
{
    if (!command)
        return;

    QQuick3DCustomMaterialRenderPass *that = qobject_cast<QQuick3DCustomMaterialRenderPass *>(list->object);
    that->m_commands.push_back(command);
}

QQuick3DCustomMaterialRenderCommand *QQuick3DCustomMaterialRenderPass::qmlCommandAt(QQmlListProperty<QQuick3DCustomMaterialRenderCommand> *list, int index)
{
    QQuick3DCustomMaterialRenderPass *that = qobject_cast<QQuick3DCustomMaterialRenderPass *>(list->object);
    return that->m_commands.at(index);
}

int QQuick3DCustomMaterialRenderPass::qmlCommandCount(QQmlListProperty<QQuick3DCustomMaterialRenderCommand> *list)
{
    QQuick3DCustomMaterialRenderPass *that = qobject_cast<QQuick3DCustomMaterialRenderPass *>(list->object);
    return that->m_commands.count();
}

QQmlListProperty<QQuick3DCustomMaterialRenderCommand> QQuick3DCustomMaterialRenderPass::commands()
{
    return QQmlListProperty<QQuick3DCustomMaterialRenderCommand>(this,
                                                               nullptr,
                                                               QQuick3DCustomMaterialRenderPass::qmlAppendCommand,
                                                               QQuick3DCustomMaterialRenderPass::qmlCommandCount,
                                                               QQuick3DCustomMaterialRenderPass::qmlCommandAt,
                                                               nullptr);
}

void QQuick3DCustomMaterialRenderPass::qmlAppendShader(QQmlListProperty<QQuick3DCustomMaterialShader> *list, QQuick3DCustomMaterialShader *shader)
{
    if (!shader)
        return;

    QQuick3DCustomMaterialRenderPass *that = qobject_cast<QQuick3DCustomMaterialRenderPass *>(list->object);
    that->m_shaders[int(shader->stage)] = shader;
}

QQuick3DCustomMaterialShader *QQuick3DCustomMaterialRenderPass::qmlShaderAt(QQmlListProperty<QQuick3DCustomMaterialShader> *list, int index)
{
    QQuick3DCustomMaterialRenderPass *that = qobject_cast<QQuick3DCustomMaterialRenderPass *>(list->object);
    return that->m_shaders.at(index);
}

int QQuick3DCustomMaterialRenderPass::qmlShaderCount(QQmlListProperty<QQuick3DCustomMaterialShader> *list)
{
    QQuick3DCustomMaterialRenderPass *that = qobject_cast<QQuick3DCustomMaterialRenderPass *>(list->object);
    return that->m_shaders.count();
}

void QQuick3DCustomMaterialRenderPass::qmlShaderClear(QQmlListProperty<QQuick3DCustomMaterialShader> *list)
{
    QQuick3DCustomMaterialRenderPass *that = qobject_cast<QQuick3DCustomMaterialRenderPass *>(list->object);
    auto it = that->m_shaders.begin();
    const auto end = that->m_shaders.end();
    for (;it != end; ++it)
        *it = nullptr;
}

QQmlListProperty<QQuick3DCustomMaterialShader> QQuick3DCustomMaterialRenderPass::shaders()
{
    return QQmlListProperty<QQuick3DCustomMaterialShader>(this,
                                                        nullptr,
                                                        QQuick3DCustomMaterialRenderPass::qmlAppendShader,
                                                        QQuick3DCustomMaterialRenderPass::qmlShaderCount,
                                                        QQuick3DCustomMaterialRenderPass::qmlShaderAt,
                                                        QQuick3DCustomMaterialRenderPass::qmlShaderClear);
}

QT_END_NAMESPACE
