/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part 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 "qpaintervideosurface_p.h"

#include <qmath.h>

#include <qpainter.h>
#include <qvariant.h>
#include <qvideosurfaceformat.h>
#include <private/qmediaopenglhelper_p.h>

#if QT_CONFIG(opengl)
#include <QOpenGLContext>
#include <QOpenGLFunctions>
#include <QOpenGLShaderProgram>
#include <QtGui/QWindow>
#ifndef GL_CLAMP_TO_EDGE
#define GL_CLAMP_TO_EDGE 0x812F
#endif
#ifndef GL_RGB8
#define GL_RGB8 0x8051
#endif
#endif

#include <QtDebug>
QT_BEGIN_NAMESPACE

QVideoSurfacePainter::~QVideoSurfacePainter()
{
}

class QVideoSurfaceGenericPainter : public QVideoSurfacePainter
{
public:
    QVideoSurfaceGenericPainter();

    QList<QVideoFrame::PixelFormat> supportedPixelFormats(
            QAbstractVideoBuffer::HandleType handleType) const override;

    bool isFormatSupported(const QVideoSurfaceFormat &format) const override;

    QAbstractVideoSurface::Error start(const QVideoSurfaceFormat &format) override;
    void stop() override;

    QAbstractVideoSurface::Error setCurrentFrame(const QVideoFrame &frame) override;

    QAbstractVideoSurface::Error paint(
            const QRectF &target, QPainter *painter, const QRectF &source) override;

    void updateColors(int brightness, int contrast, int hue, int saturation) override;

private:
    QList<QVideoFrame::PixelFormat> m_imagePixelFormats;
    QVideoFrame m_frame;
    QSize m_imageSize;
    QImage::Format m_imageFormat;
    QVideoSurfaceFormat::Direction m_scanLineDirection;
    bool m_mirrored;
};

QVideoSurfaceGenericPainter::QVideoSurfaceGenericPainter()
    : m_imageFormat(QImage::Format_Invalid)
    , m_scanLineDirection(QVideoSurfaceFormat::TopToBottom)
    , m_mirrored(false)
{
    m_imagePixelFormats << QVideoFrame::Format_RGB32;

    // The raster formats should be a subset of the GL formats.
#ifndef QT_NO_OPENGL
    if (QOpenGLContext::openGLModuleType() != QOpenGLContext::LibGLES)
#endif
        m_imagePixelFormats << QVideoFrame::Format_RGB24;

     m_imagePixelFormats << QVideoFrame::Format_ARGB32
                         << QVideoFrame::Format_RGB565
                         << QVideoFrame::Format_Y8;
}

QList<QVideoFrame::PixelFormat> QVideoSurfaceGenericPainter::supportedPixelFormats(
        QAbstractVideoBuffer::HandleType handleType) const
{
    switch (handleType) {
    case QAbstractVideoBuffer::QPixmapHandle:
    case QAbstractVideoBuffer::NoHandle:
        return m_imagePixelFormats;
    default:
        ;
    }
    return QList<QVideoFrame::PixelFormat>();
}

bool QVideoSurfaceGenericPainter::isFormatSupported(const QVideoSurfaceFormat &format) const
{
    switch (format.handleType()) {
    case QAbstractVideoBuffer::QPixmapHandle:
        return true;
    case QAbstractVideoBuffer::NoHandle:
        return m_imagePixelFormats.contains(format.pixelFormat())
               && !format.frameSize().isEmpty();
    default:
        ;
    }
    return false;
}

QAbstractVideoSurface::Error QVideoSurfaceGenericPainter::start(const QVideoSurfaceFormat &format)
{
    m_frame = QVideoFrame();
    m_imageFormat = QVideoFrame::imageFormatFromPixelFormat(format.pixelFormat());
    // Do not render into ARGB32 images using QPainter.
    // Using QImage::Format_ARGB32_Premultiplied is significantly faster.
    if (m_imageFormat == QImage::Format_ARGB32)
        m_imageFormat = QImage::Format_ARGB32_Premultiplied;

    m_imageSize = format.frameSize();
    m_scanLineDirection = format.scanLineDirection();
    m_mirrored = format.property("mirrored").toBool();

    const QAbstractVideoBuffer::HandleType t = format.handleType();
    if (t == QAbstractVideoBuffer::NoHandle) {
        bool ok = m_imageFormat != QImage::Format_Invalid && !m_imageSize.isEmpty();
#ifndef QT_NO_OPENGL
        if (QOpenGLContext::openGLModuleType() == QOpenGLContext::LibGLES)
            ok &= format.pixelFormat() != QVideoFrame::Format_RGB24;
#endif
        if (ok)
            return QAbstractVideoSurface::NoError;
    } else if (t == QAbstractVideoBuffer::QPixmapHandle) {
        return QAbstractVideoSurface::NoError;
    }
    return QAbstractVideoSurface::UnsupportedFormatError;
}

void QVideoSurfaceGenericPainter::stop()
{
    m_frame = QVideoFrame();
}

QAbstractVideoSurface::Error QVideoSurfaceGenericPainter::setCurrentFrame(const QVideoFrame &frame)
{
    m_frame = frame;

    return QAbstractVideoSurface::NoError;
}

QAbstractVideoSurface::Error QVideoSurfaceGenericPainter::paint(
            const QRectF &target, QPainter *painter, const QRectF &source)
{
    if (!m_frame.isValid()) {
        painter->fillRect(target, Qt::black);
        return QAbstractVideoSurface::NoError;
    }

    if (m_frame.handleType() == QAbstractVideoBuffer::QPixmapHandle) {
        painter->drawPixmap(target, m_frame.handle().value<QPixmap>(), source);
    } else if (m_frame.map(QAbstractVideoBuffer::ReadOnly)) {
        QImage image(
                m_frame.bits(),
                m_imageSize.width(),
                m_imageSize.height(),
                m_frame.bytesPerLine(),
                m_imageFormat);

        const QTransform oldTransform = painter->transform();
        QTransform transform = oldTransform;
        QRectF targetRect = target;
        if (m_scanLineDirection == QVideoSurfaceFormat::BottomToTop) {
            transform.scale(1, -1);
            transform.translate(0, -target.bottom());
            targetRect = QRectF(target.x(), 0, target.width(), target.height());
        }

        if (m_mirrored) {
            transform.scale(-1, 1);
            transform.translate(-target.right(), 0);
            targetRect = QRectF(0, targetRect.y(), target.width(), target.height());
        }
        painter->setTransform(transform);
        painter->drawImage(targetRect, image, source);
        painter->setTransform(oldTransform);

        m_frame.unmap();
    } else if (m_frame.isValid()) {
        return QAbstractVideoSurface::IncorrectFormatError;
    } else {
        painter->fillRect(target, Qt::black);
    }
    return QAbstractVideoSurface::NoError;
}

void QVideoSurfaceGenericPainter::updateColors(int, int, int, int)
{
}

#if QT_CONFIG(opengl)

#ifndef APIENTRYP
#  ifdef APIENTRY
#    define APIENTRYP APIENTRY *
#  else
#    define APIENTRY
#    define APIENTRYP *
#  endif
#endif

#ifndef GL_TEXTURE0
#  define GL_TEXTURE0    0x84C0
#  define GL_TEXTURE1    0x84C1
#  define GL_TEXTURE2    0x84C2
#endif
#ifndef GL_PROGRAM_ERROR_STRING_ARB
#  define GL_PROGRAM_ERROR_STRING_ARB       0x8874
#endif

#ifndef GL_UNSIGNED_SHORT_5_6_5
#  define GL_UNSIGNED_SHORT_5_6_5 33635
#endif

