diff options
Diffstat (limited to 'src/opengl')
51 files changed, 641 insertions, 253 deletions
diff --git a/src/opengl/CMakeLists.txt b/src/opengl/CMakeLists.txt index 11dc6db158..825e4cb71b 100644 --- a/src/opengl/CMakeLists.txt +++ b/src/opengl/CMakeLists.txt @@ -1,4 +1,5 @@ -# Generated from opengl.pro. +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: BSD-3-Clause ##################################################################### ## OpenGL Module: @@ -25,15 +26,20 @@ qt_internal_add_module(OpenGL qopengltextureglyphcache.cpp qopengltextureglyphcache_p.h qopengltexturehelper.cpp qopengltexturehelper_p.h qopengltextureuploader.cpp qopengltextureuploader_p.h + qopengltimerquery.h qopenglversionfunctions.cpp qopenglversionfunctions.h qopenglversionfunctions_p.h qopenglversionfunctionsfactory.cpp qopenglversionfunctionsfactory.h qopenglversionprofile.cpp qopenglversionprofile.h qopenglvertexarrayobject.cpp qopenglvertexarrayobject.h qopenglvertexarrayobject_p.h qopenglwindow.cpp qopenglwindow.h qtopenglglobal.h + NO_UNITY_BUILD_SOURCES + qopengltextureblitter.cpp # qDebug()<< ambiguities DEFINES + QT_NO_CONTEXTLESS_CONNECT QT_NO_FOREACH QT_NO_USING_NAMESPACE + QT_USE_NODISCARD_FILE_OPEN LIBRARIES Qt::CorePrivate Qt::GuiPrivate @@ -49,6 +55,11 @@ qt_internal_add_module(OpenGL ## Scopes: ##################################################################### +qt_internal_extend_target(OpenGL CONDITION APPLE + NO_UNITY_BUILD_SOURCES + qopenglversionfunctionsfactory.cpp +) + qt_internal_extend_target(OpenGL CONDITION QT_FEATURE_opengles2 SOURCES qopenglfunctions_es2.cpp qopenglfunctions_es2.h @@ -83,7 +94,7 @@ qt_internal_extend_target(OpenGL CONDITION NOT QT_FEATURE_opengles2 qopenglfunctions_4_5_compatibility.cpp qopenglfunctions_4_5_compatibility.h qopenglfunctions_4_5_core.cpp qopenglfunctions_4_5_core.h qopenglqueryhelper_p.h - qopengltimerquery.cpp qopengltimerquery.h + qopengltimerquery.cpp ) qt_internal_extend_target(OpenGL CONDITION QT_FEATURE_vulkan @@ -101,9 +112,12 @@ qt_internal_extend_target(OpenGL CONDITION QT_FEATURE_egl qopenglcompositorbackingstore.cpp qopenglcompositorbackingstore_p.h ) - -qt_internal_create_tracepoints(OpenGL qtopengl.tracepoints) +qt_internal_generate_tracepoints(OpenGL opengl + SOURCES + qopenglframebufferobject.cpp + qopenglpaintengine.cpp + qopengltexturecache.cpp +) qt_internal_add_docs(OpenGL doc/qtopengl.qdocconf ) - diff --git a/src/opengl/doc/qtopengl.qdocconf b/src/opengl/doc/qtopengl.qdocconf index 58f16e7d2e..7af173aac8 100644 --- a/src/opengl/doc/qtopengl.qdocconf +++ b/src/opengl/doc/qtopengl.qdocconf @@ -15,18 +15,17 @@ project = QtOpenGL # <rootdir>/examples. # Paths are relative to the location of this file. -headerdirs += .. \ - ../../openglwidgets -sourcedirs += .. \ - ../../openglwidgets \ - ../../../examples/opengl/doc/src +{sourcedirs,headerdirs} += \ + .. \ + ../../openglwidgets + exampledirs += ../../../examples/opengl \ . \ snippets \ .. \ ../../gui/doc/snippets -imagedirs += images \ - ../../../examples/opengl/doc/images + +imagedirs += images depends += qtcore qtgui qtwidgets qtdoc qmake qtcmake qtquick @@ -65,5 +64,5 @@ qhp.QtOpenGL.subprojects.classes.sortPages = true navigation.landingpage = "Qt OpenGL" navigation.cppclassespage = "Qt OpenGL C++ Classes" -# Fail the documentation build if there are more warnings than the limit +# Enforce zero documentation warnings warninglimit = 0 diff --git a/src/opengl/doc/snippets/CMakeLists.txt b/src/opengl/doc/snippets/CMakeLists.txt index aff5f13c15..419e0923e0 100644 --- a/src/opengl/doc/snippets/CMakeLists.txt +++ b/src/opengl/doc/snippets/CMakeLists.txt @@ -1,3 +1,6 @@ +# Copyright (C) 2022 The Qt Company Ltd. +# SPDX-License-Identifier: LicenseRef-Qt-Commercial OR BSD-3-Clause + #! [cmake_use] find_package(Qt6 REQUIRED COMPONENTS OpenGL) target_link_libraries(mytarget PRIVATE Qt6::OpenGL) diff --git a/src/opengl/doc/src/qt6-changes.qdoc b/src/opengl/doc/src/qt6-changes.qdoc index 1bde84fb62..e227476868 100644 --- a/src/opengl/doc/src/qt6-changes.qdoc +++ b/src/opengl/doc/src/qt6-changes.qdoc @@ -5,7 +5,7 @@ \page opengl-changes-qt6.html \title Changes to Qt OpenGL \ingroup changes-qt-5-to-6 - \brief Migrate Qt OpenGL to Qt 6. + \brief QOpenGL classes migrated, QOpenGLWidget class has been moved to Qt OpenGL Widgets. Qt 6 is a result of the conscious effort to make the framework more efficient and easy to use. diff --git a/src/opengl/doc/src/qtopengl-examples.qdoc b/src/opengl/doc/src/qtopengl-examples.qdoc index 4843407b0b..3a98c16c70 100644 --- a/src/opengl/doc/src/qtopengl-examples.qdoc +++ b/src/opengl/doc/src/qtopengl-examples.qdoc @@ -3,7 +3,7 @@ /*! \ingroup all-examples - \title OpenGL Examples from the Qt OpenGL module + \title Qt OpenGL Examples \brief Accessing OpenGL from Qt. \group examples-widgets-opengl diff --git a/src/opengl/doc/src/qtopengl-index.qdoc b/src/opengl/doc/src/qtopengl-index.qdoc index 0b0080edf0..7ea1635827 100644 --- a/src/opengl/doc/src/qtopengl-index.qdoc +++ b/src/opengl/doc/src/qtopengl-index.qdoc @@ -61,7 +61,7 @@ \section1 Examples \list - \li \l {OpenGL Window Example} + \li \l {Qt OpenGL Examples} \endlist \section1 Reference diff --git a/src/opengl/qopengl2pexvertexarray_p.h b/src/opengl/qopengl2pexvertexarray_p.h index 9a7831578f..84c77f32ff 100644 --- a/src/opengl/qopengl2pexvertexarray_p.h +++ b/src/opengl/qopengl2pexvertexarray_p.h @@ -41,6 +41,7 @@ public: operator QPointF() {return QPointF(x,y);} operator QPointF() const {return QPointF(x,y);} }; +Q_DECLARE_TYPEINFO(QOpenGLPoint, Q_PRIMITIVE_TYPE); struct QOpenGLRect { @@ -57,6 +58,7 @@ struct QOpenGLRect operator QRectF() const {return QRectF(left, top, right-left, bottom-top);} }; +Q_DECLARE_TYPEINFO(QOpenGLRect, Q_PRIMITIVE_TYPE); class QOpenGL2PEXVertexArray { diff --git a/src/opengl/qopenglbuffer.cpp b/src/opengl/qopenglbuffer.cpp index 62d2d5edd2..64e7975043 100644 --- a/src/opengl/qopenglbuffer.cpp +++ b/src/opengl/qopenglbuffer.cpp @@ -166,7 +166,7 @@ QOpenGLBuffer::QOpenGLBuffer(const QOpenGLBuffer &other) */ QOpenGLBuffer::~QOpenGLBuffer() { - if (!d_ptr->ref.deref()) { + if (d_ptr && !d_ptr->ref.deref()) { destroy(); delete d_ptr; } @@ -182,7 +182,7 @@ QOpenGLBuffer &QOpenGLBuffer::operator=(const QOpenGLBuffer &other) { if (d_ptr != other.d_ptr) { other.d_ptr->ref.ref(); - if (!d_ptr->ref.deref()) { + if (d_ptr && !d_ptr->ref.deref()) { destroy(); delete d_ptr; } @@ -192,6 +192,36 @@ QOpenGLBuffer &QOpenGLBuffer::operator=(const QOpenGLBuffer &other) } /*! + \fn QOpenGLBuffer::QOpenGLBuffer(QOpenGLBuffer &&other) + \since 6.5 + + Move-constructs a new QOpenGLBuffer from \a other. + + \note The moved-from object \a other is placed in a partially-formed state, + in which the only valid operations are destruction and assignment of a new + value. +*/ + +/*! + \fn QOpenGLBuffer &QOpenGLBuffer::operator=(QOpenGLBuffer &&other) + \since 6.5 + + Move-assigns \a other to this QOpenGLBuffer instance. + + \note The moved-from object \a other is placed in a partially-formed state, + in which the only valid operations are destruction and assignment of a new + value. +*/ + +/*! + \fn QOpenGLBuffer::swap(QOpenGLBuffer &other) + \since 6.5 + + Swaps buffer \a other with this buffer. This operation is very fast and + never fails. +*/ + +/*! Returns the type of buffer represented by this object. */ QOpenGLBuffer::Type QOpenGLBuffer::type() const diff --git a/src/opengl/qopenglbuffer.h b/src/opengl/qopenglbuffer.h index 1325b7e6e0..b9f2265ca0 100644 --- a/src/opengl/qopenglbuffer.h +++ b/src/opengl/qopenglbuffer.h @@ -8,7 +8,6 @@ #ifndef QT_NO_OPENGL -#include <QtCore/qscopedpointer.h> #include <QtGui/qopengl.h> QT_BEGIN_NAMESPACE @@ -30,9 +29,15 @@ public: QOpenGLBuffer(); explicit QOpenGLBuffer(QOpenGLBuffer::Type type); QOpenGLBuffer(const QOpenGLBuffer &other); + QOpenGLBuffer(QOpenGLBuffer &&other) noexcept + : d_ptr{std::exchange(other.d_ptr, nullptr)} {} ~QOpenGLBuffer(); QOpenGLBuffer &operator=(const QOpenGLBuffer &other); + QT_MOVE_ASSIGNMENT_OPERATOR_IMPL_VIA_MOVE_AND_SWAP(QOpenGLBuffer) + + void swap(QOpenGLBuffer &other) noexcept + { return qt_ptr_swap(d_ptr, other.d_ptr); } enum UsagePattern { @@ -99,6 +104,7 @@ private: Q_DECLARE_PRIVATE(QOpenGLBuffer) }; +Q_DECLARE_SHARED(QOpenGLBuffer) Q_DECLARE_OPERATORS_FOR_FLAGS(QOpenGLBuffer::RangeAccessFlags) diff --git a/src/opengl/qopenglcompositor.cpp b/src/opengl/qopenglcompositor.cpp index ae500181e4..3c5b1df905 100644 --- a/src/opengl/qopenglcompositor.cpp +++ b/src/opengl/qopenglcompositor.cpp @@ -4,7 +4,7 @@ #include <QtOpenGL/QOpenGLFramebufferObject> #include <QtGui/QOpenGLContext> #include <QtGui/QWindow> -#include <QtGui/private/qrhi_p.h> +#include <rhi/qrhi.h> #include <qpa/qplatformbackingstore.h> #include "qopenglcompositor_p.h" @@ -85,10 +85,23 @@ void QOpenGLCompositor::update() QImage QOpenGLCompositor::grab() { Q_ASSERT(m_context && m_targetWindow); + QOpenGLFramebufferObject fbo(m_nativeTargetGeometry.size()); + grabToFrameBufferObject(&fbo); + return fbo.toImage(); +} + +bool QOpenGLCompositor::grabToFrameBufferObject(QOpenGLFramebufferObject *fbo, GrabOrientation orientation) +{ + Q_ASSERT(fbo); + if (fbo->size() != m_nativeTargetGeometry.size() + || fbo->format().textureTarget() != GL_TEXTURE_2D) + return false; + m_context->makeCurrent(m_targetWindow); - QScopedPointer<QOpenGLFramebufferObject> fbo(new QOpenGLFramebufferObject(m_nativeTargetGeometry.size())); - renderAll(fbo.data()); - return fbo->toImage(); + renderAll(fbo, + orientation == Flipped ? QOpenGLTextureBlitter::OriginTopLeft + : QOpenGLTextureBlitter::OriginBottomLeft); + return true; } void QOpenGLCompositor::handleRenderAllRequest() @@ -98,7 +111,7 @@ void QOpenGLCompositor::handleRenderAllRequest() renderAll(0); } -void QOpenGLCompositor::renderAll(QOpenGLFramebufferObject *fbo) +void QOpenGLCompositor::renderAll(QOpenGLFramebufferObject *fbo, QOpenGLTextureBlitter::Origin origin) { if (fbo) fbo->bind(); @@ -115,7 +128,7 @@ void QOpenGLCompositor::renderAll(QOpenGLFramebufferObject *fbo) m_windows.at(i)->beginCompositing(); for (int i = 0; i < m_windows.size(); ++i) - render(m_windows.at(i)); + render(m_windows.at(i), origin); m_blitter.release(); if (!fbo) @@ -156,9 +169,10 @@ static inline QRect toBottomLeftRect(const QRect &topLeftRect, int windowHeight) topLeftRect.width(), topLeftRect.height()); } -static void clippedBlit(const QPlatformTextureList *textures, int idx, const QRect &sourceWindowRect, - const QRect &targetWindowRect, - QOpenGLTextureBlitter *blitter, QMatrix4x4 *rotationMatrix) +static void clippedBlit(const QPlatformTextureList *textures, int idx, + const QRect &sourceWindowRect, const QRect &targetWindowRect, + QOpenGLTextureBlitter *blitter, QMatrix4x4 *rotationMatrix, + QOpenGLTextureBlitter::Origin sourceOrigin) { const QRect clipRect = textures->clipRect(idx); if (clipRect.isEmpty()) @@ -173,13 +187,13 @@ static void clippedBlit(const QPlatformTextureList *textures, int idx, const QRe target = *rotationMatrix * target; const QMatrix3x3 source = QOpenGLTextureBlitter::sourceTransform(srcRect, rectInWindow.size(), - QOpenGLTextureBlitter::OriginBottomLeft); + sourceOrigin); const uint textureId = textures->texture(idx)->nativeTexture().object; blitter->blit(textureId, target, source); } -void QOpenGLCompositor::render(QOpenGLCompositorWindow *window) +void QOpenGLCompositor::render(QOpenGLCompositorWindow *window, QOpenGLTextureBlitter::Origin origin) { const QPlatformTextureList *textures = window->textures(); if (!textures) @@ -189,6 +203,9 @@ void QOpenGLCompositor::render(QOpenGLCompositorWindow *window) float currentOpacity = 1.0f; BlendStateBinder blend; const QRect sourceWindowRect = window->sourceWindow()->geometry(); + auto clippedBlitSourceOrigin = origin == QOpenGLTextureBlitter::OriginTopLeft + ? QOpenGLTextureBlitter::OriginBottomLeft + : QOpenGLTextureBlitter::OriginTopLeft; for (int i = 0; i < textures->count(); ++i) { const uint textureId = textures->texture(i)->nativeTexture().object; const float opacity = window->sourceWindow()->opacity(); @@ -203,7 +220,7 @@ void QOpenGLCompositor::render(QOpenGLCompositorWindow *window) QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect); if (m_rotation) target = m_rotationMatrix * target; - m_blitter.blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft); + m_blitter.blit(textureId, target, origin); } else if (textures->count() == 1) { // A regular QWidget window const bool translucent = window->sourceWindow()->requestedFormat().alphaBufferSize() > 0; @@ -211,18 +228,20 @@ void QOpenGLCompositor::render(QOpenGLCompositorWindow *window) QMatrix4x4 target = QOpenGLTextureBlitter::targetTransform(textures->geometry(i), targetWindowRect); if (m_rotation) target = m_rotationMatrix * target; - m_blitter.blit(textureId, target, QOpenGLTextureBlitter::OriginTopLeft); + m_blitter.blit(textureId, target, origin); } else if (!textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) { // Texture from an FBO belonging to a QOpenGLWidget or QQuickWidget blend.set(false); - clippedBlit(textures, i, sourceWindowRect, targetWindowRect, &m_blitter, m_rotation ? &m_rotationMatrix : nullptr); + clippedBlit(textures, i, sourceWindowRect, targetWindowRect, &m_blitter, + m_rotation ? &m_rotationMatrix : nullptr, clippedBlitSourceOrigin); } } for (int i = 0; i < textures->count(); ++i) { if (textures->flags(i).testFlag(QPlatformTextureList::StacksOnTop)) { blend.set(true); - clippedBlit(textures, i, sourceWindowRect, targetWindowRect, &m_blitter, m_rotation ? &m_rotationMatrix : nullptr); + clippedBlit(textures, i, sourceWindowRect, targetWindowRect, &m_blitter, + m_rotation ? &m_rotationMatrix : nullptr, clippedBlitSourceOrigin); } } @@ -246,7 +265,9 @@ void QOpenGLCompositor::addWindow(QOpenGLCompositorWindow *window) { if (!m_windows.contains(window)) { m_windows.append(window); - emit topWindowChanged(window); + ensureCorrectZOrder(); + if (window == m_windows.constLast()) + emit topWindowChanged(window); } } @@ -259,9 +280,17 @@ void QOpenGLCompositor::removeWindow(QOpenGLCompositorWindow *window) void QOpenGLCompositor::moveToTop(QOpenGLCompositorWindow *window) { + if (!m_windows.isEmpty() && window == m_windows.constLast()) { + // Already on top + return; + } + m_windows.removeOne(window); m_windows.append(window); - emit topWindowChanged(window); + ensureCorrectZOrder(); + + if (window == m_windows.constLast()) + emit topWindowChanged(window); } void QOpenGLCompositor::changeWindowIndex(QOpenGLCompositorWindow *window, int newIdx) @@ -269,11 +298,63 @@ void QOpenGLCompositor::changeWindowIndex(QOpenGLCompositorWindow *window, int n int idx = m_windows.indexOf(window); if (idx != -1 && idx != newIdx) { m_windows.move(idx, newIdx); - if (newIdx == m_windows.size() - 1) + ensureCorrectZOrder(); + if (window == m_windows.constLast()) emit topWindowChanged(m_windows.last()); } } +void QOpenGLCompositor::ensureCorrectZOrder() +{ + const auto originalOrder = m_windows; + + std::sort(m_windows.begin(), m_windows.end(), + [this, &originalOrder](QOpenGLCompositorWindow *cw1, QOpenGLCompositorWindow *cw2) { + QWindow *w1 = cw1->sourceWindow(); + QWindow *w2 = cw2->sourceWindow(); + + // Case #1: The main window needs to have less z-order. It can never be in + // front of our tool windows, popups etc, because it's fullscreen! + if (w1 == m_targetWindow || w2 == m_targetWindow) + return w1 == m_targetWindow; + + // Case #2: + if (w2->isAncestorOf(w1)) { + // w1 is transient child of w2. W1 goes in front then. + return false; + } + + if (w1->isAncestorOf(w2)) { + // Or the other way around + return true; + } + + // Case #3: Modality gets higher Z + if (w1->modality() != Qt::NonModal && w2->modality() == Qt::NonModal) + return false; + + if (w2->modality() != Qt::NonModal && w1->modality() == Qt::NonModal) + return true; + + const bool isTool1 = (w1->flags() & Qt::Tool) == Qt::Tool; + const bool isTool2 = (w2->flags() & Qt::Tool) == Qt::Tool; + const bool isPurePopup1 = !isTool1 && (w1->flags() & Qt::Popup) == Qt::Popup; + const bool isPurePopup2 = !isTool2 && (w2->flags() & Qt::Popup) == Qt::Popup; + + // Case #4: By pure-popup we mean menus and tooltips. Qt::Tool implies Qt::Popup + // and we don't want to catch QDockWidget and other tool windows just yet + if (isPurePopup1 != isPurePopup2) + return !isPurePopup1; + + // Case #5: One of the window is a Tool, that goes to front, as done in other QPAs + if (isTool1 != isTool2) + return !isTool1; + + // Case #6: Just preserve original sorting: + return originalOrder.indexOf(cw1) < originalOrder.indexOf(cw2); + }); +} + QT_END_NAMESPACE #include "moc_qopenglcompositor_p.cpp" diff --git a/src/opengl/qopenglcompositor_p.h b/src/opengl/qopenglcompositor_p.h index 6ab738c58e..86229b13ca 100644 --- a/src/opengl/qopenglcompositor_p.h +++ b/src/opengl/qopenglcompositor_p.h @@ -29,6 +29,7 @@ class QOpenGLFramebufferObject; class QWindow; class QPlatformTextureList; +class QOpenGLCompositorBackingStore; class QOpenGLCompositorWindow { public: @@ -37,6 +38,8 @@ public: virtual const QPlatformTextureList *textures() const = 0; virtual void beginCompositing() { } virtual void endCompositing() { } + virtual void setBackingStore(QOpenGLCompositorBackingStore *backingStore) = 0; + virtual QOpenGLCompositorBackingStore *backingStore() const = 0; }; class Q_OPENGL_EXPORT QOpenGLCompositor : public QObject @@ -44,6 +47,11 @@ class Q_OPENGL_EXPORT QOpenGLCompositor : public QObject Q_OBJECT public: + enum GrabOrientation { + Flipped, + NotFlipped, + }; + static QOpenGLCompositor *instance(); static void destroy(); @@ -52,10 +60,13 @@ public: void setRotation(int degrees); QOpenGLContext *context() const { return m_context; } QWindow *targetWindow() const { return m_targetWindow; } + QRect nativeTargetGeometry() const { return m_nativeTargetGeometry; } void update(); QImage grab(); + bool grabToFrameBufferObject(QOpenGLFramebufferObject *fbo, GrabOrientation orientation = Flipped); + QList<QOpenGLCompositorWindow *> windows() const { return m_windows; } void addWindow(QOpenGLCompositorWindow *window); void removeWindow(QOpenGLCompositorWindow *window); @@ -72,8 +83,11 @@ private: QOpenGLCompositor(); ~QOpenGLCompositor(); - void renderAll(QOpenGLFramebufferObject *fbo); - void render(QOpenGLCompositorWindow *window); + void renderAll(QOpenGLFramebufferObject *fbo, + QOpenGLTextureBlitter::Origin origin = QOpenGLTextureBlitter::OriginTopLeft); + void render(QOpenGLCompositorWindow *window, + QOpenGLTextureBlitter::Origin origin = QOpenGLTextureBlitter::OriginTopLeft); + void ensureCorrectZOrder(); QOpenGLContext *m_context; QWindow *m_targetWindow; diff --git a/src/opengl/qopenglcompositorbackingstore.cpp b/src/opengl/qopenglcompositorbackingstore.cpp index a5cc391e48..931734cf60 100644 --- a/src/opengl/qopenglcompositorbackingstore.cpp +++ b/src/opengl/qopenglcompositorbackingstore.cpp @@ -6,7 +6,7 @@ #include <QtGui/QPainter> #include <qpa/qplatformbackingstore.h> #include <private/qwindow_p.h> -#include <private/qrhi_p.h> +#include <rhi/qrhi.h> #include "qopenglcompositorbackingstore_p.h" #include "qopenglcompositor_p.h" @@ -137,6 +137,9 @@ void QOpenGLCompositorBackingStore::updateTexture() void QOpenGLCompositorBackingStore::flush(QWindow *window, const QRegion ®ion, const QPoint &offset) { // Called for ordinary raster windows. + auto *handle = dynamic_cast<QOpenGLCompositorWindow *>(window->handle()); + if (handle && !handle->backingStore()) + handle->setBackingStore(this); Q_UNUSED(region); Q_UNUSED(offset); @@ -246,6 +249,8 @@ void QOpenGLCompositorBackingStore::resize(const QSize &size, const QRegion &sta QOpenGLCompositor *compositor = QOpenGLCompositor::instance(); QOpenGLContext *dstCtx = compositor->context(); + if (!dstCtx) + return; QWindow *dstWin = compositor->targetWindow(); if (!dstWin) return; diff --git a/src/opengl/qopenglcustomshaderstage.cpp b/src/opengl/qopenglcustomshaderstage.cpp index d26bebfd61..1be8d783d6 100644 --- a/src/opengl/qopenglcustomshaderstage.cpp +++ b/src/opengl/qopenglcustomshaderstage.cpp @@ -6,6 +6,8 @@ #include "qopenglpaintengine_p.h" #include <private/qpainter_p.h> +#include <QtCore/qpointer.h> + QT_BEGIN_NAMESPACE class QOpenGLCustomShaderStagePrivate diff --git a/src/opengl/qopengldebug.cpp b/src/opengl/qopengldebug.cpp index 522aa2dba7..b774d0a85e 100644 --- a/src/opengl/qopengldebug.cpp +++ b/src/opengl/qopengldebug.cpp @@ -1147,7 +1147,7 @@ void QOpenGLDebugLoggerPrivate::controlDebugMessages(QOpenGLDebugMessage::Source QVarLengthArray<GLenum, 8> glTypes; QVarLengthArray<GLenum, 8> glSeverities; - if (ids.count() > 0) { + if (ids.size() > 0) { Q_ASSERT(severities == QOpenGLDebugMessage::AnySeverity); // The GL_KHR_debug extension says: @@ -1188,7 +1188,7 @@ void QOpenGLDebugLoggerPrivate::controlDebugMessages(QOpenGLDebugMessage::Source CONVERT_TO_GL_DEBUG_MESSAGE_CONTROL_PARAMETERS(Severity, severities, glSeverities) #undef CONVERT_TO_GL_DEBUG_MESSAGE_CONTROL_PARAMETERS - const GLsizei idCount = ids.count(); + const GLsizei idCount = ids.size(); // The GL_KHR_debug extension says that if idCount is 0, idPtr must be ignored. // Unfortunately, some bugged drivers do NOT ignore it, so pass NULL in case. const GLuint * const idPtr = idCount ? ids.constData() : nullptr; @@ -1504,9 +1504,9 @@ void QOpenGLDebugLogger::logMessage(const QOpenGLDebugMessage &debugMessage) QByteArray rawMessage = debugMessage.message().toUtf8(); rawMessage.append('\0'); - if (rawMessage.length() > d->maxMessageLength) { + if (rawMessage.size() > d->maxMessageLength) { qWarning("QOpenGLDebugLogger::logMessage(): message too long, truncating it\n" - " (%d bytes long, but the GL accepts up to %d bytes)", int(rawMessage.length()), d->maxMessageLength); + " (%d bytes long, but the GL accepts up to %d bytes)", int(rawMessage.size()), d->maxMessageLength); rawMessage.resize(d->maxMessageLength - 1); rawMessage.append('\0'); } @@ -1556,9 +1556,9 @@ void QOpenGLDebugLogger::pushGroup(const QString &name, GLuint id, QOpenGLDebugM QByteArray rawName = name.toUtf8(); rawName.append('\0'); - if (rawName.length() > d->maxMessageLength) { + if (rawName.size() > d->maxMessageLength) { qWarning("QOpenGLDebugLogger::pushGroup(): group name too long, truncating it\n" - " (%d bytes long, but the GL accepts up to %d bytes)", int(rawName.length()), d->maxMessageLength); + " (%d bytes long, but the GL accepts up to %d bytes)", int(rawName.size()), d->maxMessageLength); rawName.resize(d->maxMessageLength - 1); rawName.append('\0'); } diff --git a/src/opengl/qopengldebug.h b/src/opengl/qopengldebug.h index 22bf0ce2c5..843ab7212a 100644 --- a/src/opengl/qopengldebug.h +++ b/src/opengl/qopengldebug.h @@ -15,7 +15,7 @@ #include <QtCore/qdebug.h> #include <QtGui/qopenglcontext.h> -#if defined(Q_CLANG_QDOC) +#if defined(Q_QDOC) #undef GLuint typedef unsigned int GLuint; #endif diff --git a/src/opengl/qopenglengineshadermanager.cpp b/src/opengl/qopenglengineshadermanager.cpp index d37da00a87..4b0c9ffdcf 100644 --- a/src/opengl/qopenglengineshadermanager.cpp +++ b/src/opengl/qopenglengineshadermanager.cpp @@ -431,7 +431,7 @@ QOpenGLEngineShaderProg *QOpenGLEngineSharedShaders::findProgramInCache(const QO newProg->program->setUniformValue(location, QT_MASK_TEXTURE_UNIT); } - if (cachedPrograms.count() > 30) { + if (cachedPrograms.size() > 30) { // The cache is full, so delete the last 5 programs in the list. // These programs will be least used, as a program us bumped to // the top of the list when it's used. diff --git a/src/opengl/qopenglframebufferobject.cpp b/src/opengl/qopenglframebufferobject.cpp index 7bb4f49f6e..5c8f769d39 100644 --- a/src/opengl/qopenglframebufferobject.cpp +++ b/src/opengl/qopenglframebufferobject.cpp @@ -18,6 +18,15 @@ QT_BEGIN_NAMESPACE +Q_TRACE_PREFIX(qtopengl, + "#include <private/qopengl2pexvertexarray_p.h>" \ + "#include <private/qopengltextureuploader_p.h>" \ + "#include <qopenglframebufferobject.h>" +); +Q_TRACE_PARAM_REPLACE(GLenum, int); +Q_TRACE_PARAM_REPLACE(GLint, int); +Q_TRACE_METADATA(qtopengl, "ENUM { } QOpenGLFramebufferObject::Attachment; "); + #ifndef QT_NO_DEBUG #define QT_RESET_GLERROR() \ { \ @@ -452,10 +461,11 @@ namespace } } -void QOpenGLFramebufferObjectPrivate::init(QOpenGLFramebufferObject *qfbo, const QSize &size, - QOpenGLFramebufferObject::Attachment attachment, - GLenum texture_target, GLenum internal_format, - GLint samples, bool mipmap) +void Q_TRACE_INSTRUMENT(qtopengl) QOpenGLFramebufferObjectPrivate::init( + QOpenGLFramebufferObject *qfbo, const QSize &size, + QOpenGLFramebufferObject::Attachment attachment, + GLenum texture_target, GLenum internal_format, + GLint samples, bool mipmap) { Q_TRACE_SCOPE(QOpenGLFramebufferObjectPrivate_init, qfbo, size, attachment, texture_target, internal_format, samples, mipmap); Q_UNUSED(qfbo); @@ -540,8 +550,22 @@ void QOpenGLFramebufferObjectPrivate::initTexture(int idx) else if (color.internalFormat == GL_RGB16F || color.internalFormat == GL_RGBA16F) pixelType = GL_HALF_FLOAT; + bool isOpaque = false; + switch (color.internalFormat) { + case GL_RGB8: + case GL_RGB16: + case GL_RGB16F: + case GL_RGB32F: + isOpaque = true; + break; + case GL_RGB10: + // opaque but the pixel type (INT_2_10_10_10) has alpha and so requires RGBA texture format + break; + } + const GLuint textureFormat = isOpaque ? GL_RGB : GL_RGBA; + funcs.glTexImage2D(target, 0, color.internalFormat, color.size.width(), color.size.height(), 0, - GL_RGBA, pixelType, nullptr); + textureFormat, pixelType, nullptr); if (format.mipmap()) { int width = color.size.width(); int height = color.size.height(); @@ -550,8 +574,8 @@ void QOpenGLFramebufferObjectPrivate::initTexture(int idx) width = qMax(1, width >> 1); height = qMax(1, height >> 1); ++level; - funcs.glTexImage2D(target, level, color.internalFormat, width, height, 0, - GL_RGBA, pixelType, nullptr); + funcs.glTexImage2D(target, level, color.internalFormat, width, height, 0, textureFormat, + pixelType, nullptr); } } funcs.glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0 + idx, @@ -993,7 +1017,7 @@ QOpenGLFramebufferObject::~QOpenGLFramebufferObject() if (isBound()) release(); - for (const auto &color : qAsConst(d->colorAttachments)) { + for (const auto &color : std::as_const(d->colorAttachments)) { if (color.guard) color.guard->free(); } @@ -1053,7 +1077,7 @@ void QOpenGLFramebufferObject::addColorAttachment(const QSize &size, GLenum inte QOpenGLFramebufferObjectPrivate::ColorAttachment color(size, effectiveInternalFormat(internalFormat)); d->colorAttachments.append(color); - const int idx = d->colorAttachments.count() - 1; + const int idx = d->colorAttachments.size() - 1; if (d->requestedSamples == 0) { d->initTexture(idx); @@ -1134,7 +1158,7 @@ bool QOpenGLFramebufferObject::bind() if (d->format.samples() == 0) { // Create new textures to replace the ones stolen via takeTexture(). - for (int i = 0; i < d->colorAttachments.count(); ++i) { + for (int i = 0; i < d->colorAttachments.size(); ++i) { if (!d->colorAttachments.at(i).guard) d->initTexture(i); } @@ -1214,7 +1238,7 @@ QList<GLuint> QOpenGLFramebufferObject::textures() const QList<GLuint> ids; if (d->format.samples() != 0) return ids; - ids.reserve(d->colorAttachments.count()); + ids.reserve(d->colorAttachments.size()); for (const auto &color : d->colorAttachments) ids.append(color.guard ? color.guard->id() : 0); return ids; @@ -1266,7 +1290,7 @@ GLuint QOpenGLFramebufferObject::takeTexture(int colorAttachmentIndex) { Q_D(QOpenGLFramebufferObject); GLuint id = 0; - if (isValid() && d->format.samples() == 0 && d->colorAttachments.count() > colorAttachmentIndex) { + if (isValid() && d->format.samples() == 0 && d->colorAttachments.size() > colorAttachmentIndex) { QOpenGLContext *current = QOpenGLContext::currentContext(); if (current && current->shareGroup() == d->fbo_guard->group() && isBound()) release(); @@ -1334,7 +1358,8 @@ static inline QImage qt_gl_read_framebuffer_rgba8(const QSize &size, bool includ bool isOpenGL12orBetter = !context->isOpenGLES() && (context->format().majorVersion() >= 2 || context->format().minorVersion() >= 2); if (isOpenGL12orBetter) { QImage img(size, include_alpha ? QImage::Format_ARGB32_Premultiplied : QImage::Format_RGB32); - funcs->glReadPixels(0, 0, w, h, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, img.bits()); + if (!img.isNull()) + funcs->glReadPixels(0, 0, w, h, GL_BGRA, GL_UNSIGNED_INT_8_8_8_8_REV, img.bits()); return img; } @@ -1344,7 +1369,8 @@ static inline QImage qt_gl_read_framebuffer_rgba8(const QSize &size, bool includ // BGRA capable impl would return BGRA from there) QImage rgbaImage(size, include_alpha ? QImage::Format_RGBA8888_Premultiplied : QImage::Format_RGBX8888); - funcs->glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, rgbaImage.bits()); + if (!rgbaImage.isNull()) + funcs->glReadPixels(0, 0, w, h, GL_RGBA, GL_UNSIGNED_BYTE, rgbaImage.bits()); return rgbaImage; } @@ -1352,7 +1378,8 @@ static inline QImage qt_gl_read_framebuffer_rgb10a2(const QSize &size, bool incl { // We assume OpenGL 1.2+ or ES 3.0+ here. QImage img(size, include_alpha ? QImage::Format_A2BGR30_Premultiplied : QImage::Format_BGR30); - context->functions()->glReadPixels(0, 0, size.width(), size.height(), GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, img.bits()); + if (!img.isNull()) + context->functions()->glReadPixels(0, 0, size.width(), size.height(), GL_RGBA, GL_UNSIGNED_INT_2_10_10_10_REV, img.bits()); return img; } @@ -1360,7 +1387,8 @@ static inline QImage qt_gl_read_framebuffer_rgba16(const QSize &size, bool inclu { // We assume OpenGL 1.2+ or ES 3.0+ here. QImage img(size, include_alpha ? QImage::Format_RGBA64_Premultiplied : QImage::Format_RGBX64); - context->functions()->glReadPixels(0, 0, size.width(), size.height(), GL_RGBA, GL_UNSIGNED_SHORT, img.bits()); + if (!img.isNull()) + context->functions()->glReadPixels(0, 0, size.width(), size.height(), GL_RGBA, GL_UNSIGNED_SHORT, img.bits()); return img; } @@ -1368,14 +1396,16 @@ static inline QImage qt_gl_read_framebuffer_rgba16f(const QSize &size, bool incl { // We assume OpenGL (ES) 3.0+ here. QImage img(size, include_alpha ? QImage::Format_RGBA16FPx4_Premultiplied : QImage::Format_RGBX16FPx4); - context->functions()->glReadPixels(0, 0, size.width(), size.height(), GL_RGBA, GL_HALF_FLOAT, img.bits()); + if (!img.isNull()) + context->functions()->glReadPixels(0, 0, size.width(), size.height(), GL_RGBA, GL_HALF_FLOAT, img.bits()); return img; } static inline QImage qt_gl_read_framebuffer_rgba32f(const QSize &size, bool include_alpha, QOpenGLContext *context) { QImage img(size, include_alpha ? QImage::Format_RGBA32FPx4_Premultiplied : QImage::Format_RGBX32FPx4); - context->functions()->glReadPixels(0, 0, size.width(), size.height(), GL_RGBA, GL_FLOAT, img.bits()); + if (!img.isNull()) + context->functions()->glReadPixels(0, 0, size.width(), size.height(), GL_RGBA, GL_FLOAT, img.bits()); return img; } @@ -1414,8 +1444,7 @@ static QImage qt_gl_read_framebuffer(const QSize &size, GLenum internal_format, return qt_gl_read_framebuffer_rgba8(size, include_alpha, ctx).mirrored(false, flip); } - Q_UNREACHABLE(); - return QImage(); + Q_UNREACHABLE_RETURN(QImage()); } Q_OPENGL_EXPORT QImage qt_gl_read_framebuffer(const QSize &size, bool alpha_format, bool include_alpha) @@ -1491,7 +1520,7 @@ QImage QOpenGLFramebufferObject::toImage(bool flipped, int colorAttachmentIndex) return QImage(); } - if (d->colorAttachments.count() <= colorAttachmentIndex) { + if (d->colorAttachments.size() <= colorAttachmentIndex) { qWarning("QOpenGLFramebufferObject::toImage() called for missing color attachment"); return QImage(); } diff --git a/src/opengl/qopenglframebufferobject.h b/src/opengl/qopenglframebufferobject.h index bff4d8b4c0..1701901e9d 100644 --- a/src/opengl/qopenglframebufferobject.h +++ b/src/opengl/qopenglframebufferobject.h @@ -11,7 +11,7 @@ #include <QtCore/qscopedpointer.h> -#if defined(Q_CLANG_QDOC) +#if defined(Q_QDOC) #undef GLuint typedef unsigned int GLuint; #undef GLenum diff --git a/src/opengl/qopenglfunctions_2_0.cpp b/src/opengl/qopenglfunctions_2_0.cpp index 834136d3dd..0641f41390 100644 --- a/src/opengl/qopenglfunctions_2_0.cpp +++ b/src/opengl/qopenglfunctions_2_0.cpp @@ -44,7 +44,6 @@ QOpenGLFunctions_2_0::QOpenGLFunctions_2_0() , d_1_2_Deprecated(nullptr) , d_1_3_Deprecated(nullptr) , d_1_4_Deprecated(nullptr) - , m_reserved_2_0_Deprecated(nullptr) { } diff --git a/src/opengl/qopenglfunctions_2_0.h b/src/opengl/qopenglfunctions_2_0.h index f45a56b4f3..cca8d590e7 100644 --- a/src/opengl/qopenglfunctions_2_0.h +++ b/src/opengl/qopenglfunctions_2_0.h @@ -656,7 +656,7 @@ private: QOpenGLFunctions_1_2_DeprecatedBackend* d_1_2_Deprecated; QOpenGLFunctions_1_3_DeprecatedBackend* d_1_3_Deprecated; QOpenGLFunctions_1_4_DeprecatedBackend* d_1_4_Deprecated; - void *m_reserved_2_0_Deprecated; // To maintain BC + Q_DECL_UNUSED_MEMBER void *m_reserved_2_0_Deprecated = nullptr; // To maintain BC }; // OpenGL 1.0 core functions diff --git a/src/opengl/qopenglfunctions_2_1.cpp b/src/opengl/qopenglfunctions_2_1.cpp index 984bb16d11..28f8b29dab 100644 --- a/src/opengl/qopenglfunctions_2_1.cpp +++ b/src/opengl/qopenglfunctions_2_1.cpp @@ -45,7 +45,6 @@ QOpenGLFunctions_2_1::QOpenGLFunctions_2_1() , d_1_2_Deprecated(nullptr) , d_1_3_Deprecated(nullptr) , d_1_4_Deprecated(nullptr) - , m_reserved_2_0_Deprecated(nullptr) { } diff --git a/src/opengl/qopenglfunctions_2_1.h b/src/opengl/qopenglfunctions_2_1.h index 249ede3608..3b192e3b62 100644 --- a/src/opengl/qopenglfunctions_2_1.h +++ b/src/opengl/qopenglfunctions_2_1.h @@ -667,7 +667,7 @@ private: QOpenGLFunctions_1_2_DeprecatedBackend* d_1_2_Deprecated; QOpenGLFunctions_1_3_DeprecatedBackend* d_1_3_Deprecated; QOpenGLFunctions_1_4_DeprecatedBackend* d_1_4_Deprecated; - void *m_reserved_2_0_Deprecated; // To maintain BC + Q_DECL_UNUSED_MEMBER void *m_reserved_2_0_Deprecated = nullptr; // To maintain BC }; // OpenGL 1.0 core functions diff --git a/src/opengl/qopenglfunctions_3_0.cpp b/src/opengl/qopenglfunctions_3_0.cpp index 5fcf1c9b2c..b186ff2a9f 100644 --- a/src/opengl/qopenglfunctions_3_0.cpp +++ b/src/opengl/qopenglfunctions_3_0.cpp @@ -46,8 +46,6 @@ QOpenGLFunctions_3_0::QOpenGLFunctions_3_0() , d_1_2_Deprecated(nullptr) , d_1_3_Deprecated(nullptr) , d_1_4_Deprecated(nullptr) - , m_reserved_2_0_Deprecated(nullptr) - , m_reserved_3_0_Deprecated(nullptr) { } diff --git a/src/opengl/qopenglfunctions_3_0.h b/src/opengl/qopenglfunctions_3_0.h index 5276fc730a..01d6ccefaf 100644 --- a/src/opengl/qopenglfunctions_3_0.h +++ b/src/opengl/qopenglfunctions_3_0.h @@ -756,8 +756,8 @@ private: QOpenGLFunctions_1_2_DeprecatedBackend* d_1_2_Deprecated; QOpenGLFunctions_1_3_DeprecatedBackend* d_1_3_Deprecated; QOpenGLFunctions_1_4_DeprecatedBackend* d_1_4_Deprecated; - void *m_reserved_2_0_Deprecated; // To maintain BC - void *m_reserved_3_0_Deprecated; // To maintain BC + Q_DECL_UNUSED_MEMBER void *m_reserved_2_0_Deprecated = nullptr; // To maintain BC + Q_DECL_UNUSED_MEMBER void *m_reserved_3_0_Deprecated = nullptr; // To maintain BC }; // OpenGL 1.0 core functions diff --git a/src/opengl/qopenglfunctions_3_2_compatibility.cpp b/src/opengl/qopenglfunctions_3_2_compatibility.cpp index 6c90c569d7..c1b1806998 100644 --- a/src/opengl/qopenglfunctions_3_2_compatibility.cpp +++ b/src/opengl/qopenglfunctions_3_2_compatibility.cpp @@ -48,8 +48,6 @@ QOpenGLFunctions_3_2_Compatibility::QOpenGLFunctions_3_2_Compatibility() , d_1_2_Deprecated(nullptr) , d_1_3_Deprecated(nullptr) , d_1_4_Deprecated(nullptr) - , m_reserved_2_0_Deprecated(nullptr) - , m_reserved_3_0_Deprecated(nullptr) { } diff --git a/src/opengl/qopenglfunctions_3_2_compatibility.h b/src/opengl/qopenglfunctions_3_2_compatibility.h index 416ceb2725..b01c232385 100644 --- a/src/opengl/qopenglfunctions_3_2_compatibility.h +++ b/src/opengl/qopenglfunctions_3_2_compatibility.h @@ -797,8 +797,8 @@ private: QOpenGLFunctions_1_2_DeprecatedBackend* d_1_2_Deprecated; QOpenGLFunctions_1_3_DeprecatedBackend* d_1_3_Deprecated; QOpenGLFunctions_1_4_DeprecatedBackend* d_1_4_Deprecated; - void *m_reserved_2_0_Deprecated; // To maintain BC - void *m_reserved_3_0_Deprecated; // To maintain BC + Q_DECL_UNUSED_MEMBER void *m_reserved_2_0_Deprecated = nullptr; // To maintain BC + Q_DECL_UNUSED_MEMBER void *m_reserved_3_0_Deprecated = nullptr; // To maintain BC }; // OpenGL 1.0 core functions diff --git a/src/opengl/qopenglfunctions_3_3_compatibility.cpp b/src/opengl/qopenglfunctions_3_3_compatibility.cpp index 0c61516ca1..60ef10553b 100644 --- a/src/opengl/qopenglfunctions_3_3_compatibility.cpp +++ b/src/opengl/qopenglfunctions_3_3_compatibility.cpp @@ -49,7 +49,6 @@ QOpenGLFunctions_3_3_Compatibility::QOpenGLFunctions_3_3_Compatibility() , d_1_2_Deprecated(nullptr) , d_1_3_Deprecated(nullptr) , d_1_4_Deprecated(nullptr) - , m_reserved_2_0_Deprecated(nullptr) , d_3_3_Deprecated(nullptr) { } diff --git a/src/opengl/qopenglfunctions_3_3_compatibility.h b/src/opengl/qopenglfunctions_3_3_compatibility.h index 92f6bd8bde..25490648f3 100644 --- a/src/opengl/qopenglfunctions_3_3_compatibility.h +++ b/src/opengl/qopenglfunctions_3_3_compatibility.h @@ -860,7 +860,7 @@ private: QOpenGLFunctions_1_2_DeprecatedBackend* d_1_2_Deprecated; QOpenGLFunctions_1_3_DeprecatedBackend* d_1_3_Deprecated; QOpenGLFunctions_1_4_DeprecatedBackend* d_1_4_Deprecated; - void *m_reserved_2_0_Deprecated; // To maintain BC + Q_DECL_UNUSED_MEMBER void *m_reserved_2_0_Deprecated = nullptr; // To maintain BC QOpenGLFunctions_3_3_DeprecatedBackend* d_3_3_Deprecated; }; diff --git a/src/opengl/qopenglfunctions_4_0_compatibility.cpp b/src/opengl/qopenglfunctions_4_0_compatibility.cpp index c380e73cb5..7074de5bde 100644 --- a/src/opengl/qopenglfunctions_4_0_compatibility.cpp +++ b/src/opengl/qopenglfunctions_4_0_compatibility.cpp @@ -50,7 +50,6 @@ QOpenGLFunctions_4_0_Compatibility::QOpenGLFunctions_4_0_Compatibility() , d_1_2_Deprecated(nullptr) , d_1_3_Deprecated(nullptr) , d_1_4_Deprecated(nullptr) - , m_reserved_2_0_Deprecated(nullptr) , d_3_3_Deprecated(nullptr) { } diff --git a/src/opengl/qopenglfunctions_4_0_compatibility.h b/src/opengl/qopenglfunctions_4_0_compatibility.h index ba725464af..b72d01305a 100644 --- a/src/opengl/qopenglfunctions_4_0_compatibility.h +++ b/src/opengl/qopenglfunctions_4_0_compatibility.h @@ -911,7 +911,7 @@ private: QOpenGLFunctions_1_2_DeprecatedBackend* d_1_2_Deprecated; QOpenGLFunctions_1_3_DeprecatedBackend* d_1_3_Deprecated; QOpenGLFunctions_1_4_DeprecatedBackend* d_1_4_Deprecated; - void *m_reserved_2_0_Deprecated; // To maintain BC + Q_DECL_UNUSED_MEMBER void *m_reserved_2_0_Deprecated = nullptr; // To maintain BC QOpenGLFunctions_3_3_DeprecatedBackend* d_3_3_Deprecated; }; diff --git a/src/opengl/qopenglfunctions_4_1_compatibility.cpp b/src/opengl/qopenglfunctions_4_1_compatibility.cpp index 399fd5c990..035cc79276 100644 --- a/src/opengl/qopenglfunctions_4_1_compatibility.cpp +++ b/src/opengl/qopenglfunctions_4_1_compatibility.cpp @@ -51,7 +51,6 @@ QOpenGLFunctions_4_1_Compatibility::QOpenGLFunctions_4_1_Compatibility() , d_1_2_Deprecated(nullptr) , d_1_3_Deprecated(nullptr) , d_1_4_Deprecated(nullptr) - , m_reserved_2_0_Deprecated(nullptr) , d_3_3_Deprecated(nullptr) { } diff --git a/src/opengl/qopenglfunctions_4_1_compatibility.h b/src/opengl/qopenglfunctions_4_1_compatibility.h index ee8ab6be44..08b7c05232 100644 --- a/src/opengl/qopenglfunctions_4_1_compatibility.h +++ b/src/opengl/qopenglfunctions_4_1_compatibility.h @@ -1004,7 +1004,7 @@ private: QOpenGLFunctions_1_2_DeprecatedBackend* d_1_2_Deprecated; QOpenGLFunctions_1_3_DeprecatedBackend* d_1_3_Deprecated; QOpenGLFunctions_1_4_DeprecatedBackend* d_1_4_Deprecated; - void *m_reserved_2_0_Deprecated; // To maintain BC + Q_DECL_UNUSED_MEMBER void *m_reserved_2_0_Deprecated = nullptr; // To maintain BC QOpenGLFunctions_3_3_DeprecatedBackend* d_3_3_Deprecated; }; diff --git a/src/opengl/qopenglfunctions_4_2_compatibility.cpp b/src/opengl/qopenglfunctions_4_2_compatibility.cpp index 5bf2eedbaf..faf0ca845f 100644 --- a/src/opengl/qopenglfunctions_4_2_compatibility.cpp +++ b/src/opengl/qopenglfunctions_4_2_compatibility.cpp @@ -52,7 +52,6 @@ QOpenGLFunctions_4_2_Compatibility::QOpenGLFunctions_4_2_Compatibility() , d_1_2_Deprecated(nullptr) , d_1_3_Deprecated(nullptr) , d_1_4_Deprecated(nullptr) - , m_reserved_2_0_Deprecated(nullptr) , d_3_3_Deprecated(nullptr) { } diff --git a/src/opengl/qopenglfunctions_4_2_compatibility.h b/src/opengl/qopenglfunctions_4_2_compatibility.h index ca5b4127db..2bc4f8b228 100644 --- a/src/opengl/qopenglfunctions_4_2_compatibility.h +++ b/src/opengl/qopenglfunctions_4_2_compatibility.h @@ -1027,7 +1027,7 @@ private: QOpenGLFunctions_1_2_DeprecatedBackend* d_1_2_Deprecated; QOpenGLFunctions_1_3_DeprecatedBackend* d_1_3_Deprecated; QOpenGLFunctions_1_4_DeprecatedBackend* d_1_4_Deprecated; - void *m_reserved_2_0_Deprecated; // To maintain BC + Q_DECL_UNUSED_MEMBER void *m_reserved_2_0_Deprecated = nullptr; // To maintain BC QOpenGLFunctions_3_3_DeprecatedBackend* d_3_3_Deprecated; }; diff --git a/src/opengl/qopenglfunctions_4_3_compatibility.cpp b/src/opengl/qopenglfunctions_4_3_compatibility.cpp index c401a93189..c3a3d5d32b 100644 --- a/src/opengl/qopenglfunctions_4_3_compatibility.cpp +++ b/src/opengl/qopenglfunctions_4_3_compatibility.cpp @@ -53,7 +53,6 @@ QOpenGLFunctions_4_3_Compatibility::QOpenGLFunctions_4_3_Compatibility() , d_1_2_Deprecated(nullptr) , d_1_3_Deprecated(nullptr) , d_1_4_Deprecated(nullptr) - , m_reserved_2_0_Deprecated(nullptr) , d_3_3_Deprecated(nullptr) { } diff --git a/src/opengl/qopenglfunctions_4_3_compatibility.h b/src/opengl/qopenglfunctions_4_3_compatibility.h index e79cecb542..0370637653 100644 --- a/src/opengl/qopenglfunctions_4_3_compatibility.h +++ b/src/opengl/qopenglfunctions_4_3_compatibility.h @@ -1065,7 +1065,7 @@ private: QOpenGLFunctions_1_2_DeprecatedBackend* d_1_2_Deprecated; QOpenGLFunctions_1_3_DeprecatedBackend* d_1_3_Deprecated; QOpenGLFunctions_1_4_DeprecatedBackend* d_1_4_Deprecated; - void *m_reserved_2_0_Deprecated; // To maintain BC + Q_DECL_UNUSED_MEMBER void *m_reserved_2_0_Deprecated = nullptr; // To maintain BC QOpenGLFunctions_3_3_DeprecatedBackend* d_3_3_Deprecated; }; diff --git a/src/opengl/qopenglfunctions_4_5_compatibility.h b/src/opengl/qopenglfunctions_4_5_compatibility.h index 229a0b4288..cca3eae9e2 100644 --- a/src/opengl/qopenglfunctions_4_5_compatibility.h +++ b/src/opengl/qopenglfunctions_4_5_compatibility.h @@ -700,25 +700,52 @@ public: void glNamedFramebufferParameteri(GLuint framebuffer, GLenum pname, GLint param); void glNamedFramebufferRenderbuffer(GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); void glCreateFramebuffers(GLsizei n, GLuint *framebuffers); +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) + void glGetNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr size, void *data); +#else void glGetNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizei size, void *data); +#endif void glGetNamedBufferPointerv(GLuint buffer, GLenum pname, void * *params); void glGetNamedBufferParameteri64v(GLuint buffer, GLenum pname, GLint64 *params); void glGetNamedBufferParameteriv(GLuint buffer, GLenum pname, GLint *params); +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) + void glFlushMappedNamedBufferRange(GLuint buffer, GLintptr offset, GLsizeiptr length); +#else void glFlushMappedNamedBufferRange(GLuint buffer, GLintptr offset, GLsizei length); +#endif GLboolean glUnmapNamedBuffer(GLuint buffer); +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) + void * glMapNamedBufferRange(GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); +#else void * glMapNamedBufferRange(GLuint buffer, GLintptr offset, GLsizei length, GLbitfield access); +#endif void * glMapNamedBuffer(GLuint buffer, GLenum access); +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) + void glClearNamedBufferSubData(GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); +#else void glClearNamedBufferSubData(GLuint buffer, GLenum internalformat, GLintptr offset, GLsizei size, GLenum format, GLenum type, const void *data); +#endif void glClearNamedBufferData(GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) + void glCopyNamedBufferSubData(GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); + void glNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); + void glNamedBufferData(GLuint buffer, GLsizeiptr size, const void *data, GLenum usage); + void glNamedBufferStorage(GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags); +#else void glCopyNamedBufferSubData(GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizei size); void glNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizei size, const void *data); void glNamedBufferData(GLuint buffer, GLsizei size, const void *data, GLenum usage); void glNamedBufferStorage(GLuint buffer, GLsizei size, const void *data, GLbitfield flags); +#endif void glCreateBuffers(GLsizei n, GLuint *buffers); void glGetTransformFeedbacki64_v(GLuint xfb, GLenum pname, GLuint index, GLint64 *param); void glGetTransformFeedbacki_v(GLuint xfb, GLenum pname, GLuint index, GLint *param); void glGetTransformFeedbackiv(GLuint xfb, GLenum pname, GLint *param); +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) + void glTransformFeedbackBufferRange(GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +#else void glTransformFeedbackBufferRange(GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizei size); +#endif void glTransformFeedbackBufferBase(GLuint xfb, GLuint index, GLuint buffer); void glCreateTransformFeedbacks(GLsizei n, GLuint *ids); void glClipControl(GLenum origin, GLenum depth); @@ -4381,7 +4408,11 @@ inline void QOpenGLFunctions_4_5_Compatibility::glCreateFramebuffers(GLsizei n, d_4_5_Core->f.CreateFramebuffers(n, framebuffers); } +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) +inline void QOpenGLFunctions_4_5_Compatibility::glGetNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr size, void *data) +#else inline void QOpenGLFunctions_4_5_Compatibility::glGetNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizei size, void *data) +#endif { d_4_5_Core->f.GetNamedBufferSubData(buffer, offset, size, data); } @@ -4401,7 +4432,11 @@ inline void QOpenGLFunctions_4_5_Compatibility::glGetNamedBufferParameteriv(GLui d_4_5_Core->f.GetNamedBufferParameteriv(buffer, pname, params); } +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) +inline void QOpenGLFunctions_4_5_Compatibility::glFlushMappedNamedBufferRange(GLuint buffer, GLintptr offset, GLsizeiptr length) +#else inline void QOpenGLFunctions_4_5_Compatibility::glFlushMappedNamedBufferRange(GLuint buffer, GLintptr offset, GLsizei length) +#endif { d_4_5_Core->f.FlushMappedNamedBufferRange(buffer, offset, length); } @@ -4411,7 +4446,11 @@ inline GLboolean QOpenGLFunctions_4_5_Compatibility::glUnmapNamedBuffer(GLuint b return d_4_5_Core->f.UnmapNamedBuffer(buffer); } +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) +inline void * QOpenGLFunctions_4_5_Compatibility::glMapNamedBufferRange(GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access) +#else inline void * QOpenGLFunctions_4_5_Compatibility::glMapNamedBufferRange(GLuint buffer, GLintptr offset, GLsizei length, GLbitfield access) +#endif { return d_4_5_Core->f.MapNamedBufferRange(buffer, offset, length, access); } @@ -4421,7 +4460,11 @@ inline void * QOpenGLFunctions_4_5_Compatibility::glMapNamedBuffer(GLuint buffer return d_4_5_Core->f.MapNamedBuffer(buffer, access); } +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) +inline void QOpenGLFunctions_4_5_Compatibility::glClearNamedBufferSubData(GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data) +#else inline void QOpenGLFunctions_4_5_Compatibility::glClearNamedBufferSubData(GLuint buffer, GLenum internalformat, GLintptr offset, GLsizei size, GLenum format, GLenum type, const void *data) +#endif { d_4_5_Core->f.ClearNamedBufferSubData(buffer, internalformat, offset, size, format, type, data); } @@ -4431,22 +4474,38 @@ inline void QOpenGLFunctions_4_5_Compatibility::glClearNamedBufferData(GLuint bu d_4_5_Core->f.ClearNamedBufferData(buffer, internalformat, format, type, data); } +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) +inline void QOpenGLFunctions_4_5_Compatibility::glCopyNamedBufferSubData(GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) +#else inline void QOpenGLFunctions_4_5_Compatibility::glCopyNamedBufferSubData(GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizei size) +#endif { d_4_5_Core->f.CopyNamedBufferSubData(readBuffer, writeBuffer, readOffset, writeOffset, size); } +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) +inline void QOpenGLFunctions_4_5_Compatibility::glNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data) +#else inline void QOpenGLFunctions_4_5_Compatibility::glNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizei size, const void *data) +#endif { d_4_5_Core->f.NamedBufferSubData(buffer, offset, size, data); } +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) +inline void QOpenGLFunctions_4_5_Compatibility::glNamedBufferData(GLuint buffer, GLsizeiptr size, const void *data, GLenum usage) +#else inline void QOpenGLFunctions_4_5_Compatibility::glNamedBufferData(GLuint buffer, GLsizei size, const void *data, GLenum usage) +#endif { d_4_5_Core->f.NamedBufferData(buffer, size, data, usage); } +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) +inline void QOpenGLFunctions_4_5_Compatibility::glNamedBufferStorage(GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags) +#else inline void QOpenGLFunctions_4_5_Compatibility::glNamedBufferStorage(GLuint buffer, GLsizei size, const void *data, GLbitfield flags) +#endif { d_4_5_Core->f.NamedBufferStorage(buffer, size, data, flags); } @@ -4471,7 +4530,11 @@ inline void QOpenGLFunctions_4_5_Compatibility::glGetTransformFeedbackiv(GLuint d_4_5_Core->f.GetTransformFeedbackiv(xfb, pname, param); } +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) +inline void QOpenGLFunctions_4_5_Compatibility::glTransformFeedbackBufferRange(GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) +#else inline void QOpenGLFunctions_4_5_Compatibility::glTransformFeedbackBufferRange(GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizei size) +#endif { d_4_5_Core->f.TransformFeedbackBufferRange(xfb, index, buffer, offset, size); } diff --git a/src/opengl/qopenglfunctions_4_5_core.h b/src/opengl/qopenglfunctions_4_5_core.h index 24ad0fd544..e3944f0741 100644 --- a/src/opengl/qopenglfunctions_4_5_core.h +++ b/src/opengl/qopenglfunctions_4_5_core.h @@ -700,25 +700,52 @@ public: void glNamedFramebufferParameteri(GLuint framebuffer, GLenum pname, GLint param); void glNamedFramebufferRenderbuffer(GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer); void glCreateFramebuffers(GLsizei n, GLuint *framebuffers); +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) + void glGetNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr size, void *data); +#else void glGetNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizei size, void *data); +#endif void glGetNamedBufferPointerv(GLuint buffer, GLenum pname, void * *params); void glGetNamedBufferParameteri64v(GLuint buffer, GLenum pname, GLint64 *params); void glGetNamedBufferParameteriv(GLuint buffer, GLenum pname, GLint *params); +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) + void glFlushMappedNamedBufferRange(GLuint buffer, GLintptr offset, GLsizeiptr length); +#else void glFlushMappedNamedBufferRange(GLuint buffer, GLintptr offset, GLsizei length); +#endif GLboolean glUnmapNamedBuffer(GLuint buffer); +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) + void * glMapNamedBufferRange(GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access); +#else void * glMapNamedBufferRange(GLuint buffer, GLintptr offset, GLsizei length, GLbitfield access); +#endif void * glMapNamedBuffer(GLuint buffer, GLenum access); +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) + void glClearNamedBufferSubData(GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data); +#else void glClearNamedBufferSubData(GLuint buffer, GLenum internalformat, GLintptr offset, GLsizei size, GLenum format, GLenum type, const void *data); +#endif void glClearNamedBufferData(GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data); +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) + void glCopyNamedBufferSubData(GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size); + void glNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data); + void glNamedBufferData(GLuint buffer, GLsizeiptr size, const void *data, GLenum usage); + void glNamedBufferStorage(GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags); +#else void glCopyNamedBufferSubData(GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizei size); void glNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizei size, const void *data); void glNamedBufferData(GLuint buffer, GLsizei size, const void *data, GLenum usage); void glNamedBufferStorage(GLuint buffer, GLsizei size, const void *data, GLbitfield flags); +#endif void glCreateBuffers(GLsizei n, GLuint *buffers); void glGetTransformFeedbacki64_v(GLuint xfb, GLenum pname, GLuint index, GLint64 *param); void glGetTransformFeedbacki_v(GLuint xfb, GLenum pname, GLuint index, GLint *param); void glGetTransformFeedbackiv(GLuint xfb, GLenum pname, GLint *param); +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) + void glTransformFeedbackBufferRange(GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size); +#else void glTransformFeedbackBufferRange(GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizei size); +#endif void glTransformFeedbackBufferBase(GLuint xfb, GLuint index, GLuint buffer); void glCreateTransformFeedbacks(GLsizei n, GLuint *ids); void glClipControl(GLenum origin, GLenum depth); @@ -3914,7 +3941,11 @@ inline void QOpenGLFunctions_4_5_Core::glCreateFramebuffers(GLsizei n, GLuint *f d_4_5_Core->f.CreateFramebuffers(n, framebuffers); } +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) +inline void QOpenGLFunctions_4_5_Core::glGetNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr size, void *data) +#else inline void QOpenGLFunctions_4_5_Core::glGetNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizei size, void *data) +#endif { d_4_5_Core->f.GetNamedBufferSubData(buffer, offset, size, data); } @@ -3934,7 +3965,11 @@ inline void QOpenGLFunctions_4_5_Core::glGetNamedBufferParameteriv(GLuint buffer d_4_5_Core->f.GetNamedBufferParameteriv(buffer, pname, params); } +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) +inline void QOpenGLFunctions_4_5_Core::glFlushMappedNamedBufferRange(GLuint buffer, GLintptr offset, GLsizeiptr length) +#else inline void QOpenGLFunctions_4_5_Core::glFlushMappedNamedBufferRange(GLuint buffer, GLintptr offset, GLsizei length) +#endif { d_4_5_Core->f.FlushMappedNamedBufferRange(buffer, offset, length); } @@ -3944,7 +3979,11 @@ inline GLboolean QOpenGLFunctions_4_5_Core::glUnmapNamedBuffer(GLuint buffer) return d_4_5_Core->f.UnmapNamedBuffer(buffer); } +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) +inline void * QOpenGLFunctions_4_5_Core::glMapNamedBufferRange(GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access) +#else inline void * QOpenGLFunctions_4_5_Core::glMapNamedBufferRange(GLuint buffer, GLintptr offset, GLsizei length, GLbitfield access) +#endif { return d_4_5_Core->f.MapNamedBufferRange(buffer, offset, length, access); } @@ -3954,7 +3993,11 @@ inline void * QOpenGLFunctions_4_5_Core::glMapNamedBuffer(GLuint buffer, GLenum return d_4_5_Core->f.MapNamedBuffer(buffer, access); } +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) +inline void QOpenGLFunctions_4_5_Core::glClearNamedBufferSubData(GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data) +#else inline void QOpenGLFunctions_4_5_Core::glClearNamedBufferSubData(GLuint buffer, GLenum internalformat, GLintptr offset, GLsizei size, GLenum format, GLenum type, const void *data) +#endif { d_4_5_Core->f.ClearNamedBufferSubData(buffer, internalformat, offset, size, format, type, data); } @@ -3964,22 +4007,38 @@ inline void QOpenGLFunctions_4_5_Core::glClearNamedBufferData(GLuint buffer, GLe d_4_5_Core->f.ClearNamedBufferData(buffer, internalformat, format, type, data); } +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) +inline void QOpenGLFunctions_4_5_Core::glCopyNamedBufferSubData(GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size) +#else inline void QOpenGLFunctions_4_5_Core::glCopyNamedBufferSubData(GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizei size) +#endif { d_4_5_Core->f.CopyNamedBufferSubData(readBuffer, writeBuffer, readOffset, writeOffset, size); } +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) +inline void QOpenGLFunctions_4_5_Core::glNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data) +#else inline void QOpenGLFunctions_4_5_Core::glNamedBufferSubData(GLuint buffer, GLintptr offset, GLsizei size, const void *data) +#endif { d_4_5_Core->f.NamedBufferSubData(buffer, offset, size, data); } +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) +inline void QOpenGLFunctions_4_5_Core::glNamedBufferData(GLuint buffer, GLsizeiptr size, const void *data, GLenum usage) +#else inline void QOpenGLFunctions_4_5_Core::glNamedBufferData(GLuint buffer, GLsizei size, const void *data, GLenum usage) +#endif { d_4_5_Core->f.NamedBufferData(buffer, size, data, usage); } +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) +inline void QOpenGLFunctions_4_5_Core::glNamedBufferStorage(GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags) +#else inline void QOpenGLFunctions_4_5_Core::glNamedBufferStorage(GLuint buffer, GLsizei size, const void *data, GLbitfield flags) +#endif { d_4_5_Core->f.NamedBufferStorage(buffer, size, data, flags); } @@ -4004,7 +4063,11 @@ inline void QOpenGLFunctions_4_5_Core::glGetTransformFeedbackiv(GLuint xfb, GLen d_4_5_Core->f.GetTransformFeedbackiv(xfb, pname, param); } +#if QT_VERSION >= QT_VERSION_CHECK(7, 0, 0) +inline void QOpenGLFunctions_4_5_Core::glTransformFeedbackBufferRange(GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size) +#else inline void QOpenGLFunctions_4_5_Core::glTransformFeedbackBufferRange(GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizei size) +#endif { d_4_5_Core->f.TransformFeedbackBufferRange(xfb, index, buffer, offset, size); } diff --git a/src/opengl/qopenglpaintengine.cpp b/src/opengl/qopenglpaintengine.cpp index 2556881e12..972e276370 100644 --- a/src/opengl/qopenglpaintengine.cpp +++ b/src/opengl/qopenglpaintengine.cpp @@ -160,10 +160,14 @@ template<typename T> void QOpenGL2PaintEngineExPrivate::updateTexture(GLenum textureUnit, const T &texture, GLenum wrapMode, GLenum filterMode, TextureUpdateMode updateMode) { static const GLenum target = GL_TEXTURE_2D; + bool newTextureCreated = false; activateTextureUnit(textureUnit); - GLuint textureId = bindTexture(texture); + GLuint textureId = bindTexture(texture, &newTextureCreated); + + if (newTextureCreated) + lastTextureUsed = GLuint(-1); if (updateMode == UpdateIfNeeded && textureId == lastTextureUsed) return; @@ -192,8 +196,11 @@ void QOpenGL2PaintEngineExPrivate::activateTextureUnit(GLenum textureUnit) } template<> -GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const GLuint &textureId) +GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const GLuint &textureId, bool *newTextureCreated) { + if (newTextureCreated) + *newTextureCreated = false; + if (textureId != lastTextureUsed) funcs.glBindTexture(GL_TEXTURE_2D, textureId); @@ -201,19 +208,25 @@ GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const GLuint &textureId) } template<> -GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const QImage &image) +GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const QImage &image, bool *newTextureCreated) { - return QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, image); + QOpenGLTextureCache::BindResult result = QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, image); + if (newTextureCreated) + *newTextureCreated = result.flags.testFlag(QOpenGLTextureCache::BindResultFlag::NewTexture); + return result.id; } template<> -GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const QPixmap &pixmap) +GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const QPixmap &pixmap, bool *newTextureCreated) { - return QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, pixmap); + QOpenGLTextureCache::BindResult result = QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, pixmap); + if (newTextureCreated) + *newTextureCreated = result.flags.testFlag(QOpenGLTextureCache::BindResultFlag::NewTexture); + return result.id; } template<> -GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const QGradient &gradient) +GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const QGradient &gradient, bool *newTextureCreated) { // We apply global opacity in the fragment shaders, so we always pass 1.0 // for opacity to the cache. @@ -223,7 +236,7 @@ GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const QGradient &gradient) // hasn't been cached yet, but will otherwise return an unbound texture id. To // be sure that the texture is bound, we unfortunately have to bind again, // which results in the initial generation of the texture doing two binds. - return bindTexture(textureId); + return bindTexture(textureId, newTextureCreated); } struct ImageWithBindOptions @@ -233,9 +246,14 @@ struct ImageWithBindOptions }; template<> -GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const ImageWithBindOptions &imageWithOptions) +GLuint QOpenGL2PaintEngineExPrivate::bindTexture(const ImageWithBindOptions &imageWithOptions, bool *newTextureCreated) { - return QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, imageWithOptions.image, imageWithOptions.options); + QOpenGLTextureCache::BindResult result = QOpenGLTextureCache::cacheForContext(ctx)->bindTexture(ctx, + imageWithOptions.image, + imageWithOptions.options); + if (newTextureCreated) + *newTextureCreated = result.flags.testFlag(QOpenGLTextureCache::BindResultFlag::NewTexture); + return result.id; } inline static bool isPowerOfTwo(int x) @@ -606,8 +624,9 @@ static inline void setCoords(GLfloat *coords, const QOpenGLRect &rect) coords[7] = rect.bottom; } -void QOpenGL2PaintEngineExPrivate::drawTexture(const QOpenGLRect& dest, const QOpenGLRect& src, const QSize &textureSize, bool opaque, bool pattern) +void Q_TRACE_INSTRUMENT(qtopengl) QOpenGL2PaintEngineExPrivate::drawTexture(const QOpenGLRect& dest, const QOpenGLRect& src, const QSize &textureSize, bool opaque, bool pattern) { + Q_TRACE_PARAM_REPLACE(QOpenGLRect, QRectF); Q_TRACE_SCOPE(QOpenGL2PaintEngineExPrivate_drawTexture, dest, src, textureSize, opaque, pattern); // Setup for texture drawing @@ -726,11 +745,11 @@ void QOpenGL2PaintEngineExPrivate::resetGLState() float color[] = { 1.0f, 1.0f, 1.0f, 1.0f }; funcs.glVertexAttrib4fv(3, color); } - if (vao.isCreated()) { + if (vao.isCreated()) vao.release(); - funcs.glBindBuffer(GL_ARRAY_BUFFER, 0); - funcs.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); - } + + funcs.glBindBuffer(GL_ARRAY_BUFFER, 0); + funcs.glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, 0); } void QOpenGL2PaintEngineEx::endNativePainting() @@ -2132,6 +2151,10 @@ void QOpenGL2PaintEngineExPrivate::drawPixmapFragments(const QPainter::PixmapFra transferMode(ImageOpacityArrayDrawingMode); + uploadData(QT_VERTEX_COORDS_ATTR, (GLfloat*)vertexCoordinateArray.data(), vertexCoordinateArray.vertexCount() * 2); + uploadData(QT_TEXTURE_COORDS_ATTR, (GLfloat*)textureCoordinateArray.data(), textureCoordinateArray.vertexCount() * 2); + uploadData(QT_OPACITY_ATTR, (GLfloat*)opacityArray.data(), opacityArray.size()); + GLenum filterMode = q->state()->renderHints & QPainter::SmoothPixmapTransform ? GL_LINEAR : GL_NEAREST; updateTexture(QT_IMAGE_TEXTURE_UNIT, pixmap, GL_CLAMP_TO_EDGE, filterMode); @@ -2198,28 +2221,27 @@ bool QOpenGL2PaintEngineEx::begin(QPaintDevice *pdev) bool created = d->vao.create(); // If we managed to create it then we have a profile that supports VAOs - if (created) { + if (created) d->vao.bind(); + } - // Generate a new Vertex Buffer Object if we don't have one already - if (!d->vertexBuffer.isCreated()) { - d->vertexBuffer.create(); - // Set its usage to StreamDraw, we will use this buffer only a few times before refilling it - d->vertexBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw); - } - if (!d->texCoordBuffer.isCreated()) { - d->texCoordBuffer.create(); - d->texCoordBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw); - } - if (!d->opacityBuffer.isCreated()) { - d->opacityBuffer.create(); - d->opacityBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw); - } - if (!d->indexBuffer.isCreated()) { - d->indexBuffer.create(); - d->indexBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw); - } - } + // Generate a new Vertex Buffer Object if we don't have one already + if (!d->vertexBuffer.isCreated()) { + d->vertexBuffer.create(); + // Set its usage to StreamDraw, we will use this buffer only a few times before refilling it + d->vertexBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw); + } + if (!d->texCoordBuffer.isCreated()) { + d->texCoordBuffer.create(); + d->texCoordBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw); + } + if (!d->opacityBuffer.isCreated()) { + d->opacityBuffer.create(); + d->opacityBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw); + } + if (!d->indexBuffer.isCreated()) { + d->indexBuffer.create(); + d->indexBuffer.setUsagePattern(QOpenGLBuffer::StreamDraw); } for (int i = 0; i < QT_GL_VERTEX_ARRAY_TRACKED_COUNT; ++i) diff --git a/src/opengl/qopenglpaintengine_p.h b/src/opengl/qopenglpaintengine_p.h index 2548d9db94..40ed7fe609 100644 --- a/src/opengl/qopenglpaintengine_p.h +++ b/src/opengl/qopenglpaintengine_p.h @@ -177,7 +177,7 @@ public: template<typename T> void updateTexture(GLenum textureUnit, const T &texture, GLenum wrapMode, GLenum filterMode, TextureUpdateMode updateMode = UpdateIfNeeded); template<typename T> - GLuint bindTexture(const T &texture); + GLuint bindTexture(const T &texture, bool *newTextureCreated); void activateTextureUnit(GLenum textureUnit); void resetGLState(); @@ -307,51 +307,32 @@ void QOpenGL2PaintEngineExPrivate::uploadData(unsigned int arrayIndex, const GLf { Q_ASSERT(arrayIndex < 3); - // If a vertex array object is created we have a profile that supports them - // and we will upload the data via a QOpenGLBuffer. Otherwise we will use - // the legacy way of uploading the data via glVertexAttribPointer. - if (vao.isCreated()) { - if (arrayIndex == QT_VERTEX_COORDS_ATTR) { - vertexBuffer.bind(); - vertexBuffer.allocate(data, count * sizeof(float)); - } - if (arrayIndex == QT_TEXTURE_COORDS_ATTR) { - texCoordBuffer.bind(); - texCoordBuffer.allocate(data, count * sizeof(float)); - } - if (arrayIndex == QT_OPACITY_ATTR) { - opacityBuffer.bind(); - opacityBuffer.allocate(data, count * sizeof(float)); - } - if (arrayIndex == QT_OPACITY_ATTR) - funcs.glVertexAttribPointer(arrayIndex, 1, GL_FLOAT, GL_FALSE, 0, nullptr); - else - funcs.glVertexAttribPointer(arrayIndex, 2, GL_FLOAT, GL_FALSE, 0, nullptr); + if (arrayIndex == QT_VERTEX_COORDS_ATTR) { + vertexBuffer.bind(); + vertexBuffer.allocate(data, count * sizeof(float)); + } + if (arrayIndex == QT_TEXTURE_COORDS_ATTR) { + texCoordBuffer.bind(); + texCoordBuffer.allocate(data, count * sizeof(float)); + } + if (arrayIndex == QT_OPACITY_ATTR) { + opacityBuffer.bind(); + opacityBuffer.allocate(data, count * sizeof(float)); + + funcs.glVertexAttribPointer(arrayIndex, 1, GL_FLOAT, GL_FALSE, 0, nullptr); } else { - // If we already uploaded the data we don't have to do it again - if (data == vertexAttribPointers[arrayIndex]) - return; - - // Store the data in cache and upload it to the graphics card. - vertexAttribPointers[arrayIndex] = data; - if (arrayIndex == QT_OPACITY_ATTR) - funcs.glVertexAttribPointer(arrayIndex, 1, GL_FLOAT, GL_FALSE, 0, data); - else - funcs.glVertexAttribPointer(arrayIndex, 2, GL_FLOAT, GL_FALSE, 0, data); + funcs.glVertexAttribPointer(arrayIndex, 2, GL_FLOAT, GL_FALSE, 0, nullptr); } } bool QOpenGL2PaintEngineExPrivate::uploadIndexData(const void *data, GLenum indexValueType, GLuint count) { - // Follow the uploadData() logic: VBOs are used only when VAO support is available. - // Otherwise the legacy client-side pointer path is used. - if (vao.isCreated()) { - Q_ASSERT(indexValueType == GL_UNSIGNED_SHORT || indexValueType == GL_UNSIGNED_INT); - indexBuffer.bind(); - indexBuffer.allocate(data, count * (indexValueType == GL_UNSIGNED_SHORT ? sizeof(quint16) : sizeof(quint32))); - return true; - } - return false; + Q_ASSERT(indexValueType == GL_UNSIGNED_SHORT || indexValueType == GL_UNSIGNED_INT); + indexBuffer.bind(); + indexBuffer.allocate( + data, + count * (indexValueType == GL_UNSIGNED_SHORT ? sizeof(quint16) : sizeof(quint32))); + return true; } QT_END_NAMESPACE diff --git a/src/opengl/qopenglshaderprogram.cpp b/src/opengl/qopenglshaderprogram.cpp index 3f4089c4d6..fb33bf0d5c 100644 --- a/src/opengl/qopenglshaderprogram.cpp +++ b/src/opengl/qopenglshaderprogram.cpp @@ -629,7 +629,7 @@ bool QOpenGLShader::compileSourceCode(const char *source) // Append #line directive in order to compensate for text insertion lineDirective = QStringLiteral("#line %1\n").arg(versionDirectivePosition.line).toUtf8(); sourceChunks.append(lineDirective.constData()); - sourceChunkLengths.append(GLint(lineDirective.length())); + sourceChunkLengths.append(GLint(lineDirective.size())); } // Append rest of shader code @@ -1230,7 +1230,7 @@ void QOpenGLShaderProgram::removeAllShaders() { Q_D(QOpenGLShaderProgram); d->removingShaders = true; - for (QOpenGLShader *shader : qAsConst(d->shaders)) { + for (QOpenGLShader *shader : std::as_const(d->shaders)) { if (d->programGuard && d->programGuard->id() && shader && shader->d_func()->shaderGuard) { @@ -3727,7 +3727,7 @@ bool QOpenGLShaderProgramPrivate::isCacheDisabled() const bool QOpenGLShaderProgramPrivate::compileCacheable() { Q_Q(QOpenGLShaderProgram); - for (const QOpenGLProgramBinaryCache::ShaderDesc &shader : qAsConst(binaryProgram.shaders)) { + for (const QOpenGLProgramBinaryCache::ShaderDesc &shader : std::as_const(binaryProgram.shaders)) { auto s = std::make_unique<QOpenGLShader>(qt_shaderStageToType(shader.stage), q); if (!s->compileSourceCode(shader.source)) { log = s->log(); @@ -3749,7 +3749,7 @@ bool QOpenGLShaderProgramPrivate::linkBinary() const QByteArray cacheKey = binaryProgram.cacheKey(); if (lcOpenGLProgramDiskCache().isEnabled(QtDebugMsg)) qCDebug(lcOpenGLProgramDiskCache, "program with %d shaders, cache key %s", - int(binaryProgram.shaders.count()), cacheKey.constData()); + int(binaryProgram.shaders.size()), cacheKey.constData()); bool needsCompile = true; if (binCache.load(cacheKey, q->programId())) { diff --git a/src/opengl/qopengltexture.cpp b/src/opengl/qopengltexture.cpp index 8dc30cca61..3b8e14490b 100644 --- a/src/opengl/qopengltexture.cpp +++ b/src/opengl/qopengltexture.cpp @@ -431,8 +431,7 @@ static bool isSizedTextureFormat(QOpenGLTexture::TextureFormat internalFormat) return false; } - Q_UNREACHABLE(); - return false; + Q_UNREACHABLE_RETURN(false); } static bool isTextureTargetMultisample(QOpenGLTexture::Target target) @@ -456,8 +455,7 @@ static bool isTextureTargetMultisample(QOpenGLTexture::Target target) return false; } - Q_UNREACHABLE(); - return false; + Q_UNREACHABLE_RETURN(false); } bool QOpenGLTexturePrivate::isUsingImmutableStorage() const @@ -756,8 +754,7 @@ static QOpenGLTexture::PixelFormat pixelFormatCompatibleWithInternalFormat(QOpen return QOpenGLTexture::LuminanceAlpha; } - Q_UNREACHABLE(); - return QOpenGLTexture::NoSourceFormat; + Q_UNREACHABLE_RETURN(QOpenGLTexture::NoSourceFormat); } static QOpenGLTexture::PixelType pixelTypeCompatibleWithInternalFormat(QOpenGLTexture::TextureFormat internalFormat) @@ -936,8 +933,7 @@ static QOpenGLTexture::PixelType pixelTypeCompatibleWithInternalFormat(QOpenGLTe return QOpenGLTexture::UInt8; } - Q_UNREACHABLE(); - return QOpenGLTexture::NoPixelType; + Q_UNREACHABLE_RETURN(QOpenGLTexture::NoPixelType); } static bool isCompressedFormat(QOpenGLTexture::TextureFormat internalFormat) @@ -1080,8 +1076,7 @@ static bool isCompressedFormat(QOpenGLTexture::TextureFormat internalFormat) return false; } - Q_UNREACHABLE(); - return false; + Q_UNREACHABLE_RETURN(false); } void QOpenGLTexturePrivate::allocateMutableStorage(QOpenGLTexture::PixelFormat pixelFormat, QOpenGLTexture::PixelType pixelType) @@ -2461,6 +2456,9 @@ QOpenGLTexture::QOpenGLTexture(Target target) This does create the underlying OpenGL texture object. Therefore, construction using this constructor does require a valid current OpenGL context. + + \note \a image is automatically converted to QImage::Format_RGBA8888 which + may have performance implications for large images with a different format. */ QOpenGLTexture::QOpenGLTexture(const QImage& image, MipMapGeneration genMipMaps) : QOpenGLTexture(QOpenGLTexture::Target2D) @@ -3615,6 +3613,9 @@ void QOpenGLTexture::setData(int xOffset, int yOffset, int zOffset, The pixel data is contained in \a image. Mipmaps are generated by default. Set \a genMipMaps to \l DontGenerateMipMaps to turn off mipmap generation. + \note \a image is automatically converted to QImage::Format_RGBA8888 which + may have performance implications for large images with a different format. + \overload */ void QOpenGLTexture::setData(const QImage& image, MipMapGeneration genMipMaps) @@ -3630,6 +3631,12 @@ void QOpenGLTexture::setData(const QImage& image, MipMapGeneration genMipMaps) return; } + QImage glImage = image.convertToFormat(QImage::Format_RGBA8888); + if (glImage.isNull()) { + qWarning("QOpenGLTexture::setData() failed to convert image"); + return; + } + if (context->isOpenGLES() && context->format().majorVersion() < 3) setFormat(QOpenGLTexture::RGBAFormat); else @@ -3640,7 +3647,6 @@ void QOpenGLTexture::setData(const QImage& image, MipMapGeneration genMipMaps) allocateStorage(QOpenGLTexture::RGBA, QOpenGLTexture::UInt8); // Upload pixel data and generate mipmaps - QImage glImage = image.convertToFormat(QImage::Format_RGBA8888); QOpenGLPixelTransferOptions uploadOptions; uploadOptions.setAlignment(1); setData(0, QOpenGLTexture::RGBA, QOpenGLTexture::UInt8, glImage.constBits(), &uploadOptions); diff --git a/src/opengl/qopengltextureblitter.cpp b/src/opengl/qopengltextureblitter.cpp index 664aa5e11b..5f58876f32 100644 --- a/src/opengl/qopengltextureblitter.cpp +++ b/src/opengl/qopengltextureblitter.cpp @@ -169,14 +169,14 @@ static const GLfloat texture_buffer_data[] = { 1, 1 }; -class TextureBinder +class QBlitterTextureBinder { public: - TextureBinder(GLenum target, GLuint textureId) : m_target(target) + explicit QBlitterTextureBinder(GLenum target, GLuint textureId) : m_target(target) { QOpenGLContext::currentContext()->functions()->glBindTexture(m_target, textureId); } - ~TextureBinder() + ~QBlitterTextureBinder() { QOpenGLContext::currentContext()->functions()->glBindTexture(m_target, 0); } @@ -200,7 +200,8 @@ public: TEXTURE_RECTANGLE }; - QOpenGLTextureBlitterPrivate() : + QOpenGLTextureBlitterPrivate(QOpenGLTextureBlitter *q_ptr) : + q(q_ptr), swizzle(false), opacity(1.0f), vao(new QOpenGLVertexArrayObject), @@ -208,14 +209,16 @@ public: { } bool buildProgram(ProgramIndex idx, const char *vs, const char *fs); + bool ensureProgram(ProgramIndex idx); void blit(GLuint texture, const QMatrix4x4 &targetTransform, const QMatrix3x3 &sourceTransform); void blit(GLuint texture, const QMatrix4x4 &targetTransform, QOpenGLTextureBlitter::Origin origin); QMatrix3x3 toTextureCoordinates(const QMatrix3x3 &sourceTransform) const; - void prepareProgram(const QMatrix4x4 &vertexTransform); + bool prepareProgram(const QMatrix4x4 &vertexTransform); + QOpenGLTextureBlitter *q; QOpenGLBuffer vertexBuffer; QOpenGLBuffer textureBuffer; struct Program { @@ -262,9 +265,13 @@ static inline QOpenGLTextureBlitterPrivate::ProgramIndex targetToProgramIndex(GL } } -void QOpenGLTextureBlitterPrivate::prepareProgram(const QMatrix4x4 &vertexTransform) +bool QOpenGLTextureBlitterPrivate::prepareProgram(const QMatrix4x4 &vertexTransform) { - Program *program = &programs[targetToProgramIndex(currentTarget)]; + ProgramIndex programIndex = targetToProgramIndex(currentTarget); + if (!ensureProgram(programIndex)) + return false; + + Program *program = &programs[programIndex]; vertexBuffer.bind(); program->glProgram->setAttributeBuffer(program->vertexCoordAttribPos, GL_FLOAT, 0, 3, 0); @@ -287,6 +294,8 @@ void QOpenGLTextureBlitterPrivate::prepareProgram(const QMatrix4x4 &vertexTransf program->glProgram->setUniformValue(program->opacityUniformPos, opacity); program->opacity = opacity; } + + return true; } QMatrix3x3 QOpenGLTextureBlitterPrivate::toTextureCoordinates(const QMatrix3x3 &sourceTransform) const @@ -310,8 +319,9 @@ void QOpenGLTextureBlitterPrivate::blit(GLuint texture, const QMatrix4x4 &targetTransform, const QMatrix3x3 &sourceTransform) { - TextureBinder binder(currentTarget, texture); - prepareProgram(targetTransform); + QBlitterTextureBinder binder(currentTarget, texture); + if (!prepareProgram(targetTransform)) + return; Program *program = &programs[targetToProgramIndex(currentTarget)]; @@ -326,8 +336,9 @@ void QOpenGLTextureBlitterPrivate::blit(GLuint texture, const QMatrix4x4 &targetTransform, QOpenGLTextureBlitter::Origin origin) { - TextureBinder binder(currentTarget, texture); - prepareProgram(targetTransform); + QBlitterTextureBinder binder(currentTarget, texture); + if (!prepareProgram(targetTransform)) + return; Program *program = &programs[targetToProgramIndex(currentTarget)]; @@ -380,6 +391,35 @@ bool QOpenGLTextureBlitterPrivate::buildProgram(ProgramIndex idx, const char *vs return true; } +bool QOpenGLTextureBlitterPrivate::ensureProgram(ProgramIndex idx) +{ + if (programs[idx].glProgram) + return true; + + QOpenGLContext *currentContext = QOpenGLContext::currentContext(); + if (!currentContext) + return false; + + QSurfaceFormat format = currentContext->format(); + if (format.profile() == QSurfaceFormat::CoreProfile && format.version() >= qMakePair(3,2)) { + if (idx == QOpenGLTextureBlitterPrivate::TEXTURE_RECTANGLE && q->supportsRectangleTarget()) { + if (!buildProgram(idx, vertex_shader150, fragment_shader150_rectangle)) + return false; + } + } else { + if (idx == QOpenGLTextureBlitterPrivate::TEXTURE_RECTANGLE && q->supportsRectangleTarget()) { + if (!buildProgram(idx, vertex_shader, fragment_shader_rectangle)) + return false; + } + if (idx == QOpenGLTextureBlitterPrivate::TEXTURE_EXTERNAL_OES && q->supportsExternalOESTarget()) { + if (!buildProgram(idx, vertex_shader, fragment_shader_external_oes)) + return false; + } + } + + return !programs[idx].glProgram.isNull(); +} + /*! Constructs a new QOpenGLTextureBlitter instance. @@ -390,7 +430,7 @@ bool QOpenGLTextureBlitterPrivate::buildProgram(ProgramIndex idx, const char *vs create(). */ QOpenGLTextureBlitter::QOpenGLTextureBlitter() - : d_ptr(new QOpenGLTextureBlitterPrivate) + : d_ptr(new QOpenGLTextureBlitterPrivate(this)) { } @@ -430,21 +470,14 @@ bool QOpenGLTextureBlitter::create() return true; QSurfaceFormat format = currentContext->format(); + // Build the most common, 2D texture shader variant. + // The other special ones are deferred and compiled only when first needed. if (format.profile() == QSurfaceFormat::CoreProfile && format.version() >= qMakePair(3,2)) { if (!d->buildProgram(QOpenGLTextureBlitterPrivate::TEXTURE_2D, vertex_shader150, fragment_shader150)) return false; - if (supportsRectangleTarget()) - if (!d->buildProgram(QOpenGLTextureBlitterPrivate::TEXTURE_RECTANGLE, vertex_shader150, fragment_shader150_rectangle)) - return false; } else { if (!d->buildProgram(QOpenGLTextureBlitterPrivate::TEXTURE_2D, vertex_shader, fragment_shader)) return false; - if (supportsExternalOESTarget()) - if (!d->buildProgram(QOpenGLTextureBlitterPrivate::TEXTURE_EXTERNAL_OES, vertex_shader, fragment_shader_external_oes)) - return false; - if (supportsRectangleTarget()) - if (!d->buildProgram(QOpenGLTextureBlitterPrivate::TEXTURE_RECTANGLE, vertex_shader, fragment_shader_rectangle)) - return false; } // Create and bind the VAO, if supported. @@ -553,7 +586,11 @@ void QOpenGLTextureBlitter::bind(GLenum target) d->vao->bind(); d->currentTarget = target; - QOpenGLTextureBlitterPrivate::Program *p = &d->programs[targetToProgramIndex(target)]; + QOpenGLTextureBlitterPrivate::ProgramIndex programIndex = targetToProgramIndex(target); + if (!d->ensureProgram(programIndex)) + return; + + QOpenGLTextureBlitterPrivate::Program *p = &d->programs[programIndex]; p->glProgram->bind(); d->vertexBuffer.bind(); @@ -575,7 +612,9 @@ void QOpenGLTextureBlitter::bind(GLenum target) void QOpenGLTextureBlitter::release() { Q_D(QOpenGLTextureBlitter); - d->programs[targetToProgramIndex(d->currentTarget)].glProgram->release(); + QOpenGLTextureBlitterPrivate::Program *p = &d->programs[targetToProgramIndex(d->currentTarget)]; + if (p->glProgram) + p->glProgram->release(); if (d->vao->isCreated()) d->vao->release(); } diff --git a/src/opengl/qopengltexturecache.cpp b/src/opengl/qopengltexturecache.cpp index f2b7565316..64583c03a9 100644 --- a/src/opengl/qopengltexturecache.cpp +++ b/src/opengl/qopengltexturecache.cpp @@ -61,9 +61,19 @@ void QOpenGLTextureCacheWrapper::cleanupTexturesForPixmapData(QPlatformPixmap *p cleanupTexturesForCacheKey(pmd->cacheKey()); } +static quint64 cacheSize() +{ + bool ok = false; + const int envCacheSize = qEnvironmentVariableIntValue("QT_OPENGL_TEXTURE_CACHE_SIZE", &ok); + if (ok) + return envCacheSize; + + return 1024 * 1024; // 1024 MB cache default +} + QOpenGLTextureCache::QOpenGLTextureCache(QOpenGLContext *ctx) : QOpenGLSharedResource(ctx->shareGroup()) - , m_cache(256 * 1024) // 256 MB cache + , m_cache(cacheSize()) { } @@ -71,10 +81,12 @@ QOpenGLTextureCache::~QOpenGLTextureCache() { } -GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, const QPixmap &pixmap, QOpenGLTextureUploader::BindOptions options) +QOpenGLTextureCache::BindResult QOpenGLTextureCache::bindTexture(QOpenGLContext *context, + const QPixmap &pixmap, + QOpenGLTextureUploader::BindOptions options) { if (pixmap.isNull()) - return 0; + return { 0, {} }; QMutexLocker locker(&m_mutex); qint64 key = pixmap.cacheKey(); @@ -83,21 +95,23 @@ GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, const QPixmap & QOpenGLCachedTexture *entry = m_cache.object(key); if (entry && entry->options() == options) { context->functions()->glBindTexture(GL_TEXTURE_2D, entry->id()); - return entry->id(); + return { entry->id(), {} }; } } - GLuint id = bindTexture(context, key, pixmap.toImage(), options); - if (id > 0) + BindResult result = bindTexture(context, key, pixmap.toImage(), options); + if (result.id > 0) QImagePixmapCleanupHooks::enableCleanupHooks(pixmap); - return id; + return result; } -GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, const QImage &image, QOpenGLTextureUploader::BindOptions options) +QOpenGLTextureCache::BindResult QOpenGLTextureCache::bindTexture(QOpenGLContext *context, + const QImage &image, + QOpenGLTextureUploader::BindOptions options) { if (image.isNull()) - return 0; + return { 0, {} }; QMutexLocker locker(&m_mutex); qint64 key = image.cacheKey(); @@ -106,7 +120,7 @@ GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, const QImage &i QOpenGLCachedTexture *entry = m_cache.object(key); if (entry && entry->options() == options) { context->functions()->glBindTexture(GL_TEXTURE_2D, entry->id()); - return entry->id(); + return { entry->id(), {} }; } } @@ -114,16 +128,22 @@ GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, const QImage &i if (!context->functions()->hasOpenGLFeature(QOpenGLFunctions::NPOTTextures)) options |= QOpenGLTextureUploader::PowerOfTwoBindOption; - GLuint id = bindTexture(context, key, img, options); - if (id > 0) + BindResult result = bindTexture(context, key, img, options); + if (result.id > 0) QImagePixmapCleanupHooks::enableCleanupHooks(image); - return id; + return result; } -GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, qint64 key, const QImage &image, QOpenGLTextureUploader::BindOptions options) +Q_TRACE_POINT(qtopengl, QOpenGLTextureCache_bindTexture_entry, QOpenGLContext *context, qint64 key, const unsigned char *image, int options); +Q_TRACE_POINT(qtopengl, QOpenGLTextureCache_bindTexture_exit); + +QOpenGLTextureCache::BindResult QOpenGLTextureCache::bindTexture(QOpenGLContext *context, + qint64 key, + const QImage &image, + QOpenGLTextureUploader::BindOptions options) { - Q_TRACE_SCOPE(QOpenGLTextureCache_bindTexture, context, key, image, options); + Q_TRACE_SCOPE(QOpenGLTextureCache_bindTexture, context, key, image.bits(), options); GLuint id; QOpenGLFunctions *funcs = context->functions(); @@ -134,7 +154,7 @@ GLuint QOpenGLTextureCache::bindTexture(QOpenGLContext *context, qint64 key, con m_cache.insert(key, new QOpenGLCachedTexture(id, options, context), cost / 1024); - return id; + return { id, BindResultFlag::NewTexture }; } void QOpenGLTextureCache::invalidate(qint64 key) diff --git a/src/opengl/qopengltexturecache_p.h b/src/opengl/qopengltexturecache_p.h index afc12f0b38..b70520aa1c 100644 --- a/src/opengl/qopengltexturecache_p.h +++ b/src/opengl/qopengltexturecache_p.h @@ -35,10 +35,20 @@ public: QOpenGLTextureCache(QOpenGLContext *); ~QOpenGLTextureCache(); - GLuint bindTexture(QOpenGLContext *context, const QPixmap &pixmap, - QOpenGLTextureUploader::BindOptions options = QOpenGLTextureUploader::PremultipliedAlphaBindOption); - GLuint bindTexture(QOpenGLContext *context, const QImage &image, - QOpenGLTextureUploader::BindOptions options = QOpenGLTextureUploader::PremultipliedAlphaBindOption); + enum class BindResultFlag : quint8 { + NewTexture = 0x01 + }; + Q_DECLARE_FLAGS(BindResultFlags, BindResultFlag) + + struct BindResult { + GLuint id; + BindResultFlags flags; + }; + + BindResult bindTexture(QOpenGLContext *context, const QPixmap &pixmap, + QOpenGLTextureUploader::BindOptions options = QOpenGLTextureUploader::PremultipliedAlphaBindOption); + BindResult bindTexture(QOpenGLContext *context, const QImage &image, + QOpenGLTextureUploader::BindOptions options = QOpenGLTextureUploader::PremultipliedAlphaBindOption); void invalidate(qint64 key); @@ -46,12 +56,14 @@ public: void freeResource(QOpenGLContext *ctx) override; private: - GLuint bindTexture(QOpenGLContext *context, qint64 key, const QImage &image, QOpenGLTextureUploader::BindOptions options); + BindResult bindTexture(QOpenGLContext *context, qint64 key, const QImage &image, QOpenGLTextureUploader::BindOptions options); QMutex m_mutex; QCache<quint64, QOpenGLCachedTexture> m_cache; }; +Q_DECLARE_OPERATORS_FOR_FLAGS(QOpenGLTextureCache::BindResultFlags) + class QOpenGLCachedTexture { public: diff --git a/src/opengl/qopengltextureglyphcache.cpp b/src/opengl/qopengltextureglyphcache.cpp index 39f39c554d..0bab710b1b 100644 --- a/src/opengl/qopengltextureglyphcache.cpp +++ b/src/opengl/qopengltextureglyphcache.cpp @@ -13,7 +13,7 @@ QT_BEGIN_NAMESPACE static int next_qopengltextureglyphcache_serial_number() { - static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(0); + Q_CONSTINIT static QBasicAtomicInt serial = Q_BASIC_ATOMIC_INITIALIZER(0); return 1 + serial.fetchAndAddRelaxed(1); } @@ -407,7 +407,10 @@ void QOpenGLTextureGlyphCache::fillTexture(const Coord &c, int QOpenGLTextureGlyphCache::glyphPadding() const { - return 1; + if (m_format == QFontEngine::Format_Mono) + return 8; + else + return 1; } int QOpenGLTextureGlyphCache::maxTextureWidth() const diff --git a/src/opengl/qopenglversionfunctions.cpp b/src/opengl/qopenglversionfunctions.cpp index 0180fb542d..a03fa2c2d3 100644 --- a/src/opengl/qopenglversionfunctions.cpp +++ b/src/opengl/qopenglversionfunctions.cpp @@ -21,7 +21,7 @@ QT_BEGIN_NAMESPACE QOpenGLContextVersionData::~QOpenGLContextVersionData() { - for (auto *f : qAsConst(externalFunctions)) { + for (auto *f : std::as_const(externalFunctions)) { auto *fp = QAbstractOpenGLFunctionsPrivate::get(f); fp->owningContext = nullptr; fp->initialized = false; diff --git a/src/opengl/qopenglversionfunctions.h b/src/opengl/qopenglversionfunctions.h index c1942548db..dc01b940bb 100644 --- a/src/opengl/qopenglversionfunctions.h +++ b/src/opengl/qopenglversionfunctions.h @@ -1179,25 +1179,25 @@ public: F(void, NamedFramebufferParameteri, (GLuint framebuffer, GLenum pname, GLint param)) \ F(void, NamedFramebufferRenderbuffer, (GLuint framebuffer, GLenum attachment, GLenum renderbuffertarget, GLuint renderbuffer)) \ F(void, CreateFramebuffers, (GLsizei n, GLuint *framebuffers)) \ - F(void, GetNamedBufferSubData, (GLuint buffer, GLintptr offset, GLsizei size, void *data)) \ + F(void, GetNamedBufferSubData, (GLuint buffer, GLintptr offset, GLsizeiptr size, void *data)) \ F(void, GetNamedBufferPointerv, (GLuint buffer, GLenum pname, GLvoid* *params)) \ F(void, GetNamedBufferParameteri64v, (GLuint buffer, GLenum pname, GLint64 *params)) \ F(void, GetNamedBufferParameteriv, (GLuint buffer, GLenum pname, GLint *params)) \ - F(void, FlushMappedNamedBufferRange, (GLuint buffer, GLintptr offset, GLsizei length)) \ + F(void, FlushMappedNamedBufferRange, (GLuint buffer, GLintptr offset, GLsizeiptr length)) \ F(GLboolean, UnmapNamedBuffer, (GLuint buffer)) \ - F(GLvoid *, MapNamedBufferRange, (GLuint buffer, GLintptr offset, GLsizei length, GLbitfield access)) \ + F(GLvoid *, MapNamedBufferRange, (GLuint buffer, GLintptr offset, GLsizeiptr length, GLbitfield access)) \ F(GLvoid *, MapNamedBuffer, (GLuint buffer, GLenum access)) \ - F(void, ClearNamedBufferSubData, (GLuint buffer, GLenum internalformat, GLintptr offset, GLsizei size, GLenum format, GLenum type, const void *data)) \ + F(void, ClearNamedBufferSubData, (GLuint buffer, GLenum internalformat, GLintptr offset, GLsizeiptr size, GLenum format, GLenum type, const void *data)) \ F(void, ClearNamedBufferData, (GLuint buffer, GLenum internalformat, GLenum format, GLenum type, const void *data)) \ - F(void, CopyNamedBufferSubData, (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizei size)) \ - F(void, NamedBufferSubData, (GLuint buffer, GLintptr offset, GLsizei size, const void *data)) \ - F(void, NamedBufferData, (GLuint buffer, GLsizei size, const void *data, GLenum usage)) \ - F(void, NamedBufferStorage, (GLuint buffer, GLsizei size, const void *data, GLbitfield flags)) \ + F(void, CopyNamedBufferSubData, (GLuint readBuffer, GLuint writeBuffer, GLintptr readOffset, GLintptr writeOffset, GLsizeiptr size)) \ + F(void, NamedBufferSubData, (GLuint buffer, GLintptr offset, GLsizeiptr size, const void *data)) \ + F(void, NamedBufferData, (GLuint buffer, GLsizeiptr size, const void *data, GLenum usage)) \ + F(void, NamedBufferStorage, (GLuint buffer, GLsizeiptr size, const void *data, GLbitfield flags)) \ F(void, CreateBuffers, (GLsizei n, GLuint *buffers)) \ F(void, GetTransformFeedbacki64_v,(GLuint xfb, GLenum pname, GLuint index, GLint64 *param)) \ F(void, GetTransformFeedbacki_v,(GLuint xfb, GLenum pname, GLuint index, GLint *param)) \ F(void, GetTransformFeedbackiv, (GLuint xfb, GLenum pname, GLint *param)) \ - F(void, TransformFeedbackBufferRange, (GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizei size)) \ + F(void, TransformFeedbackBufferRange, (GLuint xfb, GLuint index, GLuint buffer, GLintptr offset, GLsizeiptr size)) \ F(void, TransformFeedbackBufferBase, (GLuint xfb, GLuint index, GLuint buffer)) \ F(void, CreateTransformFeedbacks, (GLsizei n, GLuint *ids)) \ F(void, ClipControl, (GLenum origin, GLenum depth)) \ diff --git a/src/opengl/qopenglversionfunctionsfactory.cpp b/src/opengl/qopenglversionfunctionsfactory.cpp index aad4971fd3..12d00c0554 100644 --- a/src/opengl/qopenglversionfunctionsfactory.cpp +++ b/src/opengl/qopenglversionfunctionsfactory.cpp @@ -135,7 +135,7 @@ static QAbstractOpenGLFunctions *createFunctions(const QOpenGLVersionProfile &ve */ /*! - \fn static T *QOpenGLVersionFunctionsFactory::get(QOpenGLContext *context) + \fn template <class T> static T *QOpenGLVersionFunctionsFactory::get(QOpenGLContext *context) \overload get() diff --git a/src/opengl/qopenglwindow.cpp b/src/opengl/qopenglwindow.cpp index 4c0e9323fa..a3677aa828 100644 --- a/src/opengl/qopenglwindow.cpp +++ b/src/opengl/qopenglwindow.cpp @@ -44,7 +44,7 @@ QT_BEGIN_NAMESPACE immediately result in a call to paintGL(). Calling update() multiple times in a row will not change the behavior in any way. - This is a slot so it can be connected to a \l QTimer::timeout() signal to + This is a slot so it can be connected to a \l QChronoTimer::timeout() signal to perform animation. Note however that in the modern OpenGL world it is a much better choice to rely on synchronization to the vertical refresh rate of the display. See \l{QSurfaceFormat::setSwapInterval()}{setSwapInterval()} on a @@ -60,6 +60,23 @@ QT_BEGIN_NAMESPACE given OpenGL version and profile, or enabling depth and stencil buffers. + \note It is up to the application to ensure depth and stencil buffers are + requested from the underlying windowing system interface. Without requesting + a non-zero depth buffer size there is no guarantee that a depth buffer will + be available, and as a result depth testing related OpenGL operations may fail + to function as expected. + + Commonly used depth and stencil buffer size requests are 24 and 8, + respectively. For example, a QOpenGLWindow subclass could do this in its + constructor: + + \code + QSurfaceFormat format; + format.setDepthBufferSize(24); + format.setStencilBufferSize(8); + setFormat(format); + \endcode + Unlike QWindow, QOpenGLWindow allows opening a painter on itself and perform QPainter-based drawing. @@ -376,7 +393,7 @@ bool QOpenGLWindow::isValid() const /*! Prepares for rendering OpenGL content for this window by making the corresponding context current and binding the framebuffer object, if there is - one, in that context context. + one, in that context. It is not necessary to call this function in most cases, because it is called automatically before invoking paintGL(). It is provided nonetheless to support diff --git a/src/opengl/qtopengl.tracepoints b/src/opengl/qtopengl.tracepoints deleted file mode 100644 index 1602f572d4..0000000000 --- a/src/opengl/qtopengl.tracepoints +++ /dev/null @@ -1,12 +0,0 @@ -{ -#include <private/qopengl2pexvertexarray_p.h> -#include <private/qopengltextureuploader_p.h> -#include <qopenglframebufferobject.h> -} - -QOpenGLFramebufferObjectPrivate_init_entry(QOpenGLFramebufferObject *qfbo, const QSize &size, QOpenGLFramebufferObject::Attachment attachment, GLenum texture_target, GLenum internal_format, GLint samples, bool mipmap) -QOpenGLFramebufferObjectPrivate_init_exit() -QOpenGL2PaintEngineExPrivate_drawTexture_entry(const QOpenGLRect& dest, const QOpenGLRect& src, const QSize &textureSize, bool opaque, bool pattern) -QOpenGL2PaintEngineExPrivate_drawTexture_exit() -QOpenGLTextureCache_bindTexture_entry(QOpenGLContext *context, qint64 key, const QImage &image, QOpenGLTextureUploader::BindOptions options) -QOpenGLTextureCache_bindTexture_exit() |