QOpenGLWidget: use (and prefer) InvalidateFramebuffer
Desktop GL does not have the GL_EXT_discard_framebuffer extension at all. Instead, it may have GL_ARB_invalidate_subdata. Furthermore, GLES >= 3.0 and GL >= 4.3 both support FBO invalidation through glInvalidateFramebuffer. Extend the semantics of OpenGLExtension::DiscardFramebuffer to mean that *any* possibility above is supported, and wrap it in a helper function that calls whatever support is present. (This is all private API anyhow.) Technically speaking glInvalidateFramebuffer supports a superset of what glDiscardFramebufferEXT supports, but we never use such superset, and the two APIs are otherwise identical. Then, make QOpenGLWidget call that wrapper. Change-Id: I64e042daf51493d3834c3ba1b53ae6e224bbc4ed Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>bb10
parent
abe7c77d6d
commit
8cc8bbb466
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -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()
|
||||
{
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
}
|
||||
|
|
|
|||
Loading…
Reference in New Issue