class QVideoSurfaceGLPainter : public QVideoSurfacePainter, protected QOpenGLFunctions
{
public:
    QVideoSurfaceGLPainter(QOpenGLContext *context);
    ~QVideoSurfaceGLPainter();
    QList<QVideoFrame::PixelFormat> supportedPixelFormats(
            QAbstractVideoBuffer::HandleType handleType) const override;

    bool isFormatSupported(const QVideoSurfaceFormat &format) const override;

    void stop() override;

    QAbstractVideoSurface::Error setCurrentFrame(const QVideoFrame &frame) override;

    QAbstractVideoSurface::Error paint(
            const QRectF &target, QPainter *painter, const QRectF &source) override;

    void updateColors(int brightness, int contrast, int hue, int saturation) override;
    void viewportDestroyed() override;

protected:
    void initRgbTextureInfo(GLenum internalFormat, GLuint format, GLenum type, const QSize &size);
    void initYuv420PTextureInfo(const QSize &size);
    void initYv12TextureInfo(const QSize &size);

    bool needsSwizzling(const QVideoSurfaceFormat &format) const {
        return !QMediaOpenGLHelper::isANGLE()
                && (format.pixelFormat() == QVideoFrame::Format_RGB32
                    || format.pixelFormat() == QVideoFrame::Format_ARGB32);
    }

    QList<QVideoFrame::PixelFormat> m_imagePixelFormats;
    QList<QVideoFrame::PixelFormat> m_glPixelFormats;
    QMatrix4x4 m_colorMatrix;
    QVideoFrame m_frame;

    QOpenGLContext *m_context;
    QAbstractVideoBuffer::HandleType m_handleType;
    QVideoSurfaceFormat::Direction m_scanLineDirection;
    bool m_mirrored;
    QVideoSurfaceFormat::YCbCrColorSpace m_colorSpace;
    GLenum m_textureFormat;
    GLuint m_textureInternalFormat;
    GLenum m_textureType;
    int m_textureCount;

    static const uint Max_Textures = 3;
    GLuint m_textureIds[Max_Textures];
    int m_textureWidths[Max_Textures];
    int m_textureHeights[Max_Textures];
    int m_textureOffsets[Max_Textures];
    bool m_yuv;
};

QVideoSurfaceGLPainter::QVideoSurfaceGLPainter(QOpenGLContext *context)
    : m_context(context)
    , m_handleType(QAbstractVideoBuffer::NoHandle)
    , m_scanLineDirection(QVideoSurfaceFormat::TopToBottom)
    , m_mirrored(false)
    , m_colorSpace(QVideoSurfaceFormat::YCbCr_BT601)
    , m_textureFormat(0)
    , m_textureInternalFormat(0)
    , m_textureType(0)
    , m_textureCount(0)
    , m_yuv(false)
{
    memset(m_textureIds, 0, sizeof(m_textureIds));
    memset(m_textureWidths, 0, sizeof(m_textureWidths));
    memset(m_textureHeights, 0, sizeof(m_textureHeights));
    memset(m_textureOffsets, 0, sizeof(m_textureOffsets));

    initializeOpenGLFunctions();
}

QVideoSurfaceGLPainter::~QVideoSurfaceGLPainter()
{
}

void QVideoSurfaceGLPainter::viewportDestroyed()
{
    m_context = 0;
}

QList<QVideoFrame::PixelFormat> QVideoSurfaceGLPainter::supportedPixelFormats(
        QAbstractVideoBuffer::HandleType handleType) const
{
    switch (handleType) {
    case QAbstractVideoBuffer::NoHandle:
        return m_imagePixelFormats;
    case QAbstractVideoBuffer::QPixmapHandle:
    case QAbstractVideoBuffer::GLTextureHandle:
        return m_glPixelFormats;
    default:
        ;
    }
    return QList<QVideoFrame::PixelFormat>();
}

bool QVideoSurfaceGLPainter::isFormatSupported(const QVideoSurfaceFormat &format) const
{
    if (format.frameSize().isEmpty()) {
        return false;
    } else {
        switch (format.handleType()) {
        case QAbstractVideoBuffer::NoHandle:
            return m_imagePixelFormats.contains(format.pixelFormat());
        case QAbstractVideoBuffer::QPixmapHandle:
        case QAbstractVideoBuffer::GLTextureHandle:
            return m_glPixelFormats.contains(format.pixelFormat());
        default:
            ;
        }
    }
    return false;
}


void QVideoSurfaceGLPainter::stop()
{
    m_frame = QVideoFrame();
}

QAbstractVideoSurface::Error QVideoSurfaceGLPainter::setCurrentFrame(const QVideoFrame &frame)
{
    m_frame = frame;

    if (m_handleType == QAbstractVideoBuffer::GLTextureHandle) {
        m_textureIds[0] = frame.handle().toInt();
        glBindTexture(GL_TEXTURE_2D, m_textureIds[0]);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
    } else if (m_frame.map(QAbstractVideoBuffer::ReadOnly)) {
        for (int i = 0; i < m_textureCount; ++i) {
            glBindTexture(GL_TEXTURE_2D, m_textureIds[i]);
            glTexImage2D(
                    GL_TEXTURE_2D,
                    0,
                    m_textureInternalFormat,
                    m_textureWidths[i],
                    m_textureHeights[i],
                    0,
                    m_textureFormat,
                    m_textureType,
                    m_frame.bits() + m_textureOffsets[i]);
            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);
            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);
            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
            glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        }
        m_frame.unmap();
    } else if (m_handleType != QAbstractVideoBuffer::QPixmapHandle && m_frame.isValid()) {
        return QAbstractVideoSurface::IncorrectFormatError;
    }

    return QAbstractVideoSurface::NoError;
}

QAbstractVideoSurface::Error QVideoSurfaceGLPainter::paint(
        const QRectF &target, QPainter *painter, const QRectF &source)
{
    if (!m_frame.isValid()) {
        painter->fillRect(target, Qt::black);
        return QAbstractVideoSurface::NoError;
    }

    if (m_frame.handleType() == QAbstractVideoBuffer::QPixmapHandle) {
        painter->drawPixmap(target, m_frame.handle().value<QPixmap>(), source);
    } else if (m_frame.isValid()) {
        return QAbstractVideoSurface::IncorrectFormatError;
    } else {
        painter->fillRect(target, Qt::black);
    }
    return QAbstractVideoSurface::NoError;
}

