diff --git a/plugins/platforms/x11/standalone/omlsynccontrolvsyncmonitor.cpp b/plugins/platforms/x11/standalone/omlsynccontrolvsyncmonitor.cpp index 02af539e03..ef61e41f40 100644 --- a/plugins/platforms/x11/standalone/omlsynccontrolvsyncmonitor.cpp +++ b/plugins/platforms/x11/standalone/omlsynccontrolvsyncmonitor.cpp @@ -5,6 +5,7 @@ */ #include "omlsynccontrolvsyncmonitor.h" +#include "glxconvenience.h" #include "logging.h" #include @@ -38,30 +39,52 @@ OMLSyncControlVsyncMonitorHelper::OMLSyncControlVsyncMonitorHelper(QObject *pare return; } + Window rootWindow = DefaultRootWindow(m_display); + const int attribs[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, 0 }; - int count; - GLXFBConfig *configs = glXChooseFBConfig(m_display, DefaultScreen(m_display), - attribs, &count); - if (!count) { + GLXFBConfig config = chooseGlxFbConfig(m_display, attribs); + if (!config) { qCDebug(KWIN_X11STANDALONE) << "Couldn't find any suitable FBConfig for vsync monitor"; return; } - GLXFBConfig config = configs[0]; - XFree(configs); + XVisualInfo *visualInfo = glXGetVisualFromFBConfig(m_display, config); + if (!visualInfo) { + return; + } + + Visual *visual = visualInfo->visual; + const int depth = visualInfo->depth; + XFree(visualInfo); + + Colormap colormap = XCreateColormap(m_display, rootWindow, visual, AllocNone); + XSetWindowAttributes attributes; + attributes.colormap = colormap; + + m_dummyWindow = XCreateWindow(m_display, rootWindow, 0, 0, 1, 1, 0, depth, + InputOutput, visual, CWColormap, &attributes); + XFreeColormap(m_display, colormap); + if (!m_dummyWindow) { + qCDebug(KWIN_X11STANDALONE) << "Failed to create a dummy window for vsync monitor"; + return; + } + + m_drawable = glXCreateWindow(m_display, config, m_dummyWindow, nullptr); + if (!m_drawable) { + qCDebug(KWIN_X11STANDALONE) << "Failed to create GLXWindow for dummy window"; + return; + } m_localContext = glXCreateNewContext(m_display, config, GLX_RGBA_TYPE, 0, true); if (!m_localContext) { qCDebug(KWIN_X11STANDALONE) << "Failed to create opengl context for vsync monitor"; return; } - - m_drawable = DefaultRootWindow(m_display); } OMLSyncControlVsyncMonitorHelper::~OMLSyncControlVsyncMonitorHelper() @@ -69,6 +92,12 @@ OMLSyncControlVsyncMonitorHelper::~OMLSyncControlVsyncMonitorHelper() if (m_localContext) { glXDestroyContext(m_display, m_localContext); } + if (m_drawable) { + glXDestroyWindow(m_display, m_drawable); + } + if (m_dummyWindow) { + XDestroyWindow(m_display, m_dummyWindow); + } if (m_display) { XCloseDisplay(m_display); } diff --git a/plugins/platforms/x11/standalone/omlsynccontrolvsyncmonitor.h b/plugins/platforms/x11/standalone/omlsynccontrolvsyncmonitor.h index fda11a72d8..7c1ba4c18b 100644 --- a/plugins/platforms/x11/standalone/omlsynccontrolvsyncmonitor.h +++ b/plugins/platforms/x11/standalone/omlsynccontrolvsyncmonitor.h @@ -40,6 +40,7 @@ Q_SIGNALS: private: Display *m_display = nullptr; + Window m_dummyWindow = 0; GLXContext m_localContext = 0; GLXDrawable m_drawable = 0; }; diff --git a/plugins/platforms/x11/standalone/sgivideosyncvsyncmonitor.cpp b/plugins/platforms/x11/standalone/sgivideosyncvsyncmonitor.cpp index 13ddc190c0..9478b90849 100644 --- a/plugins/platforms/x11/standalone/sgivideosyncvsyncmonitor.cpp +++ b/plugins/platforms/x11/standalone/sgivideosyncvsyncmonitor.cpp @@ -5,6 +5,7 @@ */ #include "sgivideosyncvsyncmonitor.h" +#include "glxconvenience.h" #include "logging.h" #include @@ -38,30 +39,52 @@ SGIVideoSyncVsyncMonitorHelper::SGIVideoSyncVsyncMonitorHelper(QObject *parent) return; } + Window rootWindow = DefaultRootWindow(m_display); + const int attribs[] = { GLX_RENDER_TYPE, GLX_RGBA_BIT, GLX_DRAWABLE_TYPE, GLX_WINDOW_BIT, 0 }; - int count; - GLXFBConfig *configs = glXChooseFBConfig(m_display, DefaultScreen(m_display), - attribs, &count); - if (!count) { + GLXFBConfig config = chooseGlxFbConfig(m_display, attribs); + if (!config) { qCDebug(KWIN_X11STANDALONE) << "Couldn't find any suitable FBConfig for vsync monitor"; return; } - GLXFBConfig config = configs[0]; - XFree(configs); + XVisualInfo *visualInfo = glXGetVisualFromFBConfig(m_display, config); + if (!visualInfo) { + return; + } + + Visual *visual = visualInfo->visual; + const int depth = visualInfo->depth; + XFree(visualInfo); + + Colormap colormap = XCreateColormap(m_display, rootWindow, visual, AllocNone); + XSetWindowAttributes attributes; + attributes.colormap = colormap; + + m_dummyWindow = XCreateWindow(m_display, rootWindow, 0, 0, 1, 1, 0, depth, + InputOutput, visual, CWColormap, &attributes); + XFreeColormap(m_display, colormap); + if (!m_dummyWindow) { + qCDebug(KWIN_X11STANDALONE) << "Failed to create a dummy window for vsync monitor"; + return; + } + + m_drawable = glXCreateWindow(m_display, config, m_dummyWindow, nullptr); + if (!m_drawable) { + qCDebug(KWIN_X11STANDALONE) << "Failed to create GLXWindow for dummy window"; + return; + } m_localContext = glXCreateNewContext(m_display, config, GLX_RGBA_TYPE, 0, true); if (!m_localContext) { qCDebug(KWIN_X11STANDALONE) << "Failed to create opengl context for vsync monitor"; return; } - - m_drawable = DefaultRootWindow(m_display); } SGIVideoSyncVsyncMonitorHelper::~SGIVideoSyncVsyncMonitorHelper() @@ -69,6 +92,12 @@ SGIVideoSyncVsyncMonitorHelper::~SGIVideoSyncVsyncMonitorHelper() if (m_localContext) { glXDestroyContext(m_display, m_localContext); } + if (m_drawable) { + glXDestroyWindow(m_display, m_drawable); + } + if (m_dummyWindow) { + XDestroyWindow(m_display, m_dummyWindow); + } if (m_display) { XCloseDisplay(m_display); } diff --git a/plugins/platforms/x11/standalone/sgivideosyncvsyncmonitor.h b/plugins/platforms/x11/standalone/sgivideosyncvsyncmonitor.h index 3698ea6622..709b4e3d10 100644 --- a/plugins/platforms/x11/standalone/sgivideosyncvsyncmonitor.h +++ b/plugins/platforms/x11/standalone/sgivideosyncvsyncmonitor.h @@ -40,6 +40,7 @@ Q_SIGNALS: private: Display *m_display = nullptr; + Window m_dummyWindow = 0; GLXContext m_localContext = 0; GLXDrawable m_drawable = 0; };