/****************************************************************************
**
** 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 "qquickpainteditem.h"
#include <private/qquickpainteditem_p.h>

#include <QtQuick/private/qsgdefaultpainternode_p.h>
#include <QtQuick/private/qsgcontext_p.h>
#include <private/qsgadaptationlayer_p.h>
#include <qsgtextureprovider.h>

#include <qmath.h>

QT_BEGIN_NAMESPACE

class QQuickPaintedItemTextureProvider : public QSGTextureProvider
{
public:
    QSGPainterNode *node;
    QSGTexture *texture() const override { return node ? node->texture() : nullptr; }
    void fireTextureChanged() { emit textureChanged(); }
};

/*!
    \class QQuickPaintedItem
    \brief The QQuickPaintedItem class provides a way to use the QPainter API in the
    QML Scene Graph.

    \inmodule QtQuick

    The QQuickPaintedItem makes it possible to use the QPainter API with the
    QML Scene Graph. It sets up a textured rectangle in the Scene Graph and
    uses a QPainter to paint onto the texture. The render target can be either
    a QImage or, when OpenGL is in use, a QOpenGLFramebufferObject. When the
    render target is a QImage, QPainter first renders into the image then the
    content is uploaded to the texture. When a QOpenGLFramebufferObject is
    used, QPainter paints directly onto the texture. Call update() to trigger a
    repaint.

    To enable QPainter to do anti-aliased rendering, use setAntialiasing().

    To write your own painted item, you first create a subclass of
    QQuickPaintedItem, and then start by implementing its only pure virtual
    public function: paint(), which implements the actual painting. The
    painting will be inside the rectangle spanning from 0,0 to
    width(),height().

    \note It important to understand the performance implications such items
    can incur. See QQuickPaintedItem::RenderTarget and
    QQuickPaintedItem::renderTarget.
*/

/*!
    \enum QQuickPaintedItem::RenderTarget

    This enum describes QQuickPaintedItem's render targets. The render target is the
    surface QPainter paints onto before the item is rendered on screen.

    \value Image The default; QPainter paints into a QImage using the raster paint engine.
    The image's content needs to be uploaded to graphics memory afterward, this operation
    can potentially be slow if the item is large. This render target allows high quality
    anti-aliasing and fast item resizing.

    \value FramebufferObject QPainter paints into a QOpenGLFramebufferObject using the GL
    paint engine. Painting can be faster as no texture upload is required, but anti-aliasing
    quality is not as good as if using an image. This render target allows faster rendering
    in some cases, but you should avoid using it if the item is resized often.

    \value InvertedYFramebufferObject Exactly as for FramebufferObject above, except once
    the painting is done, prior to rendering the painted image is flipped about the
    x-axis so that the top-most pixels are now at the bottom.  Since this is done with the
    OpenGL texture coordinates it is a much faster way to achieve this effect than using a
    painter transform.

    \sa setRenderTarget()
*/

/*!
    \enum QQuickPaintedItem::PerformanceHint

    This enum describes flags that you can enable to improve rendering
    performance in QQuickPaintedItem. By default, none of these flags are set.

    \value FastFBOResizing Resizing an FBO can be a costly operation on a few
    OpenGL driver implementations. To work around this, one can set this flag
    to let the QQuickPaintedItem allocate one large framebuffer object and
    instead draw into a subregion of it. This saves the resize at the cost of
    using more memory. Please note that this is not a common problem.

*/

/*!
    \internal
*/
QQuickPaintedItemPrivate::QQuickPaintedItemPrivate()
    : QQuickItemPrivate()
    , contentsScale(1.0)
    , fillColor(Qt::transparent)
    , renderTarget(QQuickPaintedItem::Image)
    , performanceHints(nullptr)
    , opaquePainting(false)
    , antialiasing(false)
    , mipmap(false)
    , textureProvider(nullptr)
    , node(nullptr)
{
}

/*!
    Constructs a QQuickPaintedItem with the given \a parent item.
 */
QQuickPaintedItem::QQuickPaintedItem(QQuickItem *parent)
    : QQuickItem(*(new QQuickPaintedItemPrivate), parent)
{
    setFlag(ItemHasContents);
}

/*!
    \internal
*/
QQuickPaintedItem::QQuickPaintedItem(QQuickPaintedItemPrivate &dd, QQuickItem *parent)
    : QQuickItem(dd, parent)
{
    setFlag(ItemHasContents);
}

/*!
    Destroys the QQuickPaintedItem.
*/
QQuickPaintedItem::~QQuickPaintedItem()
{
    Q_D(QQuickPaintedItem);
    if (d->textureProvider)
        QQuickWindowQObjectCleanupJob::schedule(window(), d->textureProvider);
}

