/****************************************************************************
**
** Copyright (C) 2016 The Qt Company Ltd.
** Contact: https://www.qt.io/licensing/
**
** This file is part of the QtOpenGL module of the Qt Toolkit.
**
** $QT_BEGIN_LICENSE:LGPL$
** Commercial License Usage
** Licensees holding valid commercial Qt licenses may use this file in
** accordance with the commercial license agreement provided with the
** Software or, alternatively, in accordance with the terms contained in
** a written agreement between you and The Qt Company. For licensing terms
** and conditions see https://www.qt.io/terms-conditions. For further
** information use the contact form at https://www.qt.io/contact-us.
**
** GNU Lesser General Public License Usage
** Alternatively, this file may be used under the terms of the GNU Lesser
** General Public License version 3 as published by the Free Software
** Foundation and appearing in the file LICENSE.LGPL3 included in the
** packaging of this file. Please review the following information to
** ensure the GNU Lesser General Public License version 3 requirements
** will be met: https://www.gnu.org/licenses/lgpl-3.0.html.
**
** GNU General Public License Usage
** Alternatively, this file may be used under the terms of the GNU
** General Public License version 2.0 or (at your option) the GNU General
** Public license version 3 or any later version approved by the KDE Free
** Qt Foundation. The licenses are as published by the Free Software
** Foundation and appearing in the file LICENSE.GPL2 and LICENSE.GPL3
** included in the packaging of this file. Please review the following
** information to ensure the GNU General Public License requirements will
** be met: https://www.gnu.org/licenses/gpl-2.0.html and
** https://www.gnu.org/licenses/gpl-3.0.html.
**
** $QT_END_LICENSE$
**
****************************************************************************/

#include "qglframebufferobject.h"
#include "qglframebufferobject_p.h"

#include <qdebug.h>
#include <private/qgl_p.h>
#include <private/qfont_p.h>
#include "gl2paintengineex/qpaintengineex_opengl2_p.h"

#include <qimage.h>
#include <qwindow.h>

QT_BEGIN_NAMESPACE

extern QImage qt_gl_read_frame_buffer(const QSize&, bool, bool);

#define QGL_FUNC_CONTEXT const QGLContext *ctx = QGLContext::currentContext();
#define QGL_FUNCP_CONTEXT const QGLContext *ctx = QGLContext::currentContext();

#ifndef QT_NO_DEBUG
#define QT_RESET_GLERROR()                                \
{                                                         \
    while (QOpenGLContext::currentContext()->functions()->glGetError() != GL_NO_ERROR) {} \
}
#define QT_CHECK_GLERROR()                                \
{                                                         \
    GLenum err = QOpenGLContext::currentContext()->functions()->glGetError(); \
    if (err != GL_NO_ERROR) {                             \
        qDebug("[%s line %d] GL Error: %d",               \
               __FILE__, __LINE__, (int)err);             \
    }                                                     \
}
#else
#define QT_RESET_GLERROR() {}
#define QT_CHECK_GLERROR() {}
#endif

// ####TODO Properly #ifdef this class to use #define symbols actually defined
// by OpenGL/ES includes
#ifndef GL_MAX_SAMPLES
#define GL_MAX_SAMPLES 0x8D57
#endif

#ifndef GL_RENDERBUFFER_SAMPLES
#define GL_RENDERBUFFER_SAMPLES 0x8CAB
#endif

#ifndef GL_DEPTH24_STENCIL8
#define GL_DEPTH24_STENCIL8 0x88F0
#endif

#ifndef GL_DEPTH_COMPONENT24
#define GL_DEPTH_COMPONENT24 0x81A6
#endif

#ifndef GL_DEPTH_COMPONENT24_OES
#define GL_DEPTH_COMPONENT24_OES 0x81A6
#endif

#ifndef GL_READ_FRAMEBUFFER
#define GL_READ_FRAMEBUFFER 0x8CA8
#endif

#ifndef GL_DRAW_FRAMEBUFFER
#define GL_DRAW_FRAMEBUFFER 0x8CA9
#endif

#ifndef GL_DEPTH_STENCIL_ATTACHMENT
#define GL_DEPTH_STENCIL_ATTACHMENT 0x821A
#endif

#ifndef GL_DEPTH_STENCIL
#define GL_DEPTH_STENCIL 0x84F9
#endif

/*!
    \class QGLFramebufferObjectFormat
    \inmodule QtOpenGL
    \brief The QGLFramebufferObjectFormat class specifies the format of an OpenGL
    framebuffer object.

    \since 4.6
    \obsolete

    \ingroup painting-3D

    A framebuffer object has several characteristics:
    \list
    \li \l{setSamples()}{Number of samples per pixels.}
    \li \l{setAttachment()}{Depth and/or stencil attachments.}
    \li \l{setTextureTarget()}{Texture target.}
    \li \l{setInternalTextureFormat()}{Internal texture format.}
    \endlist

    Note that the desired attachments or number of samples per pixels might not
    be supported by the hardware driver. Call QGLFramebufferObject::format()
    after creating a QGLFramebufferObject to find the exact format that was
    used to create the frame buffer object.

    \note This class has been deprecated in favor of QOpenGLFramebufferObjectFormat.

    \sa QGLFramebufferObject
*/

/*!
    \internal
*/
void QGLFramebufferObjectFormat::detach()
{
    if (d->ref.loadRelaxed() != 1) {
        QGLFramebufferObjectFormatPrivate *newd
            = new QGLFramebufferObjectFormatPrivate(d);
        if (!d->ref.deref())
            delete d;
        d = newd;
    }
}

/*!
    Creates a QGLFramebufferObjectFormat object for specifying
    the format of an OpenGL framebuffer object.

    By default the format specifies a non-multisample framebuffer object with no
    attachments, texture target \c GL_TEXTURE_2D, and internal format \c GL_RGBA8.
    On OpenGL/ES systems, the default internal format is \c GL_RGBA.

    \sa samples(), attachment(), internalTextureFormat()
*/

QGLFramebufferObjectFormat::QGLFramebufferObjectFormat()
{
    d = new QGLFramebufferObjectFormatPrivate;
}

/*!
    Constructs a copy of \a other.
*/

