From af2a4a7e2aeb38fbca79529a1d200ecc2621dfd7 Mon Sep 17 00:00:00 2001 From: reuk Date: Mon, 6 Mar 2023 11:40:35 +0000 Subject: [PATCH] OpenGL: Avoid enabling GL_TEXTURE_2D in core profile contexts --- examples/GUI/OpenGLDemo.h | 4 +- modules/juce_opengl/juce_opengl.cpp | 16 -------- .../juce_opengl/opengl/juce_OpenGLContext.cpp | 38 +++++++++++++------ .../juce_opengl/opengl/juce_OpenGLContext.h | 17 ++++++++- .../opengl/juce_OpenGLFrameBuffer.cpp | 4 +- .../opengl/juce_OpenGLGraphicsContext.cpp | 7 +++- 6 files changed, 54 insertions(+), 32 deletions(-) diff --git a/examples/GUI/OpenGLDemo.h b/examples/GUI/OpenGLDemo.h index 8718acdf3c..b4d54d0481 100644 --- a/examples/GUI/OpenGLDemo.h +++ b/examples/GUI/OpenGLDemo.h @@ -841,7 +841,9 @@ public: glEnable (GL_BLEND); glBlendFunc (GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); glActiveTexture (GL_TEXTURE0); - glEnable (GL_TEXTURE_2D); + + if (! openGLContext.isCoreProfile()) + glEnable (GL_TEXTURE_2D); glViewport (0, 0, roundToInt (desktopScale * (float) bounds.getWidth()), diff --git a/modules/juce_opengl/juce_opengl.cpp b/modules/juce_opengl/juce_opengl.cpp index 66d7be3f8b..a83d61bcaa 100644 --- a/modules/juce_opengl/juce_opengl.cpp +++ b/modules/juce_opengl/juce_opengl.cpp @@ -240,22 +240,6 @@ private: OpenGLTargetSaver& operator= (const OpenGLTargetSaver&); }; -static bool contextRequiresTexture2DEnableDisable() -{ - #if JUCE_OPENGL_ES - return false; - #else - clearGLError(); - GLint mask = 0; - glGetIntegerv (GL_CONTEXT_PROFILE_MASK, &mask); - - if (glGetError() == GL_INVALID_ENUM) - return true; - - return (mask & (GLint) GL_CONTEXT_CORE_PROFILE_BIT) == 0; - #endif -} - } // namespace juce //============================================================================== diff --git a/modules/juce_opengl/opengl/juce_OpenGLContext.cpp b/modules/juce_opengl/opengl/juce_OpenGLContext.cpp index ccb4a7fabd..2a24efccb7 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLContext.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLContext.cpp @@ -537,7 +537,7 @@ public: void drawComponentBuffer() { - if (contextRequiresTexture2DEnableDisable()) + if (! isCoreProfile()) glEnable (GL_TEXTURE_2D); #if JUCE_WINDOWS @@ -644,6 +644,7 @@ public: if (getOpenGLVersion() >= Version { 4, 3 } && glDebugMessageCallback != nullptr) { glEnable (GL_DEBUG_OUTPUT); + glEnable (GL_DEBUG_OUTPUT_SYNCHRONOUS); glDebugMessageCallback ([] (GLenum, GLenum type, GLuint, GLenum severity, GLsizei, const GLchar* message, const void*) { // This may reiterate issues that are also flagged by JUCE_CHECK_OPENGL_ERROR. @@ -674,6 +675,24 @@ public: return InitResult::success; } + bool isCoreProfile() const + { + #if JUCE_OPENGL_ES + return true; + #else + clearGLError(); + GLint mask = 0; + glGetIntegerv (GL_CONTEXT_PROFILE_MASK, &mask); + + // The context isn't aware of the profile mask, so it pre-dates the core profile + if (glGetError() == GL_INVALID_ENUM) + return false; + + // Also assumes a compatibility profile if the mask is completely empty for some reason + return (mask & (GLint) GL_CONTEXT_CORE_PROFILE_BIT) != 0; + #endif + } + /* Returns true if the context requires a non-zero vertex array object (VAO) to be bound. If the context is a compatibility context, we can just pretend that VAOs don't exist, @@ -686,16 +705,7 @@ public: #if JUCE_OPENGL_ES return false; #else - clearGLError(); - GLint mask = 0; - glGetIntegerv (GL_CONTEXT_PROFILE_MASK, &mask); - - // The context isn't aware of the profile mask, so it pre-dates the core profile - if (glGetError() == GL_INVALID_ENUM) - return false; - - // Also assumes a compatibility profile if the mask is completely empty for some reason - return (mask & (GLint) GL_CONTEXT_CORE_PROFILE_BIT) != 0; + return isCoreProfile(); #endif } @@ -1443,6 +1453,12 @@ void* OpenGLContext::getRawContext() const noexcept return nativeContext != nullptr ? nativeContext->getRawContext() : nullptr; } +bool OpenGLContext::isCoreProfile() const +{ + auto* c = getCachedImage(); + return c != nullptr && c->isCoreProfile(); +} + OpenGLContext::CachedImage* OpenGLContext::getCachedImage() const noexcept { if (auto* comp = getTargetComponent()) diff --git a/modules/juce_opengl/opengl/juce_OpenGLContext.h b/modules/juce_opengl/opengl/juce_OpenGLContext.h index 86191f842e..cb9ed766ac 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLContext.h +++ b/modules/juce_opengl/opengl/juce_OpenGLContext.h @@ -133,7 +133,16 @@ public: /** Returns true if non-power-of-two textures are supported in this context. */ bool isTextureNpotSupported() const; - /** OpenGL versions, used by setOpenGLVersionRequired(). */ + /** OpenGL versions, used by setOpenGLVersionRequired(). + + The Core profile doesn't include some legacy functionality, including the + fixed-function pipeline. + + The Compatibility profile is backwards-compatible, and includes functionality + deprecated in the Core profile. However, not all implementations provide + compatibility profiles targeting later versions of OpenGL. To run on the + broadest range of hardware, using the 3.2 Core profile is recommended. + */ enum OpenGLVersion { defaultGLVersion = 0, ///< Whatever the device decides to give us, normally a compatibility profile @@ -285,6 +294,12 @@ public: */ void* getRawContext() const noexcept; + /** Returns true if this context is using the core profile. + + @see OpenGLVersion + */ + bool isCoreProfile() const; + /** This structure holds a set of dynamically loaded GL functions for use on this context. */ OpenGLExtensionFunctions extensions; diff --git a/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp b/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp index e2f339ed50..85fd1c2c3d 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLFrameBuffer.cpp @@ -216,7 +216,9 @@ bool OpenGLFrameBuffer::initialise (OpenGLFrameBuffer& other) pimpl->bind(); #if ! JUCE_ANDROID - glEnable (GL_TEXTURE_2D); + if (! pimpl->context.isCoreProfile()) + glEnable (GL_TEXTURE_2D); + clearGLError(); #endif glBindTexture (GL_TEXTURE_2D, p->textureID); diff --git a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp index 38074a69bc..172b1e9840 100644 --- a/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp +++ b/modules/juce_opengl/opengl/juce_OpenGLGraphicsContext.cpp @@ -1086,7 +1086,7 @@ struct StateHelpers GLuint currentTextureID[numTextures]; int texturesEnabled = 0, currentActiveTexture = -1; const OpenGLContext& context; - const bool needsToEnableTexture = contextRequiresTexture2DEnableDisable(); + const bool needsToEnableTexture = ! context.isCoreProfile(); ActiveTextures& operator= (const ActiveTextures&); }; @@ -1784,7 +1784,10 @@ struct NonShaderContext : public LowLevelGraphicsSoftwareRenderer #if ! JUCE_ANDROID target.context.extensions.glActiveTexture (GL_TEXTURE0); - glEnable (GL_TEXTURE_2D); + + if (! target.context.isCoreProfile()) + glEnable (GL_TEXTURE_2D); + clearGLError(); #endif