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 <maciej.suminski@cern.ch>
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 
35 int checkGlError( const std::string& aInfo, bool aThrow )
36 {
37  int result = glGetError();
38  wxString errorMsg;
39 
40  switch( result )
41  {
42  case GL_NO_ERROR:
43  // all good
44  break;
45 
46  case GL_INVALID_ENUM:
47  errorMsg = wxString::Format( "Error: %s: invalid enum", aInfo );
48  break;
49 
50  case GL_INVALID_VALUE:
51  errorMsg = wxString::Format( "Error: %s: invalid value", aInfo );
52  break;
53 
54  case GL_INVALID_OPERATION:
55  errorMsg = wxString::Format( "Error: %s: invalid operation", aInfo );
56  break;
57 
58  case GL_INVALID_FRAMEBUFFER_OPERATION:
59  {
60  GLenum status = glCheckFramebufferStatusEXT( GL_FRAMEBUFFER_EXT );
61 
62  if( status != GL_FRAMEBUFFER_COMPLETE_EXT )
63  {
64  switch( status )
65  {
66  case GL_FRAMEBUFFER_INCOMPLETE_ATTACHMENT_EXT:
67  errorMsg = "The framebuffer attachment points are incomplete.";
68  break;
69 
70  case GL_FRAMEBUFFER_INCOMPLETE_MISSING_ATTACHMENT_EXT:
71  errorMsg = "No images attached to the framebuffer.";
72  break;
73 
74  case GL_FRAMEBUFFER_INCOMPLETE_DRAW_BUFFER_EXT:
75  errorMsg = "The framebuffer does not have at least one image attached to it.";
76  break;
77 
78  case GL_FRAMEBUFFER_INCOMPLETE_READ_BUFFER_EXT:
79  errorMsg = "The framebuffer read buffer is incomplete.";
80  break;
81 
82  case GL_FRAMEBUFFER_UNSUPPORTED_EXT:
83  errorMsg = "The combination of internal formats of the attached images violates an "
84  "implementation dependent set of restrictions.";
85  break;
86 
87  case GL_FRAMEBUFFER_INCOMPLETE_MULTISAMPLE_EXT:
88  errorMsg =
89  "GL_RENDERBUFFER_SAMPLES is not the same for all attached render buffers.";
90  break;
91 
92  case GL_FRAMEBUFFER_INCOMPLETE_LAYER_TARGETS_EXT:
93  errorMsg = "Framebuffer incomplete layer targets errors.";
94  break;
95 
96  case GL_FRAMEBUFFER_INCOMPLETE_DIMENSIONS_EXT:
97  errorMsg = "Framebuffer attachments have different dimensions";
98  break;
99 
100  default:
101  errorMsg.Printf( "Unknown incomplete framebuffer error id %X", status );
102  }
103  }
104  else
105  {
106  errorMsg = wxString::Format( "Error: %s: invalid framebuffer operation", aInfo );
107  }
108  }
109  break;
110 
111  case GL_OUT_OF_MEMORY:
112  errorMsg = wxString::Format( "Error: %s: out of memory", aInfo );
113  break;
114 
115  case GL_STACK_UNDERFLOW:
116  errorMsg = wxString::Format( "Error: %s: stack underflow", aInfo );
117  break;
118 
119  case GL_STACK_OVERFLOW:
120  errorMsg = wxString::Format( "Error: %s: stack overflow", aInfo );
121  break;
122 
123  default:
124  errorMsg = wxString::Format( "Error: %s: unknown error", aInfo );
125  break;
126  }
127 
128  if( result != GL_NO_ERROR )
129  {
130  if( aThrow )
131  throw std::runtime_error( (const char*) errorMsg.char_str() );
132  else
133  DisplayErrorMessage( nullptr, "OpenGL error occurred", errorMsg );
134  }
135 
136  return result;
137 }
138 
139 
140 // debugMsgCallback is a callback function for glDebugMessageCallback.
141 // It must have the right type ( GLAPIENTRY )
142 static void GLAPIENTRY debugMsgCallback( GLenum aSource, GLenum aType, GLuint aId, GLenum aSeverity,
143  GLsizei aLength, const GLchar* aMessage,
144  const void* aUserParam )
145 {
146  switch( aSeverity )
147  {
148  case GL_DEBUG_SEVERITY_HIGH: wxLogDebug( "OpenGL ERROR: " ); break;
149  case GL_DEBUG_SEVERITY_MEDIUM: wxLogDebug( "OpenGL WARNING: " ); break;
150  case GL_DEBUG_SEVERITY_LOW: wxLogDebug( "OpenGL INFO: " ); break;
151  case GL_DEBUG_SEVERITY_NOTIFICATION: return;
152  }
153 
154  wxLogDebug( "%s\n", aMessage );
155 }
156 
157 
158 void enableGlDebug( bool aEnable )
159 {
160  if( aEnable )
161  {
162  glEnable( GL_DEBUG_OUTPUT );
163  glDebugMessageCallback( (GLDEBUGPROC) debugMsgCallback, nullptr );
164  }
165  else
166  {
167  glDisable( GL_DEBUG_OUTPUT );
168  }
169 }
void DisplayErrorMessage(wxWindow *aParent, const wxString &aText, const wxString &aExtraInfo)
Display an error message with aMessage.
Definition: confirm.cpp:266
static void GLAPIENTRY debugMsgCallback(GLenum aSource, GLenum aType, GLuint aId, GLenum aSeverity, GLsizei aLength, const GLchar *aMessage, const void *aUserParam)
Definition: utils.cpp:142
This file is part of the common library.
int checkGlError(const std::string &aInfo, bool aThrow)
Checks if one of recent OpenGL operations has failed.
Definition: utils.cpp:35
void enableGlDebug(bool aEnable)
Enables/disables OpenGL driver messages output.
Definition: utils.cpp:158
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