/*!
    Schedules a redraw of the area covered by \a rect in this item. You can call this function
    whenever your item needs to be redrawn, such as if it changes appearance or size.

    This function does not cause an immediate paint; instead it schedules a paint request that
    is processed by the QML Scene Graph when the next frame is rendered. The item will only be
    redrawn if it is visible.

    \sa paint()
*/
void QQuickPaintedItem::update(const QRect &rect)
{
    Q_D(QQuickPaintedItem);

    if (rect.isNull() && !d->dirtyRect.isNull())
        d->dirtyRect = contentsBoundingRect().toAlignedRect();
    else
        d->dirtyRect |= (contentsBoundingRect() & rect).toAlignedRect();
    QQuickItem::update();
}

/*!
    Returns true if this item is opaque; otherwise, false is returned.

    By default, painted items are not opaque.

    \sa setOpaquePainting()
*/
bool QQuickPaintedItem::opaquePainting() const
{
    Q_D(const QQuickPaintedItem);
    return d->opaquePainting;
}

/*!
    If \a opaque is true, the item is opaque; otherwise, it is considered as translucent.

    Opaque items are not blended with the rest of the scene, you should set this to true
    if the content of the item is opaque to speed up rendering.

    By default, painted items are not opaque.

    \sa opaquePainting()
*/
void QQuickPaintedItem::setOpaquePainting(bool opaque)
{
    Q_D(QQuickPaintedItem);

    if (d->opaquePainting == opaque)
        return;

    d->opaquePainting = opaque;
    QQuickItem::update();
}

/*!
    Returns true if antialiased painting is enabled; otherwise, false is returned.

    By default, antialiasing is not enabled.

    \sa setAntialiasing()
*/
bool QQuickPaintedItem::antialiasing() const
{
    Q_D(const QQuickPaintedItem);
    return d->antialiasing;
}

/*!
    If \a enable is true, antialiased painting is enabled.

    By default, antialiasing is not enabled.

    \sa antialiasing()
*/
void QQuickPaintedItem::setAntialiasing(bool enable)
{
    Q_D(QQuickPaintedItem);

    if (d->antialiasing == enable)
        return;

    d->antialiasing = enable;
    update();
}

/*!
    Returns true if mipmaps are enabled; otherwise, false is returned.

    By default, mipmapping is not enabled.

    \sa setMipmap()
*/
bool QQuickPaintedItem::mipmap() const
{
    Q_D(const QQuickPaintedItem);
    return d->mipmap;
}

/*!
    If \a enable is true, mipmapping is enabled on the associated texture.

    Mipmapping increases rendering speed and reduces aliasing artifacts when the item is
    scaled down.

    By default, mipmapping is not enabled.

    \sa mipmap()
*/
void QQuickPaintedItem::setMipmap(bool enable)
{
    Q_D(QQuickPaintedItem);

    if (d->mipmap == enable)
        return;

    d->mipmap = enable;
    update();
}

/*!
    Returns the performance hints.

    By default, no performance hint is enabled.

    \sa setPerformanceHint(), setPerformanceHints()
*/
QQuickPaintedItem::PerformanceHints QQuickPaintedItem::performanceHints() const
{
    Q_D(const QQuickPaintedItem);
    return d->performanceHints;
}

/*!
    Sets the given performance \a hint on the item if \a enabled is true;
    otherwise clears the performance hint.

    By default, no performance hint is enabled/

    \sa setPerformanceHints(), performanceHints()
*/
void QQuickPaintedItem::setPerformanceHint(QQuickPaintedItem::PerformanceHint hint, bool enabled)
{
    Q_D(QQuickPaintedItem);
    PerformanceHints oldHints = d->performanceHints;
    if (enabled)
        d->performanceHints |= hint;
    else
        d->performanceHints &= ~hint;
    if (oldHints != d->performanceHints)
       update();
}

/*!
    Sets the performance hints to \a hints

    By default, no performance hint is enabled/

    \sa setPerformanceHint(), performanceHints()
*/
void QQuickPaintedItem::setPerformanceHints(QQuickPaintedItem::PerformanceHints hints)
{
    Q_D(QQuickPaintedItem);
    if (d->performanceHints == hints)
        return;
    d->performanceHints = hints;
    update();
}

QSize QQuickPaintedItem::textureSize() const
{
    Q_D(const QQuickPaintedItem);
    return d->textureSize;
}

/*!
    \property QQuickPaintedItem::textureSize

    \brief Defines the size of the texture.

    Changing the texture's size does not affect the coordinate system used in
    paint(). A scale factor is instead applied so painting should still happen
    inside 0,0 to width(),height().

    By default, the texture size will have the same size as this item.

    \note If the item is on a window with a device pixel ratio different from
    1, this scale factor will be implicitly applied to the texture size.

 */