void QVideoSurfaceGLPainter::updateColors(int brightness, int contrast, int hue, int saturation)
{
    const qreal b = brightness / 200.0;
    const qreal c = contrast / 100.0 + 1.0;
    const qreal h = hue / 100.0;
    const qreal s = saturation / 100.0 + 1.0;

    const qreal cosH = qCos(M_PI * h);
    const qreal sinH = qSin(M_PI * h);

    const qreal h11 =  0.787 * cosH - 0.213 * sinH + 0.213;
    const qreal h21 = -0.213 * cosH + 0.143 * sinH + 0.213;
    const qreal h31 = -0.213 * cosH - 0.787 * sinH + 0.213;

    const qreal h12 = -0.715 * cosH - 0.715 * sinH + 0.715;
    const qreal h22 =  0.285 * cosH + 0.140 * sinH + 0.715;
    const qreal h32 = -0.715 * cosH + 0.715 * sinH + 0.715;

    const qreal h13 = -0.072 * cosH + 0.928 * sinH + 0.072;
    const qreal h23 = -0.072 * cosH - 0.283 * sinH + 0.072;
    const qreal h33 =  0.928 * cosH + 0.072 * sinH + 0.072;

    const qreal sr = (1.0 - s) * 0.3086;
    const qreal sg = (1.0 - s) * 0.6094;
    const qreal sb = (1.0 - s) * 0.0820;

    const qreal sr_s = sr + s;
    const qreal sg_s = sg + s;
    const qreal sb_s = sr + s;

    const float m4 = (s + sr + sg + sb) * (0.5 - 0.5 * c + b);

    m_colorMatrix(0, 0) = c * (sr_s * h11 + sg * h21 + sb * h31);
    m_colorMatrix(0, 1) = c * (sr_s * h12 + sg * h22 + sb * h32);
    m_colorMatrix(0, 2) = c * (sr_s * h13 + sg * h23 + sb * h33);
    m_colorMatrix(0, 3) = m4;

    m_colorMatrix(1, 0) = c * (sr * h11 + sg_s * h21 + sb * h31);
    m_colorMatrix(1, 1) = c * (sr * h12 + sg_s * h22 + sb * h32);
    m_colorMatrix(1, 2) = c * (sr * h13 + sg_s * h23 + sb * h33);
    m_colorMatrix(1, 3) = m4;

    m_colorMatrix(2, 0) = c * (sr * h11 + sg * h21 + sb_s * h31);
    m_colorMatrix(2, 1) = c * (sr * h12 + sg * h22 + sb_s * h32);
    m_colorMatrix(2, 2) = c * (sr * h13 + sg * h23 + sb_s * h33);
    m_colorMatrix(2, 3) = m4;

    m_colorMatrix(3, 0) = 0.0;
    m_colorMatrix(3, 1) = 0.0;
    m_colorMatrix(3, 2) = 0.0;
    m_colorMatrix(3, 3) = 1.0;

    if (m_yuv) {
        QMatrix4x4 colorSpaceMatrix;

        switch (m_colorSpace) {
        case QVideoSurfaceFormat::YCbCr_JPEG:
            colorSpaceMatrix = QMatrix4x4(
                        1.0f,  0.000f,  1.402f, -0.701f,
                        1.0f, -0.344f, -0.714f,  0.529f,
                        1.0f,  1.772f,  0.000f, -0.886f,
                        0.0f,  0.000f,  0.000f,  1.0000f);
            break;
        case QVideoSurfaceFormat::YCbCr_BT709:
        case QVideoSurfaceFormat::YCbCr_xvYCC709:
            colorSpaceMatrix = QMatrix4x4(
                        1.164f,  0.000f,  1.793f, -0.5727f,
                        1.164f, -0.534f, -0.213f,  0.3007f,
                        1.164f,  2.115f,  0.000f, -1.1302f,
                        0.0f,    0.000f,  0.000f,  1.0000f);
            break;
        default: //BT 601:
            colorSpaceMatrix = QMatrix4x4(
                        1.164f,  0.000f,  1.596f, -0.8708f,
                        1.164f, -0.392f, -0.813f,  0.5296f,
                        1.164f,  2.017f,  0.000f, -1.081f,
                        0.0f,    0.000f,  0.000f,  1.0000f);
        }

        m_colorMatrix = m_colorMatrix * colorSpaceMatrix;
    }
}

void QVideoSurfaceGLPainter::initRgbTextureInfo(
        GLenum internalFormat, GLuint format, GLenum type, const QSize &size)
{
    m_yuv = false;
    m_textureInternalFormat = internalFormat;
    m_textureFormat = format;
    m_textureType = type;
    m_textureCount = 1; // Note: ensure this is always <= Max_Textures
    m_textureWidths[0] = size.width();
    m_textureHeights[0] = size.height();
    m_textureOffsets[0] = 0;
}

void QVideoSurfaceGLPainter::initYuv420PTextureInfo(const QSize &size)
{
    int bytesPerLine = (size.width() + 3) & ~3;
    int bytesPerLine2 = (size.width() / 2 + 3) & ~3;

    m_yuv = true;
    m_textureInternalFormat = GL_LUMINANCE;
    m_textureFormat = GL_LUMINANCE;
    m_textureType = GL_UNSIGNED_BYTE;
    m_textureCount = 3; // Note: ensure this is always <= Max_Textures
    m_textureWidths[0] = bytesPerLine;
    m_textureHeights[0] = size.height();
    m_textureOffsets[0] = 0;
    m_textureWidths[1] = bytesPerLine2;
    m_textureHeights[1] = size.height() / 2;
    m_textureOffsets[1] = bytesPerLine * size.height();
    m_textureWidths[2] = bytesPerLine2;
    m_textureHeights[2] = size.height() / 2;
    m_textureOffsets[2] = bytesPerLine * size.height() + bytesPerLine2 * size.height()/2;
}

void QVideoSurfaceGLPainter::initYv12TextureInfo(const QSize &size)
{
    int bytesPerLine = (size.width() + 3) & ~3;
    int bytesPerLine2 = (size.width() / 2 + 3) & ~3;

    m_yuv = true;
    m_textureInternalFormat = GL_LUMINANCE;
    m_textureFormat = GL_LUMINANCE;
    m_textureType = GL_UNSIGNED_BYTE;
    m_textureCount = 3; // Note: ensure this is always <= Max_Textures
    m_textureWidths[0] = bytesPerLine;
    m_textureHeights[0] = size.height();
    m_textureOffsets[0] = 0;
    m_textureWidths[1] = bytesPerLine2;
    m_textureHeights[1] = size.height() / 2;
    m_textureOffsets[1] = bytesPerLine * size.height() + bytesPerLine2 * size.height()/2;
    m_textureWidths[2] = bytesPerLine2;
    m_textureHeights[2] = size.height() / 2;
    m_textureOffsets[2] = bytesPerLine * size.height();
}

#if !defined(QT_OPENGL_ES) && !defined(QT_OPENGL_DYNAMIC)

# ifndef GL_FRAGMENT_PROGRAM_ARB
#  define GL_FRAGMENT_PROGRAM_ARB           0x8804
#  define GL_PROGRAM_FORMAT_ASCII_ARB       0x8875
# endif

// Paints an RGB32 frame
static const char *qt_arbfp_xrgbShaderProgram =
    "!!ARBfp1.0\n"
    "PARAM matrix[4] = { program.local[0..2],"
    "{ 0.0, 0.0, 0.0, 1.0 } };\n"
    "TEMP xrgb;\n"
    "TEX xrgb.xyz, fragment.texcoord[0], texture[0], 2D;\n"
    "MOV xrgb.w, matrix[3].w;\n"
    "DP4 result.color.x, xrgb.zyxw, matrix[0];\n"
    "DP4 result.color.y, xrgb.zyxw, matrix[1];\n"
    "DP4 result.color.z, xrgb.zyxw, matrix[2];\n"
    "END";

// Paints an ARGB frame.
static const char *qt_arbfp_argbShaderProgram =
    "!!ARBfp1.0\n"
    "PARAM matrix[4] = { program.local[0..2],"
    "{ 0.0, 0.0, 0.0, 1.0 } };\n"
    "TEMP argb;\n"
    "TEX argb, fragment.texcoord[0], texture[0], 2D;\n"
    "MOV argb.w, matrix[3].w;\n"
    "DP4 result.color.x, argb.zyxw, matrix[0];\n"
    "DP4 result.color.y, argb.zyxw, matrix[1];\n"
    "DP4 result.color.z, argb.zyxw, matrix[2];\n"
    "TEX result.color.w, fragment.texcoord[0], texture, 2D;\n"
    "END";

// Paints an RGB(A) frame.
static const char *qt_arbfp_rgbShaderProgram =
    "!!ARBfp1.0\n"
    "PARAM matrix[4] = { program.local[0..2],"
    "{ 0.0, 0.0, 0.0, 1.0 } };\n"
    "TEMP rgb;\n"
    "TEX rgb, fragment.texcoord[0], texture[0], 2D;\n"
    "MOV rgb.w, matrix[3].w;\n"
    "DP4 result.color.x, rgb, matrix[0];\n"
    "DP4 result.color.y, rgb, matrix[1];\n"
    "DP4 result.color.z, rgb, matrix[2];\n"
    "TEX result.color.w, fragment.texcoord[0], texture, 2D;\n"
    "END";