QGLFramebufferObjectFormat::QGLFramebufferObjectFormat(const QGLFramebufferObjectFormat &other)
{
    d = other.d;
    d->ref.ref();
}

/*!
    Assigns \a other to this object.
*/

QGLFramebufferObjectFormat &QGLFramebufferObjectFormat::operator=(const QGLFramebufferObjectFormat &other)
{
    if (d != other.d) {
        other.d->ref.ref();
        if (!d->ref.deref())
            delete d;
        d = other.d;
    }
    return *this;
}

/*!
    Destroys the QGLFramebufferObjectFormat.
*/
QGLFramebufferObjectFormat::~QGLFramebufferObjectFormat()
{
    if (!d->ref.deref())
        delete d;
}

/*!
    Sets the number of samples per pixel for a multisample framebuffer object
    to \a samples.  The default sample count of 0 represents a regular
    non-multisample framebuffer object.

    If the desired amount of samples per pixel is not supported by the hardware
    then the maximum number of samples per pixel will be used. Note that
    multisample framebuffer objects cannot be bound as textures. Also, the
    \c{GL_EXT_framebuffer_multisample} extension is required to create a
    framebuffer with more than one sample per pixel.

    \sa samples()
*/
void QGLFramebufferObjectFormat::setSamples(int samples)
{
    detach();
    d->samples = samples;
}

/*!
    Returns the number of samples per pixel if a framebuffer object
    is a multisample framebuffer object. Otherwise, returns 0.
    The default value is 0.

    \sa setSamples()
*/
int QGLFramebufferObjectFormat::samples() const
{
    return d->samples;
}

/*!
    \since 4.8

    Enables mipmapping if \a enabled is true; otherwise disables it.

    Mipmapping is disabled by default.

    If mipmapping is enabled, additional memory will be allocated for
    the mipmap levels. The mipmap levels can be updated by binding the
    texture and calling glGenerateMipmap(). Mipmapping cannot be enabled
    for multisampled framebuffer objects.

    \sa mipmap(), QGLFramebufferObject::texture()
*/
void QGLFramebufferObjectFormat::setMipmap(bool enabled)
{
    detach();
    d->mipmap = enabled;
}

/*!
    \since 4.8

    Returns \c true if mipmapping is enabled.

    \sa setMipmap()
*/
bool QGLFramebufferObjectFormat::mipmap() const
{
    return d->mipmap;
}

/*!
    Sets the attachment configuration of a framebuffer object to \a attachment.

    \sa attachment()
*/
void QGLFramebufferObjectFormat::setAttachment(QGLFramebufferObject::Attachment attachment)
{
    detach();
    d->attachment = attachment;
}

/*!
    Returns the configuration of the depth and stencil buffers attached to
    a framebuffer object.  The default is QGLFramebufferObject::NoAttachment.

    \sa setAttachment()
*/
QGLFramebufferObject::Attachment QGLFramebufferObjectFormat::attachment() const
{
    return d->attachment;
}

/*!
    Sets the texture target of the texture attached to a framebuffer object to
    \a target. Ignored for multisample framebuffer objects.

    \sa textureTarget(), samples()
*/
void QGLFramebufferObjectFormat::setTextureTarget(GLenum target)
{
    detach();
    d->target = target;
}

/*!
    Returns the texture target of the texture attached to a framebuffer object.
    Ignored for multisample framebuffer objects.  The default is
    \c GL_TEXTURE_2D.

    \sa setTextureTarget(), samples()
*/
GLenum QGLFramebufferObjectFormat::textureTarget() const
{
    return d->target;
}

/*!
    Sets the internal format of a framebuffer object's texture or
    multisample framebuffer object's color buffer to
    \a internalTextureFormat.

    \sa internalTextureFormat()
*/
void QGLFramebufferObjectFormat::setInternalTextureFormat(GLenum internalTextureFormat)
{
    detach();
    d->internal_format = internalTextureFormat;
}

/*!
    Returns the internal format of a framebuffer object's texture or
    multisample framebuffer object's color buffer.  The default is
    \c GL_RGBA8 on desktop OpenGL systems, and \c GL_RGBA on
    OpenGL/ES systems.

    \sa setInternalTextureFormat()
*/
GLenum QGLFramebufferObjectFormat::internalTextureFormat() const
{
    return d->internal_format;
}

/*!
    Returns \c true if all the options of this framebuffer object format
    are the same as \a other; otherwise returns \c false.
*/
bool QGLFramebufferObjectFormat::operator==(const QGLFramebufferObjectFormat& other) const
{
    if (d == other.d)
        return true;
    else
        return d->equals(other.d);
}

/*!
    Returns \c false if all the options of this framebuffer object format
    are the same as \a other; otherwise returns \c true.
*/
bool QGLFramebufferObjectFormat::operator!=(const QGLFramebufferObjectFormat& other) const
{
    return !(*this == other);
}

void QGLFBOGLPaintDevice::setFBO(QGLFramebufferObject* f,
                                 QGLFramebufferObject::Attachment attachment)
{
    fbo = f;
    m_thisFBO = fbo->d_func()->fbo(); // This shouldn't be needed

    // The context that the fbo was created in may not have depth
    // and stencil buffers, but the fbo itself might.
    fboFormat = QGLContext::currentContext()->format();
    if (attachment == QGLFramebufferObject::CombinedDepthStencil) {
        fboFormat.setDepth(true);
        fboFormat.setStencil(true);
    } else if (attachment == QGLFramebufferObject::Depth) {
        fboFormat.setDepth(true);
        fboFormat.setStencil(false);
    } else {
        fboFormat.setDepth(false);
        fboFormat.setStencil(false);
    }

    GLenum format = f->format().internalTextureFormat();
    reqAlpha = (format != GL_RGB
#ifdef GL_RGB5
                && format != GL_RGB5
#endif
#ifdef GL_RGB8
                && format != GL_RGB8
#endif
    );
}

QGLContext *QGLFBOGLPaintDevice::context() const
{
    return const_cast<QGLContext *>(QGLContext::currentContext());
}

