/****************************************************************************
**
** 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)
    , 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"
