/****************************************************************************
**
** Copyright (C) 2018 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 "qsgadaptationlayer_p.h"

#include <qmath.h>
#include <QtQuick/private/qsgdistancefieldglyphnode_p.h>
#include <QtQuick/private/qsgcontext_p.h>
#include <private/qrawfont_p.h>
#include <QtGui/qguiapplication.h>
#include <qdir.h>
#include <qsgrendernode.h>

#include <private/qquickprofiler_p.h>
#include <QElapsedTimer>

QT_BEGIN_NAMESPACE

static QElapsedTimer qsg_render_timer;

QSGDistanceFieldGlyphCache::Texture QSGDistanceFieldGlyphCache::s_emptyTexture;

QSGDistanceFieldGlyphCache::QSGDistanceFieldGlyphCache(const QRawFont &font)
    : m_pendingGlyphs(64)
{
    Q_ASSERT(font.isValid());

    QRawFontPrivate *fontD = QRawFontPrivate::get(font);
    m_glyphCount = fontD->fontEngine->glyphCount();

    m_doubleGlyphResolution = qt_fontHasNarrowOutlines(font) && m_glyphCount < QT_DISTANCEFIELD_HIGHGLYPHCOUNT();

    m_referenceFont = font;
    // we set the same pixel size as used by the distance field internally.
    // this allows us to call pathForGlyph once and reuse the result.
    m_referenceFont.setPixelSize(QT_DISTANCEFIELD_BASEFONTSIZE(m_doubleGlyphResolution) * QT_DISTANCEFIELD_SCALE(m_doubleGlyphResolution));
    Q_ASSERT(m_referenceFont.isValid());
}

QSGDistanceFieldGlyphCache::~QSGDistanceFieldGlyphCache()
{
}

QSGDistanceFieldGlyphCache::GlyphData &QSGDistanceFieldGlyphCache::emptyData(glyph_t glyph)
{
    GlyphData gd;
    gd.texture = &s_emptyTexture;
    QHash<glyph_t, GlyphData>::iterator it = m_glyphsData.insert(glyph, gd);
    return it.value();
}

QSGDistanceFieldGlyphCache::GlyphData &QSGDistanceFieldGlyphCache::glyphData(glyph_t glyph)
{
    QHash<glyph_t, GlyphData>::iterator data = m_glyphsData.find(glyph);
    if (data == m_glyphsData.end()) {
        GlyphData &gd = emptyData(glyph);
        gd.path = m_referenceFont.pathForGlyph(glyph);
        // need bounding rect in base font size scale
        qreal scaleFactor = qreal(1) / QT_DISTANCEFIELD_SCALE(m_doubleGlyphResolution);
        QTransform scaleDown;
        scaleDown.scale(scaleFactor, scaleFactor);
        gd.boundingRect = scaleDown.mapRect(gd.path.boundingRect());
        return gd;
    }
    return data.value();
}

QSGDistanceFieldGlyphCache::Metrics QSGDistanceFieldGlyphCache::glyphMetrics(glyph_t glyph, qreal pixelSize)
{
    GlyphData &gd = glyphData(glyph);
    qreal scale = fontScale(pixelSize);

    Metrics m;
    m.width = gd.boundingRect.width() * scale;
    m.height = gd.boundingRect.height() * scale;
    m.baselineX = gd.boundingRect.x() * scale;
    m.baselineY = -gd.boundingRect.y() * scale;

    return m;
}

void QSGDistanceFieldGlyphCache::populate(const QVector<glyph_t> &glyphs)
{
    QSet<glyph_t> referencedGlyphs;
    QSet<glyph_t> newGlyphs;
    int count = glyphs.count();
    for (int i = 0; i < count; ++i) {
        glyph_t glyphIndex = glyphs.at(i);
        if ((int) glyphIndex >= glyphCount() && glyphCount() > 0) {
            qWarning("Warning: distance-field glyph is not available with index %d", glyphIndex);
            continue;
        }

        GlyphData &gd = glyphData(glyphIndex);
        ++gd.ref;
        referencedGlyphs.insert(glyphIndex);

        if (gd.texCoord.isValid() || m_populatingGlyphs.contains(glyphIndex))
            continue;

        m_populatingGlyphs.insert(glyphIndex);

        if (gd.boundingRect.isEmpty()) {
            gd.texCoord.width = 0;
            gd.texCoord.height = 0;
        } else {
            newGlyphs.insert(glyphIndex);
        }
    }

    referenceGlyphs(referencedGlyphs);
    if (!newGlyphs.isEmpty())
        requestGlyphs(newGlyphs);
}

void QSGDistanceFieldGlyphCache::release(const QVector<glyph_t> &glyphs)
{
    QSet<glyph_t> unusedGlyphs;
    int count = glyphs.count();
    for (int i = 0; i < count; ++i) {
        glyph_t glyphIndex = glyphs.at(i);
        GlyphData &gd = glyphData(glyphIndex);
        if (--gd.ref == 0 && !gd.texCoord.isNull())
            unusedGlyphs.insert(glyphIndex);
    }
    releaseGlyphs(unusedGlyphs);
}

void QSGDistanceFieldGlyphCache::update()
{
    m_populatingGlyphs.clear();

    if (m_pendingGlyphs.isEmpty())
        return;

    bool profileFrames = QSG_LOG_TIME_GLYPH().isDebugEnabled();
    if (profileFrames)
        qsg_render_timer.start();
    Q_QUICK_SG_PROFILE_START(QQuickProfiler::SceneGraphAdaptationLayerFrame);

    QList<QDistanceField> distanceFields;
    const int pendingGlyphsSize = m_pendingGlyphs.size();
    distanceFields.reserve(pendingGlyphsSize);
    for (int i = 0; i < pendingGlyphsSize; ++i) {
        GlyphData &gd = glyphData(m_pendingGlyphs.at(i));
        distanceFields.append(QDistanceField(gd.path,
                                             m_pendingGlyphs.at(i),
                                             m_doubleGlyphResolution));
        gd.path = QPainterPath(); // no longer needed, so release memory used by the painter path
    }

    qint64 renderTime = 0;
    int count = m_pendingGlyphs.size();
    if (profileFrames)
        renderTime = qsg_render_timer.nsecsElapsed();
    Q_QUICK_SG_PROFILE_RECORD(QQuickProfiler::SceneGraphAdaptationLayerFrame,
                              QQuickProfiler::SceneGraphAdaptationLayerGlyphRender);

    m_pendingGlyphs.reset();

    storeGlyphs(distanceFields);

#if defined(QSG_DISTANCEFIELD_CACHE_DEBUG)
    for (Texture texture : qAsConst(m_textures))
        saveTexture(texture.textureId, texture.size.width(), texture.size.height());
#endif

    if (QSG_LOG_TIME_GLYPH().isDebugEnabled()) {
        quint64 now = qsg_render_timer.elapsed();
        qCDebug(QSG_LOG_TIME_GLYPH,
                "distancefield: %d glyphs prepared in %dms, rendering=%d, upload=%d",
                count,
                (int) now,
                int(renderTime / 1000000),
                int((now - (renderTime / 1000000))));
    }
    Q_QUICK_SG_PROFILE_END_WITH_PAYLOAD(QQuickProfiler::SceneGraphAdaptationLayerFrame,
                                        QQuickProfiler::SceneGraphAdaptationLayerGlyphStore,
                                        (qint64)count);
}

void QSGDistanceFieldGlyphCache::setGlyphsPosition(const QList<GlyphPosition> &glyphs)
{
    QVector<quint32> invalidatedGlyphs;

    int count = glyphs.count();
    for (int i = 0; i < count; ++i) {
        GlyphPosition glyph = glyphs.at(i);
        GlyphData &gd = glyphData(glyph.glyph);

        if (!gd.texCoord.isNull())
            invalidatedGlyphs.append(glyph.glyph);

        gd.texCoord.xMargin = QT_DISTANCEFIELD_RADIUS(m_doubleGlyphResolution) / qreal(QT_DISTANCEFIELD_SCALE(m_doubleGlyphResolution));
        gd.texCoord.yMargin = QT_DISTANCEFIELD_RADIUS(m_doubleGlyphResolution) / qreal(QT_DISTANCEFIELD_SCALE(m_doubleGlyphResolution));
        gd.texCoord.x = glyph.position.x();
        gd.texCoord.y = glyph.position.y();
        gd.texCoord.width = gd.boundingRect.width();
        gd.texCoord.height = gd.boundingRect.height();
    }

    if (!invalidatedGlyphs.isEmpty()) {
        for (QSGDistanceFieldGlyphConsumerList::iterator iter = m_registeredNodes.begin(); iter != m_registeredNodes.end(); ++iter) {
            iter->invalidateGlyphs(invalidatedGlyphs);
        }
    }
}

void QSGDistanceFieldGlyphCache::registerOwnerElement(QQuickItem *ownerElement)
{
    Q_UNUSED(ownerElement);
}

void QSGDistanceFieldGlyphCache::unregisterOwnerElement(QQuickItem *ownerElement)
{
    Q_UNUSED(ownerElement);
}

void QSGDistanceFieldGlyphCache::processPendingGlyphs()
{
    /* Intentionally empty */
}