// Paints a YUV420P or YV12 frame.
static const char *qt_arbfp_yuvPlanarShaderProgram =
    "!!ARBfp1.0\n"
    "PARAM matrix[4] = { program.local[0..2],"
    "{ 0.0, 0.0, 0.0, 1.0 } };\n"
    "TEMP yuv;\n"
    "TEX yuv.x, fragment.texcoord[0], texture[0], 2D;\n"
    "TEX yuv.y, fragment.texcoord[0], texture[1], 2D;\n"
    "TEX yuv.z, fragment.texcoord[0], texture[2], 2D;\n"
    "MOV yuv.w, matrix[3].w;\n"
    "DP4 result.color.x, yuv, matrix[0];\n"
    "DP4 result.color.y, yuv, matrix[1];\n"
    "DP4 result.color.z, yuv, matrix[2];\n"
    "END";

// Paints a YUV444 frame.
static const char *qt_arbfp_xyuvShaderProgram =
    "!!ARBfp1.0\n"
    "PARAM matrix[4] = { program.local[0..2],"
    "{ 0.0, 0.0, 0.0, 1.0 } };\n"
    "TEMP ayuv;\n"
    "TEX ayuv, fragment.texcoord[0], texture[0], 2D;\n"
    "MOV ayuv.x, matrix[3].w;\n"
    "DP4 result.color.x, ayuv.yzwx, matrix[0];\n"
    "DP4 result.color.y, ayuv.yzwx, matrix[1];\n"
    "DP4 result.color.z, ayuv.yzwx, matrix[2];\n"
    "END";

// Paints a AYUV444 frame.
static const char *qt_arbfp_ayuvShaderProgram =
    "!!ARBfp1.0\n"
    "PARAM matrix[4] = { program.local[0..2],"
    "{ 0.0, 0.0, 0.0, 1.0 } };\n"
    "TEMP ayuv;\n"
    "TEX ayuv, fragment.texcoord[0], texture[0], 2D;\n"
    "MOV ayuv.x, matrix[3].w;\n"
    "DP4 result.color.x, ayuv.yzwx, matrix[0];\n"
    "DP4 result.color.y, ayuv.yzwx, matrix[1];\n"
    "DP4 result.color.z, ayuv.yzwx, matrix[2];\n"
    "TEX result.color.w, fragment.texcoord[0], texture, 2D;\n"
    "END";

class QVideoSurfaceArbFpPainter : public QVideoSurfaceGLPainter
{
public:
    QVideoSurfaceArbFpPainter(QOpenGLContext *context);

    QAbstractVideoSurface::Error start(const QVideoSurfaceFormat &format) override;
    void stop() override;

    QAbstractVideoSurface::Error paint(
            const QRectF &target, QPainter *painter, const QRectF &source) override;

private:
    typedef void (APIENTRY *_glProgramStringARB) (GLenum, GLenum, GLsizei, const GLvoid *);
    typedef void (APIENTRY *_glBindProgramARB) (GLenum, GLuint);
    typedef void (APIENTRY *_glDeleteProgramsARB) (GLsizei, const GLuint *);
    typedef void (APIENTRY *_glGenProgramsARB) (GLsizei, GLuint *);
    typedef void (APIENTRY *_glProgramLocalParameter4fARB) (
            GLenum, GLuint, GLfloat, GLfloat, GLfloat, GLfloat);
    typedef void (APIENTRY *_glActiveTexture) (GLenum);

    _glProgramStringARB glProgramStringARB;
    _glBindProgramARB glBindProgramARB;
    _glDeleteProgramsARB glDeleteProgramsARB;
    _glGenProgramsARB glGenProgramsARB;
    _glProgramLocalParameter4fARB glProgramLocalParameter4fARB;

    GLuint m_programId;
    QSize m_frameSize;
};

QVideoSurfaceArbFpPainter::QVideoSurfaceArbFpPainter(QOpenGLContext *context)
    : QVideoSurfaceGLPainter(context)
    , m_programId(0)
{
    glProgramStringARB = (_glProgramStringARB) m_context->getProcAddress(
                QByteArray("glProgramStringARB"));
    glBindProgramARB = (_glBindProgramARB) m_context->getProcAddress(
                QByteArray("glBindProgramARB"));
    glDeleteProgramsARB = (_glDeleteProgramsARB) m_context->getProcAddress(
                QByteArray("glDeleteProgramsARB"));
    glGenProgramsARB = (_glGenProgramsARB) m_context->getProcAddress(
                QByteArray("glGenProgramsARB"));
    glProgramLocalParameter4fARB = (_glProgramLocalParameter4fARB) m_context->getProcAddress(
                QByteArray("glProgramLocalParameter4fARB"));

    m_imagePixelFormats
            << QVideoFrame::Format_RGB32
            << QVideoFrame::Format_BGR32
            << QVideoFrame::Format_ARGB32
            << QVideoFrame::Format_RGB24
            << QVideoFrame::Format_BGR24
            << QVideoFrame::Format_RGB565
            << QVideoFrame::Format_AYUV444
            << QVideoFrame::Format_YUV444
            << QVideoFrame::Format_YV12
            << QVideoFrame::Format_YUV420P;
    m_glPixelFormats
            << QVideoFrame::Format_RGB32
            << QVideoFrame::Format_ARGB32
            << QVideoFrame::Format_BGR32
            << QVideoFrame::Format_BGRA32;
}

QAbstractVideoSurface::Error QVideoSurfaceArbFpPainter::start(const QVideoSurfaceFormat &format)
{
    Q_ASSERT(m_textureCount == 0);

    QAbstractVideoSurface::Error error = QAbstractVideoSurface::NoError;

    const char *program = 0;

    if (format.handleType() == QAbstractVideoBuffer::NoHandle) {
        switch (format.pixelFormat()) {
        case QVideoFrame::Format_RGB32:
            initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
            program = qt_arbfp_xrgbShaderProgram;
            break;
        case QVideoFrame::Format_BGR32:
            initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
            program = qt_arbfp_rgbShaderProgram;
            break;
        case QVideoFrame::Format_ARGB32:
            initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
            program = qt_arbfp_argbShaderProgram;
            break;
        case QVideoFrame::Format_RGB24:
            initRgbTextureInfo(GL_RGB8, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
            program = qt_arbfp_rgbShaderProgram;
            break;
        case QVideoFrame::Format_BGR24:
            initRgbTextureInfo(GL_RGB8, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
            program = qt_arbfp_xrgbShaderProgram;
            break;
        case QVideoFrame::Format_RGB565:
            initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, format.frameSize());
            program = qt_arbfp_rgbShaderProgram;
            break;
        case QVideoFrame::Format_YUV444:
            initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize());
            program = qt_arbfp_xyuvShaderProgram;
            m_yuv = true;
            break;
        case QVideoFrame::Format_AYUV444:
            initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
            program = qt_arbfp_ayuvShaderProgram;
            m_yuv = true;
            break;
        case QVideoFrame::Format_YV12:
            initYv12TextureInfo(format.frameSize());
            program = qt_arbfp_yuvPlanarShaderProgram;
            break;
        case QVideoFrame::Format_YUV420P:
            initYuv420PTextureInfo(format.frameSize());
            program = qt_arbfp_yuvPlanarShaderProgram;
            break;
        default:
            break;
        }
    } else if (format.handleType() == QAbstractVideoBuffer::GLTextureHandle) {
        switch (format.pixelFormat()) {
        case QVideoFrame::Format_RGB32:
        case QVideoFrame::Format_ARGB32:
        case QVideoFrame::Format_BGR32:
        case QVideoFrame::Format_BGRA32:
            m_yuv = false;
            m_textureCount = 1;
            if (needsSwizzling(format))
                program = qt_arbfp_xrgbShaderProgram;
            else
                program = qt_arbfp_rgbShaderProgram;
            break;
        default:
            break;
        }
    } else if (format.handleType() == QAbstractVideoBuffer::QPixmapHandle) {
        m_handleType = QAbstractVideoBuffer::QPixmapHandle;
        return QAbstractVideoSurface::NoError;
    }

    if (!program) {
        error = QAbstractVideoSurface::UnsupportedFormatError;
    } else {
        while (glGetError() != GL_NO_ERROR) { } // clear previous unrelated errors

        glGenProgramsARB(1, &m_programId);

        GLenum glError = glGetError();
        if (glError != GL_NO_ERROR) {
            qWarning("QPainterVideoSurface: ARBfb Shader allocation error %x", int(glError));
            m_textureCount = 0;
            m_programId = 0;

            error = QAbstractVideoSurface::ResourceError;
        } else {
            glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_programId);
            glProgramStringARB(
                    GL_FRAGMENT_PROGRAM_ARB,
                    GL_PROGRAM_FORMAT_ASCII_ARB,
                    qstrlen(program),
                    reinterpret_cast<const GLvoid *>(program));

            if ((glError = glGetError()) != GL_NO_ERROR) {
                const GLubyte* errorString = glGetString(GL_PROGRAM_ERROR_STRING_ARB);

                qWarning("QPainterVideoSurface: ARBfp Shader compile error %x, %s",
                         int(glError),
                         reinterpret_cast<const char *>(errorString));
                glDeleteProgramsARB(1, &m_programId);

                m_textureCount = 0;
                m_programId = 0;

                error = QAbstractVideoSurface::ResourceError;
            } else {
                m_handleType = format.handleType();
                m_scanLineDirection = format.scanLineDirection();
                m_mirrored = format.property("mirrored").toBool();
                m_frameSize = format.frameSize();
                m_colorSpace = format.yCbCrColorSpace();

                if (m_handleType == QAbstractVideoBuffer::NoHandle)
                    glGenTextures(m_textureCount, m_textureIds);
            }
        }
    }

    return error;
}

