/****************************************************************************
**
** 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 <QtQuick/private/qsgcontext_p.h>
#include <QtQuick/private/qsgtexture_p.h>
#include <QtQuick/private/qquickpixmapcache_p.h>
#include <QtQuick/private/qsgadaptationlayer_p.h>

#include <QGuiApplication>
#include <QScreen>
#include <QQuickWindow>

#include <private/qqmlglobal_p.h>

#include <QtQuick/private/qsgtexture_p.h>
#include <QtGui/private/qguiapplication_p.h>
#include <QtCore/private/qabstractanimation_p.h>

#include <private/qobject_p.h>
#include <qmutex.h>

/*
    Comments about this class from Gunnar:

    The QSGContext class is right now two things.. The first is the
    adaptation layer and central storage ground for all the things
    in the scene graph, like textures and materials. This part really
    belongs inside the scene graph coreapi.

    The other part is the QML adaptation classes, like how to implement
    rectangle nodes. This is not part of the scene graph core API, but
    more part of the QML adaptation of scene graph.

    If we ever move the scene graph core API into its own thing, this class
    needs to be split in two. Right now its one because we're lazy when it comes
    to defining plugin interfaces..
*/

QT_BEGIN_NAMESPACE

// Used for very high-level info about the renderering and gl context
// Includes GL_VERSION, type of render loop, atlas size, etc.
Q_LOGGING_CATEGORY(QSG_LOG_INFO,                "qt.scenegraph.general")

// Used to debug the renderloop logic. Primarily useful for platform integrators
// and when investigating the render loop logic.
Q_LOGGING_CATEGORY(QSG_LOG_RENDERLOOP,          "qt.scenegraph.renderloop")


// GLSL shader compilation
Q_LOGGING_CATEGORY(QSG_LOG_TIME_COMPILATION,    "qt.scenegraph.time.compilation")

// polish, animations, sync, render and swap in the render loop
Q_LOGGING_CATEGORY(QSG_LOG_TIME_RENDERLOOP,     "qt.scenegraph.time.renderloop")

// Texture uploads and swizzling
Q_LOGGING_CATEGORY(QSG_LOG_TIME_TEXTURE,        "qt.scenegraph.time.texture")

// Glyph preparation (only for distance fields atm)
Q_LOGGING_CATEGORY(QSG_LOG_TIME_GLYPH,          "qt.scenegraph.time.glyph")

// Timing inside the renderer base class
Q_LOGGING_CATEGORY(QSG_LOG_TIME_RENDERER,       "qt.scenegraph.time.renderer")

bool qsg_useConsistentTiming()
{
    int use = -1;
    if (use < 0) {
        use = !qEnvironmentVariableIsEmpty("QSG_FIXED_ANIMATION_STEP") && qgetenv("QSG_FIXED_ANIMATION_STEP") != "no"
            ? 1 : 0;
        qCDebug(QSG_LOG_INFO, "Using %s", bool(use) ? "fixed animation steps" : "sg animation driver");
    }
    return bool(use);
}

class QSGAnimationDriver : public QAnimationDriver
{
    Q_OBJECT
public:
    enum Mode {
        VSyncMode,
        TimerMode
    };

    QSGAnimationDriver(QObject *parent)
        : QAnimationDriver(parent)
        , m_time(0)
        , m_vsync(0)
        , m_mode(VSyncMode)
        , m_lag(0)
        , m_bad(0)
        , m_good(0)
    {
        QScreen *screen = QGuiApplication::primaryScreen();
        if (screen && !qsg_useConsistentTiming()) {
            m_vsync = 1000.0 / screen->refreshRate();
            if (m_vsync <= 0)
                m_mode = TimerMode;
        } else {
            m_mode = TimerMode;
            if (qsg_useConsistentTiming())
                QUnifiedTimer::instance(true)->setConsistentTiming(true);
        }
        if (m_mode == VSyncMode)
            qCDebug(QSG_LOG_INFO, "Animation Driver: using vsync: %.2f ms", m_vsync);
        else
            qCDebug(QSG_LOG_INFO, "Animation Driver: using walltime");
    }

    void start() override
    {
        m_time = 0;
        m_timer.start();
        m_wallTime.restart();
        QAnimationDriver::start();
    }

    qint64 elapsed() const override
    {
        return m_mode == VSyncMode
                ? qint64(m_time)
                : qint64(m_time) + m_wallTime.elapsed();
    }