bool QGLFramebufferObjectPrivate::checkFramebufferStatus() const
{
    QGL_FUNCP_CONTEXT;
    if (!ctx)
        return false;   // Context no longer exists.
    GLenum status = ctx->contextHandle()->functions()->glCheckFramebufferStatus(GL_FRAMEBUFFER);
    switch(status) {
    case GL_NO_ERROR:
    case GL_FRAMEBUFFER_COMPLETE:
        return true;
    case GL_FRAMEBUFFER_UNSUPPORTED:
        qDebug("QGLFramebufferObject: Unsupported framebuffer format.");
        break;
    case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT:
        qDebug("QGLFramebufferObject: Framebuffer incomplete attachment.");
        break;
    case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT:
        qDebug("QGLFramebufferObject: Framebuffer incomplete, missing attachment.");
        break;
#ifdef GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT
    case GL_FRAMEBUFFER_INCOMPLETE_DUPLICATE_ATTACHMENT:
        qDebug("QGLFramebufferObject: Framebuffer incomplete, duplicate attachment.");
        break;
#endif
#ifdef GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS
    case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS:
        qDebug("QGLFramebufferObject: Framebuffer incomplete, attached images must have same dimensions.");
        break;
#endif
#ifdef GL_FRAMEBUFFER_INCOMPLETE_FORMATS
    case GL_FRAMEBUFFER_INCOMPLETE_FORMATS:
        qDebug("QGLFramebufferObject: Framebuffer incomplete, attached images must have same format.");
        break;
#endif
#ifdef GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER
    case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER:
        qDebug("QGLFramebufferObject: Framebuffer incomplete, missing draw buffer.");
        break;
#endif
#ifdef GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER
    case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER:
        qDebug("QGLFramebufferObject: Framebuffer incomplete, missing read buffer.");
        break;
#endif
#ifdef GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE
    case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE:
        qDebug("QGLFramebufferObject: Framebuffer incomplete, attachments must have same number of samples per pixel.");
        break;
#endif
    default:
        qDebug() <<"QGLFramebufferObject: An undefined error has occurred: "<< status;
        break;
    }
    return false;
}

namespace
{
    void freeFramebufferFunc(QGLContext *ctx, GLuint id)
    {
        Q_ASSERT(ctx);
        ctx->contextHandle()->functions()->glDeleteFramebuffers(1, &id);
    }

    void freeRenderbufferFunc(QGLContext *ctx, GLuint id)
    {
        Q_ASSERT(ctx);
        ctx->contextHandle()->functions()->glDeleteRenderbuffers(1, &id);
    }

    void freeTextureFunc(QGLContext *ctx, GLuint id)
    {
        Q_UNUSED(ctx);
        ctx->contextHandle()->functions()->glDeleteTextures(1, &id);
    }
}

void QGLFramebufferObjectPrivate::init(QGLFramebufferObject *q, const QSize &sz,
                                       QGLFramebufferObject::Attachment attachment,
                                       GLenum texture_target, GLenum internal_format,
                                       GLint samples, bool mipmap)
{
    QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());

    funcs.initializeOpenGLFunctions();

    if (!funcs.hasOpenGLFeature(QOpenGLFunctions::Framebuffers))
        return;

    ctx->d_ptr->refreshCurrentFbo();

    size = sz;
    target = texture_target;
    // texture dimensions

    QT_RESET_GLERROR(); // reset error state
    GLuint fbo = 0;
    funcs.glGenFramebuffers(1, &fbo);
    funcs.glBindFramebuffer(GL_FRAMEBUFFER, fbo);

    GLuint texture = 0;
    GLuint color_buffer = 0;
    GLuint depth_buffer = 0;
    GLuint stencil_buffer = 0;

    QT_CHECK_GLERROR();
    // init texture
    if (samples == 0) {
        funcs.glGenTextures(1, &texture);
        funcs.glBindTexture(target, texture);
        funcs.glTexImage2D(target, 0, internal_format, size.width(), size.height(), 0,
                           GL_RGBA, GL_UNSIGNED_BYTE, NULL);
        if (mipmap) {
            int width = size.width();
            int height = size.height();
            int level = 0;
            while (width > 1 || height > 1) {
                width = qMax(1, width >> 1);
                height = qMax(1, height >> 1);
                ++level;
                funcs.glTexImage2D(target, level, internal_format, width, height, 0,
                                   GL_RGBA, GL_UNSIGNED_BYTE, NULL);
            }
        }
        funcs.glTexParameteri(target, GL_TEXTURE_MIN_FILTER, GL_NEAREST);
        funcs.glTexParameteri(target, GL_TEXTURE_MAG_FILTER, GL_NEAREST);
        funcs.glTexParameteri(target, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
        funcs.glTexParameteri(target, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
        funcs.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                target, texture, 0);

        QT_CHECK_GLERROR();
        valid = checkFramebufferStatus();
        funcs.glBindTexture(target, 0);

        color_buffer = 0;
    } else {
        mipmap = false;
        GLint maxSamples;
        funcs.glGetIntegerv(GL_MAX_SAMPLES, &maxSamples);

        samples = qBound(0, int(samples), int(maxSamples));

        funcs.glGenRenderbuffers(1, &color_buffer);
        funcs.glBindRenderbuffer(GL_RENDERBUFFER, color_buffer);
        if (funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample) && samples > 0) {
            funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
                internal_format, size.width(), size.height());
        } else {
            samples = 0;
            funcs.glRenderbufferStorage(GL_RENDERBUFFER, internal_format,
                size.width(), size.height());
        }

        funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0,
                                     GL_RENDERBUFFER, color_buffer);

        QT_CHECK_GLERROR();
        valid = checkFramebufferStatus();

        if (valid)
            funcs.glGetRenderbufferParameteriv(GL_RENDERBUFFER, GL_RENDERBUFFER_SAMPLES, &samples);
    }

    // In practice, a combined depth-stencil buffer is supported by all desktop platforms, while a
    // separate stencil buffer is not. On embedded devices however, a combined depth-stencil buffer
    // might not be supported while separate buffers are, according to QTBUG-12861.

    if (attachment == QGLFramebufferObject::CombinedDepthStencil
        && funcs.hasOpenGLExtension(QOpenGLExtensions::PackedDepthStencil)) {
        // depth and stencil buffer needs another extension
        funcs.glGenRenderbuffers(1, &depth_buffer);
        funcs.glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer);
        Q_ASSERT(funcs.glIsRenderbuffer(depth_buffer));