void QSGDistanceFieldGlyphCache::setGlyphsTexture(const QVector<glyph_t> &glyphs, const Texture &tex)
{
    int i = m_textures.indexOf(tex);
    if (i == -1) {
        m_textures.append(tex);
        i = m_textures.size() - 1;
    } else {
        m_textures[i].size = tex.size;
    }
    Texture *texture = &(m_textures[i]);

    QVector<quint32> invalidatedGlyphs;

    int count = glyphs.count();
    for (int j = 0; j < count; ++j) {
        glyph_t glyphIndex = glyphs.at(j);
        GlyphData &gd = glyphData(glyphIndex);
        if (gd.texture != &s_emptyTexture)
            invalidatedGlyphs.append(glyphIndex);
        gd.texture = texture;
    }

    if (!invalidatedGlyphs.isEmpty()) {
        for (QSGDistanceFieldGlyphConsumerList::iterator iter = m_registeredNodes.begin(); iter != m_registeredNodes.end(); ++iter) {
            iter->invalidateGlyphs(invalidatedGlyphs);
        }
    }
}

void QSGDistanceFieldGlyphCache::markGlyphsToRender(const QVector<glyph_t> &glyphs)
{
    int count = glyphs.count();
    for (int i = 0; i < count; ++i)
        m_pendingGlyphs.add(glyphs.at(i));
}