    void advance() override
    {
        qint64 delta = m_timer.restart();

        if (m_mode == VSyncMode) {
            // If a frame is skipped, either because rendering was slow or because
            // the QML was slow, we accept it and continue advancing with a single
            // vsync tick. The reason for this is that by the time we notice this
            // on the GUI thread, the temporal distortion has already gone to screen
            // and by catching up, we will introduce a second distortion which will
            // worse. We accept that the animation time falls behind wall time because
            // it comes out looking better.
            // Only when multiple bad frames are hit in a row, do we consider
            // switching. A few really bad frames and we switch right away. For frames
            // just above the vsync delta, we tolerate a bit more since a buffered
            // driver can have vsync deltas on the form: 4, 21, 21, 2, 23, 16, and
            // still manage to put the frames to screen at 16 ms intervals. In addition
            // to that, we tolerate a 25% margin of error on the value of m_vsync
            // reported from the system as this value is often not precise.

            m_time += m_vsync;

            if (delta > m_vsync * 1.25) {
                m_lag += (delta / m_vsync);
                m_bad++;
               // We tolerate one bad frame without resorting to timer based. This is
                // done to cope with a slow loader frame followed by smooth animation.
                // However, on the second frame with massive lag, we switch.
                if (m_lag > 10 && m_bad > 2) {
                    m_mode = TimerMode;
                    qCDebug(QSG_LOG_INFO, "animation driver switched to timer mode");
                    m_wallTime.restart();
                }
            } else {
                m_lag = 0;
                m_bad = 0;
            }

        } else {
            if (delta < 1.25 * m_vsync) {
                ++m_good;
            } else {
                m_good = 0;
            }

            // We've been solid for a while, switch back to vsync mode. Tolerance
            // for switching back is lower than switching to timer mode, as we
            // want to stay in vsync mode as much as possible.
            if (m_good > 10 && !qsg_useConsistentTiming()) {
                m_time = elapsed();
                m_mode = VSyncMode;
                m_bad = 0;
                m_lag = 0;
                qCDebug(QSG_LOG_INFO, "animation driver switched to vsync mode");
            }
        }

        advanceAnimation();
    }

    double m_time;
    double m_vsync;
    Mode m_mode;
    QElapsedTimer m_timer;
    QElapsedTimer m_wallTime;
    double m_lag;
    int m_bad;
    int m_good;
};

/*!
    \class QSGContext

    \brief The QSGContext holds the scene graph entry points for one QML engine.

    The context is not ready for use until it has a QOpenGLContext. Once that happens,
    the scene graph population can start.

    \internal
 */

QSGContext::QSGContext(QObject *parent) :
    QObject(parent)
{
}

QSGContext::~QSGContext()
{
}

void QSGContext::renderContextInitialized(QSGRenderContext *)
{
}

void QSGContext::renderContextInvalidated(QSGRenderContext *)
{
}


/*!
    Convenience factory function for creating a colored rectangle with the given geometry.
 */
QSGInternalRectangleNode *QSGContext::createInternalRectangleNode(const QRectF &rect, const QColor &c)
{
    QSGInternalRectangleNode *node = createInternalRectangleNode();
    node->setRect(rect);
    node->setColor(c);
    node->update();
    return node;
}

/*!
    Creates a new shader effect helper instance. This function is called on the
    gui thread, unlike the others. This is necessary in order to provide
    adaptable, backend-specific shader effect functionality to the gui thread too.
 */
QSGGuiThreadShaderEffectManager *QSGContext::createGuiThreadShaderEffectManager()
{
    return nullptr;
}

/*!
    Creates a new shader effect node. The default of returning nullptr is
    valid as long as the backend does not claim SupportsShaderEffectNode or
    ignoring ShaderEffect elements is acceptable.
 */
QSGShaderEffectNode *QSGContext::createShaderEffectNode(QSGRenderContext *, QSGGuiThreadShaderEffectManager *)
{
    return nullptr;
}

/*!
    Creates a new animation driver.
 */
QAnimationDriver *QSGContext::createAnimationDriver(QObject *parent)
{
    return new QSGAnimationDriver(parent);
}

QSize QSGContext::minimumFBOSize() const
{
    return QSize(1, 1);
}

/*!
    Returns a pointer to the (presumably) global renderer interface.

    \note This function may be called on the gui thread in order to get access
    to QSGRendererInterface::graphicsApi() and other getters.

    \note it is expected that the simple queries (graphicsApi, shaderType,
    etc.) are available regardless of the render context validity (i.e.
    scenegraph status). This does not apply to engine-specific getters like
    getResource(). In the end this means that this function must always return
    a valid object in subclasses, even when renderContext->isValid() is false.
    The typical pattern is to implement the QSGRendererInterface in the
    QSGContext or QSGRenderContext subclass itself, whichever is more suitable.
 */
