diff --git a/CMakeLists.txt b/CMakeLists.txt index b05e106030..d87291e39b 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -195,6 +195,7 @@ find_package(XCB IMAGE SHM XTEST + GLX OPTIONAL_COMPONENTS ICCCM ) @@ -513,6 +514,7 @@ set(kwin_XCB_LIBS XCB::KEYSYMS XCB::SHM XCB::XTEST + XCB::GLX ) set(kwin_WAYLAND_LIBS diff --git a/compositingprefs.cpp b/compositingprefs.cpp index b675872faf..ee92851cff 100644 --- a/compositingprefs.cpp +++ b/compositingprefs.cpp @@ -116,20 +116,9 @@ QString CompositingPrefs::compositingNotPossibleReason() return QString(); } -static bool s_glxDetected = false; -static bool s_hasGlx = false; - bool CompositingPrefs::hasGlx() { - if (s_glxDetected) { - return s_hasGlx; - } -#ifndef KWIN_HAVE_OPENGLES - int event_base, error_base; - s_hasGlx = glXQueryExtension(display(), &event_base, &error_base); -#endif - s_glxDetected = true; - return s_hasGlx; + return Xcb::Extensions::self()->hasGlx(); } } // namespace diff --git a/xcbutils.cpp b/xcbutils.cpp index 1ac3b09e21..a536f67f7f 100644 --- a/xcbutils.cpp +++ b/xcbutils.cpp @@ -30,6 +30,7 @@ along with this program. If not, see . #include #include #include +#include // system #include #include @@ -266,6 +267,70 @@ QVector syncOpCodes() QByteArrayLiteral("AwaitFence")}); } +static QVector glxOpCodes() +{ + return QVector{ + QByteArrayLiteral(""), + QByteArrayLiteral("Render"), + QByteArrayLiteral("RenderLarge"), + QByteArrayLiteral("CreateContext"), + QByteArrayLiteral("DestroyContext"), + QByteArrayLiteral("MakeCurrent"), + QByteArrayLiteral("IsDirect"), + QByteArrayLiteral("QueryVersion"), + QByteArrayLiteral("WaitGL"), + QByteArrayLiteral("WaitX"), + QByteArrayLiteral("CopyContext"), + QByteArrayLiteral("SwapBuffers"), + QByteArrayLiteral("UseXFont"), + QByteArrayLiteral("CreateGLXPixmap"), + QByteArrayLiteral("GetVisualConfigs"), + QByteArrayLiteral("DestroyGLXPixmap"), + QByteArrayLiteral("VendorPrivate"), + QByteArrayLiteral("VendorPrivateWithReply"), + QByteArrayLiteral("QueryExtensionsString"), + QByteArrayLiteral("QueryServerString"), + QByteArrayLiteral("ClientInfo"), + QByteArrayLiteral("GetFBConfigs"), + QByteArrayLiteral("CreatePixmap"), + QByteArrayLiteral("DestroyPixmap"), + QByteArrayLiteral("CreateNewContext"), + QByteArrayLiteral("QueryContext"), + QByteArrayLiteral("MakeContextCurrent"), + QByteArrayLiteral("CreatePbuffer"), + QByteArrayLiteral("DestroyPbuffer"), + QByteArrayLiteral("GetDrawableAttributes"), + QByteArrayLiteral("ChangeDrawableAttributes"), + QByteArrayLiteral("CreateWindow"), + QByteArrayLiteral("DeleteWindow"), + QByteArrayLiteral("SetClientInfoARB"), + QByteArrayLiteral("CreateContextAttribsARB"), + QByteArrayLiteral("SetClientInfo2ARB") + // Opcodes 36-100 are unused + // The GL single commands begin at opcode 101 + }; +} + +static QVector glxErrorCodes() +{ + return QVector{ + QByteArrayLiteral("BadContext"), + QByteArrayLiteral("BadContextState"), + QByteArrayLiteral("BadDrawable"), + QByteArrayLiteral("BadPixmap"), + QByteArrayLiteral("BadContextTag"), + QByteArrayLiteral("BadCurrentWindow"), + QByteArrayLiteral("BadRenderRequest"), + QByteArrayLiteral("BadLargeRequest"), + QByteArrayLiteral("UnsupportedPrivateRequest"), + QByteArrayLiteral("BadFBConfig"), + QByteArrayLiteral("BadPbuffer"), + QByteArrayLiteral("BadCurrentDrawable"), + QByteArrayLiteral("BadWindow"), + QByteArrayLiteral("GLXBadProfileARB") + }; +} + ExtensionData::ExtensionData() : version(0) , eventBase(0) @@ -317,6 +382,7 @@ void Extensions::init() xcb_prefetch_extension_data(c, &xcb_xfixes_id); xcb_prefetch_extension_data(c, &xcb_render_id); xcb_prefetch_extension_data(c, &xcb_sync_id); + xcb_prefetch_extension_data(c, &xcb_glx_id); m_shape.name = QByteArray("SHAPE"); m_randr.name = QByteArray("RANDR"); @@ -325,6 +391,7 @@ void Extensions::init() m_fixes.name = QByteArray("XFIXES"); m_render.name = QByteArray("RENDER"); m_sync.name = QByteArray("SYNC"); + m_glx.name = QByteArray("GLX"); m_shape.opCodes = shapeOpCodes(); m_randr.opCodes = randrOpCodes(); @@ -333,10 +400,12 @@ void Extensions::init() m_fixes.opCodes = fixesOpCodes(); m_render.opCodes = renderOpCodes(); m_sync.opCodes = syncOpCodes(); + m_glx.opCodes = glxOpCodes(); m_randr.errorCodes = randrErrorCodes(); m_damage.errorCodes = damageErrorCodes(); m_fixes.errorCodes = fixesErrorCodes(); + m_glx.errorCodes = glxErrorCodes(); extensionQueryReply(xcb_get_extension_data(c, &xcb_shape_id), &m_shape); extensionQueryReply(xcb_get_extension_data(c, &xcb_randr_id), &m_randr); @@ -345,6 +414,7 @@ void Extensions::init() extensionQueryReply(xcb_get_extension_data(c, &xcb_xfixes_id), &m_fixes); extensionQueryReply(xcb_get_extension_data(c, &xcb_render_id), &m_render); extensionQueryReply(xcb_get_extension_data(c, &xcb_sync_id), &m_sync); + extensionQueryReply(xcb_get_extension_data(c, &xcb_glx_id), &m_glx); // extension specific queries xcb_shape_query_version_cookie_t shapeVersion; @@ -480,7 +550,8 @@ QVector Extensions::extensions() const << m_composite << m_render << m_fixes - << m_sync; + << m_sync + << m_glx; return extensions; } diff --git a/xcbutils.h b/xcbutils.h index 2640e52c94..39ca05b383 100644 --- a/xcbutils.h +++ b/xcbutils.h @@ -909,6 +909,15 @@ public: } int syncAlarmNotifyEvent() const; QVector extensions() const; + bool hasGlx() const { + return m_glx.present; + } + int glxEventBase() const { + return m_glx.eventBase; + } + int glxMajorOpcode() const { + return m_glx.majorOpcode; + } static Extensions *self(); static void destroy(); @@ -927,6 +936,7 @@ private: ExtensionData m_render; ExtensionData m_fixes; ExtensionData m_sync; + ExtensionData m_glx; static Extensions *s_self; };