void QQuickPaintedItem::setTextureSize(const QSize &size)
{
    Q_D(QQuickPaintedItem);
    if (d->textureSize == size)
        return;
    d->textureSize = size;
    emit textureSizeChanged();
}

#if QT_VERSION >= 0x060000
#warning "Remove: QQuickPaintedItem::contentsBoundingRect, contentsScale, contentsSize. Also remove them from qsgadaptationlayer_p.h and qsgdefaultpainternode.h/cpp."
#endif

/*!
    \obsolete

    This function is provided for compatibility, use size in combination
    with textureSize to decide the size of what you are drawing.

    \sa width(), height(), textureSize()
*/
QRectF QQuickPaintedItem::contentsBoundingRect() const
{
    Q_D(const QQuickPaintedItem);

    qreal w = d->width;
    QSizeF sz = d->contentsSize * d->contentsScale;
    if (w < sz.width())
        w = sz.width();
    qreal h = d->height;
    if (h < sz.height())
        h = sz.height();

    return QRectF(0, 0, w, h);
}

/*!
    \property QQuickPaintedItem::contentsSize
    \brief Obsolete method for setting the contents size.
    \obsolete

    This function is provided for compatibility, use size in combination
    with textureSize to decide the size of what you are drawing.

    \sa width(), height(), textureSize()
*/
QSize QQuickPaintedItem::contentsSize() const
{
    Q_D(const QQuickPaintedItem);
    return d->contentsSize;
}

void QQuickPaintedItem::setContentsSize(const QSize &size)
{
    Q_D(QQuickPaintedItem);

    if (d->contentsSize == size)
        return;

    d->contentsSize = size;
    update();

    emit contentsSizeChanged();
}

/*!
    \obsolete
    This convenience function is equivalent to calling setContentsSize(QSize()).
*/
void QQuickPaintedItem::resetContentsSize()
{
    setContentsSize(QSize());
}

/*!
    \property QQuickPaintedItem::contentsScale
    \brief Obsolete method for scaling the contents.
    \obsolete

    This function is provided for compatibility, use size() in combination
    with textureSize() to decide the size of what you are drawing.

    \sa width(), height(), textureSize()
*/
qreal QQuickPaintedItem::contentsScale() const
{
    Q_D(const QQuickPaintedItem);
    return d->contentsScale;
}

void QQuickPaintedItem::setContentsScale(qreal scale)
{
    Q_D(QQuickPaintedItem);

    if (d->contentsScale == scale)
        return;

    d->contentsScale = scale;
    update();

    emit contentsScaleChanged();
}

/*!
    \property QQuickPaintedItem::fillColor
    \brief The item's background fill color.

    By default, the fill color is set to Qt::transparent.
*/
QColor QQuickPaintedItem::fillColor() const
{
    Q_D(const QQuickPaintedItem);
    return d->fillColor;
}

void QQuickPaintedItem::setFillColor(const QColor &c)
{
    Q_D(QQuickPaintedItem);

    if (d->fillColor == c)
        return;

    d->fillColor = c;
    update();

    emit fillColorChanged();
}

/*!
    \property QQuickPaintedItem::renderTarget
    \brief The item's render target.

    This property defines which render target the QPainter renders into, it can be either
    QQuickPaintedItem::Image, QQuickPaintedItem::FramebufferObject or QQuickPaintedItem::InvertedYFramebufferObject.

    Each has certain benefits, typically performance versus quality. Using a framebuffer
    object avoids a costly upload of the image contents to the texture in graphics memory,
    while using an image enables high quality anti-aliasing.

    \warning Resizing a framebuffer object is a costly operation, avoid using
    the QQuickPaintedItem::FramebufferObject render target if the item gets resized often.

    By default, the render target is QQuickPaintedItem::Image.

    \note Some Qt Quick backends may not support all render target options. For
    example, it is likely that non-OpenGL backends will lack support for
    QQuickPaintedItem::FramebufferObject and
    QQuickPaintedItem::InvertedYFramebufferObject. Requesting these will then
    be ignored.
*/
QQuickPaintedItem::RenderTarget QQuickPaintedItem::renderTarget() const
{
    Q_D(const QQuickPaintedItem);
    return d->renderTarget;
}

void QQuickPaintedItem::setRenderTarget(RenderTarget target)
{
    Q_D(QQuickPaintedItem);

    if (d->renderTarget == target)
        return;

    d->renderTarget = target;
    update();

    emit renderTargetChanged();
}