void QVideoSurfaceArbFpPainter::stop()
{
    if (m_context) {
        if (m_handleType != QAbstractVideoBuffer::GLTextureHandle)
            glDeleteTextures(m_textureCount, m_textureIds);
        glDeleteProgramsARB(1, &m_programId);
    }

    m_textureCount = 0;
    m_programId = 0;
    m_handleType = QAbstractVideoBuffer::NoHandle;

    QVideoSurfaceGLPainter::stop();
}

QAbstractVideoSurface::Error QVideoSurfaceArbFpPainter::paint(
        const QRectF &target, QPainter *painter, const QRectF &source)
{
    if (!m_frame.isValid()) {
        painter->fillRect(target, Qt::black);
        return QAbstractVideoSurface::NoError;
    }

    const QAbstractVideoBuffer::HandleType h = m_frame.handleType();
    if (h == QAbstractVideoBuffer::NoHandle || h == QAbstractVideoBuffer::GLTextureHandle) {
        bool stencilTestEnabled = glIsEnabled(GL_STENCIL_TEST);
        bool scissorTestEnabled = glIsEnabled(GL_SCISSOR_TEST);

        painter->beginNativePainting();

        if (stencilTestEnabled)
            glEnable(GL_STENCIL_TEST);
        if (scissorTestEnabled)
            glEnable(GL_SCISSOR_TEST);

        const float txLeft = m_mirrored ? source.right() / m_frameSize.width()
                                        : source.left() / m_frameSize.width();
        const float txRight = m_mirrored ? source.left() / m_frameSize.width()
                                         : source.right() / m_frameSize.width();
        const float txTop = m_scanLineDirection == QVideoSurfaceFormat::TopToBottom
                ? source.top() / m_frameSize.height()
                : source.bottom() / m_frameSize.height();
        const float txBottom = m_scanLineDirection == QVideoSurfaceFormat::TopToBottom
                ? source.bottom() / m_frameSize.height()
                : source.top() / m_frameSize.height();

        const float tx_array[] =
        {
            txLeft , txBottom,
            txRight, txBottom,
            txLeft , txTop,
            txRight, txTop
        };

        const GLfloat v_array[] =
        {
            GLfloat(target.left())     , GLfloat(target.bottom() + 1),
            GLfloat(target.right() + 1), GLfloat(target.bottom() + 1),
            GLfloat(target.left())     , GLfloat(target.top()),
            GLfloat(target.right() + 1), GLfloat(target.top())
        };

        glEnable(GL_FRAGMENT_PROGRAM_ARB);
        glBindProgramARB(GL_FRAGMENT_PROGRAM_ARB, m_programId);

        glProgramLocalParameter4fARB(
                GL_FRAGMENT_PROGRAM_ARB,
                0,
                m_colorMatrix(0, 0),
                m_colorMatrix(0, 1),
                m_colorMatrix(0, 2),
                m_colorMatrix(0, 3));
        glProgramLocalParameter4fARB(
                GL_FRAGMENT_PROGRAM_ARB,
                1,
                m_colorMatrix(1, 0),
                m_colorMatrix(1, 1),
                m_colorMatrix(1, 2),
                m_colorMatrix(1, 3));
        glProgramLocalParameter4fARB(
                GL_FRAGMENT_PROGRAM_ARB,
                2,
                m_colorMatrix(2, 0),
                m_colorMatrix(2, 1),
                m_colorMatrix(2, 2),
                m_colorMatrix(2, 3));

        glActiveTexture(GL_TEXTURE0);
        glBindTexture(GL_TEXTURE_2D, m_textureIds[0]);

        if (m_textureCount == 3) {
            glActiveTexture(GL_TEXTURE1);
            glBindTexture(GL_TEXTURE_2D, m_textureIds[1]);
            glActiveTexture(GL_TEXTURE2);
            glBindTexture(GL_TEXTURE_2D, m_textureIds[2]);
            glActiveTexture(GL_TEXTURE0);
        }

        glVertexPointer(2, GL_FLOAT, 0, v_array);
        glTexCoordPointer(2, GL_FLOAT, 0, tx_array);

        glEnableClientState(GL_VERTEX_ARRAY);
        glEnableClientState(GL_TEXTURE_COORD_ARRAY);

        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

        glDisableClientState(GL_TEXTURE_COORD_ARRAY);
        glDisableClientState(GL_VERTEX_ARRAY);
        glDisable(GL_FRAGMENT_PROGRAM_ARB);

        painter->endNativePainting();

        return QAbstractVideoSurface::NoError;
    }

    return QVideoSurfaceGLPainter::paint(target, painter, source);
}

#endif // !QT_OPENGL_ES && !QT_OPENGL_DYNAMIC

static const char *qt_glsl_vertexShaderProgram =
        "attribute highp vec4 vertexCoordArray;\n"
        "attribute highp vec2 textureCoordArray;\n"
        "uniform highp mat4 positionMatrix;\n"
        "varying highp vec2 textureCoord;\n"
        "void main(void)\n"
        "{\n"
        "   gl_Position = positionMatrix * vertexCoordArray;\n"
        "   textureCoord = textureCoordArray;\n"
        "}\n";

// Paints an RGB32 frame
static const char *qt_glsl_xrgbShaderProgram =
        "uniform sampler2D texRgb;\n"
        "uniform mediump mat4 colorMatrix;\n"
        "varying highp vec2 textureCoord;\n"
        "void main(void)\n"
        "{\n"
        "    highp vec4 color = vec4(texture2D(texRgb, textureCoord.st).bgr, 1.0);\n"
        "    gl_FragColor = colorMatrix * color;\n"
        "}\n";

