/****************************************************************************
**
** Copyright (C) 2020 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the test suite of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:GPL-EXCEPT$
** 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 General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 3 as published by the Free Software
** Foundation with exceptions as appearing in the file LICENSE.GPL3-EXCEPT
** 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-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/
#include <QtGui>
#include <QtOpenGL>
#include <QtCore/QElapsedTimer>

#include <qtest.h>

#include <private/qpaintengine_opengl_p.h>

class OpenGLBench : public QObject
{
    Q_OBJECT

private slots:
    void initTestCase();
    void cleanupTestCase();

    void imageDrawing_data();
    void imageDrawing();

    void pathDrawing_data();
    void pathDrawing();

    void painterOverhead();

    void startupCost_data();
    void startupCost();

    void lineDrawing();

    void textDrawing_data();
    void textDrawing();

    void clippedPainting_data();
    void clippedPainting();

    void gradients_data();
    void gradients();

    void textureUpload_data();
    void textureUpload();


private:
    QGLPixelBuffer *pb;
};

void OpenGLBench::initTestCase()
{
    pb = new QGLPixelBuffer(512, 512);

    QPainter p(pb);
    p.setRenderHint(QPainter::Antialiasing);

    p.drawImage(0, 0, QImage(256, 256, QImage::Format_ARGB32_Premultiplied));
}

void OpenGLBench::cleanupTestCase()
{
    delete pb;
}

void OpenGLBench::imageDrawing_data()
{
    QTest::addColumn<bool>("smoothPixmapTransform");
    QTest::addColumn<bool>("highQualityAntialiasing");
    QTest::addColumn<bool>("pixmap");

    for (int i = 0; i < (1 << 3); ++i) {
        bool smoothPixmapTransform = i & 1;
        bool highQualityAntialiasing = i & 2;
        bool pixmap = i & 4;

        QTest::newRow(QString("pixmap=%1 highQualityAntialiasing=%2 smoothPixmapTransform=%3")
                      .arg(pixmap).arg(highQualityAntialiasing).arg(smoothPixmapTransform).toLatin1().data())
            << pixmap << highQualityAntialiasing << smoothPixmapTransform;
    }
}

void OpenGLBench::imageDrawing()
{
    QFETCH(bool, smoothPixmapTransform);
    QFETCH(bool, highQualityAntialiasing);
    QFETCH(bool, pixmap);

    QImage img;
    QPixmap pm;

    if (pixmap)
        pm = QPixmap(800, 800);
    else
        img = QImage(800, 800, QImage::Format_ARGB32_Premultiplied);

    QPainter p(pb);
    p.setRenderHint(QPainter::SmoothPixmapTransform, smoothPixmapTransform);
    p.setRenderHint(QPainter::Antialiasing, highQualityAntialiasing);

    QBENCHMARK {
        if (pixmap) {
            pm.detach();
            p.drawPixmap(0, 0, pm);
        } else {
            img.detach();
            p.drawImage(0, 0, img);
        }
    }
}

Q_DECLARE_METATYPE(QPainterPath)

void OpenGLBench::pathDrawing_data()
{
    QTest::addColumn<QPainterPath>("path");
    QTest::addColumn<bool>("highQualityAntialiasing");

    QList<QPair<QPainterPath, QLatin1String> > paths;

    {
        QPainterPath path;
        path.addRect(-100, -100, 200, 200);
        paths << qMakePair(path, QLatin1String("plain rect"));
    }

    {
        QPainterPath path;
        path.addRoundedRect(-100, -100, 200, 200, 50, 50);
        paths << qMakePair(path, QLatin1String("rounded rect"));
    }

    {
        QPainterPath path;
        path.addEllipse(-100, -100, 200, 200);
        paths << qMakePair(path, QLatin1String("ellipse"));
    }

    for (int j = 0; j < (1 << 1); ++j) {
        bool highQualityAntialiasing = j & 1;

        for (int i = 0; i < paths.size(); ++i) {
            QTest::newRow(QString("path=%1 highQualityAntialiasing=%2")
                    .arg(paths[i].second).arg(highQualityAntialiasing).toLatin1().data())
                << paths[i].first << highQualityAntialiasing;
        }
    }
}

void OpenGLBench::pathDrawing()
{
    QFETCH(QPainterPath, path);
    QFETCH(bool, highQualityAntialiasing);

    // warm-up
    {
        QPainterPath dummy;
        dummy.addRect(-1, -1, 2, 2);
        QPainter p(pb);
        p.setRenderHint(QPainter::Antialiasing, highQualityAntialiasing);
        p.translate(pb->width() / 2, pb->height() / 2);
        p.rotate(30);
        p.drawPath(dummy);
        p.end();
    }

    QPainter p(pb);
    p.setPen(Qt::NoPen);
    p.setBrush(Qt::black);
    p.translate(pb->width() / 2, pb->height() / 2);

    QBENCHMARK {
        p.setRenderHint(QPainter::Antialiasing, highQualityAntialiasing);

        p.rotate(0.01);
        p.drawPath(path);
    }
}

void OpenGLBench::painterOverhead()
{
    QBENCHMARK {
        QPainter p(pb);
    }
}

void OpenGLBench::startupCost_data()
{
    QTest::addColumn<bool>("highQualityAntialiasing");

    QTest::newRow("highQualityAntialiasing=0") << false;
    QTest::newRow("highQualityAntialiasing=1") << true;
}

void OpenGLBench::startupCost()
{
    QFETCH(bool, highQualityAntialiasing);
    QPainterPath path;
    path.addRoundedRect(-100, -100, 200, 200, 20, 20);
    QBENCHMARK {
        QGLPixelBuffer buffer(512, 512);
        QPainter p(&buffer);
        p.setRenderHint(QPainter::Antialiasing, highQualityAntialiasing);

        p.translate(buffer.width() / 2, buffer.height() / 2);
        p.drawPath(path);
    }
}

void OpenGLBench::lineDrawing()
{
    QPainter p(pb);

    QBENCHMARK {
        p.drawLine(10, 10, 500, 500);
    }
}

void OpenGLBench::textDrawing_data()
{
    QTest::addColumn<int>("lines");

    int lines[] = { 1, 2, 4, 8, 16, 32, 64, 128 };

    QTest::newRow("text lines=1 (warmup run)") << 1;
    for (unsigned int i = 0; i < sizeof(lines) / sizeof(int); ++i)
        QTest::newRow(QString("text lines=%0").arg(lines[i]).toLatin1().data()) << lines[i];
}

void OpenGLBench::textDrawing()
{
    QPainter p(pb);

    QFETCH(int, lines);

    p.translate(0, 16);
    QBENCHMARK {
        for (int i = 0; i < lines; ++i)
            p.drawText(0, i, "Hello World!");
    }
}

void OpenGLBench::clippedPainting_data()
{
    QTest::addColumn<QPainterPath>("path");

    QRectF rect = QRectF(0, 0, pb->width(), pb->height()).adjusted(5, 5, -5, -5);

    {
        QPainterPath path;
        path.addRect(rect);
        QTest::newRow("rect path") << path;
    }

    {
        QPainterPath path;
        path.addRoundedRect(rect, 5, 5);
        QTest::newRow("rounded rect path") << path;
    }

    {
        QPainterPath path;
        path.addEllipse(rect);
        QTest::newRow("ellipse path") << path;
    }
}

void OpenGLBench::clippedPainting()
{
    QFETCH(QPainterPath, path);

    QBENCHMARK {
        QPainter p(pb);
        p.setPen(Qt::NoPen);
        p.setBrush(Qt::black);

        p.setClipPath(path);
        p.drawRect(0, 0, pb->width(), pb->height());
    }
}

Q_DECLARE_METATYPE(QGradient::Type)

void OpenGLBench::gradients_data()
{
    QTest::addColumn<QGradient::Type>("gradientType");
    QTest::addColumn<bool>("objectBoundingMode");

    QTest::newRow("warmup run") << QGradient::LinearGradient << false;

    QTest::newRow("linear gradient") << QGradient::LinearGradient << false;
    QTest::newRow("radial gradient") << QGradient::RadialGradient << false;
    QTest::newRow("conical gradient") << QGradient::ConicalGradient << false;

    QTest::newRow("linear gradient, object bounding mode") << QGradient::LinearGradient << true;
    QTest::newRow("radial gradient, object bounding mode") << QGradient::RadialGradient << true;
    QTest::newRow("conical gradient, object bounding mode") << QGradient::ConicalGradient << true;
}

void OpenGLBench::gradients()
{
    QFETCH(QGradient::Type, gradientType);
    QFETCH(bool, objectBoundingMode);

    QPointF a;
    QPointF b = objectBoundingMode ? QPointF(1, 1) : QPointF(pb->width(), pb->height());

    QGradient gradient;
    switch (gradientType) {
    case QGradient::LinearGradient:
        gradient = QLinearGradient(a, b);
        break;
    case QGradient::RadialGradient:
        gradient = QRadialGradient(a, b.x() / 2, b);
        break;
    case QGradient::ConicalGradient:
        gradient = QConicalGradient((a + b)/2, 0);
        break;
    default:
        break;
    }

    if (objectBoundingMode)
        gradient.setCoordinateMode(QGradient::ObjectBoundingMode);

    gradient.setColorAt(0, Qt::red);
    gradient.setColorAt(0.2, Qt::blue);
    gradient.setColorAt(0.4, Qt::transparent);
    gradient.setColorAt(0.6, Qt::green);
    gradient.setColorAt(0.8, Qt::black);
    gradient.setColorAt(1, Qt::white);

    QPainter p(pb);

    QBENCHMARK {
        p.fillRect(0, 0, pb->width(), pb->height(), gradient);
        glFinish();
    }
}

void OpenGLBench::textureUpload_data()
{
    QTest::addColumn<int>("size");
    QTest::addColumn<int>("flags");
    QTest::addColumn<int>("format");

    int sizes[] = { 8, 10, 16, 20, 32, 50, 64, 100, 128, 200, 256, 500, 512, 1000, 1024, 2000, 2048, -1 };
    int flags[] = { QGLContext::InternalBindOption,
                  QGLContext::DefaultBindOption,
                  -1 };
    int formats[] = { GL_RGB, GL_RGBA, -1 };

    for (int s = 0; sizes[s] != -1; ++s) {
        for (int f = 0; flags[f] != -1; ++f) {
            for (int a = 0; formats[a] != -1; ++a) {
                QByteArray name;
                name.append("size=").append(QByteArray::number(sizes[s]));
                name.append(", flags=").append(f == 0 ? "internal" : "default");
                name.append(", format=").append(a == 0 ? "RGB" : "RGBA");
                QTest::newRow(name.constData()) << sizes[s] << flags[f] << formats[a];
            }
        }
    }
}

void OpenGLBench::textureUpload()
{
    QFETCH(int, size);
    QFETCH(int, flags);
    QFETCH(int, format);

    QPixmap pixmap(size, size);

    if (format == GL_RGB)
        pixmap.fill(Qt::red);
    else
        pixmap.fill(Qt::transparent);

    pb->makeCurrent();
    QGLContext *context = const_cast<QGLContext *>(QGLContext::currentContext());
    QElapsedTimer time;

    time.start();
    context->bindTexture(pixmap, GL_TEXTURE_2D, format, (QGLContext::BindOptions) flags);
    QTest::setBenchmarkResult(time.elapsed(), QTest::WalltimeMilliseconds);
}

QTEST_MAIN(OpenGLBench)

#include "main.moc"
