diff options
Diffstat (limited to 'src/gui/opengl/qopenglframebufferobject.cpp')
-rw-r--r-- | src/gui/opengl/qopenglframebufferobject.cpp | 117 |
1 files changed, 95 insertions, 22 deletions
diff --git a/src/gui/opengl/qopenglframebufferobject.cpp b/src/gui/opengl/qopenglframebufferobject.cpp index 5184283a31..5f5b7f46ec 100644 --- a/src/gui/opengl/qopenglframebufferobject.cpp +++ b/src/gui/opengl/qopenglframebufferobject.cpp @@ -1,31 +1,37 @@ /**************************************************************************** ** -** Copyright (C) 2015 The Qt Company Ltd. -** Contact: http://www.qt.io/licensing/ +** Copyright (C) 2016 The Qt Company Ltd. +** Contact: https://www.qt.io/licensing/ ** ** This file is part of the QtGui module of the Qt Toolkit. ** -** $QT_BEGIN_LICENSE:LGPL21$ +** $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 http://www.qt.io/terms-conditions. For further -** information use the contact form at http://www.qt.io/contact-us. +** 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 2.1 or version 3 as published by the Free -** Software Foundation and appearing in the file LICENSE.LGPLv21 and -** LICENSE.LGPLv3 included in the packaging of this file. Please review the -** following information to ensure the GNU Lesser General Public License -** requirements will be met: https://www.gnu.org/licenses/lgpl.html and -** http://www.gnu.org/licenses/old-licenses/lgpl-2.1.html. +** 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. ** -** As a special exception, The Qt Company gives you certain additional -** rights. These rights are described in The Qt Company LGPL Exception -** version 1.1, included in the file LGPL_EXCEPTION.txt in this package. +** GNU General Public License Usage +** Alternatively, this file may be used under the terms of the GNU +** General Public License version 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$ ** @@ -937,7 +943,7 @@ QOpenGLFramebufferObject::~QOpenGLFramebufferObject() if (isBound()) release(); - foreach (const QOpenGLFramebufferObjectPrivate::ColorAttachment &color, d->colorAttachments) { + for (const auto &color : qAsConst(d->colorAttachments)) { if (color.guard) color.guard->free(); } @@ -1150,7 +1156,7 @@ QVector<GLuint> QOpenGLFramebufferObject::textures() const if (d->format.samples() != 0) return ids; ids.reserve(d->colorAttachments.count()); - foreach (const QOpenGLFramebufferObjectPrivate::ColorAttachment &color, d->colorAttachments) + for (const auto &color : d->colorAttachments) ids.append(color.guard ? color.guard->id() : 0); return ids; } @@ -1234,7 +1240,7 @@ QVector<QSize> QOpenGLFramebufferObject::sizes() const Q_D(const QOpenGLFramebufferObject); QVector<QSize> sz; sz.reserve(d->colorAttachments.size()); - foreach (const QOpenGLFramebufferObjectPrivate::ColorAttachment &color, d->colorAttachments) + for (const auto &color : d->colorAttachments) sz.append(color.size); return sz; } @@ -1624,6 +1630,29 @@ void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target, } /*! + \enum QOpenGLFramebufferObject::FramebufferRestorePolicy + \since 5.7 + + This enum type is used to configure the behavior related to restoring + framebuffer bindings when calling blitFramebuffer(). + + \value DontRestoreFramebufferBinding Do not restore the previous framebuffer binding. + The caller is responsible for tracking and setting + the framebuffer binding as needed. + + \value RestoreFramebufferBindingToDefault After the blit operation, bind the default + framebuffer. + + \value RestoreFrameBufferBinding Restore the previously bound framebuffer. This is + potentially expensive because of the need to + query the currently bound framebuffer. + + \sa blitFramebuffer() +*/ + +/*! + \since 5.7 + Blits from the \a sourceRect rectangle in the \a source framebuffer object to the \a targetRect rectangle in the \a target framebuffer object. @@ -1655,6 +1684,13 @@ void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target, drawColorAttachmentIndex specify the index of the color attachments in the source and destination framebuffers. + The \a restorePolicy determines if the framebuffer that was bound prior to + calling this function should be restored, or if the default framebuffer + should be bound before returning, of if the caller is responsible for + tracking and setting the bound framebuffer. Restoring the previous + framebuffer can be relatively expensive due to the call to \c{glGetIntegerv} + which on some OpenGL drivers may imply a pipeline stall. + \sa hasOpenGLFramebufferBlit() */ void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target, const QRect &targetRect, @@ -1662,7 +1698,8 @@ void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target, GLbitfield buffers, GLenum filter, int readColorAttachmentIndex, - int drawColorAttachmentIndex) + int drawColorAttachmentIndex, + QOpenGLFramebufferObject::FramebufferRestorePolicy restorePolicy) { QOpenGLContext *ctx = QOpenGLContext::currentContext(); if (!ctx) @@ -1673,7 +1710,8 @@ void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target, return; GLuint prevFbo = 0; - ctx->functions()->glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint *) &prevFbo); + if (restorePolicy == RestoreFrameBufferBinding) + ctx->functions()->glGetIntegerv(GL_FRAMEBUFFER_BINDING, (GLint *) &prevFbo); const int sx0 = sourceRect.left(); const int sx1 = sourceRect.left() + sourceRect.width(); @@ -1690,7 +1728,8 @@ void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target, extensions.glBindFramebuffer(GL_READ_FRAMEBUFFER, source ? source->handle() : defaultFboId); extensions.glBindFramebuffer(GL_DRAW_FRAMEBUFFER, target ? target->handle() : defaultFboId); - if (extensions.hasOpenGLFeature(QOpenGLFunctions::MultipleRenderTargets)) { + const bool supportsMRT = extensions.hasOpenGLFeature(QOpenGLFunctions::MultipleRenderTargets); + if (supportsMRT) { extensions.glReadBuffer(GL_COLOR_ATTACHMENT0 + readColorAttachmentIndex); if (target) { GLenum drawBuf = GL_COLOR_ATTACHMENT0 + drawColorAttachmentIndex; @@ -1702,10 +1741,44 @@ void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target, tx0, ty0, tx1, ty1, buffers, filter); - if (extensions.hasOpenGLFeature(QOpenGLFunctions::MultipleRenderTargets)) + if (supportsMRT) extensions.glReadBuffer(GL_COLOR_ATTACHMENT0); - ctx->functions()->glBindFramebuffer(GL_FRAMEBUFFER, prevFbo); // sets both READ and DRAW + switch (restorePolicy) { + case RestoreFrameBufferBinding: + ctx->functions()->glBindFramebuffer(GL_FRAMEBUFFER, prevFbo); // sets both READ and DRAW + break; + + case RestoreFramebufferBindingToDefault: + ctx->functions()->glBindFramebuffer(GL_FRAMEBUFFER, ctx->defaultFramebufferObject()); // sets both READ and DRAW + break; + + case DontRestoreFramebufferBinding: + break; + } +} + +/*! + \overload + + Convenience overload to blit between two framebuffer objects and + to restore the previous framebuffer binding. Equivalent to calling + blitFramebuffer(target, targetRect, source, sourceRect, buffers, filter, + readColorAttachmentIndex, drawColorAttachmentIndex, + RestoreFrameBufferBinding). +*/ +void QOpenGLFramebufferObject::blitFramebuffer(QOpenGLFramebufferObject *target, const QRect &targetRect, + QOpenGLFramebufferObject *source, const QRect &sourceRect, + GLbitfield buffers, + GLenum filter, + int readColorAttachmentIndex, + int drawColorAttachmentIndex) +{ + blitFramebuffer(target, targetRect, source, sourceRect, + buffers, filter, + readColorAttachmentIndex, + drawColorAttachmentIndex, + RestoreFrameBufferBinding); } QT_END_NAMESPACE |