KiCad PCB EDA Suite
Loading...
Searching...
No Matches
gl_utils.h
Go to the documentation of this file.
1/*
2 * This program source code file is part of KiCad, a free EDA CAD application.
3 *
4 * Copyright The KiCad Developers, see AUTHORS.txt for contributors
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, you may find one here:
18 * http://www.gnu.org/licenses/old-licenses/gpl-3.0.html
19 * or you may search the http://www.gnu.org website for the version 3 license,
20 * or you may write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
22 */
23
24#ifndef GL_UTILS_H
25#define GL_UTILS_H
26
27#include <gal/opengl/kiglew.h> // Must be included first
28#include <wx/version.h>
29#include <wx/glcanvas.h>
30#include <wx/utils.h>
31
33{
34public:
35
36 static wxString DetectGLBackend( wxGLCanvas* aCanvas )
37 {
38 wxString backend;
39
40#ifdef __WXGTK__
41 #if wxCHECK_VERSION( 3, 3, 2 )
42 int eglMajor = 0, eglMinor = 0;
43
44 if( aCanvas->GetEGLVersion( &eglMajor, &eglMinor ) )
45 backend = wxString::Format( "EGL %d.%d", eglMajor, eglMinor );
46 else if( int glxVersion = aCanvas->GetGLXVersion() )
47 backend = wxString::Format( "GLX %d.%d", glxVersion / 10, glxVersion % 10 );
48
49 #else // !wxCHECK_VERSION( 3, 3, 2 )
50 #if wxUSE_GLCANVAS_EGL
51 backend = "EGL";
52 #else
53 if( int glxVersion = aCanvas->GetGLXVersion() )
54 backend = wxString::Format( "GLX %d.%d", glxVersion / 10, glxVersion % 10 );
55 #endif
56
57 #endif // !wxCHECK_VERSION( 3, 3, 2 )
58#endif // __WXGTK__
59
60 return backend;
61 }
62
63#if !wxCHECK_VERSION( 3, 3, 3 )
70 static int SetSwapInterval( int aVal )
71 {
72#if ( defined( __linux__ ) || defined( __FreeBSD__ ) ) && !defined( KICAD_USE_EGL )
73
74 if( Display* dpy = glXGetCurrentDisplay() )
75 {
76 GLXDrawable drawable = glXGetCurrentDrawable();
77
78 std::string exts( glXQueryExtensionsString( dpy, DefaultScreen( dpy ) ) );
79
80 if( glXSwapIntervalEXT && glXQueryDrawable && drawable
81 && exts.find( "GLX_EXT_swap_control" ) != std::string::npos )
82 {
83 if( aVal == -1 && exts.find( "GLX_EXT_swap_control_tear" ) == std::string::npos )
84 aVal = 1; // Late swaps not available
85
86 unsigned clampedInterval;
87 glXSwapIntervalEXT( dpy, drawable, aVal );
88 glXQueryDrawable( dpy, drawable, GLX_SWAP_INTERVAL_EXT, &clampedInterval );
89
90 if( aVal == -1 )
91 {
92 unsigned lateSwapsEnabled = 0;
93 glXQueryDrawable( dpy, drawable, GLX_LATE_SWAPS_TEAR_EXT, &lateSwapsEnabled );
94
95 if( lateSwapsEnabled )
96 clampedInterval = -1;
97 }
98
99 return clampedInterval;
100 }
101
102 if( glXSwapIntervalMESA && glXGetSwapIntervalMESA
103 && exts.find( "GLX_MESA_swap_control" ) != std::string::npos )
104 {
105 if( aVal == -1 )
106 aVal = 1;
107
108 if( !glXSwapIntervalMESA( aVal ) )
109 return aVal;
110 }
111
112 if( glXSwapIntervalSGI && exts.find( "GLX_SGI_swap_control" ) != std::string::npos )
113 {
114 if( aVal == -1 )
115 aVal = 1;
116
117 if( !glXSwapIntervalSGI( aVal ) )
118 return aVal;
119 }
120 }
121
122#elif defined( _WIN32 )
123
124 const GLubyte* vendor = glGetString( GL_VENDOR );
125 const GLubyte* version = glGetString( GL_VERSION );
126
127 if( wglSwapIntervalEXT && wxGLCanvas::IsExtensionSupported( "WGL_EXT_swap_control" ) )
128 {
129 wxString vendorStr = vendor;
130 wxString versionStr = version;
131
132 if( aVal == -1 && ( !wxGLCanvas::IsExtensionSupported( "WGL_EXT_swap_control_tear" ) ) )
133 aVal = 1;
134
135 // Trying to enable adaptive swapping on AMD drivers from 2017 or older leads to crash
136 if( aVal == -1 && vendorStr == wxS( "ATI Technologies Inc." ) )
137 {
138 wxArrayString parts = wxSplit( versionStr.AfterLast( ' ' ), '.', 0 );
139
140 if( parts.size() == 4 )
141 {
142 long majorVer = 0;
143
144 if( parts[0].ToLong( &majorVer ) )
145 {
146 if( majorVer <= 22 )
147 aVal = 1;
148 }
149 }
150 }
151
152 HDC hdc = wglGetCurrentDC();
153 HGLRC hglrc = wglGetCurrentContext();
154
155 if( hdc && hglrc )
156 {
157 int currentInterval = wglGetSwapIntervalEXT();
158
159 if( currentInterval != aVal )
160 {
161 wglSwapIntervalEXT( aVal );
162 currentInterval = wglGetSwapIntervalEXT();
163 }
164
165 return currentInterval;
166 }
167 }
168
169#endif
170 return 0;
171 }
172#endif /* !wxCHECK_VERSION( 3, 3, 3 ) */
173
174};
175
176#endif /* GL_CONTEXT_MANAGER_H */
static wxString DetectGLBackend(wxGLCanvas *aCanvas)
Definition gl_utils.h:36
static int SetSwapInterval(int aVal)
Attempt to set the OpenGL swap interval.
Definition gl_utils.h:70