#ifndef Q_OS_WASM
        if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample))
            funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
                GL_DEPTH24_STENCIL8, size.width(), size.height());
        else
            funcs.glRenderbufferStorage(GL_RENDERBUFFER,
                GL_DEPTH24_STENCIL8, size.width(), size.height());

        stencil_buffer = depth_buffer;
        funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
                                     GL_RENDERBUFFER, depth_buffer);
        funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
                                     GL_RENDERBUFFER, stencil_buffer);
#else
        // webgl does not allow separate depth and stencil attachments
        if (samples != 0) {
            funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
                                                   GL_DEPTH_STENCIL, size.width(), size.height());
        } else {
            funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_STENCIL,
                                        size.width(), size.height());
        }
        stencil_buffer = depth_buffer;
        funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_STENCIL_ATTACHMENT,
                                        GL_RENDERBUFFER, depth_buffer);
#endif

        valid = checkFramebufferStatus();
        if (!valid) {
            funcs.glDeleteRenderbuffers(1, &depth_buffer);
            stencil_buffer = depth_buffer = 0;
        }
    }

    if (depth_buffer == 0 && (attachment == QGLFramebufferObject::CombinedDepthStencil
        || (attachment == QGLFramebufferObject::Depth)))
    {
        funcs.glGenRenderbuffers(1, &depth_buffer);
        funcs.glBindRenderbuffer(GL_RENDERBUFFER, depth_buffer);
        Q_ASSERT(funcs.glIsRenderbuffer(depth_buffer));
        if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample)) {
#ifdef QT_OPENGL_ES
            if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) {
                funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
                    GL_DEPTH_COMPONENT24_OES, size.width(), size.height());
            } else {
                funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
                    GL_DEPTH_COMPONENT16, size.width(), size.height());
            }
#else
            if (ctx->contextHandle()->isOpenGLES()) {
                if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24))
                    funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
                                                           GL_DEPTH_COMPONENT24, size.width(), size.height());
                else
                    funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
                                                           GL_DEPTH_COMPONENT16, size.width(), size.height());
            } else {
                funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples,
                                                       GL_DEPTH_COMPONENT, size.width(), size.height());
            }
#endif
        } else {
#ifdef QT_OPENGL_ES
            if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) {
                funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24_OES,
                                        size.width(), size.height());
            } else {
                funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
                                        size.width(), size.height());
            }
#else
            if (ctx->contextHandle()->isOpenGLES()) {
                if (funcs.hasOpenGLExtension(QOpenGLExtensions::Depth24)) {
                    funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT24,
                                                size.width(), size.height());
                } else {
                    funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT16,
                                                size.width(), size.height());
                }
            } else {
                funcs.glRenderbufferStorage(GL_RENDERBUFFER, GL_DEPTH_COMPONENT, size.width(), size.height());
            }
#endif
        }
        funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_DEPTH_ATTACHMENT,
                                     GL_RENDERBUFFER, depth_buffer);
        valid = checkFramebufferStatus();
        if (!valid) {
            funcs.glDeleteRenderbuffers(1, &depth_buffer);
            depth_buffer = 0;
        }
    }

    if (stencil_buffer == 0 && (attachment == QGLFramebufferObject::CombinedDepthStencil)) {
        funcs.glGenRenderbuffers(1, &stencil_buffer);
        funcs.glBindRenderbuffer(GL_RENDERBUFFER, stencil_buffer);
        Q_ASSERT(funcs.glIsRenderbuffer(stencil_buffer));

#ifdef QT_OPENGL_ES
        GLenum storage = GL_STENCIL_INDEX8;
#else
        GLenum storage = ctx->contextHandle()->isOpenGLES() ? GL_STENCIL_INDEX8 : GL_STENCIL_INDEX;
#endif

        if (samples != 0 && funcs.hasOpenGLExtension(QOpenGLExtensions::FramebufferMultisample))
            funcs.glRenderbufferStorageMultisample(GL_RENDERBUFFER, samples, storage, size.width(), size.height());
        else
            funcs.glRenderbufferStorage(GL_RENDERBUFFER, storage, size.width(), size.height());

        funcs.glFramebufferRenderbuffer(GL_FRAMEBUFFER, GL_STENCIL_ATTACHMENT,
                                  GL_RENDERBUFFER, stencil_buffer);
        valid = checkFramebufferStatus();
        if (!valid) {
            funcs.glDeleteRenderbuffers(1, &stencil_buffer);
            stencil_buffer = 0;
        }
    }

    // The FBO might have become valid after removing the depth or stencil buffer.
    valid = checkFramebufferStatus();

    if (depth_buffer && stencil_buffer) {
        fbo_attachment = QGLFramebufferObject::CombinedDepthStencil;
    } else if (depth_buffer) {
        fbo_attachment = QGLFramebufferObject::Depth;
    } else {
        fbo_attachment = QGLFramebufferObject::NoAttachment;
    }

    funcs.glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_ptr->current_fbo);
    if (valid) {
        fbo_guard = createSharedResourceGuard(ctx, fbo, freeFramebufferFunc);
        if (color_buffer)
            color_buffer_guard = createSharedResourceGuard(ctx, color_buffer, freeRenderbufferFunc);
        else
            texture_guard = createSharedResourceGuard(ctx, texture, freeTextureFunc);
        if (depth_buffer)
            depth_buffer_guard = createSharedResourceGuard(ctx, depth_buffer, freeRenderbufferFunc);
        if (stencil_buffer) {
            if (stencil_buffer == depth_buffer)
                stencil_buffer_guard = depth_buffer_guard;
            else
                stencil_buffer_guard = createSharedResourceGuard(ctx, stencil_buffer, freeRenderbufferFunc);
        }
    } else {
        if (color_buffer)
            funcs.glDeleteRenderbuffers(1, &color_buffer);
        else
            funcs.glDeleteTextures(1, &texture);
        if (depth_buffer)
            funcs.glDeleteRenderbuffers(1, &depth_buffer);
        if (stencil_buffer && depth_buffer != stencil_buffer)
            funcs.glDeleteRenderbuffers(1, &stencil_buffer);
        funcs.glDeleteFramebuffers(1, &fbo);
    }
    QT_CHECK_GLERROR();

    format.setTextureTarget(target);
    format.setSamples(int(samples));
    format.setAttachment(fbo_attachment);
    format.setInternalTextureFormat(internal_format);
    format.setMipmap(mipmap);

    glDevice.setFBO(q, attachment);
}