/*!
    \fn virtual void QQuickPaintedItem::paint(QPainter *painter) = 0

    This function, which is usually called by the QML Scene Graph, paints the
    contents of an item in local coordinates.

    The underlying texture will have a size defined by textureSize when set,
    or the item's size, multiplied by the window's device pixel ratio.

    The function is called after the item has been filled with the fillColor.

    Reimplement this function in a QQuickPaintedItem subclass to provide the
    item's painting implementation, using \a painter.

    \note The QML Scene Graph uses two separate threads, the main thread does things such as
    processing events or updating animations while a second thread does the actual OpenGL rendering.
    As a consequence, paint() is not called from the main GUI thread but from the GL enabled
    renderer thread. At the moment paint() is called, the GUI thread is blocked and this is
    therefore thread-safe.

    \warning Extreme caution must be used when creating QObjects, emitting signals, starting
    timers and similar inside this function as these will have affinity to the rendering thread.

    \sa width(), height(), textureSize
*/

/*!
    \reimp
*/
QSGNode *QQuickPaintedItem::updatePaintNode(QSGNode *oldNode, UpdatePaintNodeData *data)
{
    Q_UNUSED(data);
    Q_D(QQuickPaintedItem);

    if (width() <= 0 || height() <= 0) {
        delete oldNode;
        if (d->textureProvider) {
            d->textureProvider->node = nullptr;
            d->textureProvider->fireTextureChanged();
        }
        return nullptr;
    }

    QSGPainterNode *node = static_cast<QSGPainterNode *>(oldNode);
    if (!node) {
        node = d->sceneGraphContext()->createPainterNode(this);
        d->node = node;
    }

    bool hasTextureSize = d->textureSize.width() > 0 && d->textureSize.height() > 0;

    // Use the compat mode if any of the compat things are set and
    // textureSize is 0x0.
    if (!hasTextureSize
        && (d->contentsScale != 1
            || (d->contentsSize.width() > 0 && d->contentsSize.height() > 0))) {
        QRectF br = contentsBoundingRect();
        node->setContentsScale(d->contentsScale);
        QSize size = QSize(qRound(br.width()), qRound(br.height()));
        node->setSize(size);
        node->setTextureSize(size);
    } else {
        // The default, use textureSize or item's size * device pixel ratio
        node->setContentsScale(1);
        QSize itemSize(qRound(width()), qRound(height()));
        node->setSize(itemSize);
        QSize textureSize = (hasTextureSize ? d->textureSize : itemSize)
                            * window()->effectiveDevicePixelRatio();
        node->setTextureSize(textureSize);
    }

    node->setPreferredRenderTarget(d->renderTarget);
    node->setFastFBOResizing(d->performanceHints & FastFBOResizing);
    node->setSmoothPainting(d->antialiasing);
    node->setLinearFiltering(d->smooth);
    node->setMipmapping(d->mipmap);
    node->setOpaquePainting(d->opaquePainting);
    node->setFillColor(d->fillColor);
    node->setDirty(d->dirtyRect);
    node->update();

    d->dirtyRect = QRect();

    if (d->textureProvider) {
        d->textureProvider->node = node;
        d->textureProvider->fireTextureChanged();
    }

    return node;
}

/*!
   \reimp
*/
void QQuickPaintedItem::releaseResources()
{
    Q_D(QQuickPaintedItem);
    if (d->textureProvider) {
        QQuickWindowQObjectCleanupJob::schedule(window(), d->textureProvider);
        d->textureProvider = nullptr;
    }
    d->node = nullptr; // Managed by the scene graph, just clear the pointer.
}

void QQuickPaintedItem::invalidateSceneGraph()
{
    Q_D(QQuickPaintedItem);
    delete d->textureProvider;
    d->textureProvider = nullptr;
    d->node = nullptr; // Managed by the scene graph, just clear the pointer
}

/*!
   \reimp
*/
bool QQuickPaintedItem::isTextureProvider() const
{
    return true;
}

/*!
   \reimp
*/
QSGTextureProvider *QQuickPaintedItem::textureProvider() const
{
    // When Item::layer::enabled == true, QQuickItem will be a texture
    // provider. In this case we should prefer to return the layer rather
    // than the image itself. The layer will include any children and any
    // the image's wrap and fill mode.
    if (QQuickItem::isTextureProvider())
        return QQuickItem::textureProvider();

    Q_D(const QQuickPaintedItem);
#if QT_CONFIG(opengl)
    QQuickWindow *w = window();
    if (!w || !w->openglContext() || QThread::currentThread() != w->openglContext()->thread()) {
        qWarning("QQuickPaintedItem::textureProvider: can only be queried on the rendering thread of an exposed window");
        return nullptr;
    }
#endif
    if (!d->textureProvider)
        d->textureProvider = new QQuickPaintedItemTextureProvider();
    d->textureProvider->node = d->node;
    return d->textureProvider;
}


/*!
   \reimp
*/
void QQuickPaintedItem::itemChange(ItemChange change, const ItemChangeData &value)
{
    if (change == ItemDevicePixelRatioHasChanged)
        update();
    QQuickItem::itemChange(change, value);
}

QT_END_NAMESPACE

#include "moc_qquickpainteditem.cpp"