void QSGDistanceFieldGlyphCache::updateTexture(uint oldTex, uint newTex, const QSize &newTexSize)
{
    int count = m_textures.count();
    for (int i = 0; i < count; ++i) {
        Texture &tex = m_textures[i];
        if (tex.textureId == oldTex) {
            tex.textureId = newTex;
            tex.size = newTexSize;
            return;
        }
    }
}

void QSGDistanceFieldGlyphCache::updateRhiTexture(QRhiTexture *oldTex, QRhiTexture *newTex, const QSize &newTexSize)
{
    int count = m_textures.count();
    for (int i = 0; i < count; ++i) {
        Texture &tex = m_textures[i];
        if (tex.texture == oldTex) {
            tex.texture = newTex;
            tex.size = newTexSize;
            return;
        }
    }
}

#if defined(QSG_DISTANCEFIELD_CACHE_DEBUG)
#include <QtGui/qopenglfunctions.h>

void QSGDistanceFieldGlyphCache::saveTexture(GLuint textureId, int width, int height) const
{
    QOpenGLFunctions *functions = QOpenGLContext::currentContext()->functions();

    GLuint fboId;
    functions->glGenFramebuffers(1, &fboId);

    GLuint tmpTexture = 0;
    functions->glGenTextures(1, &tmpTexture);
    functions->glBindTexture(GL_TEXTURE_2D, tmpTexture);
    functions->glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, width, height, 0, GL_RGBA, GL_UNSIGNED_BYTE, NULL);
    functions->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
    functions->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
    functions->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
    functions->glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    functions->glBindTexture(GL_TEXTURE_2D, 0);

    functions->glBindFramebuffer(GL_FRAMEBUFFER_EXT, fboId);
    functions->glFramebufferTexture2D(GL_FRAMEBUFFER_EXT, GL_COLOR_ATTACHMENT0_EXT, GL_TEXTURE_2D,
                                      tmpTexture, 0);

    functions->glActiveTexture(GL_TEXTURE0);
    functions->glBindTexture(GL_TEXTURE_2D, textureId);

    functions->glDisable(GL_STENCIL_TEST);
    functions->glDisable(GL_DEPTH_TEST);
    functions->glDisable(GL_SCISSOR_TEST);
    functions->glDisable(GL_BLEND);

    GLfloat textureCoordinateArray[8];
    textureCoordinateArray[0] = 0.0f;
    textureCoordinateArray[1] = 0.0f;
    textureCoordinateArray[2] = 1.0f;
    textureCoordinateArray[3] = 0.0f;
    textureCoordinateArray[4] = 1.0f;
    textureCoordinateArray[5] = 1.0f;
    textureCoordinateArray[6] = 0.0f;
    textureCoordinateArray[7] = 1.0f;

    GLfloat vertexCoordinateArray[8];
    vertexCoordinateArray[0] = -1.0f;
    vertexCoordinateArray[1] = -1.0f;
    vertexCoordinateArray[2] =  1.0f;
    vertexCoordinateArray[3] = -1.0f;
    vertexCoordinateArray[4] =  1.0f;
    vertexCoordinateArray[5] =  1.0f;
    vertexCoordinateArray[6] = -1.0f;
    vertexCoordinateArray[7] =  1.0f;

    functions->glViewport(0, 0, width, height);
    functions->glVertexAttribPointer(0, 2, GL_FLOAT, GL_FALSE, 0, vertexCoordinateArray);
    functions->glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, textureCoordinateArray);

    {
        static const char *vertexShaderSource =
                "attribute vec4      vertexCoordsArray; \n"
                "attribute vec2      textureCoordArray; \n"
                "varying   vec2      textureCoords;     \n"
                "void main(void) \n"
                "{ \n"
                "    gl_Position = vertexCoordsArray;   \n"
                "    textureCoords = textureCoordArray; \n"
                "} \n";

        static const char *fragmentShaderSource =
                "varying   vec2      textureCoords; \n"
                "uniform   sampler2D         texture;       \n"
                "void main() \n"
                "{ \n"
                "    gl_FragColor = texture2D(texture, textureCoords); \n"
                "} \n";

        GLuint vertexShader = functions->glCreateShader(GL_VERTEX_SHADER);
        GLuint fragmentShader = functions->glCreateShader(GL_FRAGMENT_SHADER);

        if (vertexShader == 0 || fragmentShader == 0) {
            GLenum error = functions->glGetError();
            qWarning("QSGDistanceFieldGlyphCache::saveTexture: Failed to create shaders. (GL error: %x)",
                     error);
            return;
        }

        functions->glShaderSource(vertexShader, 1, &vertexShaderSource, NULL);
        functions->glShaderSource(fragmentShader, 1, &fragmentShaderSource, NULL);
        functions->glCompileShader(vertexShader);

        GLint len = 1;
        functions->glGetShaderiv(vertexShader, GL_INFO_LOG_LENGTH, &len);

        char infoLog[2048];
        functions->glGetShaderInfoLog(vertexShader, 2048, NULL, infoLog);
        if (qstrlen(infoLog) > 0)
            qWarning("Problems compiling vertex shader:\n %s", infoLog);

        functions->glCompileShader(fragmentShader);
        functions->glGetShaderInfoLog(fragmentShader, 2048, NULL, infoLog);
        if (qstrlen(infoLog) > 0)
            qWarning("Problems compiling fragment shader:\n %s", infoLog);

        GLuint shaderProgram = functions->glCreateProgram();
        functions->glAttachShader(shaderProgram, vertexShader);
        functions->glAttachShader(shaderProgram, fragmentShader);

        functions->glBindAttribLocation(shaderProgram, 0, "vertexCoordsArray");
        functions->glBindAttribLocation(shaderProgram, 1, "textureCoordArray");

        functions->glLinkProgram(shaderProgram);
        functions->glGetProgramInfoLog(shaderProgram, 2048, NULL, infoLog);
        if (qstrlen(infoLog) > 0)
            qWarning("Problems linking shaders:\n %s", infoLog);

        functions->glUseProgram(shaderProgram);
        functions->glEnableVertexAttribArray(0);
        functions->glEnableVertexAttribArray(1);

        int textureUniformLocation = functions->glGetUniformLocation(shaderProgram, "texture");
        functions->glUniform1i(textureUniformLocation, 0);
    }

    functions->glDrawArrays(GL_TRIANGLE_FAN, 0, 4);

    {
        GLenum error = functions->glGetError();
        if (error != GL_NO_ERROR)
            qWarning("glDrawArrays reported error 0x%x", error);
    }

    uchar *data = new uchar[width * height * 4];

    functions->glReadPixels(0, 0, width, height, GL_RGBA, GL_UNSIGNED_BYTE, data);

    QImage image(data, width, height, QImage::Format_ARGB32);

    QByteArray fileName = m_referenceFont.familyName().toLatin1() + '_' + QByteArray::number(textureId);
    fileName = fileName.replace('/', '_').replace(' ', '_') + ".png";

    image.save(QString::fromLocal8Bit(fileName));

    {
        GLenum error = functions->glGetError();
        if (error != GL_NO_ERROR)
            qWarning("glReadPixels reported error 0x%x", error);
    }

    functions->glDisableVertexAttribArray(0);
    functions->glDisableVertexAttribArray(1);

    functions->glDeleteFramebuffers(1, &fboId);
    functions->glDeleteTextures(1, &tmpTexture);

    delete[] data;
}
#endif