/*!
    \class QGLFramebufferObject
    \inmodule QtOpenGL
    \brief The QGLFramebufferObject class encapsulates an OpenGL framebuffer object.
    \since 4.2

    \obsolete

    \ingroup painting-3D

    The QGLFramebufferObject class encapsulates an OpenGL framebuffer
    object, defined by the \c{GL_EXT_framebuffer_object} extension. In
    addition it provides a rendering surface that can be painted on
    with a QPainter, rendered to using native GL calls, or both. This
    surface can be bound and used as a regular texture in your own GL
    drawing code.  By default, the QGLFramebufferObject class
    generates a 2D GL texture (using the \c{GL_TEXTURE_2D} target),
    which is used as the internal rendering target.

    \b{It is important to have a current GL context when creating a
    QGLFramebufferObject, otherwise initialization will fail.}

    OpenGL framebuffer objects and pbuffers (see
    \l{QGLPixelBuffer}{QGLPixelBuffer}) can both be used to render to
    offscreen surfaces, but there are a number of advantages with
    using framebuffer objects instead of pbuffers:

    \list 1
    \li A framebuffer object does not require a separate rendering
    context, so no context switching will occur when switching
    rendering targets. There is an overhead involved in switching
    targets, but in general it is cheaper than a context switch to a
    pbuffer.

    \li Rendering to dynamic textures (i.e. render-to-texture
    functionality) works on all platforms. No need to do explicit copy
    calls from a render buffer into a texture, as was necessary on
    systems that did not support the \c{render_texture} extension.

    \li It is possible to attach several rendering buffers (or texture
    objects) to the same framebuffer object, and render to all of them
    without doing a context switch.

    \li The OpenGL framebuffer extension is a pure GL extension with no
    system dependant WGL, CGL, or GLX parts. This makes using
    framebuffer objects more portable.
    \endlist

    When using a QPainter to paint to a QGLFramebufferObject you should take
    care that the QGLFramebufferObject is created with the CombinedDepthStencil
    attachment for QPainter to be able to render correctly.
    Note that you need to create a QGLFramebufferObject with more than one
    sample per pixel for primitives to be antialiased when drawing using a
    QPainter. To create a multisample framebuffer object you should use one of
    the constructors that take a QGLFramebufferObjectFormat parameter, and set
    the QGLFramebufferObjectFormat::samples() property to a non-zero value.

    When painting to a QGLFramebufferObject using QPainter, the state of
    the current GL context will be altered by the paint engine to reflect
    its needs.  Applications should not rely upon the GL state being reset
    to its original conditions, particularly the current shader program,
    GL viewport, texture units, and drawing modes.

    For multisample framebuffer objects a color render buffer is created,
    otherwise a texture with the specified texture target is created.
    The color render buffer or texture will have the specified internal
    format, and will be bound to the \c GL_COLOR_ATTACHMENT0
    attachment in the framebuffer object.

    If you want to use a framebuffer object with multisampling enabled
    as a texture, you first need to copy from it to a regular framebuffer
    object using QGLContext::blitFramebuffer().

    \section1 Threading

    As of Qt 4.8, it's possible to draw into a QGLFramebufferObject
    using a QPainter in a separate thread. Note that OpenGL 2.0 or
    OpenGL ES 2.0 is required for this to work.

    \note This class has been deprecated in favor of QOpenGLFramebufferObject.
*/


/*!
    \enum QGLFramebufferObject::Attachment
    \since 4.3

    This enum type is used to configure the depth and stencil buffers
    attached to the framebuffer object when it is created.

    \value NoAttachment         No attachment is added to the framebuffer object. Note that the
                                OpenGL depth and stencil tests won't work when rendering to a
                                framebuffer object without any depth or stencil buffers.
                                This is the default value.

    \value CombinedDepthStencil If the \c GL_EXT_packed_depth_stencil extension is present,
                                a combined depth and stencil buffer is attached.
                                If the extension is not present, only a depth buffer is attached.

    \value Depth                A depth buffer is attached to the framebuffer object.

    \sa attachment()
*/


/*! \fn QGLFramebufferObject::QGLFramebufferObject(const QSize &size, GLenum target)

    Constructs an OpenGL framebuffer object and binds a 2D GL texture
    to the buffer of the size \a size. The texture is bound to the
    \c GL_COLOR_ATTACHMENT0 target in the framebuffer object.

    The \a target parameter is used to specify the GL texture
    target. The default target is \c GL_TEXTURE_2D. Keep in mind that
    \c GL_TEXTURE_2D textures must have a power of 2 width and height
    (e.g. 256x512), unless you are using OpenGL 2.0 or higher.

    By default, no depth and stencil buffers are attached. This behavior
    can be toggled using one of the overloaded constructors.

    The default internal texture format is \c GL_RGBA8 for desktop
    OpenGL, and \c GL_RGBA for OpenGL/ES.

    It is important that you have a current GL context set when
    creating the QGLFramebufferObject, otherwise the initialization
    will fail.

    \sa size(), texture(), attachment()
*/

QGLFramebufferObject::QGLFramebufferObject(const QSize &size, GLenum target)
    : d_ptr(new QGLFramebufferObjectPrivate)
{
    Q_D(QGLFramebufferObject);
    d->init(this, size, NoAttachment, target,
#ifndef QT_OPENGL_ES_2
            QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8
#else
            GL_RGBA
#endif
        );
}

