diff --git a/autotests/effect/kwinglplatformtest.cpp b/autotests/effect/kwinglplatformtest.cpp index fc075cf3d7..ce0c8304a2 100644 --- a/autotests/effect/kwinglplatformtest.cpp +++ b/autotests/effect/kwinglplatformtest.cpp @@ -18,11 +18,6 @@ Q_DECLARE_METATYPE(KWin::ChipClass) using namespace KWin; -void KWin::cleanupGL() -{ - GLPlatform::cleanup(); -} - class GLPlatformTest : public QObject { Q_OBJECT @@ -40,7 +35,7 @@ private Q_SLOTS: void GLPlatformTest::cleanup() { - cleanupGL(); + GLPlatform::cleanup(); delete s_gl; s_gl = nullptr; } diff --git a/src/backends/x11/standalone/x11_standalone_egl_backend.cpp b/src/backends/x11/standalone/x11_standalone_egl_backend.cpp index 37122b2363..68a103b59d 100644 --- a/src/backends/x11/standalone/x11_standalone_egl_backend.cpp +++ b/src/backends/x11/standalone/x11_standalone_egl_backend.cpp @@ -131,7 +131,7 @@ void EglBackend::init() setFailed(QStringLiteral("Required support for binding pixmaps to EGLImages not found, disabling compositing")); return; } - if (!hasGLExtension(QByteArrayLiteral("GL_OES_EGL_image"))) { + if (!m_context->hasOpenglExtension(QByteArrayLiteral("GL_OES_EGL_image"))) { setFailed(QStringLiteral("Required extension GL_OES_EGL_image not found, disabling compositing")); return; } diff --git a/src/backends/x11/standalone/x11_standalone_glx_backend.cpp b/src/backends/x11/standalone/x11_standalone_glx_backend.cpp index 2c787330d3..e859458955 100644 --- a/src/backends/x11/standalone/x11_standalone_glx_backend.cpp +++ b/src/backends/x11/standalone/x11_standalone_glx_backend.cpp @@ -157,7 +157,7 @@ GlxBackend::~GlxBackend() if (m_context) { // TODO: cleanup in error case // do cleanup after initBuffer() - cleanupGL(); + GLPlatform::cleanup(); doneCurrent(); m_context.reset(); diff --git a/src/compositor_wayland.cpp b/src/compositor_wayland.cpp index f63ead7796..532760a5c0 100644 --- a/src/compositor_wayland.cpp +++ b/src/compositor_wayland.cpp @@ -80,7 +80,7 @@ bool WaylandCompositor::attemptOpenGLCompositing() } // We only support the OpenGL 2+ shader API, not GL_ARB_shader_objects - if (!hasGLVersion(2, 0)) { + if (!backend->openglContext()->hasVersion(Version(2, 0))) { qCDebug(KWIN_CORE) << "OpenGL 2.0 is not supported"; return false; } diff --git a/src/compositor_x11.cpp b/src/compositor_x11.cpp index 10885d8ba3..19a9dcb495 100644 --- a/src/compositor_x11.cpp +++ b/src/compositor_x11.cpp @@ -220,7 +220,7 @@ bool X11Compositor::attemptOpenGLCompositing() } // We only support the OpenGL 2+ shader API, not GL_ARB_shader_objects - if (!hasGLVersion(2, 0)) { + if (!backend->openglContext()->hasVersion(Version(2, 0))) { qCDebug(KWIN_CORE) << "OpenGL 2.0 is not supported"; return false; } @@ -348,7 +348,7 @@ void X11Compositor::start() // Sets also the 'effects' pointer. kwinApp()->createEffectsHandler(this, m_scene.get()); - m_syncManager.reset(X11SyncManager::create()); + m_syncManager.reset(X11SyncManager::create(m_backend.get())); if (m_releaseSelectionTimer.isActive()) { m_releaseSelectionTimer.stop(); } diff --git a/src/debug_console.cpp b/src/debug_console.cpp index 6246c7d858..85296f9275 100644 --- a/src/debug_console.cpp +++ b/src/debug_console.cpp @@ -683,7 +683,7 @@ void DebugConsole::initGLTab() const OpenGLBackend *backend = static_cast(Compositor::self()->backend()); m_ui->platformExtensionsLabel->setText(extensionsString(backend->extensions())); - m_ui->openGLExtensionsLabel->setText(extensionsString(openGLExtensions())); + m_ui->openGLExtensionsLabel->setText(extensionsString(backend->openglContext()->openglExtensions())); } template diff --git a/src/opengl/glplatform.h b/src/opengl/glplatform.h index e5295f0058..9900829749 100644 --- a/src/opengl/glplatform.h +++ b/src/opengl/glplatform.h @@ -368,10 +368,10 @@ public: */ static QByteArray chipClassToString8(ChipClass chipClass); + static void cleanup(); + private: GLPlatform(); - friend void KWin::cleanupGL(); - static void cleanup(); private: QByteArray m_glsl_version; diff --git a/src/opengl/glshader.cpp b/src/opengl/glshader.cpp index b5113251bc..98ec166c58 100644 --- a/src/opengl/glshader.cpp +++ b/src/opengl/glshader.cpp @@ -187,7 +187,8 @@ void GLShader::bindAttributeLocation(const char *name, int index) void GLShader::bindFragDataLocation(const char *name, int index) { - if (!GLPlatform::instance()->isGLES() && (hasGLVersion(3, 0) || hasGLExtension(QByteArrayLiteral("GL_EXT_gpu_shader4")))) { + const auto context = OpenGlContext::currentContext(); + if (!context->isOpenglES() && (context->hasVersion(Version(3, 0)) || context->hasOpenglExtension(QByteArrayLiteral("GL_EXT_gpu_shader4")))) { glBindFragDataLocation(m_program, index, name); } } diff --git a/src/opengl/glutils.cpp b/src/opengl/glutils.cpp index 51865c9ce4..e2a5e01455 100644 --- a/src/opengl/glutils.cpp +++ b/src/opengl/glutils.cpp @@ -17,14 +17,13 @@ namespace KWin { -static QList glExtensions; - // Functions static void initDebugOutput() { - const bool have_KHR_debug = hasGLExtension(QByteArrayLiteral("GL_KHR_debug")); - const bool have_ARB_debug = hasGLExtension(QByteArrayLiteral("GL_ARB_debug_output")); + const auto context = OpenGlContext::currentContext(); + const bool have_KHR_debug = context->hasOpenglExtension(QByteArrayLiteral("GL_KHR_debug")); + const bool have_ARB_debug = context->hasOpenglExtension(QByteArrayLiteral("GL_ARB_debug_output")); if (!have_KHR_debug && !have_ARB_debug) { return; } @@ -32,12 +31,12 @@ static void initDebugOutput() if (!have_ARB_debug) { // if we don't have ARB debug, but only KHR debug we need to verify whether the context is a debug context // it should work without as well, but empirical tests show: no it doesn't - if (GLPlatform::instance()->isGLES()) { - if (!hasGLVersion(3, 2)) { + if (context->isOpenglES()) { + if (!context->hasVersion(Version(3, 2))) { // empirical data shows extension doesn't work return; } - } else if (!hasGLVersion(3, 0)) { + } else if (!context->hasVersion(Version(3, 0))) { return; } // can only be queried with either OpenGL >= 3.0 or OpenGL ES of at least 3.1 @@ -96,47 +95,12 @@ static void initDebugOutput() void initGL(const std::function &resolveFunction) { - // Get list of supported OpenGL extensions - if (hasGLVersion(3, 0)) { - int count; - glGetIntegerv(GL_NUM_EXTENSIONS, &count); - - for (int i = 0; i < count; i++) { - const QByteArray name = (const char *)glGetStringi(GL_EXTENSIONS, i); - glExtensions << name; - } - } else { - glExtensions = QByteArray((const char *)glGetString(GL_EXTENSIONS)).split(' '); - } - // handle OpenGL extensions functions glResolveFunctions(resolveFunction); initDebugOutput(); } -void cleanupGL() -{ - GLPlatform::cleanup(); - - glExtensions.clear(); -} - -bool hasGLVersion(int major, int minor, int release) -{ - return GLPlatform::instance()->glVersion() >= Version(major, minor, release); -} - -bool hasGLExtension(const QByteArray &extension) -{ - return glExtensions.contains(extension); -} - -QList openGLExtensions() -{ - return glExtensions; -} - static QString formatGLError(GLenum err) { switch (err) { diff --git a/src/opengl/glutils.h b/src/opengl/glutils.h index 3038a16c11..87413f9614 100644 --- a/src/opengl/glutils.h +++ b/src/opengl/glutils.h @@ -30,18 +30,10 @@ namespace KWin // Note that GL context has to be created by the time this function is called typedef void (*resolveFuncPtr)(); void KWIN_EXPORT initGL(const std::function &resolveFunction); -// Cleans up all resources hold by the GL Context -void KWIN_EXPORT cleanupGL(); - -bool KWIN_EXPORT hasGLVersion(int major, int minor, int release = 0); -// use for both OpenGL and GLX extensions -bool KWIN_EXPORT hasGLExtension(const QByteArray &extension); // detect OpenGL error (add to various places in code to pinpoint the place) bool KWIN_EXPORT checkGLError(const char *txt); -QList KWIN_EXPORT openGLExtensions(); - } // namespace /** @} */ diff --git a/src/opengl/glutils_funcs.cpp b/src/opengl/glutils_funcs.cpp index 4e36c1e8ea..7d2dac75f7 100644 --- a/src/opengl/glutils_funcs.cpp +++ b/src/opengl/glutils_funcs.cpp @@ -30,8 +30,9 @@ glGetnUniformfv_func glGetnUniformfv; void glResolveFunctions(const std::function &resolveFunction) { - const bool haveArbRobustness = hasGLExtension(QByteArrayLiteral("GL_ARB_robustness")); - const bool haveExtRobustness = hasGLExtension(QByteArrayLiteral("GL_EXT_robustness")); + const auto context = OpenGlContext::currentContext(); + const bool haveArbRobustness = context->hasOpenglExtension(QByteArrayLiteral("GL_ARB_robustness")); + const bool haveExtRobustness = context->hasOpenglExtension(QByteArrayLiteral("GL_EXT_robustness")); bool robustContext = false; if (GLPlatform::instance()->isGLES()) { if (haveExtRobustness) { @@ -41,7 +42,7 @@ void glResolveFunctions(const std::function &resol } } else { if (haveArbRobustness) { - if (hasGLVersion(3, 0)) { + if (context->hasVersion(Version(3, 0))) { GLint value = 0; glGetIntegerv(GL_CONTEXT_FLAGS, &value); if (value & GL_CONTEXT_FLAG_ROBUST_ACCESS_BIT_ARB) { diff --git a/src/opengl/openglcontext.cpp b/src/opengl/openglcontext.cpp index d6aa5dbe7a..b8195df670 100644 --- a/src/opengl/openglcontext.cpp +++ b/src/opengl/openglcontext.cpp @@ -253,6 +253,11 @@ void OpenGlContext::setIndexBuffer(IndexBuffer *buffer) m_indexBuffer = buffer; } +QSet OpenGlContext::openglExtensions() const +{ + return m_extensions; +} + OpenGlContext *OpenGlContext::currentContext() { return s_currentContext; diff --git a/src/opengl/openglcontext.h b/src/opengl/openglcontext.h index 26e44cff96..fddbffa580 100644 --- a/src/opengl/openglcontext.h +++ b/src/opengl/openglcontext.h @@ -54,6 +54,7 @@ public: ShaderManager *shaderManager() const; GLVertexBuffer *streamingVbo() const; IndexBuffer *indexBuffer() const; + QSet openglExtensions() const; /** * checks whether or not this context supports all the features that KWin requires diff --git a/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp b/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp index a0e61662af..c79b577699 100644 --- a/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp +++ b/src/platformsupport/scenes/opengl/abstract_egl_backend.cpp @@ -86,7 +86,7 @@ void AbstractEglBackend::cleanup() } cleanupSurfaces(); - cleanupGL(); + GLPlatform::cleanup(); m_context.reset(); } diff --git a/src/x11syncmanager.cpp b/src/x11syncmanager.cpp index a11684f759..1a8f029b0f 100644 --- a/src/x11syncmanager.cpp +++ b/src/x11syncmanager.cpp @@ -15,6 +15,7 @@ #include "utils/common.h" #include "opengl/glplatform.h" +#include "platformsupport/scenes/opengl/openglbackend.h" namespace KWin { @@ -137,7 +138,7 @@ void X11SyncObject::finishResetting() m_state = Ready; } -X11SyncManager *X11SyncManager::create() +X11SyncManager *X11SyncManager::create(RenderBackend *backend) { if (kwinApp()->operationMode() != Application::OperationModeX11) { return nullptr; @@ -147,12 +148,8 @@ X11SyncManager *X11SyncManager::create() return nullptr; } - GLPlatform *glPlatform = GLPlatform::instance(); - const bool haveSyncObjects = glPlatform->isGLES() - ? hasGLVersion(3, 0) - : hasGLVersion(3, 2) || hasGLExtension("GL_ARB_sync"); - - if (hasGLExtension("GL_EXT_x11_sync_object") && haveSyncObjects) { + const auto context = static_cast(backend)->openglContext(); + if (context->hasOpenglExtension("GL_EXT_x11_sync_object") && context->haveSyncFences()) { const QString useExplicitSync = qEnvironmentVariable("KWIN_EXPLICIT_SYNC"); if (useExplicitSync != QLatin1String("0")) { diff --git a/src/x11syncmanager.h b/src/x11syncmanager.h index 38c52246d3..d2913761f0 100644 --- a/src/x11syncmanager.h +++ b/src/x11syncmanager.h @@ -14,6 +14,8 @@ namespace KWin { +class RenderBackend; + /** * SyncObject represents a fence used to synchronize operations in the kwin command stream * with operations in the X command stream. @@ -61,7 +63,7 @@ public: MaxFences = 4, }; - static X11SyncManager *create(); + static X11SyncManager *create(RenderBackend *backend); ~X11SyncManager(); bool endFrame();