From e5075803ebb57b8f8bd570f4f4d9b81133e38350 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Vladim=C3=ADr=20Vondru=C5=A1?= Date: Sat, 4 Apr 2020 20:18:52 +0200 Subject: [PATCH] GL: state reset needs to unbind PBOs when entering external code. Qt is not PBO-aware and it messes with its state when resizing a window. --- doc/changelog.dox | 3 +++ src/Magnum/GL/Context.cpp | 11 ++++++++++ src/Magnum/GL/Context.h | 46 +++++++++++++++++++++++++++------------ 3 files changed, 46 insertions(+), 14 deletions(-) diff --git a/doc/changelog.dox b/doc/changelog.dox index a393ef820..e44340866 100644 --- a/doc/changelog.dox +++ b/doc/changelog.dox @@ -300,6 +300,9 @@ See also: - @ref GL::DynamicAttribute can now describe matrix attributes similarly to @ref GL::Attribute, previously this was possible only by specifying each column vector separately +- Added @ref GL::Context::State::UnbindPixelBuffer that's now implicitly + included in @ref GL::Context::State::EnterExternal to make Magnum work + correctly with 3rd party code that's not aware of PBOs. @subsubsection changelog-latest-changes-math Math library diff --git a/src/Magnum/GL/Context.cpp b/src/Magnum/GL/Context.cpp index e362e9dc3..430311edb 100644 --- a/src/Magnum/GL/Context.cpp +++ b/src/Magnum/GL/Context.cpp @@ -1008,6 +1008,17 @@ Version Context::supportedVersion(std::initializer_list versions) const } void Context::resetState(const States states) { + #ifndef MAGNUM_TARGET_GLES2 + /* Unbind a PBO (if any) to avoid confusing external GL code that is not + aware of those. Doing this before all buffer state is reset so we can + reuse the knowledge in our state tracker and unbind only if Magnum + actually bound a PBO before. */ + if(states & State::UnbindPixelBuffer) { + Buffer::unbindInternal(Buffer::TargetHint::PixelPack); + Buffer::unbindInternal(Buffer::TargetHint::PixelUnpack); + } + #endif + if(states & State::Buffers) _state->buffer->reset(); if(states & State::Framebuffers) diff --git a/src/Magnum/GL/Context.h b/src/Magnum/GL/Context.h index 3fa63e8fa..2cb8b8b1a 100644 --- a/src/Magnum/GL/Context.h +++ b/src/Magnum/GL/Context.h @@ -267,11 +267,23 @@ class MAGNUM_GL_EXPORT Context { /** Reset tracked buffer-related bindings and state */ Buffers = 1 << 0, + #ifndef MAGNUM_TARGET_GLES2 + /** + * Unbind currently bound PBO. + * + * Not all third-party code is aware of PBOs, and if a PBO is bound + * when Magnum transfers control to an unaware code, it can cause + * various issues with textures. This is a similar, but rarer, + * case to @ref State::MeshVao / @ref State::BindScratchVao. + */ + UnbindPixelBuffer = 1 << 1, + #endif + /** Reset tracked framebuffer-related bindings and state */ - Framebuffers = 1 << 1, + Framebuffers = 1 << 2, /** Reset tracked mesh-related bindings */ - Meshes = 1 << 2, + Meshes = 1 << 3, /** * Unbind currently bound VAO. @@ -285,7 +297,7 @@ class MAGNUM_GL_EXPORT Context { * with @ref State::MeshVao included unbounds any currently bound * VAO to fix such case. */ - MeshVao = 1 << 3, + MeshVao = 1 << 4, /** * Bind a "scratch" VAO on core profile. @@ -298,40 +310,46 @@ class MAGNUM_GL_EXPORT Context { * Does nothing on compatibility profile and ES / WebGL platforms, * as using the default VAO is allowed there. */ - BindScratchVao = 1 << 4, + BindScratchVao = 1 << 5, /** Reset tracked pixel storage-related state */ - PixelStorage = 1 << 5, + PixelStorage = 1 << 6, /** Reset tracked renderer-related state */ - Renderer = 1 << 6, + Renderer = 1 << 7, /** Reset tracked shader-related bindings */ - Shaders = 1 << 7, + Shaders = 1 << 8, /** Reset tracked texture-related bindings and state */ - Textures = 1 << 8, + Textures = 1 << 9, #ifndef MAGNUM_TARGET_GLES2 /** Reset tracked transform feedback-related bindings */ - TransformFeedback = 1 << 9, + TransformFeedback = 1 << 10, #endif /** * Reset state on entering section with external OpenGL code. * * Resets all state that could cause external code to accidentally - * modify Magnum objects. This includes only @ref State::MeshVao. - * In some pathological cases you may want to enable - * @ref State::BindScratchVao as well. + * modify Magnum objects. This includes @ref State::MeshVao and + * @ref State::UnbindPixelBuffer. In some pathological cases you + * may want to enable @ref State::BindScratchVao as well. */ - EnterExternal = MeshVao, + EnterExternal = MeshVao + #ifndef MAGNUM_TARGET_GLES2 + |UnbindPixelBuffer + #endif + , /** * Reset state on exiting section with external OpenGL code. * * Resets Magnum state tracker to avoid being confused by external - * state changes. This resets all states. + * state changes. This resets all states, however + * @ref UnbindPixelBuffer is excluded as Magnum's state tracker + * will ensure no PBO is bound when calling related OpenGL APIs. */ ExitExternal = Buffers|Framebuffers|Meshes|MeshVao|PixelStorage|Renderer|Shaders|Textures #ifndef MAGNUM_TARGET_GLES2