2626#include " QtOsgWidget.h"
2727
2828#include < QOpenGLWidget>
29+ #include < QOpenGLContext>
30+ #include < QWindow>
2931#include < iostream>
32+ #include < cstdlib>
33+ #include < cover/coVRPluginSupport.h>
3034
3135void QtGraphicsWindow::setSyncToVBlank (bool flag)
3236{
3337#if defined(USE_X11)
38+ if (flag) {
39+ // Set NVIDIA-specific environment variable for VSync
40+ // This works with __NV_PRIME_RENDER_OFFLOAD and hybrid GPU setups
41+ putenv ((char *)" __GL_SYNC_TO_VBLANK=1" );
42+ if (opencover::cover->debugLevel (2 ))
43+ std::cerr << " setSyncToVBlank: Set __GL_SYNC_TO_VBLANK=1 (GPU global)" << std::endl;
44+ }
45+ else
46+ {
47+ putenv ((char *)" __GL_SYNC_TO_VBLANK=0" );
48+ if (opencover::cover->debugLevel (2 ))
49+ std::cerr << " setSyncToVBlank: Set __GL_SYNC_TO_VBLANK=0 (GPU global)" << std::endl;
50+ }
51+
3452 auto wid = m_glWidget->effectiveWinId ();
3553 if (wid == 0 )
3654 {
37- std::cerr << " setSyncToVBlank: did not find ID of native window for QWidget" << std::endl;
55+ if (opencover::cover->debugLevel (1 ))
56+ std::cerr << " setSyncToVBlank: did not find ID of native window for QWidget" << std::endl;
3857 return ;
3958 }
4059
4160 Display *dpy = nullptr ;
4261
4362#if QT_VERSION >= QT_VERSION_CHECK(6, 2, 0)
4463 if (!qGuiApp) {
45- std::cerr << " setSyncToVBlank: qGuiApp is nullptr" << std::endl;
64+ if (opencover::cover->debugLevel (1 ))
65+ std::cerr << " setSyncToVBlank: qGuiApp is nullptr" << std::endl;
4666 return ;
4767 }
4868
@@ -51,15 +71,22 @@ void QtGraphicsWindow::setSyncToVBlank(bool flag)
5171 if (sessionType == " x11" || sessionType == " tty" ) {
5272 auto x11App = qGuiApp->nativeInterface <QNativeInterface::QX11Application>();
5373 if (!x11App) {
54- std::cerr << " setSyncToVBlank: QX11Application native interface is nullptr" << std::endl;
74+ if (opencover::cover->debugLevel (1 ))
75+ std::cerr << " setSyncToVBlank: QX11Application native interface is nullptr" << std::endl;
5576 return ;
5677 }
5778 dpy = x11App->display ();
5879 } else if (sessionType == " wayland" ) {
59- std::cerr << " setSyncToVBlank: Wayland detected, VSync via GLX is not supported." << std::endl;
80+ // On Wayland, the environment variable should be sufficient
81+ // EGL swap interval control would require active EGL context which we don't have here
82+ if (opencover::cover->debugLevel (2 )) {
83+ std::cerr << " setSyncToVBlank: Wayland detected, VSync control via __GL_SYNC_TO_VBLANK environment variable" << std::endl;
84+ std::cerr << " setSyncToVBlank: Note: Actual VSync scheduling depends on Wayland compositor" << std::endl;
85+ }
6086 return ;
6187 } else {
62- std::cerr << " setSyncToVBlank: Unknown session type: " << sessionType.constData () << std::endl;
88+ if (opencover::cover->debugLevel (2 ))
89+ std::cerr << " setSyncToVBlank: Unknown session type: " << sessionType.constData () << std::endl;
6390 return ;
6491 }
6592#else
@@ -70,25 +97,37 @@ void QtGraphicsWindow::setSyncToVBlank(bool flag)
7097
7198 if (!dpy)
7299 {
73- std::cerr << " setSyncToVBlank: did not find Display for application" << std::endl;
100+ if (opencover::cover->debugLevel (1 ))
101+ std::cerr << " setSyncToVBlank: did not find Display for application" << std::endl;
74102 return ;
75103 }
76104
77105 int screenNumber = XScreenNumberOfScreen (XDefaultScreenOfDisplay (dpy));
78106 const char *s = glXQueryExtensionsString (dpy, screenNumber);
79107 if (s==nullptr )
80108 {
81- std::cerr << " no extensions, probably running MESA" << std::endl;
109+ if (opencover::cover->debugLevel (1 ))
110+ std::cerr << " setSyncToVBlank: no GLX extensions, probably running MESA" << std::endl;
82111 return ;
83112 }
84113
114+ // Check for NVIDIA-specific extensions
115+ std::string extensions (s);
116+ bool hasNvidiaSwap = extensions.find (" GLX_NV_swap_group" ) != std::string::npos;
117+ if (hasNvidiaSwap && opencover::cover->debugLevel (2 )) {
118+ std::cerr << " setSyncToVBlank: NVIDIA GPU detected (GLX_NV_swap_group present)" << std::endl;
119+ }
120+
85121 if (!glXSwapIntervalEXT)
86122 {
87- std::cerr << " setSyncToVBlank: no glXSwapIntervalEXT" << std::endl;
123+ if (opencover::cover->debugLevel (1 ))
124+ std::cerr << " setSyncToVBlank: no glXSwapIntervalEXT" << std::endl;
88125 return ;
89126 }
90127
128+ if (opencover::cover->debugLevel (2 ))
129+ std::cerr << " setSyncToVBlank: " << (flag ? " enabled" : " disabled" )
130+ << " via GLX for XScreen " << screenNumber << std::endl;
91131 glXSwapIntervalEXT (dpy, wid, flag ? 1 : 0 );
92- std::cout << " setSyncToVBlank: " << (flag ? " enabled" : " disabled" ) << " for XScreen " << screenNumber << std::endl;
93132#endif
94133}
0 commit comments