/****************************************************************************
**
** Copyright (C) 2011 Nokia Corporation and/or its subsidiary(-ies).
** All rights reserved.
** Contact: Nokia Corporation (qt-info@nokia.com)
**
** This file is part of the QtOpenVG module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** GNU Lesser General Public License Usage
** This file may be used under the terms of the GNU Lesser General Public
** License version 2.1 as published by the Free Software Foundation and
** appearing in the file LICENSE.LGPL included in the packaging of this
** file. Please review the following information to ensure the GNU Lesser
** General Public License version 2.1 requirements will be met:
** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html.
**
** In addition, as a special exception, Nokia gives you certain additional
** rights. These rights are described in the Nokia Qt LGPL Exception
** version 1.1, included in the file LGPL_EXCEPTION.txt in this package.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU General
** Public License version 3.0 as published by the Free Software Foundation
** and appearing in the file LICENSE.GPL included in the packaging of this
** file. Please review the following information to ensure the GNU General
** Public License version 3.0 requirements will be met:
** http://www.gnu.org/copyleft/gpl.html.
**
** Other Usage
** Alternatively, this file may be used in accordance with the terms and
** conditions contained in a signed written agreement between you and Nokia.
**
**
**
**
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qpixmapdata_vg_p.h"
#include "qpaintengine_vg_p.h"
#include <QtGui/private/qdrawhelper_p.h>
#if !defined(QT_NO_EGL)
#include <QtGui/private/qegl_p.h>
#endif
#include "qvg_p.h"
#include "qvgimagepool_p.h"
#include <QBuffer>
#include <QImageReader>
#include <QtGui/private/qimage_p.h>
#include <QtGui/private/qnativeimagehandleprovider_p.h>

QT_BEGIN_NAMESPACE

static int qt_vg_pixmap_serial = 0;

QVGPixmapData::QVGPixmapData(PixelType type)
    : QPixmapData(type, OpenVGClass)
{
    Q_ASSERT(type == QPixmapData::PixmapType);
    vgImage = VG_INVALID_HANDLE;
    vgImageOpacity = VG_INVALID_HANDLE;
    cachedOpacity = 1.0f;
    recreate = true;
    inImagePool = false;
    inLRU = false;
    failedToAlloc = false;
#if defined(Q_OS_SYMBIAN)
    nativeImageHandleProvider = 0;
    nativeImageHandle = 0;
#endif
#if !defined(QT_NO_EGL)
    context = 0;
    qt_vg_register_pixmap(this);
#endif
    updateSerial();
}

QVGPixmapData::~QVGPixmapData()
{
    destroyImageAndContext();
#if !defined(QT_NO_EGL)
    qt_vg_unregister_pixmap(this);
#endif
}

void QVGPixmapData::destroyImages()
{
    if (inImagePool) {
        QVGImagePool *pool = QVGImagePool::instance();
        if (vgImage != VG_INVALID_HANDLE)
            pool->releaseImage(this, vgImage);
        if (vgImageOpacity != VG_INVALID_HANDLE)
            pool->releaseImage(this, vgImageOpacity);
    } else {
        if (vgImage != VG_INVALID_HANDLE)
            vgDestroyImage(vgImage);
        if (vgImageOpacity != VG_INVALID_HANDLE)
            vgDestroyImage(vgImageOpacity);
    }
    vgImage = VG_INVALID_HANDLE;
    vgImageOpacity = VG_INVALID_HANDLE;
    inImagePool = false;

#if defined(Q_OS_SYMBIAN)
    releaseNativeImageHandle();
#endif
}

void QVGPixmapData::destroyImageAndContext()
{
    if (vgImage != VG_INVALID_HANDLE) {
        // We need to have a context current to destroy the image.
#if !defined(QT_NO_EGL)
        if (!context)
            context = qt_vg_create_context(0, QInternal::Pixmap);
        if (context->isCurrent()) {
            destroyImages();
        } else {
            // We don't currently have a widget surface active, but we
            // need a surface to make the context current.  So use the
            // shared pbuffer surface instead.
            context->makeCurrent(qt_vg_shared_surface());
            destroyImages();
            context->lazyDoneCurrent();
        }
#else
        destroyImages();
#endif
    } else {
#if defined(Q_OS_SYMBIAN)
        releaseNativeImageHandle();
#endif
    }
#if !defined(QT_NO_EGL)
    if (context) {
        qt_vg_destroy_context(context, QInternal::Pixmap);
        context = 0;
    }
#endif
    recreate = true;
}

QPixmapData *QVGPixmapData::createCompatiblePixmapData() const
{
    return new QVGPixmapData(pixelType());
}

bool QVGPixmapData::isValid() const
{
    return (w > 0 && h > 0);
}

void QVGPixmapData::updateSerial()
{
    setSerialNumber(++qt_vg_pixmap_serial);
}

void QVGPixmapData::resize(int wid, int ht)
{
    if (w == wid && h == ht) {
        updateSerial();
        return;
    }

    w = wid;
    h = ht;
    d = 32; // We always use ARGB_Premultiplied for VG pixmaps.
    is_null = (w <= 0 || h <= 0);
    source = QVolatileImage();
    recreate = true;

    updateSerial();
}

void QVGPixmapData::fromImage(const QImage &image, Qt::ImageConversionFlags flags)
{
    if (image.isNull())
        return;

    QImage img = image;
    createPixmapForImage(img, flags, false);
}

void QVGPixmapData::fromImageReader(QImageReader *imageReader,
                                 Qt::ImageConversionFlags flags)
{
    QImage image = imageReader->read();
    if (image.isNull())
        return;

    createPixmapForImage(image, flags, true);
}

bool QVGPixmapData::fromFile(const QString &filename, const char *format,
                          Qt::ImageConversionFlags flags)
{
    QImage image = QImageReader(filename, format).read();
    if (image.isNull())
        return false;

    createPixmapForImage(image, flags, true);

    return !isNull();
}

bool QVGPixmapData::fromData(const uchar *buffer, uint len, const char *format,
                      Qt::ImageConversionFlags flags)
{
    QByteArray a = QByteArray::fromRawData(reinterpret_cast<const char *>(buffer), len);
    QBuffer b(&a);
    b.open(QIODevice::ReadOnly);
    QImage image = QImageReader(&b, format).read();
    if (image.isNull())
        return false;

    createPixmapForImage(image, flags, true);

    return !isNull();
}

QImage::Format QVGPixmapData::idealFormat(QImage *image, Qt::ImageConversionFlags flags) const
{
    QImage::Format format = sourceFormat();
    int d = image->depth();
    if (d == 1 || d == 16 || d == 24 || (d == 32 && !image->hasAlphaChannel()))
        format = QImage::Format_RGB32;
    else if (!(flags & Qt::NoOpaqueDetection) && image->data_ptr()->checkForAlphaPixels())
        format = sourceFormat();
    else
        format = image->hasAlphaChannel() ? sourceFormat() : QImage::Format_RGB32;
    return format;
}

void QVGPixmapData::createPixmapForImage(QImage &image, Qt::ImageConversionFlags flags, bool inPlace)
{
    resize(image.width(), image.height());

    QImage::Format format = idealFormat(&image, flags);

    if (inPlace && image.data_ptr()->convertInPlace(format, flags)) {
        source = QVolatileImage(image);
    } else {
        QImage convertedImage = image.convertToFormat(format);
        // convertToFormat won't detach the image if format stays the
        // same. Detaching is needed to prevent issues with painting
        // onto this QPixmap later on.
        convertedImage.detach();
        if (convertedImage.isNull())
            qWarning("QVGPixmapData: Failed to convert image data (out of memory? try increasing heap size)");
        source = QVolatileImage(convertedImage);
    }
    recreate = true;
}

void QVGPixmapData::fill(const QColor &color)
{
    if (!isValid())
        return;
    forceToImage();
    if (source.depth() == 1) {
        // Pick the best approximate color in the image's colortable.
        int gray = qGray(color.rgba());
        if (qAbs(qGray(source.imageRef().color(0)) - gray)
            < qAbs(qGray(source.imageRef().color(1)) - gray))
            source.fill(0);
        else
            source.fill(1);
    } else {
        source.fill(PREMUL(color.rgba()));
    }
}

bool QVGPixmapData::hasAlphaChannel() const
{
    ensureReadback(true);
    if (!source.isNull())
        return source.hasAlphaChannel();
    else
        return isValid();
}

void QVGPixmapData::setAlphaChannel(const QPixmap &alphaChannel)
{
    if (!isValid())
        return;
    forceToImage();
    source.setAlphaChannel(alphaChannel);
}

QImage QVGPixmapData::toImage() const
{
    if (!isValid())
        return QImage();
    ensureReadback(true);
    if (source.isNull()) {
        source = QVolatileImage(w, h, sourceFormat());
        recreate = true;
    }
    return source.toImage();
}

void QVGPixmapData::copy(const QPixmapData *data, const QRect &rect)
{
    // toImage() is potentially expensive with QVolatileImage so provide a
    // more efficient implementation of copy() that does not rely on it.
    if (!data) {
        return;
    }
    if (data->classId() != OpenVGClass) {
        fromImage(data->toImage(rect), Qt::NoOpaqueDetection);
        return;
    }
    const QVGPixmapData *pd = static_cast<const QVGPixmapData *>(data);
    QRect r = rect;
    if (r.isNull() || r.contains(QRect(0, 0, pd->w, pd->h))) {
        r = QRect(0, 0, pd->w, pd->h);
    }
    resize(r.width(), r.height());
    recreate = true;
    if (!pd->source.isNull()) {
        source = QVolatileImage(r.width(), r.height(), pd->source.format());
        source.copyFrom(&pd->source, r);
    }
}

QImage *QVGPixmapData::buffer()
{
    // Cannot be safely implemented and QVGPixmapData is not (must not be) RasterClass anyway.
    return 0;
}

QPaintEngine* QVGPixmapData::paintEngine() const
{
    // If the application wants to paint into the QPixmap, we first
    // force it to QImage format and then paint into that.
    // This is simpler than juggling multiple VG contexts.
    const_cast<QVGPixmapData *>(this)->forceToImage();
    return source.paintEngine();
}

VGImage QVGPixmapData::toVGImage()
{
    if (!isValid() || failedToAlloc)
        return VG_INVALID_HANDLE;

#if !defined(QT_NO_EGL)
    // Increase the reference count on the shared context.
    if (!context)
        context = qt_vg_create_context(0, QInternal::Pixmap);
#endif

    if (recreate && prevSize != QSize(w, h))
        destroyImages();
    else if (recreate)
        cachedOpacity = -1.0f;  // Force opacity image to be refreshed later.

#if defined(Q_OS_SYMBIAN)
    if (recreate && nativeImageHandleProvider && !nativeImageHandle) {
        createFromNativeImageHandleProvider();
    }
#endif

    if (vgImage == VG_INVALID_HANDLE) {
        vgImage = QVGImagePool::instance()->createImageForPixmap
            (qt_vg_image_to_vg_format(source.format()), w, h, VG_IMAGE_QUALITY_FASTER, this);

        // Bail out if we run out of GPU memory - try again next time.
        if (vgImage == VG_INVALID_HANDLE) {
            failedToAlloc = true;
            return VG_INVALID_HANDLE;
        }

        inImagePool = true;
    } else if (inImagePool) {
        QVGImagePool::instance()->useImage(this);
    }

    if (!source.isNull() && (recreate || source.paintingActive())) {
        source.beginDataAccess();
        vgImageSubData
            (vgImage,
             source.constBits(), source.bytesPerLine(),
             qt_vg_image_to_vg_format(source.format()), 0, 0, w, h);
        source.endDataAccess(true);
    }

    recreate = false;
    prevSize = QSize(w, h);

    return vgImage;
}

VGImage QVGPixmapData::toVGImage(qreal opacity)
{
#if !defined(QT_SHIVAVG)
    // Force the primary VG image to be recreated if necessary.
    if (toVGImage() == VG_INVALID_HANDLE)
        return VG_INVALID_HANDLE;

    if (opacity == 1.0f)
        return vgImage;

    // Create an alternative image for the selected opacity.
    if (vgImageOpacity == VG_INVALID_HANDLE || cachedOpacity != opacity) {
        if (vgImageOpacity == VG_INVALID_HANDLE) {
            if (inImagePool) {
                vgImageOpacity = QVGImagePool::instance()->createImageForPixmap
                    (VG_sARGB_8888_PRE, w, h, VG_IMAGE_QUALITY_FASTER, this);
            } else {
                vgImageOpacity = vgCreateImage
                    (VG_sARGB_8888_PRE, w, h, VG_IMAGE_QUALITY_FASTER);
            }

            // Bail out if we run out of GPU memory - try again next time.
            if (vgImageOpacity == VG_INVALID_HANDLE)
                return VG_INVALID_HANDLE;
        }
        VGfloat matrix[20] = {
            1.0f, 0.0f, 0.0f, 0.0f,
            0.0f, 1.0f, 0.0f, 0.0f,
            0.0f, 0.0f, 1.0f, 0.0f,
            0.0f, 0.0f, 0.0f, opacity,
            0.0f, 0.0f, 0.0f, 0.0f
        };
        vgColorMatrix(vgImageOpacity, vgImage, matrix);
        cachedOpacity = opacity;
    }

    return vgImageOpacity;
#else
    // vgColorMatrix() doesn't work with ShivaVG, so ignore the opacity.
    Q_UNUSED(opacity);
    return toVGImage();
#endif
}

void QVGPixmapData::detachImageFromPool()
{
    if (inImagePool) {
        QVGImagePool::instance()->detachImage(this);
        inImagePool = false;
    }
}

void QVGPixmapData::hibernate()
{
    // If the image was imported (e.g, from an SgImage under Symbian), then
    // skip the hibernation, there is no sense in copying it back to main
    // memory because the data is most likely shared between several processes.
    bool skipHibernate = (vgImage != VG_INVALID_HANDLE && source.isNull());
#if defined(Q_OS_SYMBIAN)
    // However we have to proceed normally if the image was retrieved via
    // a handle provider.
    skipHibernate &= !nativeImageHandleProvider;
#endif
    if (skipHibernate)
        return;

    forceToImage(false); // no readback allowed here
    destroyImageAndContext();
}

void QVGPixmapData::reclaimImages()
{
    if (!inImagePool)
        return;
    forceToImage();
    destroyImages();
}

Q_GUI_EXPORT int qt_defaultDpiX();
Q_GUI_EXPORT int qt_defaultDpiY();

int QVGPixmapData::metric(QPaintDevice::PaintDeviceMetric metric) const
{
    switch (metric) {
    case QPaintDevice::PdmWidth:
        return w;
    case QPaintDevice::PdmHeight:
        return h;
    case QPaintDevice::PdmNumColors:
        return 0;
    case QPaintDevice::PdmDepth:
        return d;
    case QPaintDevice::PdmWidthMM:
        return qRound(w * 25.4 / qt_defaultDpiX());
    case QPaintDevice::PdmHeightMM:
        return qRound(h * 25.4 / qt_defaultDpiY());
    case QPaintDevice::PdmDpiX:
    case QPaintDevice::PdmPhysicalDpiX:
        return qt_defaultDpiX();
    case QPaintDevice::PdmDpiY:
    case QPaintDevice::PdmPhysicalDpiY:
        return qt_defaultDpiY();
    default:
        qWarning("QVGPixmapData::metric(): Invalid metric");
        return 0;
    }
}

// Ensures that the pixmap is backed by some valid data and forces the data to
// be re-uploaded to the VGImage when toVGImage() is called next time.
void QVGPixmapData::forceToImage(bool allowReadback)
{
    if (!isValid())
        return;

    if (allowReadback)
        ensureReadback(false);

    if (source.isNull())
        source = QVolatileImage(w, h, sourceFormat());

    recreate = true;
}

void QVGPixmapData::ensureReadback(bool readOnly) const
{
    if (vgImage != VG_INVALID_HANDLE && source.isNull()) {
        source = QVolatileImage(w, h, sourceFormat());
        source.beginDataAccess();
        vgGetImageSubData(vgImage, source.bits(), source.bytesPerLine(),
                          qt_vg_image_to_vg_format(source.format()),
                          0, 0, w, h);
        source.endDataAccess();
        if (readOnly) {
            recreate = false;
        } else {
            // Once we did a readback, the original VGImage must be destroyed
            // because it may be shared (e.g. created via SgImage) and a subsequent
            // upload of the image data may produce unexpected results.
            const_cast<QVGPixmapData *>(this)->destroyImages();
#if defined(Q_OS_SYMBIAN)
            // There is now an own copy of the data so drop the handle provider,
            // otherwise toVGImage() would request the handle again, which is wrong.
            nativeImageHandleProvider = 0;
#endif
            recreate = true;
        }
    }
}

QImage::Format QVGPixmapData::sourceFormat() const
{
    return QImage::Format_ARGB32_Premultiplied;
}

/*
    \internal

    Returns the VGImage that is storing the contents of \a pixmap.
    Returns VG_INVALID_HANDLE if \a pixmap is not owned by the OpenVG
    graphics system or \a pixmap is invalid.

    This function is typically used to access the backing store
    for a pixmap when executing raw OpenVG calls.  It must only
    be used when a QPainter is active and the OpenVG paint engine
    is in use by the QPainter.

    \sa {QtOpenVG Module}
*/
Q_OPENVG_EXPORT VGImage qPixmapToVGImage(const QPixmap& pixmap)
{
    QPixmapData *pd = pixmap.pixmapData();
    if (!pd)
        return VG_INVALID_HANDLE; // null QPixmap
    if (pd->classId() == QPixmapData::OpenVGClass) {
        QVGPixmapData *vgpd = static_cast<QVGPixmapData *>(pd);
        if (vgpd->isValid())
            return vgpd->toVGImage();
    }
    return VG_INVALID_HANDLE;
}

QT_END_NAMESPACE