// Paints an ARGB frame.
static const char *qt_glsl_argbShaderProgram =
        "uniform sampler2D texRgb;\n"
        "uniform mediump mat4 colorMatrix;\n"
        "varying highp vec2 textureCoord;\n"
        "void main(void)\n"
        "{\n"
        "    highp vec4 color = vec4(texture2D(texRgb, textureCoord.st).bgr, 1.0);\n"
        "    color = colorMatrix * color;\n"
        "    gl_FragColor = vec4(color.rgb, texture2D(texRgb, textureCoord.st).a);\n"
        "}\n";

// Paints an RGB(A) frame.
static const char *qt_glsl_rgbShaderProgram =
        "uniform sampler2D texRgb;\n"
        "uniform mediump mat4 colorMatrix;\n"
        "varying highp vec2 textureCoord;\n"
        "void main(void)\n"
        "{\n"
        "    highp vec4 color = vec4(texture2D(texRgb, textureCoord.st).rgb, 1.0);\n"
        "    color = colorMatrix * color;\n"
        "    gl_FragColor = vec4(color.rgb, texture2D(texRgb, textureCoord.st).a);\n"
        "}\n";

// Paints a YUV420P or YV12 frame.
static const char *qt_glsl_yuvPlanarShaderProgram =
        "uniform sampler2D texY;\n"
        "uniform sampler2D texU;\n"
        "uniform sampler2D texV;\n"
        "uniform mediump mat4 colorMatrix;\n"
        "varying highp vec2 textureCoord;\n"
        "void main(void)\n"
        "{\n"
        "    highp vec4 color = vec4(\n"
        "           texture2D(texY, textureCoord.st).r,\n"
        "           texture2D(texU, textureCoord.st).r,\n"
        "           texture2D(texV, textureCoord.st).r,\n"
        "           1.0);\n"
        "    gl_FragColor = colorMatrix * color;\n"
        "}\n";

// Paints a YUV444 frame.
static const char *qt_glsl_xyuvShaderProgram =
        "uniform sampler2D texRgb;\n"
        "uniform mediump mat4 colorMatrix;\n"
        "varying highp vec2 textureCoord;\n"
        "void main(void)\n"
        "{\n"
        "    highp vec4 color = vec4(texture2D(texRgb, textureCoord.st).gba, 1.0);\n"
        "    gl_FragColor = colorMatrix * color;\n"
        "}\n";

// Paints a AYUV444 frame.
static const char *qt_glsl_ayuvShaderProgram =
        "uniform sampler2D texRgb;\n"
        "uniform mediump mat4 colorMatrix;\n"
        "varying highp vec2 textureCoord;\n"
        "void main(void)\n"
        "{\n"
        "    highp vec4 color = vec4(texture2D(texRgb, textureCoord.st).gba, 1.0);\n"
        "    color = colorMatrix * color;\n"
        "    gl_FragColor = vec4(color.rgb, texture2D(texRgb, textureCoord.st).r);\n"
        "}\n";

class QVideoSurfaceGlslPainter : public QVideoSurfaceGLPainter
{
public:
    QVideoSurfaceGlslPainter(QOpenGLContext *context);

    QAbstractVideoSurface::Error start(const QVideoSurfaceFormat &format) override;
    void stop() override;

    QAbstractVideoSurface::Error paint(
            const QRectF &target, QPainter *painter, const QRectF &source) override;

private:
    QOpenGLShaderProgram m_program;
    QSize m_frameSize;
};

QVideoSurfaceGlslPainter::QVideoSurfaceGlslPainter(QOpenGLContext *context)
    : QVideoSurfaceGLPainter(context)
    , m_program(context)
{
    m_imagePixelFormats
            << QVideoFrame::Format_RGB32
            << QVideoFrame::Format_BGR32
            << QVideoFrame::Format_ARGB32;
    if (!context->isOpenGLES()) {
        m_imagePixelFormats
            << QVideoFrame::Format_RGB24
            << QVideoFrame::Format_BGR24;
    }
    m_imagePixelFormats
            << QVideoFrame::Format_RGB565
            << QVideoFrame::Format_YUV444
            << QVideoFrame::Format_AYUV444
            << QVideoFrame::Format_YV12
            << QVideoFrame::Format_YUV420P;
    m_glPixelFormats
            << QVideoFrame::Format_RGB32
            << QVideoFrame::Format_ARGB32
            << QVideoFrame::Format_BGR32
            << QVideoFrame::Format_BGRA32;
}

QAbstractVideoSurface::Error QVideoSurfaceGlslPainter::start(const QVideoSurfaceFormat &format)
{
    Q_ASSERT(m_textureCount == 0);

    QAbstractVideoSurface::Error error = QAbstractVideoSurface::NoError;

    const char *fragmentProgram = 0;

    if (format.handleType() == QAbstractVideoBuffer::NoHandle) {
        switch (format.pixelFormat()) {
        case QVideoFrame::Format_RGB32:
            initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
            fragmentProgram = qt_glsl_xrgbShaderProgram;
            break;
        case QVideoFrame::Format_BGR32:
            initRgbTextureInfo(GL_RGB, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
            fragmentProgram = qt_glsl_rgbShaderProgram;
            break;
        case QVideoFrame::Format_ARGB32:
            initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
            fragmentProgram = qt_glsl_argbShaderProgram;
            break;
        case QVideoFrame::Format_RGB24:
            if (!m_context->isOpenGLES()) {
                initRgbTextureInfo(GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize());
                fragmentProgram = qt_glsl_rgbShaderProgram;
            }
            break;
        case QVideoFrame::Format_BGR24:
            if (!m_context->isOpenGLES()) {
                initRgbTextureInfo(GL_RGB8, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize());
                fragmentProgram = qt_glsl_argbShaderProgram;
            }
            break;
        case QVideoFrame::Format_RGB565:
            initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_SHORT_5_6_5, format.frameSize());
            fragmentProgram = qt_glsl_rgbShaderProgram;
            break;
        case QVideoFrame::Format_YUV444:
            initRgbTextureInfo(GL_RGB, GL_RGB, GL_UNSIGNED_BYTE, format.frameSize());
            fragmentProgram = qt_glsl_xyuvShaderProgram;
            m_yuv = true;
            break;
        case QVideoFrame::Format_AYUV444:
            initRgbTextureInfo(GL_RGBA, GL_RGBA, GL_UNSIGNED_BYTE, format.frameSize());
            fragmentProgram = qt_glsl_ayuvShaderProgram;
            m_yuv = true;
            break;
        case QVideoFrame::Format_YV12:
            initYv12TextureInfo(format.frameSize());
            fragmentProgram = qt_glsl_yuvPlanarShaderProgram;
            break;
        case QVideoFrame::Format_YUV420P:
            initYuv420PTextureInfo(format.frameSize());
            fragmentProgram = qt_glsl_yuvPlanarShaderProgram;
            break;
        default:
            break;
        }
    } else if (format.handleType() == QAbstractVideoBuffer::GLTextureHandle) {
        switch (format.pixelFormat()) {
        case QVideoFrame::Format_RGB32:
        case QVideoFrame::Format_ARGB32:
        case QVideoFrame::Format_BGR32:
        case QVideoFrame::Format_BGRA32:
            m_yuv = false;
            m_textureCount = 1;
            if (needsSwizzling(format))
                fragmentProgram = qt_glsl_xrgbShaderProgram;
            else
                fragmentProgram = qt_glsl_rgbShaderProgram;
            break;
        default:
            break;
        }
    } else if (format.handleType() == QAbstractVideoBuffer::QPixmapHandle) {
        m_handleType = QAbstractVideoBuffer::QPixmapHandle;
        return QAbstractVideoSurface::NoError;
    }

    if (!fragmentProgram) {
        error = QAbstractVideoSurface::UnsupportedFormatError;
    } else if (!m_program.addShaderFromSourceCode(QOpenGLShader::Vertex, qt_glsl_vertexShaderProgram)) {
        qWarning("QPainterVideoSurface: Vertex shader compile error %s",
                 qPrintable(m_program.log()));
        error = QAbstractVideoSurface::ResourceError;
    } else if (!m_program.addShaderFromSourceCode(QOpenGLShader::Fragment, fragmentProgram)) {
        qWarning("QPainterVideoSurface: Shader compile error %s", qPrintable(m_program.log()));
        error = QAbstractVideoSurface::ResourceError;
        m_program.removeAllShaders();
    } else if(!m_program.link()) {
        qWarning("QPainterVideoSurface: Shader link error %s", qPrintable(m_program.log()));
        m_program.removeAllShaders();
        error = QAbstractVideoSurface::ResourceError;
    } else {
        m_handleType = format.handleType();
        m_scanLineDirection = format.scanLineDirection();
        m_mirrored = format.property("mirrored").toBool();
        m_frameSize = format.frameSize();
        m_colorSpace = format.yCbCrColorSpace();

        if (m_handleType == QAbstractVideoBuffer::NoHandle)
            glGenTextures(m_textureCount, m_textureIds);
    }

    return error;
}