void QSGNodeVisitorEx::visitChildren(QSGNode *node)
{
    for (QSGNode *child = node->firstChild(); child; child = child->nextSibling()) {
        switch (child->type()) {
        case QSGNode::ClipNodeType: {
            QSGClipNode *c = static_cast<QSGClipNode*>(child);
            if (visit(c))
                visitChildren(c);
            endVisit(c);
            break;
        }
        case QSGNode::TransformNodeType: {
            QSGTransformNode *c = static_cast<QSGTransformNode*>(child);
            if (visit(c))
                visitChildren(c);
            endVisit(c);
            break;
        }
        case QSGNode::OpacityNodeType: {
            QSGOpacityNode *c = static_cast<QSGOpacityNode*>(child);
            if (visit(c))
                visitChildren(c);
            endVisit(c);
            break;
        }
        case QSGNode::GeometryNodeType: {
            if (child->flags() & QSGNode::IsVisitableNode) {
                QSGVisitableNode *v = static_cast<QSGVisitableNode*>(child);
                v->accept(this);
            } else {
                QSGGeometryNode *c = static_cast<QSGGeometryNode*>(child);
                if (visit(c))
                    visitChildren(c);
                endVisit(c);
            }
            break;
        }
        case QSGNode::RootNodeType: {
            QSGRootNode *root = static_cast<QSGRootNode*>(child);
            if (visit(root))
                visitChildren(root);
            endVisit(root);
            break;
        }
        case QSGNode::BasicNodeType: {
            visitChildren(child);
            break;
        }
        case QSGNode::RenderNodeType: {
            QSGRenderNode *r = static_cast<QSGRenderNode*>(child);
            if (visit(r))
                visitChildren(r);
            endVisit(r);
            break;
        }
        default:
            Q_UNREACHABLE();
            break;
        }
    }
}