/*! \overload

    Constructs an OpenGL framebuffer object and binds a 2D GL texture
    to the buffer of the given \a width and \a height.

    \sa size(), texture()
*/
QGLFramebufferObject::QGLFramebufferObject(int width, int height, GLenum target)
    : d_ptr(new QGLFramebufferObjectPrivate)
{
    Q_D(QGLFramebufferObject);
    d->init(this, QSize(width, height), NoAttachment, target,
#ifndef QT_OPENGL_ES_2
            QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8
#else
            GL_RGBA
#endif
        );
}

/*! \overload

    Constructs an OpenGL framebuffer object of the given \a size based on the
    supplied \a format.
*/

QGLFramebufferObject::QGLFramebufferObject(const QSize &size, const QGLFramebufferObjectFormat &format)
    : d_ptr(new QGLFramebufferObjectPrivate)
{
    Q_D(QGLFramebufferObject);
    d->init(this, size, format.attachment(), format.textureTarget(), format.internalTextureFormat(),
            format.samples(), format.mipmap());
}

/*! \overload

    Constructs an OpenGL framebuffer object of the given \a width and \a height
    based on the supplied \a format.
*/

QGLFramebufferObject::QGLFramebufferObject(int width, int height, const QGLFramebufferObjectFormat &format)
    : d_ptr(new QGLFramebufferObjectPrivate)
{
    Q_D(QGLFramebufferObject);
    d->init(this, QSize(width, height), format.attachment(), format.textureTarget(),
            format.internalTextureFormat(), format.samples(), format.mipmap());
}

/*! \overload

    Constructs an OpenGL framebuffer object and binds a texture to the
    buffer of the given \a width and \a height.

    The \a attachment parameter describes the depth/stencil buffer
    configuration, \a target the texture target and \a internal_format
    the internal texture format. The default texture target is \c
    GL_TEXTURE_2D, while the default internal format is \c GL_RGBA8
    for desktop OpenGL and \c GL_RGBA for OpenGL/ES.

    \sa size(), texture(), attachment()
*/
QGLFramebufferObject::QGLFramebufferObject(int width, int height, Attachment attachment,
                                           GLenum target, GLenum internal_format)
    : d_ptr(new QGLFramebufferObjectPrivate)
{
    Q_D(QGLFramebufferObject);
    if (!internal_format)
#ifdef QT_OPENGL_ES_2
        internal_format = GL_RGBA;
#else
    internal_format = QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8;
#endif
    d->init(this, QSize(width, height), attachment, target, internal_format);
}

/*! \overload

    Constructs an OpenGL framebuffer object and binds a texture to the
    buffer of the given \a size.

    The \a attachment parameter describes the depth/stencil buffer
    configuration, \a target the texture target and \a internal_format
    the internal texture format. The default texture target is \c
    GL_TEXTURE_2D, while the default internal format is \c GL_RGBA8
    for desktop OpenGL and \c GL_RGBA for OpenGL/ES.

    \sa size(), texture(), attachment()
*/
QGLFramebufferObject::QGLFramebufferObject(const QSize &size, Attachment attachment,
                                           GLenum target, GLenum internal_format)
    : d_ptr(new QGLFramebufferObjectPrivate)
{
    Q_D(QGLFramebufferObject);
    if (!internal_format)
#ifdef QT_OPENGL_ES_2
        internal_format = GL_RGBA;
#else
        internal_format = QOpenGLContext::currentContext()->isOpenGLES() ? GL_RGBA : GL_RGBA8;
#endif
    d->init(this, size, attachment, target, internal_format);
}

/*!
    \fn QGLFramebufferObject::~QGLFramebufferObject()

    Destroys the framebuffer object and frees any allocated resources.
*/
QGLFramebufferObject::~QGLFramebufferObject()
{
    Q_D(QGLFramebufferObject);

    delete d->engine;

    if (d->texture_guard)
        d->texture_guard->free();
    if (d->color_buffer_guard)
        d->color_buffer_guard->free();
    if (d->depth_buffer_guard)
        d->depth_buffer_guard->free();
    if (d->stencil_buffer_guard && d->stencil_buffer_guard != d->depth_buffer_guard)
        d->stencil_buffer_guard->free();
    if (d->fbo_guard)
        d->fbo_guard->free();
}

/*!
    \fn bool QGLFramebufferObject::isValid() const

    Returns \c true if the framebuffer object is valid.

    The framebuffer can become invalid if the initialization process
    fails, the user attaches an invalid buffer to the framebuffer
    object, or a non-power of two width/height is specified as the
    texture size if the texture target is \c{GL_TEXTURE_2D}.
    The non-power of two limitation does not apply if the OpenGL version
    is 2.0 or higher, or if the GL_ARB_texture_non_power_of_two extension
    is present.

    The framebuffer can also become invalid if the QGLContext that
    the framebuffer was created within is destroyed and there are
    no other shared contexts that can take over ownership of the
    framebuffer.
*/
bool QGLFramebufferObject::isValid() const
{
    Q_D(const QGLFramebufferObject);
    return d->valid && d->fbo_guard && d->fbo_guard->id();
}

/*!
    \fn bool QGLFramebufferObject::bind()

    Switches rendering from the default, windowing system provided
    framebuffer to this framebuffer object.
    Returns \c true upon success, false otherwise.

    \sa release()
*/
bool QGLFramebufferObject::bind()
{
    if (!isValid())
        return false;
    Q_D(QGLFramebufferObject);
    QGL_FUNC_CONTEXT;
    if (!ctx)
        return false;   // Context no longer exists.
    const QGLContext *current = QGLContext::currentContext();
#ifdef QT_DEBUG
    if (!current ||
        QGLContextPrivate::contextGroup(current) != QGLContextPrivate::contextGroup(ctx))
    {
        qWarning("QGLFramebufferObject::bind() called from incompatible context");
    }
#endif
    d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, d->fbo());
    d->valid = d->checkFramebufferStatus();
    if (d->valid && current)
        current->d_ptr->setCurrentFbo(d->fbo());
    return d->valid;
}

