KiCad PCB EDA Suite
utils.cpp
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 (C) 2016-2017 CERN
5 * Copyright (C) 2021 KiCad Developers, see AUTHORS.txt for contributors.
6 *
7 * @author Maciej Suminski <[email protected]>
8 *
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU General Public License
11 * as published by the Free Software Foundation; either version 2
12 * of the License, or (at your option) any later version.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License
20 * along with this program; if not, you may find one here:
21 * http://www.gnu.org/licenses/old-licenses/gpl-2.0.html
22 * or you may search the http://www.gnu.org website for the version 2 license,
23 * or you may write to the Free Software Foundation, Inc.,
24 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA
25 */
26
27#include <confirm.h> // DisplayError
28
29#include <gal/opengl/kiglew.h> // Must be included first
30
31#include <stdexcept>
32#include <wx/log.h> // wxLogDebug
33
34
42static const wxChar* const traceGalOpenGlError = wxT( "KICAD_GAL_OPENGL_ERROR" );
43
44
45int checkGlError( const std::string& aInfo, const char* aFile, int aLine, bool aThrow )
46{
47 int result = glGetError();
48 wxString errorMsg;
49
50 switch( result )
51 {
52 case GL_NO_ERROR:
53 // all good
54 break;
55
56 case GL_INVALID_ENUM:
57 errorMsg = wxString::Format( "Error: %s: invalid enum", aInfo );
58 break;
59
60 case GL_INVALID_VALUE:
61 errorMsg = wxString::Format( "Error: %s: invalid value", aInfo );
62 break;
63
64 case GL_INVALID_OPERATION:
65 errorMsg = wxString::Format( "Error: %s: invalid operation", aInfo );
66 break;
67
68 case GL_INVALID_FRAMEBUFFER_OPERATION:
69 {
70 GLenum status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
71
72 if( status != GL_FRAMEBUFFER_COMPLETE_EXT )
73 {
74 switch( status )
75 {
76 case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
77 errorMsg = "The framebuffer attachment points are incomplete.";
78 break;
79
80 case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
81 errorMsg = "No images attached to the framebuffer.";
82 break;
83
84 case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
85 errorMsg = "The framebuffer does not have at least one image attached to it.";
86 break;
87
88 case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
89 errorMsg = "The framebuffer read buffer is incomplete.";
90 break;
91
92 case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
93 errorMsg = "The combination of internal formats of the attached images violates "
94 "an implementation dependent set of restrictions.";
95 break;
96
97 case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT:
98 errorMsg = "GL_RENDERBUFFER_SAMPLES is not the same for all attached render "
99 "buffers.";
100 break;
101
102 case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT:
103 errorMsg = "Framebuffer incomplete layer targets errors.";
104 break;
105
106 case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
107 errorMsg = "Framebuffer attachments have different dimensions";
108 break;
109
110 default:
111 errorMsg.Printf( "Unknown incomplete framebuffer error id %X", status );
112 }
113 }
114 else
115 {
116 errorMsg = wxString::Format( "Error: %s: invalid framebuffer operation", aInfo );
117 }
118 }
119 break;
120
121 case GL_OUT_OF_MEMORY:
122 errorMsg = wxString::Format( "Error: %s: out of memory", aInfo );
123 break;
124
125 case GL_STACK_UNDERFLOW:
126 errorMsg = wxString::Format( "Error: %s: stack underflow", aInfo );
127 break;
128
129 case GL_STACK_OVERFLOW:
130 errorMsg = wxString::Format( "Error: %s: stack overflow", aInfo );
131 break;
132
133 default:
134 errorMsg = wxString::Format( "Error: %s: unknown error", aInfo );
135 break;
136 }
137
138 if( result != GL_NO_ERROR )
139 {
140 if( aThrow )
141 {
142 wxLogTrace( traceGalOpenGlError, wxT( "Throwing exception for glGetError() '%s' "
143 "in file '%s' on line %d." ),
144 errorMsg,
145 aFile,
146 aLine );
147
148 throw std::runtime_error( (const char*) errorMsg.char_str() );
149 }
150 else
151 {
152 wxString msg = wxString::Format( wxT( "glGetError() '%s' in file '%s' on line %d." ),
153 errorMsg,
154 aFile,
155 aLine );
156
157 DisplayErrorMessage( nullptr, "OpenGL Error", errorMsg );
158 }
159 }
160
161 return result;
162}
163
164
165// debugMsgCallback is a callback function for glDebugMessageCallback.
166// It must have the right type ( GLAPIENTRY )
167static void GLAPIENTRY debugMsgCallback( GLenum aSource, GLenum aType, GLuint aId, GLenum aSeverity,
168 GLsizei aLength, const GLchar* aMessage,
169 const void* aUserParam )
170{
171 switch( aSeverity )
172 {
173 case GL_DEBUG_SEVERITY_HIGH: wxLogDebug( "OpenGL ERROR: " ); break;
174 case GL_DEBUG_SEVERITY_MEDIUM: wxLogDebug( "OpenGL WARNING: " ); break;
175 case GL_DEBUG_SEVERITY_LOW: wxLogDebug( "OpenGL INFO: " ); break;
176 case GL_DEBUG_SEVERITY_NOTIFICATION: return;
177 }
178
179 wxLogDebug( "%s\n", aMessage );
180}
181
182
183void enableGlDebug( bool aEnable )
184{
185 if( aEnable )
186 {
187 glEnable( GL_DEBUG_OUTPUT );
188 glDebugMessageCallback( (GLDEBUGPROC) debugMsgCallback, nullptr );
189 }
190 else
191 {
192 glDisable( GL_DEBUG_OUTPUT );
193 }
194}
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:325
This file is part of the common library.
static const wxChar *const traceGalOpenGlError
Flag to enable debug output of the GAL OpenGL error checking.
Definition: utils.cpp:42
void Format(OUTPUTFORMATTER *out, int aNestLevel, int aCtl, const CPTREE &aTree)
Output a PTREE into s-expression format via an OUTPUTFORMATTER derivative.
Definition: ptree.cpp:200
void enableGlDebug(bool aEnable)
Enable or disable OpenGL driver messages output.
Definition: utils.cpp:183
static void GLAPIENTRY debugMsgCallback(GLenum aSource, GLenum aType, GLuint aId, GLenum aSeverity, GLsizei aLength, const GLchar *aMessage, const void *aUserParam)
Definition: utils.cpp:167
int checkGlError(const std::string &aInfo, const char *aFile, int aLine, bool aThrow)
Check if a recent OpenGL operation has failed.
Definition: utils.cpp:45