#14714 Release offscreen FBO OpenGL resources on context loss/recreation - #14715
Closed
magnesj wants to merge 2 commits into
Closed
#14714 Release offscreen FBO OpenGL resources on context loss/recreation#14715magnesj wants to merge 2 commits into
magnesj wants to merge 2 commits into
Conversation
…eation caf::Viewer relied on a QOpenGLContext::aboutToBeDestroyed connection to release the offscreen FBO's OpenGL resources, but the connection was dead code: OpenGLWidget's own aboutToBeDestroyed slot ran first and nulled the cvf OpenGL context, so deleteFboOpenGLResources() became a no-op. The connection was also only ever made once, so it did not fire again after a context was recreated (e.g. when a dock widget was reparented). As a result m_offscreenFbo kept OpenGL ids belonging to a destroyed context. FramebufferObject::applyOpenGL() only regenerates ids that are still 0, so a stale non-zero id caused glBindFramebuffer to silently create a fresh, attachment-less framebuffer, which rendered black until a size change forced the attachments to be reapplied. Add explicit onWidgetOpenGLAboutToBeShutdown()/onWidgetOpenGLReinitialized() hooks to cvfqt::OpenGLWidget, called with a well-defined current OpenGL context (old context before teardown, new context after reinitialization), and override them in caf::Viewer to release/reset the offscreen FBO's cached OpenGL resources in both directions.
Closed
3 tasks
Review follow-up on the offscreen FBO context loss fix. makeCurrent() silently does nothing when the widget surface is already gone, which is exactly what happens during the teardown this code targets. Issuing OpenGL calls in that case dereferences a NULL current context, or worse, deletes framebuffer names in whatever context happens to be current. Only notify derived classes when the context really did become current. FramebufferObject::deleteFramebuffer() cleared the color attachment version ticks while the attachments themselves were kept, so the next applyOpenGL() indexed an empty vector. Reset the ticks instead, keeping the array in sync with the attachment count. The offscreen textures and renderbuffers live in the shared context group (AA_ShareOpenGLContexts) and outlive the widget context, but onWidgetOpenGLAboutToBeShutdown() is never called during widget destruction since the base class disconnects from aboutToBeDestroyed first. Release them in the Viewer destructor, where the derived object and the Qt context are both still alive. Framebuffer, texture and renderbuffer names are per context, so ids minted in a destroyed context must be dropped rather than deleted through the new one. Add forgetCurrentOpenGLResources() to FramebufferObject and use it when reinitializing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01B5zb3uXFHUva7Wrb7zZBp1
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #14714.
Problem
caf::Viewer relied on a QOpenGLContext::aboutToBeDestroyed connection to release the offscreen FBO's OpenGL resources, but the connection was dead code:
As a result m_offscreenFbo kept OpenGL ids belonging to a destroyed context. FramebufferObject::applyOpenGL() only regenerates ids that are still 0, so a stale non-zero id caused glBindFramebuffer to silently create a fresh, attachment-less framebuffer. Attachments are only reapplied when the viewport size changes, so a view re-docked at an unchanged size stayed incomplete and rendered black — this is the reproducible symptom in #14708 (tiling two ensemble contour maps at the same size blacks one out), and likely the underlying cause of the RHEL8 completely-black-view reports.
Fix
Added explicit, well-documented lifecycle hooks to cvfqt::OpenGLWidget:
caf::Viewer overrides both to release/reset the offscreen FBO's cached OpenGL resources, so they get rebuilt correctly in the new context regardless of which lifecycle event actually fires on a given platform.