void QVideoSurfaceGlslPainter::stop()
{
    if (m_context) {
        if (m_handleType != QAbstractVideoBuffer::GLTextureHandle)
            glDeleteTextures(m_textureCount, m_textureIds);
    }

    m_program.removeAllShaders();

    m_textureCount = 0;
    m_handleType = QAbstractVideoBuffer::NoHandle;

    QVideoSurfaceGLPainter::stop();
}

QAbstractVideoSurface::Error QVideoSurfaceGlslPainter::paint(
        const QRectF &target, QPainter *painter, const QRectF &source)
{
    if (!m_frame.isValid()) {
        painter->fillRect(target, Qt::black);
        return QAbstractVideoSurface::NoError;
    }

    const QAbstractVideoBuffer::HandleType h = m_frame.handleType();
    if (h == QAbstractVideoBuffer::NoHandle || h == QAbstractVideoBuffer::GLTextureHandle) {
        bool stencilTestEnabled = glIsEnabled(GL_STENCIL_TEST);
        bool scissorTestEnabled = glIsEnabled(GL_SCISSOR_TEST);

        painter->beginNativePainting();

        if (stencilTestEnabled)
            glEnable(GL_STENCIL_TEST);
        if (scissorTestEnabled)
            glEnable(GL_SCISSOR_TEST);

        const int width = painter->viewport().width();
        const int height = painter->viewport().height();

        const QTransform transform = painter->deviceTransform();

        const GLfloat wfactor = 2.0 / width;
        const GLfloat hfactor = -2.0 / height;

        const GLfloat positionMatrix[4][4] =
        {
            {
                /*(0,0)*/ GLfloat(wfactor * transform.m11() - transform.m13()),
                /*(0,1)*/ GLfloat(hfactor * transform.m12() + transform.m13()),
                /*(0,2)*/ 0.0,
                /*(0,3)*/ GLfloat(transform.m13())
            }, {
                /*(1,0)*/ GLfloat(wfactor * transform.m21() - transform.m23()),
                /*(1,1)*/ GLfloat(hfactor * transform.m22() + transform.m23()),
                /*(1,2)*/ 0.0,
                /*(1,3)*/ GLfloat(transform.m23())
            }, {
                /*(2,0)*/ 0.0,
                /*(2,1)*/ 0.0,
                /*(2,2)*/ -1.0,
                /*(2,3)*/ 0.0
            }, {
                /*(3,0)*/ GLfloat(wfactor * transform.dx() - transform.m33()),
                /*(3,1)*/ GLfloat(hfactor * transform.dy() + transform.m33()),
                /*(3,2)*/ 0.0,
                /*(3,3)*/ GLfloat(transform.m33())
            }
        };

        const GLfloat vertexCoordArray[] =
        {
            GLfloat(target.left())     , GLfloat(target.bottom() + 1),
            GLfloat(target.right() + 1), GLfloat(target.bottom() + 1),
            GLfloat(target.left())     , GLfloat(target.top()),
            GLfloat(target.right() + 1), GLfloat(target.top())
        };

        const GLfloat txLeft = m_mirrored ? source.right() / m_frameSize.width()
                                          : source.left() / m_frameSize.width();
        const GLfloat txRight = m_mirrored ? source.left() / m_frameSize.width()
                                           : source.right() / m_frameSize.width();
        const GLfloat txTop = m_scanLineDirection == QVideoSurfaceFormat::TopToBottom
                ? source.top() / m_frameSize.height()
                : source.bottom() / m_frameSize.height();
        const GLfloat txBottom = m_scanLineDirection == QVideoSurfaceFormat::TopToBottom
                ? source.bottom() / m_frameSize.height()
                : source.top() / m_frameSize.height();

        const GLfloat textureCoordArray[] =
        {
            txLeft , txBottom,
            txRight, txBottom,
            txLeft , txTop,
            txRight, txTop
        };

        m_program.bind();

        m_program.enableAttributeArray("vertexCoordArray");
        m_program.enableAttributeArray("textureCoordArray");
        m_program.setAttributeArray("vertexCoordArray", vertexCoordArray, 2);
        m_program.setAttributeArray("textureCoordArray", textureCoordArray, 2);
        m_program.setUniformValue("positionMatrix", positionMatrix);

        if (m_textureCount == 3) {
            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_2D, m_textureIds[0]);
            glActiveTexture(GL_TEXTURE1);
            glBindTexture(GL_TEXTURE_2D, m_textureIds[1]);
            glActiveTexture(GL_TEXTURE2);
            glBindTexture(GL_TEXTURE_2D, m_textureIds[2]);
            glActiveTexture(GL_TEXTURE0);

            m_program.setUniformValue("texY", 0);
            m_program.setUniformValue("texU", 1);
            m_program.setUniformValue("texV", 2);
        } else {
            glActiveTexture(GL_TEXTURE0);
            glBindTexture(GL_TEXTURE_2D, m_textureIds[0]);

            m_program.setUniformValue("texRgb", 0);
        }
        m_program.setUniformValue("colorMatrix", m_colorMatrix);

        glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);

        m_program.release();

        painter->endNativePainting();

        return QAbstractVideoSurface::NoError;
    }

    return QVideoSurfaceGLPainter::paint(target, painter, source);
}

#endif

/*!
    \class QPainterVideoSurface
    \internal
*/

/*!
*/
QPainterVideoSurface::QPainterVideoSurface(QObject *parent)
    : QAbstractVideoSurface(parent)
    , m_painter(0)
#if QT_CONFIG(opengl)
    , m_glContext(0)
    , m_shaderTypes(NoShaders)
    , m_shaderType(NoShaders)
#endif
    , m_brightness(0)
    , m_contrast(0)
    , m_hue(0)
    , m_saturation(0)
    , m_pixelFormat(QVideoFrame::Format_Invalid)
    , m_colorsDirty(true)
    , m_ready(false)
{
}

/*!
*/
QPainterVideoSurface::~QPainterVideoSurface()
{
    if (isActive())
        m_painter->stop();

    delete m_painter;
}

/*!
*/
QList<QVideoFrame::PixelFormat> QPainterVideoSurface::supportedPixelFormats(
        QAbstractVideoBuffer::HandleType handleType) const
{
    if (!m_painter)
        const_cast<QPainterVideoSurface *>(this)->createPainter();

    return m_painter->supportedPixelFormats(handleType);
}

