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 
42 static const wxChar* const traceGalOpenGlError = wxT( "KICAD_GAL_OPENGL_ERROR" );
43 
44 
45 int 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 )
167 static 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 
183 void 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 }
static const wxChar *const traceGalOpenGlError
Flag to enable debug output of the GAL OpenGL error checking.
Definition: utils.cpp:42
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:292
static void GLAPIENTRY debugMsgCallback(GLenum aSource, GLenum aType, GLuint aId, GLenum aSeverity, GLsizei aLength, const GLchar *aMessage, const void *aUserParam)
Definition: utils.cpp:167
This file is part of the common library.
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
void enableGlDebug(bool aEnable)
Enable or disable OpenGL driver messages output.
Definition: utils.cpp:183
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