QSGRendererInterface *QSGContext::rendererInterface(QSGRenderContext *renderContext)
{
    Q_UNUSED(renderContext);
    qWarning("QSGRendererInterface not implemented");
    return nullptr;
}

QSGRenderContext::QSGRenderContext(QSGContext *context)
    : m_sg(context)
{
}

QSGRenderContext::~QSGRenderContext()
{
}

void QSGRenderContext::initialize(const InitParams *params)
{
    Q_UNUSED(params);
}

void QSGRenderContext::invalidate()
{
}

void QSGRenderContext::prepareSync(qreal devicePixelRatio)
{
    Q_UNUSED(devicePixelRatio);
}

void QSGRenderContext::beginNextFrame(QSGRenderer *renderer,
                                      RenderPassCallback mainPassRecordingStart,
                                      RenderPassCallback mainPassRecordingEnd,
                                      void *callbackUserData)
{
    Q_UNUSED(renderer);
    Q_UNUSED(mainPassRecordingStart);
    Q_UNUSED(mainPassRecordingEnd);
    Q_UNUSED(callbackUserData);
}

void QSGRenderContext::endNextFrame(QSGRenderer *renderer)
{
    Q_UNUSED(renderer);
}

void QSGRenderContext::beginNextRhiFrame(QSGRenderer *renderer,
                                         QRhiRenderTarget *rt, QRhiRenderPassDescriptor *rp, QRhiCommandBuffer *cb,
                                         RenderPassCallback mainPassRecordingStart,
                                         RenderPassCallback mainPassRecordingEnd,
                                         void *callbackUserData)
{
    Q_UNUSED(renderer);
    Q_UNUSED(rt);
    Q_UNUSED(rp);
    Q_UNUSED(cb);
    Q_UNUSED(mainPassRecordingStart);
    Q_UNUSED(mainPassRecordingEnd);
    Q_UNUSED(callbackUserData);
}

void QSGRenderContext::renderNextRhiFrame(QSGRenderer *renderer)
{
    Q_UNUSED(renderer);
}

void QSGRenderContext::endNextRhiFrame(QSGRenderer *renderer)
{
    Q_UNUSED(renderer);
}

void QSGRenderContext::endSync()
{
    qDeleteAll(m_texturesToDelete);
    m_texturesToDelete.clear();
}

/*!
    Factory function for scene graph backends of the distance-field glyph cache.
 */
QSGDistanceFieldGlyphCache *QSGRenderContext::distanceFieldGlyphCache(const QRawFont &)
{
    return nullptr;
}


void QSGRenderContext::registerFontengineForCleanup(QFontEngine *engine)
{
    engine->ref.ref();
    m_fontEnginesToClean << engine;
}

QRhi *QSGRenderContext::rhi() const
{
    return nullptr;
}

/*!
    Factory function for the scene graph renderers.

    The renderers are used for the toplevel renderer and once for every
    QQuickShaderEffectSource used in the QML scene.
 */

QSGTexture *QSGRenderContext::textureForFactory(QQuickTextureFactory *factory, QQuickWindow *window)
{
    if (!factory)
        return nullptr;

    m_mutex.lock();
    QSGTexture *texture = m_textures.value(factory);
    m_mutex.unlock();

    if (!texture) {
        texture = factory->createTexture(window);

        m_mutex.lock();
        m_textures.insert(factory, texture);
        m_mutex.unlock();

        connect(factory, SIGNAL(destroyed(QObject*)), this, SLOT(textureFactoryDestroyed(QObject*)), Qt::DirectConnection);
    }
    return texture;
}

void QSGRenderContext::textureFactoryDestroyed(QObject *o)
{
    m_mutex.lock();
    m_texturesToDelete << m_textures.take(o);
    m_mutex.unlock();
}

/*!
    Return the texture corresponding to a texture factory.

    This may optionally manipulate the texture in some way; for example by returning
    an atlased texture.

    This function is not a replacement for textureForFactory; both should be used
    for a single texture (this might atlas, while the other might cache).
*/
QSGTexture *QSGRenderContext::compressedTextureForFactory(const QSGCompressedTextureFactory *) const
{
    return nullptr;
}

#include "qsgcontext.moc"
#include "moc_qsgcontext_p.cpp"

QT_END_NAMESPACE