/*!
    \fn bool QGLFramebufferObject::release()

    Switches rendering back to the default, windowing system provided
    framebuffer.
    Returns \c true upon success, false otherwise.

    \sa bind()
*/
bool QGLFramebufferObject::release()
{
    if (!isValid())
        return false;
    Q_D(QGLFramebufferObject);
    QGL_FUNC_CONTEXT;
    if (!ctx)
        return false;   // Context no longer exists.

    const QGLContext *current = QGLContext::currentContext();

#ifdef QT_DEBUG
    if (!current ||
        QGLContextPrivate::contextGroup(current) != QGLContextPrivate::contextGroup(ctx))
    {
        qWarning("QGLFramebufferObject::release() called from incompatible context");
    }
#endif

    if (current) {
        current->d_ptr->setCurrentFbo(current->d_ptr->default_fbo);
        d->funcs.glBindFramebuffer(GL_FRAMEBUFFER, current->d_ptr->default_fbo);
    }

    return true;
}

/*!
    \fn GLuint QGLFramebufferObject::texture() const

    Returns the texture id for the texture attached as the default
    rendering target in this framebuffer object. This texture id can
    be bound as a normal texture in your own GL code.

    If a multisample framebuffer object is used then the value returned
    from this function will be invalid.
*/
GLuint QGLFramebufferObject::texture() const
{
    Q_D(const QGLFramebufferObject);
    return d->texture_guard ? d->texture_guard->id() : 0;
}

/*!
    \fn QSize QGLFramebufferObject::size() const

    Returns the size of the texture attached to this framebuffer
    object.
*/
QSize QGLFramebufferObject::size() const
{
    Q_D(const QGLFramebufferObject);
    return d->size;
}

/*!
    Returns the format of this framebuffer object.
*/
QGLFramebufferObjectFormat QGLFramebufferObject::format() const
{
    Q_D(const QGLFramebufferObject);
    return d->format;
}

/*!
    \fn QImage QGLFramebufferObject::toImage() const

    Returns the contents of this framebuffer object as a QImage.

    The returned image has a format of premultiplied ARGB32 or RGB32. The latter is used
    only when internalTextureFormat() is set to \c GL_RGB.

    If the rendering in the framebuffer was not done with premultiplied alpha in mind,
    create a wrapper QImage with a non-premultiplied format. This is necessary before
    performing operations like QImage::save() because otherwise the image data would get
    unpremultiplied, even though it was not premultiplied in the first place. To create
    such a wrapper without performing a copy of the pixel data, do the following:

    \code
    QImage fboImage(fbo.toImage());
    QImage image(fboImage.constBits(), fboImage.width(), fboImage.height(), QImage::Format_ARGB32);
    \endcode

    On QNX the back buffer is not preserved when a buffer swap occures. So this function
    might return old content.
*/
QImage QGLFramebufferObject::toImage() const
{
    Q_D(const QGLFramebufferObject);
    if (!d->valid)
        return QImage();

    // qt_gl_read_frame_buffer doesn't work on a multisample FBO
    if (format().samples() != 0) {
        QGLFramebufferObject temp(size(), QGLFramebufferObjectFormat());

        QRect rect(QPoint(0, 0), size());
        blitFramebuffer(&temp, rect, const_cast<QGLFramebufferObject *>(this), rect);

        return temp.toImage();
    }

    bool wasBound = isBound();
    if (!wasBound)
        const_cast<QGLFramebufferObject *>(this)->bind();
    QImage image = qt_gl_read_frame_buffer(d->size, format().internalTextureFormat() != GL_RGB, true);
    if (!wasBound)
        const_cast<QGLFramebufferObject *>(this)->release();

    return image;
}

Q_GLOBAL_STATIC(QGLEngineThreadStorage<QGL2PaintEngineEx>, qt_buffer_2_engine)

/*! \reimp */
QPaintEngine *QGLFramebufferObject::paintEngine() const
{
    Q_D(const QGLFramebufferObject);
    if (d->engine)
        return d->engine;

    QPaintEngine *engine = qt_buffer_2_engine()->engine();
    if (engine->isActive() && engine->paintDevice() != this) {
        d->engine = new QGL2PaintEngineEx;
        return d->engine;
    }
    return engine;
}

/*!
    \fn bool QGLFramebufferObject::bindDefault()

    Switches rendering back to the default, windowing system provided
    framebuffer.
    Returns \c true upon success, false otherwise.

    \sa bind(), release()
*/
bool QGLFramebufferObject::bindDefault()
{
    QGLContext *ctx = const_cast<QGLContext *>(QGLContext::currentContext());

    if (ctx) {
        QOpenGLFunctions functions(ctx->contextHandle());
        if (!functions.hasOpenGLFeature(QOpenGLFunctions::Framebuffers))
            return false;

        ctx->d_ptr->setCurrentFbo(ctx->d_ptr->default_fbo);
        functions.glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_ptr->default_fbo);
#ifdef QT_DEBUG
    } else {
        qWarning("QGLFramebufferObject::bindDefault() called without current context.");
#endif
    }

    return ctx != 0;
}

/*!
    \fn bool QGLFramebufferObject::hasOpenGLFramebufferObjects()

    Returns \c true if the OpenGL \c{GL_EXT_framebuffer_object} extension
    is present on this system; otherwise returns \c false.
*/
bool QGLFramebufferObject::hasOpenGLFramebufferObjects()
{
    return qgl_hasFeature(QOpenGLFunctions::Framebuffers);
}

/*!
    \since 4.4

    Draws the given texture, \a textureId, to the given target rectangle,
    \a target, in OpenGL model space. The \a textureTarget should be a 2D
    texture target.

    The framebuffer object should be bound when calling this function.

    Equivalent to the corresponding QGLContext::drawTexture().
*/
void QGLFramebufferObject::drawTexture(const QRectF &target, GLuint textureId, GLenum textureTarget)
{
    const_cast<QGLContext *>(QGLContext::currentContext())->drawTexture(target, textureId, textureTarget);
}

/*!
    \since 4.4

    Draws the given texture, \a textureId, at the given \a point in OpenGL
    model space. The \a textureTarget should be a 2D texture target.

    The framebuffer object should be bound when calling this function.

    Equivalent to the corresponding QGLContext::drawTexture().
*/
void QGLFramebufferObject::drawTexture(const QPointF &point, GLuint textureId, GLenum textureTarget)
{
    const_cast<QGLContext *>(QGLContext::currentContext())->drawTexture(point, textureId, textureTarget);
}

