QOpenGLWidget: invalidate the depth/stencil after rendering

We don't need them any more, only the color is used for compositing.
In principle this enables a driver to not writeback their contents into
main memory.

Change-Id: Ibde17af6c14c98ebdca956aaf902dfd728f9219c
Reviewed-by: Laszlo Agocs <laszlo.agocs@qt.io>
This commit is contained in:
Giuseppe D'Angelo 2023-07-22 00:47:28 +02:00
parent 76e650045e
commit 21d3bb9e74

View File

@ -553,7 +553,13 @@ public:
void initialize(); void initialize();
void render(); void render();
void invalidateFbo(); static constexpr GLenum gl_color_attachment0 = 0x8CE0; // GL_COLOR_ATTACHMENT0
static constexpr GLenum gl_depth_attachment = 0x8D00; // GL_DEPTH_ATTACHMENT
static constexpr GLenum gl_stencil_attachment = 0x8D20; // GL_STENCIL_ATTACHMENT
static constexpr GLenum gl_depth_stencil_attachment = 0x821A; // GL_DEPTH_STENCIL_ATTACHMENT
void invalidateFboBeforePainting();
void invalidateFboAfterPainting();
void destroyFbos(); void destroyFbos();
@ -946,11 +952,11 @@ void QOpenGLWidgetPrivate::render()
} }
if (updateBehavior == QOpenGLWidget::NoPartialUpdate && hasBeenComposed) { if (updateBehavior == QOpenGLWidget::NoPartialUpdate && hasBeenComposed) {
invalidateFbo(); invalidateFboBeforePainting();
if (stereo && fbos[QOpenGLWidget::RightBuffer]) { if (stereo && fbos[QOpenGLWidget::RightBuffer]) {
setCurrentTargetBuffer(QOpenGLWidget::RightBuffer); setCurrentTargetBuffer(QOpenGLWidget::RightBuffer);
invalidateFbo(); invalidateFboBeforePainting();
setCurrentTargetBuffer(QOpenGLWidget::LeftBuffer); setCurrentTargetBuffer(QOpenGLWidget::LeftBuffer);
} }
@ -967,11 +973,15 @@ void QOpenGLWidgetPrivate::render()
QOpenGLContextPrivate::get(ctx)->defaultFboRedirect = fbos[currentTargetBuffer]->handle(); QOpenGLContextPrivate::get(ctx)->defaultFboRedirect = fbos[currentTargetBuffer]->handle();
q->paintGL(); q->paintGL();
if (updateBehavior == QOpenGLWidget::NoPartialUpdate)
invalidateFboAfterPainting();
if (stereo && fbos[QOpenGLWidget::RightBuffer]) { if (stereo && fbos[QOpenGLWidget::RightBuffer]) {
setCurrentTargetBuffer(QOpenGLWidget::RightBuffer); setCurrentTargetBuffer(QOpenGLWidget::RightBuffer);
QOpenGLContextPrivate::get(ctx)->defaultFboRedirect = fbos[currentTargetBuffer]->handle(); QOpenGLContextPrivate::get(ctx)->defaultFboRedirect = fbos[currentTargetBuffer]->handle();
q->paintGL(); q->paintGL();
if (updateBehavior == QOpenGLWidget::NoPartialUpdate)
invalidateFboAfterPainting();
} }
QOpenGLContextPrivate::get(ctx)->defaultFboRedirect = 0; QOpenGLContextPrivate::get(ctx)->defaultFboRedirect = 0;
@ -979,32 +989,43 @@ void QOpenGLWidgetPrivate::render()
flushPending = true; flushPending = true;
} }
void QOpenGLWidgetPrivate::invalidateFbo() void QOpenGLWidgetPrivate::invalidateFboBeforePainting()
{ {
QOpenGLExtensions *f = static_cast<QOpenGLExtensions *>(QOpenGLContext::currentContext()->functions()); QOpenGLExtensions *f = static_cast<QOpenGLExtensions *>(QOpenGLContext::currentContext()->functions());
if (f->hasOpenGLExtension(QOpenGLExtensions::DiscardFramebuffer)) { if (f->hasOpenGLExtension(QOpenGLExtensions::DiscardFramebuffer)) {
const int gl_color_attachment0 = 0x8CE0; // GL_COLOR_ATTACHMENT0 const GLenum attachments[] = {
const int gl_depth_attachment = 0x8D00; // GL_DEPTH_ATTACHMENT gl_color_attachment0,
const int gl_stencil_attachment = 0x8D20; // GL_STENCIL_ATTACHMENT gl_depth_attachment,
gl_stencil_attachment,
#ifdef Q_OS_WASM #ifdef Q_OS_WASM
// webgl does not allow separate depth and stencil attachments // webgl does not allow separate depth and stencil attachments
// QTBUG-69913 // QTBUG-69913
const int gl_depth_stencil_attachment = 0x821A; // GL_DEPTH_STENCIL_ATTACHMENT gl_depth_stencil_attachment
const GLenum attachments[] = {
gl_color_attachment0, gl_depth_attachment, gl_stencil_attachment, gl_depth_stencil_attachment
};
#else
const GLenum attachments[] = {
gl_color_attachment0, gl_depth_attachment, gl_stencil_attachment
};
#endif #endif
};
f->discardFramebuffer(GL_FRAMEBUFFER, GLsizei(std::size(attachments)), attachments); f->discardFramebuffer(GL_FRAMEBUFFER, GLsizei(std::size(attachments)), attachments);
} else { } else {
f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT); f->glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT | GL_STENCIL_BUFFER_BIT);
} }
} }
void QOpenGLWidgetPrivate::invalidateFboAfterPainting()
{
QOpenGLExtensions *f = static_cast<QOpenGLExtensions *>(QOpenGLContext::currentContext()->functions());
if (f->hasOpenGLExtension(QOpenGLExtensions::DiscardFramebuffer)) {
const GLenum attachments[] = {
gl_depth_attachment,
gl_stencil_attachment,
#ifdef Q_OS_WASM
// webgl does not allow separate depth and stencil attachments
// QTBUG-69913
gl_depth_stencil_attachment
#endif
};
f->discardFramebuffer(GL_FRAMEBUFFER, GLsizei(std::size(attachments)), attachments);
}
}
void QOpenGLWidgetPrivate::destroyFbos() void QOpenGLWidgetPrivate::destroyFbos()
{ {
delete fbos[QOpenGLWidget::LeftBuffer]; delete fbos[QOpenGLWidget::LeftBuffer];