#ifndef QT_NO_DEBUG_STREAM
QDebug operator<<(QDebug debug, const QSGGuiThreadShaderEffectManager::ShaderInfo::Variable &v)
{
    QDebugStateSaver saver(debug);
    debug.space();
    debug << v.name;
    switch (v.type) {
    case QSGGuiThreadShaderEffectManager::ShaderInfo::Constant:
        debug << "cvar" << "offset" << v.offset << "size" << v.size;
        break;
    case QSGGuiThreadShaderEffectManager::ShaderInfo::Sampler:
        debug << "sampler" << "bindpoint" << v.bindPoint;
        break;
    case QSGGuiThreadShaderEffectManager::ShaderInfo::Texture:
        debug << "texture" << "bindpoint" << v.bindPoint;
        break;
    default:
        break;
    }
    return debug;
}

QDebug operator<<(QDebug debug, const QSGShaderEffectNode::VariableData &vd)
{
    QDebugStateSaver saver(debug);
    debug.space();
    debug << vd.specialType;
    return debug;
}
#endif

/*!
    \internal
 */
QSGLayer::QSGLayer(QSGTexturePrivate &dd)
    : QSGDynamicTexture(dd)
{
}

QT_END_NAMESPACE

#include "moc_qsgadaptationlayer_p.cpp"