/*! \reimp */
int QGLFramebufferObject::metric(PaintDeviceMetric metric) const
{
    Q_D(const QGLFramebufferObject);

    float dpmx = qt_defaultDpiX()*100./2.54;
    float dpmy = qt_defaultDpiY()*100./2.54;
    int w = d->size.width();
    int h = d->size.height();
    switch (metric) {
    case PdmWidth:
        return w;

    case PdmHeight:
        return h;

    case PdmWidthMM:
        return qRound(w * 1000 / dpmx);

    case PdmHeightMM:
        return qRound(h * 1000 / dpmy);

    case PdmNumColors:
        return 0;

    case PdmDepth:
        return 32;//d->depth;

    case PdmDpiX:
        return qRound(dpmx * 0.0254);

    case PdmDpiY:
        return qRound(dpmy * 0.0254);

    case PdmPhysicalDpiX:
        return qRound(dpmx * 0.0254);

    case PdmPhysicalDpiY:
        return qRound(dpmy * 0.0254);

    case QPaintDevice::PdmDevicePixelRatio:
        return 1;

    case QPaintDevice::PdmDevicePixelRatioScaled:
        return 1 * QPaintDevice::devicePixelRatioFScale();

    default:
        qWarning("QGLFramebufferObject::metric(), Unhandled metric type: %d.\n", metric);
        break;
    }
    return 0;
}

/*!
    \fn GLuint QGLFramebufferObject::handle() const

    Returns the GL framebuffer object handle for this framebuffer
    object (returned by the \c{glGenFrameBuffersEXT()} function). This
    handle can be used to attach new images or buffers to the
    framebuffer. The user is responsible for cleaning up and
    destroying these objects.
*/
GLuint QGLFramebufferObject::handle() const
{
    Q_D(const QGLFramebufferObject);
    return d->fbo();
}

/*! \fn int QGLFramebufferObject::devType() const
    \internal
*/


/*!
    Returns the status of the depth and stencil buffers attached to
    this framebuffer object.
*/

QGLFramebufferObject::Attachment QGLFramebufferObject::attachment() const
{
    Q_D(const QGLFramebufferObject);
    if (d->valid)
        return d->fbo_attachment;
    return NoAttachment;
}

/*!
    \since 4.5

    Returns \c true if the framebuffer object is currently bound to a context,
    otherwise false is returned.
*/

bool QGLFramebufferObject::isBound() const
{
    Q_D(const QGLFramebufferObject);
    const QGLContext *current = QGLContext::currentContext();
    if (current) {
        current->d_ptr->refreshCurrentFbo();
        return current->d_ptr->current_fbo == d->fbo();
    }

    return false;
}

/*!
    \fn bool QGLFramebufferObject::hasOpenGLFramebufferBlit()

    \since 4.6

    Returns \c true if the OpenGL \c{GL_EXT_framebuffer_blit} extension
    is present on this system; otherwise returns \c false.

    \sa blitFramebuffer()
*/
bool QGLFramebufferObject::hasOpenGLFramebufferBlit()
{
    return QOpenGLExtensions(QOpenGLContext::currentContext()).hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit);
}

/*!
    \since 4.6

    Blits from the \a sourceRect rectangle in the \a source framebuffer
    object to the \a targetRect rectangle in the \a target framebuffer object.

    If \a source or \a target is 0, the default framebuffer will be used
    instead of a framebuffer object as source or target respectively.

    The \a buffers parameter should be a mask consisting of any combination of
    \c GL_COLOR_BUFFER_BIT, \c GL_DEPTH_BUFFER_BIT, and
    \c GL_STENCIL_BUFFER_BIT.  Any buffer type that is not present both
    in the source and target buffers is ignored.

    The \a sourceRect and \a targetRect rectangles may have different sizes;
    in this case \a buffers should not contain \c GL_DEPTH_BUFFER_BIT or
    \c GL_STENCIL_BUFFER_BIT. The \a filter parameter should be set to
    \c GL_LINEAR or \c GL_NEAREST, and specifies whether linear or nearest
    interpolation should be used when scaling is performed.

    If \a source equals \a target a copy is performed within the same buffer.
    Results are undefined if the source and target rectangles overlap and
    have different sizes. The sizes must also be the same if any of the
    framebuffer objects are multisample framebuffers.

    Note that the scissor test will restrict the blit area if enabled.

    This function will have no effect unless hasOpenGLFramebufferBlit() returns
    true.

    \sa hasOpenGLFramebufferBlit()
*/
void QGLFramebufferObject::blitFramebuffer(QGLFramebufferObject *target, const QRect &targetRect,
                                           QGLFramebufferObject *source, const QRect &sourceRect,
                                           GLbitfield buffers,
                                           GLenum filter)
{
    const QGLContext *ctx = QGLContext::currentContext();
    if (!ctx || !ctx->contextHandle())
        return;

    QOpenGLExtensions functions(ctx->contextHandle());
    if (!functions.hasOpenGLExtension(QOpenGLExtensions::FramebufferBlit))
        return;

    QSurface *surface = ctx->contextHandle()->surface();

    const int height = static_cast<QWindow *>(surface)->height();

    const int sh = source ? source->height() : height;
    const int th = target ? target->height() : height;

    const int sx0 = sourceRect.left();
    const int sx1 = sourceRect.left() + sourceRect.width();
    const int sy0 = sh - (sourceRect.top() + sourceRect.height());
    const int sy1 = sh - sourceRect.top();

    const int tx0 = targetRect.left();
    const int tx1 = targetRect.left() + targetRect.width();
    const int ty0 = th - (targetRect.top() + targetRect.height());
    const int ty1 = th - targetRect.top();

    ctx->d_ptr->refreshCurrentFbo();

    functions.glBindFramebuffer(GL_READ_FRAMEBUFFER, source ? source->handle() : 0);
    functions.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, target ? target->handle() : 0);

    functions.glBlitFramebuffer(sx0, sy0, sx1, sy1,
                         tx0, ty0, tx1, ty1,
                         buffers, filter);

    functions.glBindFramebuffer(GL_FRAMEBUFFER, ctx->d_ptr->current_fbo);
}

QT_END_NAMESPACE
