diff --git a/src/gui/opengl/qopenglextensions_p.h b/src/gui/opengl/qopenglextensions_p.h index 58231545c6..a6c4a68c6c 100644 --- a/src/gui/opengl/qopenglextensions_p.h +++ b/src/gui/opengl/qopenglextensions_p.h @@ -70,9 +70,9 @@ public: GLvoid *glMapBuffer(GLenum target, GLenum access); void glGetBufferSubData(GLenum target, qopengl_GLintptr offset, qopengl_GLsizeiptr size, GLvoid *data); - void glDiscardFramebufferEXT (GLenum target, GLsizei numAttachments, const GLenum *attachments); void flushShared(); + void discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments); QOpenGLExtensionsPrivate *d() const; @@ -117,14 +117,6 @@ inline void QOpenGLExtensions::glGetBufferSubData(GLenum target, qopengl_GLintpt Q_OPENGL_FUNCTIONS_DEBUG } - -inline void QOpenGLExtensions::glDiscardFramebufferEXT (GLenum target, GLsizei numAttachments, const GLenum *attachments) -{ - Q_D(QOpenGLExtensions); - Q_ASSERT(QOpenGLExtensions::isInitialized(d)); - d->DiscardFramebuffer(target,numAttachments, attachments); - Q_OPENGL_FUNCTIONS_DEBUG -} QT_END_NAMESPACE #endif // QOPENGL_EXTENSIONS_P_H diff --git a/src/gui/opengl/qopenglfunctions.cpp b/src/gui/opengl/qopenglfunctions.cpp index 0b760eb2dd..c9352fbc31 100644 --- a/src/gui/opengl/qopenglfunctions.cpp +++ b/src/gui/opengl/qopenglfunctions.cpp @@ -365,6 +365,7 @@ static int qt_gl_resolve_extensions() | QOpenGLExtensions::FramebufferBlit | QOpenGLExtensions::FramebufferMultisample | QOpenGLExtensions::Sized8Formats + | QOpenGLExtensions::DiscardFramebuffer | QOpenGLExtensions::StandardDerivatives | QOpenGLExtensions::ETC2TextureCompression | QOpenGLExtensions::HalfFloatVertex; @@ -450,6 +451,9 @@ static int qt_gl_resolve_extensions() if (format.version() >= qMakePair(3, 3)) extensions |= QOpenGLExtensions::TextureSwizzle; + if (format.version() >= qMakePair(4, 3) || extensionMatcher.match("GL_ARB_invalidate_subdata")) + extensions |= QOpenGLExtensions::DiscardFramebuffer; + if (extensionMatcher.match("GL_ARB_map_buffer_range")) extensions |= QOpenGLExtensions::MapBufferRange; @@ -5051,7 +5055,23 @@ QOpenGLExtensionsPrivate::QOpenGLExtensionsPrivate(QOpenGLContext *ctx) MapBuffer = RESOLVE(MapBuffer); GetBufferSubData = RESOLVE(GetBufferSubData); DiscardFramebuffer = RESOLVE(DiscardFramebuffer); - } +} + +void QOpenGLExtensions::discardFramebuffer(GLenum target, GLsizei numAttachments, const GLenum *attachments) +{ + Q_D(QOpenGLExtensions); + Q_ASSERT(QOpenGLExtensions::isInitialized(d)); + Q_ASSERT(d->f.InvalidateFramebuffer || d->DiscardFramebuffer); + + // On GLES >= 3 we prefer glInvalidateFramebuffer, even if the + // discard extension is present + if (d->f.InvalidateFramebuffer) + d->f.InvalidateFramebuffer(target, numAttachments, attachments); + else + d->DiscardFramebuffer(target, numAttachments, attachments); + + Q_OPENGL_FUNCTIONS_DEBUG +} void QOpenGLExtensions::flushShared() { diff --git a/src/openglwidgets/qopenglwidget.cpp b/src/openglwidgets/qopenglwidget.cpp index 5fae60ee17..1733706437 100644 --- a/src/openglwidgets/qopenglwidget.cpp +++ b/src/openglwidgets/qopenglwidget.cpp @@ -504,9 +504,8 @@ QT_BEGIN_NAMESPACE benefits on certain hardware architectures common in the mobile and embedded space when a framebuffer object is used as the rendering target. The framebuffer object is invalidated between frames with - glDiscardFramebufferEXT if supported or a glClear. Please see the - documentation of EXT_discard_framebuffer for more information: - https://www.khronos.org/registry/gles/extensions/EXT/EXT_discard_framebuffer.txt + glInvalidateFramebuffer (if supported), or, as fallbacks, + glDiscardFramebufferEXT (if supported) or a call to glClear. \value PartialUpdate The framebuffer objects color buffer and ancillary buffers are not invalidated between frames. @@ -1000,7 +999,7 @@ void QOpenGLWidgetPrivate::invalidateFbo() gl_color_attachment0, gl_depth_attachment, gl_stencil_attachment }; #endif - f->glDiscardFramebufferEXT(GL_FRAMEBUFFER, sizeof attachments / sizeof *attachments, attachments); + f->discardFramebuffer(GL_FRAMEBUFFER, GLsizei(std::size(attachments)), attachments); } else { f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); }