/*!
*/
bool QPainterVideoSurface::isFormatSupported(const QVideoSurfaceFormat &format) const
{
    if (!m_painter)
        const_cast<QPainterVideoSurface *>(this)->createPainter();

    return m_painter->isFormatSupported(format);
}

/*!
*/
bool QPainterVideoSurface::start(const QVideoSurfaceFormat &format)
{
    if (isActive())
        m_painter->stop();

    if (!m_painter)
        createPainter();

    if (format.frameSize().isEmpty()) {
        setError(UnsupportedFormatError);
    } else {
        QAbstractVideoSurface::Error error = m_painter->start(format);

        if (error != QAbstractVideoSurface::NoError) {
            setError(error);
        } else {
            m_pixelFormat = format.pixelFormat();
            m_frameSize = format.frameSize();
            m_sourceRect = format.viewport();
            m_colorsDirty = true;
            m_ready = true;

            return QAbstractVideoSurface::start(format);
        }
    }

    QAbstractVideoSurface::stop();

    return false;
}

/*!
*/
void QPainterVideoSurface::stop()
{
    if (isActive()) {
        m_painter->stop();
        m_ready = false;

        QAbstractVideoSurface::stop();
    }
}

/*!
*/
bool QPainterVideoSurface::present(const QVideoFrame &frame)
{
    if (!m_ready) {
        if (!isActive()) {
            setError(StoppedError);
            return false;
        }
    } else if (frame.isValid()
            && (frame.pixelFormat() != m_pixelFormat || frame.size() != m_frameSize)) {
        setError(IncorrectFormatError);

        stop();
        return false;
    } else {
        QAbstractVideoSurface::Error error = m_painter->setCurrentFrame(frame);
        if (error != QAbstractVideoSurface::NoError) {
            setError(error);
            stop();
            return false;
        }

        m_ready = false;
        emit frameChanged();
    }
    return true;
}

/*!
*/
int QPainterVideoSurface::brightness() const
{
    return m_brightness;
}

/*!
*/
void QPainterVideoSurface::setBrightness(int brightness)
{
    m_brightness = brightness;

    m_colorsDirty = true;
}

/*!
*/
int QPainterVideoSurface::contrast() const
{
    return m_contrast;
}

/*!
*/
void QPainterVideoSurface::setContrast(int contrast)
{
    m_contrast = contrast;

    m_colorsDirty = true;
}

/*!
*/
int QPainterVideoSurface::hue() const
{
    return m_hue;
}

/*!
*/
void QPainterVideoSurface::setHue(int hue)
{
    m_hue = hue;

    m_colorsDirty = true;
}

/*!
*/
int QPainterVideoSurface::saturation() const
{
    return m_saturation;
}

/*!
*/
void QPainterVideoSurface::setSaturation(int saturation)
{
    m_saturation = saturation;

    m_colorsDirty = true;
}

/*!
*/
bool QPainterVideoSurface::isReady() const
{
    return m_ready;
}

/*!
*/
void QPainterVideoSurface::setReady(bool ready)
{
    m_ready = ready;
}

/*!
*/
void QPainterVideoSurface::paint(QPainter *painter, const QRectF &target, const QRectF &source)
{
    if (!isActive()) {
        painter->fillRect(target, QBrush(Qt::black));
    } else {
        if (m_colorsDirty) {
            m_painter->updateColors(m_brightness, m_contrast, m_hue, m_saturation);
            m_colorsDirty = false;
        }

        const QRectF sourceRect(
                m_sourceRect.x() + m_sourceRect.width() * source.x(),
                m_sourceRect.y() + m_sourceRect.height() * source.y(),
                m_sourceRect.width() * source.width(),
                m_sourceRect.height() * source.height());

        QAbstractVideoSurface::Error error = m_painter->paint(target, painter, sourceRect);

        if (error != QAbstractVideoSurface::NoError) {
            setError(error);

            stop();
        }
    }
}

/*!
    \fn QPainterVideoSurface::frameChanged()
*/

#if QT_CONFIG(opengl)

/*!
*/
const QOpenGLContext *QPainterVideoSurface::glContext() const
{
    return m_glContext;
}

/*!
*/
void QPainterVideoSurface::updateGLContext()
{
    auto oldContext = m_glContext;
    m_glContext = QOpenGLContext::currentContext();
    if (oldContext == m_glContext)
        return;

    m_shaderTypes = NoShaders;

    if (m_glContext) {
        //Set a dynamic property to access the OpenGL context
        this->setProperty("GLContext", QVariant::fromValue<QObject *>(m_glContext));

        const QByteArray extensions(reinterpret_cast<const char *>(
            m_glContext->functions()->glGetString(GL_EXTENSIONS)));
#if !defined(QT_OPENGL_ES) && !defined(QT_OPENGL_DYNAMIC)
        if (extensions.contains("ARB_fragment_program"))
            m_shaderTypes |= FragmentProgramShader;
#endif
        if (QOpenGLShaderProgram::hasOpenGLShaderPrograms(m_glContext)
#if !defined(QT_OPENGL_ES_2) && !defined(QT_OPENGL_DYNAMIC)
                && extensions.contains("ARB_shader_objects")
#endif
            )
            m_shaderTypes |= GlslShader;
    }

    ShaderType type = (m_shaderType & m_shaderTypes)
            ? m_shaderType
            : NoShaders;

    if (type != m_shaderType || type != NoShaders) {
        m_shaderType = type;

        if (isActive()) {
            m_painter->stop();
            delete m_painter;
            m_painter = 0;
            m_ready = false;

            setError(ResourceError);
            QAbstractVideoSurface::stop();
        }
        emit supportedFormatsChanged();
    }
}

/*!
    \enum QPainterVideoSurface::ShaderType

    \value NoShaders
    \value FragmentProgramShader
    \value HlslShader
*/

/*!
    \typedef QPainterVideoSurface::ShaderTypes
*/

/*!
*/
QPainterVideoSurface::ShaderTypes QPainterVideoSurface::supportedShaderTypes() const
{
    return m_shaderTypes;
}

/*!
*/
QPainterVideoSurface::ShaderType QPainterVideoSurface::shaderType() const
{
    return m_shaderType;
}

/*!
*/
void QPainterVideoSurface::setShaderType(ShaderType type)
{
    if (!(type & m_shaderTypes))
        type = NoShaders;

    if (type != m_shaderType) {
        m_shaderType = type;

        if (isActive()) {
            m_painter->stop();
            delete m_painter;
            m_painter = 0;
            m_ready = false;

            setError(ResourceError);
            QAbstractVideoSurface::stop();
        } else {
            delete m_painter;
            m_painter = 0;
        }
        emit supportedFormatsChanged();
    }
}

#endif

void QPainterVideoSurface::viewportDestroyed()
{
    if (m_painter) {
        m_painter->viewportDestroyed();

        setError(ResourceError);
        stop();
        delete m_painter;
        m_painter = 0;
    }
}

void QPainterVideoSurface::createPainter()
{
    Q_ASSERT(!m_painter);

#if QT_CONFIG(opengl)
    switch (m_shaderType) {
#if !defined(QT_OPENGL_ES) && !defined(QT_OPENGL_DYNAMIC)
    case FragmentProgramShader:
        Q_ASSERT(m_glContext);
        m_painter = new QVideoSurfaceArbFpPainter(m_glContext);
        break;
#endif // !QT_OPENGL_ES && !QT_OPENGL_DYNAMIC
    case GlslShader:
        Q_ASSERT(m_glContext);
        m_painter = new QVideoSurfaceGlslPainter(m_glContext);
        break;
    default:
        m_painter = new QVideoSurfaceGenericPainter;
        break;
    }
#else
    m_painter = new QVideoSurfaceGenericPainter;
#endif
}

QT_END_NAMESPACE

#include "moc_qpaintervideosurface_p.cpp"
