/****************************************************************************
**
** 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 QtOpenGL 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 "private/qpixmapfilter_p.h"
#include "private/qpixmapdata_gl_p.h"
#include "private/qpaintengineex_opengl2_p.h"
#include "private/qglengineshadermanager_p.h"
#include "private/qpixmapdata_p.h"
#include "private/qimagepixmapcleanuphooks_p.h"
#include "qglpixmapfilter_p.h"
#include "qgraphicssystem_gl_p.h"
#include "qpaintengine_opengl_p.h"
#include "qcache.h"

#include "qglframebufferobject.h"
#include "qglshaderprogram.h"
#include "qgl_p.h"

#include "private/qapplication_p.h"
#include "private/qdrawhelper_p.h"
#include "private/qmemrotate_p.h"
#include "private/qmath_p.h"
#include "qmath.h"

QT_BEGIN_NAMESPACE

// qpixmapfilter.cpp
Q_GUI_EXPORT void qt_blurImage(QImage &blurImage, qreal radius, bool quality, int transposed = 0);
Q_GUI_EXPORT QImage qt_halfScaled(const QImage &source);

void QGLPixmapFilterBase::bindTexture(const QPixmap &src) const
{
    const_cast<QGLContext *>(QGLContext::currentContext())->d_func()->bindTexture(src, GL_TEXTURE_2D, GL_RGBA, QGLContext::BindOptions(QGLContext::DefaultBindOption | QGLContext::MemoryManagedBindOption));
}

void QGLPixmapFilterBase::drawImpl(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF& source) const
{
    processGL(painter, pos, src, source);
}

class QGLPixmapColorizeFilter: public QGLCustomShaderStage, public QGLPixmapFilter<QPixmapColorizeFilter>
{
public:
    QGLPixmapColorizeFilter();

    void setUniforms(QGLShaderProgram *program);

protected:
    bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &pixmap, const QRectF &srcRect) const;
};

class QGLPixmapConvolutionFilter: public QGLCustomShaderStage, public QGLPixmapFilter<QPixmapConvolutionFilter>
{
public:
    QGLPixmapConvolutionFilter();
    ~QGLPixmapConvolutionFilter();

    void setUniforms(QGLShaderProgram *program);

protected:
    bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const;

private:
    QByteArray generateConvolutionShader() const;

    mutable QSize m_srcSize;
    mutable int m_prevKernelSize;
};

class QGLPixmapBlurFilter : public QGLCustomShaderStage, public QGLPixmapFilter<QPixmapBlurFilter>
{
public:
    QGLPixmapBlurFilter();

protected:
    bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const;
};

class QGLPixmapDropShadowFilter : public QGLCustomShaderStage, public QGLPixmapFilter<QPixmapDropShadowFilter>
{
public:
    QGLPixmapDropShadowFilter();

    void setUniforms(QGLShaderProgram *program);

protected:
    bool processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const;
};

extern QGLWidget *qt_gl_share_widget();

QPixmapFilter *QGL2PaintEngineEx::pixmapFilter(int type, const QPixmapFilter *prototype)
{
    Q_D(QGL2PaintEngineEx);
    switch (type) {
    case QPixmapFilter::ColorizeFilter:
        if (!d->colorizeFilter)
            d->colorizeFilter.reset(new QGLPixmapColorizeFilter);
        return d->colorizeFilter.data();

    case QPixmapFilter::BlurFilter: {
        if (!d->blurFilter)
            d->blurFilter.reset(new QGLPixmapBlurFilter());
        return d->blurFilter.data();
        }

    case QPixmapFilter::DropShadowFilter: {
        if (!d->dropShadowFilter)
            d->dropShadowFilter.reset(new QGLPixmapDropShadowFilter());
        return d->dropShadowFilter.data();
        }

    case QPixmapFilter::ConvolutionFilter:
        if (!d->convolutionFilter)
            d->convolutionFilter.reset(new QGLPixmapConvolutionFilter);
        return d->convolutionFilter.data();

    default: break;
    }
    return QPaintEngineEx::pixmapFilter(type, prototype);
}

static const char *qt_gl_colorize_filter =
        "uniform lowp vec4 colorizeColor;"
        "uniform lowp float colorizeStrength;"
        "lowp vec4 customShader(lowp sampler2D src, highp vec2 srcCoords)"
        "{"
        "        lowp vec4 srcPixel = texture2D(src, srcCoords);"
        "        lowp float gray = dot(srcPixel.rgb, vec3(0.212671, 0.715160, 0.072169));"
        "        lowp vec3 colorized = 1.0-((1.0-gray)*(1.0-colorizeColor.rgb));"
        "        return vec4(mix(srcPixel.rgb, colorized * srcPixel.a, colorizeStrength), srcPixel.a);"
        "}";

QGLPixmapColorizeFilter::QGLPixmapColorizeFilter()
{
    setSource(qt_gl_colorize_filter);
}

bool QGLPixmapColorizeFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &) const
{
    QGLPixmapColorizeFilter *filter = const_cast<QGLPixmapColorizeFilter *>(this);

    filter->setOnPainter(painter);
    painter->drawPixmap(pos, src);
    filter->removeFromPainter(painter);

    return true;
}

void QGLPixmapColorizeFilter::setUniforms(QGLShaderProgram *program)
{
    program->setUniformValue("colorizeColor", color());
    program->setUniformValue("colorizeStrength", float(strength()));
}

void QGLPixmapConvolutionFilter::setUniforms(QGLShaderProgram *program)
{
    const qreal *kernel = convolutionKernel();
    int kernelWidth = columns();
    int kernelHeight = rows();
    int kernelSize = kernelWidth * kernelHeight;

    QVarLengthArray<GLfloat> matrix(kernelSize);
    QVarLengthArray<GLfloat> offset(kernelSize * 2);

    for(int i = 0; i < kernelSize; ++i)
        matrix[i] = kernel[i];

    for(int y = 0; y < kernelHeight; ++y) {
        for(int x = 0; x < kernelWidth; ++x) {
            offset[(y * kernelWidth + x) * 2] = x - (kernelWidth / 2);
            offset[(y * kernelWidth + x) * 2 + 1] = (kernelHeight / 2) - y;
        }
    }

    const qreal iw = 1.0 / m_srcSize.width();
    const qreal ih = 1.0 / m_srcSize.height();
    program->setUniformValue("inv_texture_size", iw, ih);
    program->setUniformValueArray("matrix", matrix.constData(), kernelSize, 1);
    program->setUniformValueArray("offset", offset.constData(), kernelSize, 2);
}

// generates convolution filter code for arbitrary sized kernel
QByteArray QGLPixmapConvolutionFilter::generateConvolutionShader() const {
    QByteArray code;
    int kernelWidth = columns();
    int kernelHeight = rows();
    int kernelSize = kernelWidth * kernelHeight;
    code.append("uniform highp vec2 inv_texture_size;\n"
                "uniform mediump float matrix[");
    code.append(QByteArray::number(kernelSize));
    code.append("];\n"
                "uniform highp vec2 offset[");
    code.append(QByteArray::number(kernelSize));
    code.append("];\n");
    code.append("lowp vec4 customShader(lowp sampler2D src, highp vec2 srcCoords) {\n");

    code.append("  int i = 0;\n"
                "  lowp vec4 sum = vec4(0.0);\n"
                "  for (i = 0; i < ");
    code.append(QByteArray::number(kernelSize));
    code.append("; i++) {\n"
                "    sum += matrix[i] * texture2D(src,srcCoords+inv_texture_size*offset[i]);\n"
                "  }\n"
                "  return sum;\n"
                "}");
    return code;
}

QGLPixmapConvolutionFilter::QGLPixmapConvolutionFilter()
    : m_prevKernelSize(-1)
{
}

QGLPixmapConvolutionFilter::~QGLPixmapConvolutionFilter()
{
}

bool QGLPixmapConvolutionFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const
{
    QGLPixmapConvolutionFilter *filter = const_cast<QGLPixmapConvolutionFilter *>(this);

    m_srcSize = src.size();

    int kernelSize = rows() * columns();
    if (m_prevKernelSize == -1 || m_prevKernelSize != kernelSize) {
        filter->setSource(generateConvolutionShader());
        m_prevKernelSize = kernelSize;
    }

    filter->setOnPainter(painter);
    painter->drawPixmap(pos, src, srcRect);
    filter->removeFromPainter(painter);

    return true;
}

QGLPixmapBlurFilter::QGLPixmapBlurFilter()
{
}

class QGLBlurTextureInfo
{
public:
    QGLBlurTextureInfo(const QImage &image, GLuint tex, qreal r)
        : m_texture(tex)
        , m_radius(r)
    {
        m_paddedImage << image;
    }

    ~QGLBlurTextureInfo()
    {
        glDeleteTextures(1, &m_texture);
    }

    QImage paddedImage(int scaleLevel = 0) const;
    GLuint texture() const { return m_texture; }
    qreal radius() const { return m_radius; }

private:
    mutable QList<QImage> m_paddedImage;
    GLuint m_texture;
    qreal m_radius;
};

QImage QGLBlurTextureInfo::paddedImage(int scaleLevel) const
{
    for (int i = m_paddedImage.size() - 1; i <= scaleLevel; ++i)
        m_paddedImage << qt_halfScaled(m_paddedImage.at(i));

    return m_paddedImage.at(scaleLevel);
}

class QGLBlurTextureCache : public QObject
{
public:
    static QGLBlurTextureCache *cacheForContext(const QGLContext *context);

    QGLBlurTextureCache();
    ~QGLBlurTextureCache();

    QGLBlurTextureInfo *takeBlurTextureInfo(const QPixmap &pixmap);
    bool hasBlurTextureInfo(quint64 cacheKey) const;
    void insertBlurTextureInfo(const QPixmap &pixmap, QGLBlurTextureInfo *info);
    void clearBlurTextureInfo(quint64 cacheKey);

    void timerEvent(QTimerEvent *event);

private:
    static void pixmapDestroyed(QPixmapData *pixmap);

    QCache<quint64, QGLBlurTextureInfo > cache;

    static QList<QGLBlurTextureCache *> blurTextureCaches;

    int timerId;
};

QList<QGLBlurTextureCache *> QGLBlurTextureCache::blurTextureCaches;

static void QGLBlurTextureCache_free(void *ptr)
{
    delete reinterpret_cast<QGLBlurTextureCache *>(ptr);
}

Q_GLOBAL_STATIC_WITH_ARGS(QGLContextResource, qt_blur_texture_caches, (QGLBlurTextureCache_free))

QGLBlurTextureCache::QGLBlurTextureCache()
    : timerId(0)
{
    cache.setMaxCost(4 * 1024 * 1024);
    blurTextureCaches.append(this);
}

QGLBlurTextureCache::~QGLBlurTextureCache()
{
    blurTextureCaches.removeAt(blurTextureCaches.indexOf(this));
}

void QGLBlurTextureCache::timerEvent(QTimerEvent *)
{
    killTimer(timerId);
    timerId = 0;

    cache.clear();
}

QGLBlurTextureCache *QGLBlurTextureCache::cacheForContext(const QGLContext *context)
{
    QGLBlurTextureCache *p = reinterpret_cast<QGLBlurTextureCache *>(qt_blur_texture_caches()->value(context));
    if (!p) {
        p = new QGLBlurTextureCache;
        qt_blur_texture_caches()->insert(context, p);
    }
    return p;
}

QGLBlurTextureInfo *QGLBlurTextureCache::takeBlurTextureInfo(const QPixmap &pixmap)
{
    return cache.take(pixmap.cacheKey());
}

void QGLBlurTextureCache::clearBlurTextureInfo(quint64 cacheKey)
{
    cache.remove(cacheKey);
}

bool QGLBlurTextureCache::hasBlurTextureInfo(quint64 cacheKey) const
{
    return cache.contains(cacheKey);
}

void QGLBlurTextureCache::insertBlurTextureInfo(const QPixmap &pixmap, QGLBlurTextureInfo *info)
{
    static bool hookAdded = false;
    if (!hookAdded) {
        QImagePixmapCleanupHooks::instance()->addPixmapDataDestructionHook(pixmapDestroyed);
        QImagePixmapCleanupHooks::instance()->addPixmapDataModificationHook(pixmapDestroyed);
        hookAdded = true;
    }

    QImagePixmapCleanupHooks::enableCleanupHooks(pixmap);
    cache.insert(pixmap.cacheKey(), info, pixmap.width() * pixmap.height());

    if (timerId)
        killTimer(timerId);

    timerId = startTimer(8000);
}

void QGLBlurTextureCache::pixmapDestroyed(QPixmapData *pmd)
{
    foreach (QGLBlurTextureCache *cache, blurTextureCaches) {
        if (cache->hasBlurTextureInfo(pmd->cacheKey()))
            cache->clearBlurTextureInfo(pmd->cacheKey());
    }
}

static const int qAnimatedBlurLevelIncrement = 16;
static const int qMaxBlurHalfScaleLevel = 1;

static GLuint generateBlurTexture(const QSize &size, GLenum format = GL_RGBA)
{
    GLuint texture;
    glGenTextures(1, &texture);
    glBindTexture(GL_TEXTURE_2D, texture);
    glTexImage2D(GL_TEXTURE_2D, 0, format, size.width(), size.height(), 0, format,
                 GL_UNSIGNED_BYTE, 0);
    return texture;
}

static inline uint nextMultiple(uint x, uint multiplier)
{
    uint mod = x % multiplier;
    if (mod == 0)
        return x;
    return x + multiplier - mod;
}

Q_GUI_EXPORT void qt_memrotate90_gl(const quint32 *src, int srcWidth, int srcHeight, int srcStride,
                       quint32 *dest, int dstStride);

bool QGLPixmapBlurFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &) const
{
    if (radius() < 1) {
        painter->drawPixmap(pos, src);
        return true;
    }

    qreal actualRadius = radius();

    QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());

    QGLBlurTextureCache *blurTextureCache = QGLBlurTextureCache::cacheForContext(ctx);
    QGLBlurTextureInfo *info = 0;
    int padding = nextMultiple(qCeil(actualRadius), qAnimatedBlurLevelIncrement);
    QRect targetRect = src.rect().adjusted(-padding, -padding, padding, padding);

    // pad so that we'll be able to half-scale qMaxBlurHalfScaleLevel times
    targetRect.setWidth((targetRect.width() + (qMaxBlurHalfScaleLevel-1)) & ~(qMaxBlurHalfScaleLevel-1));
    targetRect.setHeight((targetRect.height() + (qMaxBlurHalfScaleLevel-1)) & ~(qMaxBlurHalfScaleLevel-1));

    QSize textureSize;

    info = blurTextureCache->takeBlurTextureInfo(src);
    if (!info || info->radius() < actualRadius) {
        QSize paddedSize = targetRect.size() / 2;

        QImage padded(paddedSize.height(), paddedSize.width(), QImage::Format_ARGB32_Premultiplied);
        padded.fill(0);

        if (info) {
            int oldPadding = qRound(info->radius());

            QPainter p(&padded);
            p.setCompositionMode(QPainter::CompositionMode_Source);
            p.drawImage((padding - oldPadding) / 2, (padding - oldPadding) / 2, info->paddedImage());
            p.end();
        } else {
            // TODO: combine byteswapping and memrotating into one by declaring
            // custom GL_RGBA pixel type and qt_colorConvert template for it
            QImage prepadded = qt_halfScaled(src.toImage()).convertToFormat(QImage::Format_ARGB32_Premultiplied);

            // byte-swap and memrotates in one go
            qt_memrotate90_gl(reinterpret_cast<const quint32*>(prepadded.bits()),
                              prepadded.width(), prepadded.height(), prepadded.bytesPerLine(),
                              reinterpret_cast<quint32*>(padded.scanLine(padding / 2)) + padding / 2,
                              padded.bytesPerLine());
        }

        delete info;
        info = new QGLBlurTextureInfo(padded, generateBlurTexture(paddedSize), padding);

        textureSize = paddedSize;
    } else {
        textureSize = QSize(info->paddedImage().height(), info->paddedImage().width());
    }

    actualRadius *= qreal(0.5);
    int level = 1;
    for (; level < qMaxBlurHalfScaleLevel; ++level) {
        if (actualRadius <= 16)
            break;
        actualRadius *= qreal(0.5);
    }

    const int s = (1 << level);

    int prepadding = qRound(info->radius());
    padding = qMin(prepadding, qCeil(actualRadius) << level);
    targetRect = src.rect().adjusted(-padding, -padding, padding, padding);

    targetRect.setWidth(targetRect.width() & ~(s-1));
    targetRect.setHeight(targetRect.height() & ~(s-1));

    int paddingDelta = (prepadding - padding) >> level;

    QRect subRect(paddingDelta, paddingDelta, targetRect.width() >> level, targetRect.height() >> level);
    QImage sourceImage = info->paddedImage(level-1);

    QImage subImage(subRect.height(), subRect.width(), QImage::Format_ARGB32_Premultiplied);
    qt_rectcopy((QRgb *)subImage.bits(), ((QRgb *)sourceImage.scanLine(paddingDelta)) + paddingDelta,
                0, 0, subRect.height(), subRect.width(), subImage.bytesPerLine(), sourceImage.bytesPerLine());

    GLuint texture = info->texture();

    qt_blurImage(subImage, actualRadius, blurHints() & QGraphicsBlurEffect::QualityHint, 1);

    // subtract one pixel off the end to prevent the bilinear sampling from sampling uninitialized data
    QRect textureSubRect = subImage.rect().adjusted(0, 0, -1, -1);
    QRectF targetRectF = QRectF(targetRect).adjusted(0, 0, -targetRect.width() / qreal(textureSize.width()), -targetRect.height() / qreal(textureSize.height()));

    glBindTexture(GL_TEXTURE_2D, texture);
    glTexSubImage2D(GL_TEXTURE_2D, 0, 0, 0, subImage.width(), subImage.height(), GL_RGBA,
            GL_UNSIGNED_BYTE, const_cast<const QImage &>(subImage).bits());

    QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx *>(painter->paintEngine());
    painter->setRenderHint(QPainter::SmoothPixmapTransform);

    // texture is flipped on the y-axis
    targetRectF = QRectF(targetRectF.x(), targetRectF.bottom(), targetRectF.width(), -targetRectF.height());
    engine->drawTexture(targetRectF.translated(pos), texture, textureSize, textureSubRect);

    blurTextureCache->insertBlurTextureInfo(src, info);

    return true;
}

static const char *qt_gl_drop_shadow_filter =
        "uniform lowp vec4 shadowColor;"
        "lowp vec4 customShader(lowp sampler2D src, highp vec2 srcCoords)"
        "{"
        "    return shadowColor * texture2D(src, srcCoords.yx).a;"
        "}";


QGLPixmapDropShadowFilter::QGLPixmapDropShadowFilter()
{
    setSource(qt_gl_drop_shadow_filter);
}

bool QGLPixmapDropShadowFilter::processGL(QPainter *painter, const QPointF &pos, const QPixmap &src, const QRectF &srcRect) const
{
    QGLPixmapDropShadowFilter *filter = const_cast<QGLPixmapDropShadowFilter *>(this);

    qreal r = blurRadius();
    QRectF targetRectUnaligned = QRectF(src.rect()).translated(pos + offset()).adjusted(-r, -r, r, r);
    QRect targetRect = targetRectUnaligned.toAlignedRect();

    // ensure even dimensions (going to divide by two)
    targetRect.setWidth((targetRect.width() + 1) & ~1);
    targetRect.setHeight((targetRect.height() + 1) & ~1);

    QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());
    QGLBlurTextureCache *blurTextureCache = QGLBlurTextureCache::cacheForContext(ctx);

    QGLBlurTextureInfo *info = blurTextureCache->takeBlurTextureInfo(src);
    if (!info || info->radius() != r) {
        QImage half = qt_halfScaled(src.toImage().alphaChannel());

        qreal rx = r + targetRect.left() - targetRectUnaligned.left();
        qreal ry = r + targetRect.top() - targetRectUnaligned.top();

        QImage image = QImage(targetRect.size() / 2, QImage::Format_Indexed8);
        image.setColorTable(half.colorTable());
        image.fill(0);
        int dx = qRound(rx * qreal(0.5));
        int dy = qRound(ry * qreal(0.5));
        qt_rectcopy(image.bits(), half.bits(), dx, dy,
                    half.width(), half.height(),
                    image.bytesPerLine(), half.bytesPerLine());

        qt_blurImage(image, r * qreal(0.5), false, 1);

        GLuint texture;
        glGenTextures(1, &texture);
        glBindTexture(GL_TEXTURE_2D, texture);
        glTexImage2D(GL_TEXTURE_2D, 0, GL_ALPHA, image.width(), image.height(),
                     0, GL_ALPHA, GL_UNSIGNED_BYTE, image.bits());

        info = new QGLBlurTextureInfo(image, texture, r);
    }

    GLuint texture = info->texture();

    filter->setOnPainter(painter);

    QGL2PaintEngineEx *engine = static_cast<QGL2PaintEngineEx *>(painter->paintEngine());
    painter->setRenderHint(QPainter::SmoothPixmapTransform);

    engine->drawTexture(targetRect, texture, info->paddedImage().size(), info->paddedImage().rect());

    filter->removeFromPainter(painter);

    // Now draw the actual pixmap over the top.
    painter->drawPixmap(pos, src, srcRect);

    blurTextureCache->insertBlurTextureInfo(src, info);

    return true;
}

void QGLPixmapDropShadowFilter::setUniforms(QGLShaderProgram *program)
{
    QColor col = color();
    qreal alpha = col.alphaF();
    program->setUniformValue("shadowColor", col.redF() * alpha,
                                            col.greenF() * alpha,
                                            col.blueF() * alpha,
                                            alpha);
}

QT_END_NAMESPACE
