vtkOpenGLError.h
Go to the documentation of this file.
1 // SPDX-FileCopyrightText: Copyright (c) Ken Martin, Will Schroeder, Bill Lorensen
2 // SPDX-License-Identifier: BSD-3-Clause
3 #ifndef vtkOpenGLError_h
4 #define vtkOpenGLError_h
5 
6 #include "vtkSetGet.h"
7 #include "vtk_glad.h"
8 #include <sstream>
9 
10 #ifndef NDEBUG
11 // debug build.
12 #define VTK_REPORT_OPENGL_ERRORS
13 #else // NDEBUG
14 // release build
15 /* #undef VTK_REPORT_OPENGL_ERRORS_IN_RELEASE_BUILDS */
16 #if defined(VTK_REPORT_OPENGL_ERRORS_IN_RELEASE_BUILDS)
17 #define VTK_REPORT_OPENGL_ERRORS
18 #endif // defined(VTK_REPORT_OPENGL_ERRORS_IN_RELEASE_BUILDS)
19 #endif // NDEBUG
20 
57 inline
58 const char *vtkOpenGLStrError(unsigned int code)
59 {
60  switch(static_cast<GLenum>(code))
61  {
62  case GL_NO_ERROR:
63  return "No error";
64  case GL_INVALID_ENUM:
65  return "Invalid enum";
66  case GL_INVALID_VALUE:
67  return "Invalid value";
68  case GL_INVALID_OPERATION:
69  return "Invalid operation";
70  case GL_OUT_OF_MEMORY:
71  return "Out of memory";
72 #ifndef GL_ES_VERSION_3_0
73  case GL_STACK_OVERFLOW:
74  return "Stack overflow";
75  case GL_STACK_UNDERFLOW:
76  return "Stack underflow";
77  case GL_INVALID_FRAMEBUFFER_OPERATION:
78  return "Invalid framebuffer operation";
79 #endif
80  }
81  return "Unknown error";
82 }
83 
92 #if defined(VTK_REPORT_OPENGL_ERRORS)
93 inline
95  int maxNum,
96  unsigned int *errCode,
97  const char **errDesc)
98 {
99  int i = 0;
100  GLenum code = glGetError();
101  if (i < maxNum)
102  {
103  errCode[i] = static_cast<unsigned int>(code);
104  errDesc[i] = vtkOpenGLStrError(code);
105  }
106  while (code != GL_NO_ERROR && i < maxNum)
107  {
108  i++;
109  code = glGetError();
110  if (i < maxNum)
111  {
112  errCode[i] = static_cast<unsigned int>(code);
113  errDesc[i] = vtkOpenGLStrError(code);
114  }
115  }
116  return i;
117 }
118 #else
119 inline
121  int maxNum,
122  unsigned int *errCode,
123  const char **errDesc)
124 {
125  (void)maxNum;
126  (void)errCode;
127  (void)errDesc;
128  return 0;
129 }
130 #endif
131 
138 #if defined(VTK_REPORT_OPENGL_ERRORS)
139 inline
141  ostream &os,
142  int maxErrors,
143  int numErrors,
144  unsigned int *errCode,
145  const char **errDesc)
146 {
147  os << numErrors << " OpenGL errors detected" << std::endl;
148  for (int i=0; (i<numErrors)&&(i<maxErrors); ++i)
149  {
150  os << " " << i << " : (" << errCode[i] << ") " << errDesc[i] << std::endl;
151  }
152  if (numErrors>maxErrors)
153  {
154  os
155  << "More than " << maxErrors
156  << " detected! The remainder are not reported"
157  << std::endl;
158  }
159 }
160 #else
161 inline
163  ostream &os,
164  int maxErrors,
165  int numErrors,
166  unsigned int *errCode,
167  const char **errDesc)
168 {
169  (void)os;
170  (void)maxErrors;
171  (void)numErrors;
172  (void)errCode;
173  (void)errDesc;
174 }
175 #endif
176 
182 #if defined(VTK_REPORT_OPENGL_ERRORS)
183 inline
184 bool vtkOpenGLCheckErrors(const char* headerMessage = "")
185 {
186  const int maxNumErrors = 16;
187  unsigned int errCode[maxNumErrors] = {0};
188  const char* errDesc[maxNumErrors] = {nullptr};
189  int numErrors = vtkGetOpenGLErrors(maxNumErrors, errCode, errDesc);
190  if (numErrors > 0)
191  {
192  std::ostringstream oss;
193  vtkPrintOpenGLErrors(oss, maxNumErrors, numErrors, errCode, errDesc);
194  vtkGenericWarningMacro(<< headerMessage << oss.str());
195  return false;
196  }
197  return true;
198 }
199 #else
200 inline
201 bool vtkOpenGLCheckErrors(const char* errorMessage = "")
202 {
203  (void)errorMessage;
204  return true;
205 }
206 #endif
207 
211 #if defined(VTK_REPORT_OPENGL_ERRORS)
212 inline
213 void vtkClearOpenGLErrors(const unsigned int maxErrors = 16)
214 {
215  GLenum glError;
216  unsigned int i = 0;
217  do
218  {
219  glError = glGetError();
220  ++i;
221  }
222  while(i < maxErrors && glError != GL_NO_ERROR);
223 }
224 #else
225 inline
226 void vtkClearOpenGLErrors(const unsigned int maxErrors = 16)
227 {
228  (void) maxErrors;
229 }
230 #endif
231 
232 #if !defined(VTK_REPORT_OPENGL_ERRORS)
233 # define vtkOpenGLClearErrorMacro() do {} while (false)
234 # define vtkOpenGLCheckErrorMacro(message)
235 # define vtkOpenGLStaticCheckErrorMacro(message)
236 #else
237 #define vtkOpenGLClearErrorMacro() \
238  do \
239  { \
240  vtkClearOpenGLErrors(16); \
241  } \
242  while (false)
243 # include <sstream> // for error macro
244 # define vtkOpenGLCheckErrorMacroImpl(ostr, message) \
245 do \
246 { \
247  const int maxErrors = 16; \
248  unsigned int errCode[maxErrors] = {0}; \
249  const char *errDesc[maxErrors] = {nullptr}; \
250  \
251  int numErrors \
252  = vtkGetOpenGLErrors( \
253  maxErrors, \
254  errCode, \
255  errDesc); \
256  \
257  if (numErrors) \
258  { \
259  std::ostringstream oss; \
260  vtkPrintOpenGLErrors( \
261  oss, \
262  maxErrors, \
263  numErrors, \
264  errCode, \
265  errDesc); \
266  \
267  ostr(<< message << " " << oss.str()); \
268  } \
269 } while(false)
270 # define vtkOpenGLCheckErrorMacro(message) \
271  vtkOpenGLCheckErrorMacroImpl(vtkErrorMacro, message)
272 # define vtkOpenGLStaticCheckErrorMacro(message) \
273  vtkOpenGLCheckErrorMacroImpl(vtkGenericWarningMacro, message)
274 #endif
275 
276 // Use this macro for fine grained error checking during
277 // debugging. It is removed for Release builds.
278 #ifdef NDEBUG
279 # define vtkOpenGLDebugClearErrorMacro()
280 # define vtkOpenGLDebugCheckErrorMacro(message)
281 #else
282 # define vtkOpenGLDebugClearErrorMacro() \
283  vtkOpenGLClearErrorMacro()
284 # define vtkOpenGLDebugCheckErrorMacro(message) \
285  vtkOpenGLStaticCheckErrorMacro(message)
286 #endif
287 
289 #endif
290 // VTK-HeaderTest-Exclude: vtkOpenGLError.h
void vtkClearOpenGLErrors(const unsigned int maxErrors=16)
Clear OpenGL&#39;s error flags.
VTK_ABI_NAMESPACE_BEGIN const char * vtkOpenGLStrError(unsigned int code)
The following functions can be used to detect and report, and/or silently clear OpenGL error flags...
#define VTK_ABI_NAMESPACE_END
bool vtkOpenGLCheckErrors(const char *headerMessage="")
Errors are queried and reported via vtkGenericWarningMacro.
#define VTK_ABI_NAMESPACE_BEGIN
int vtkGetOpenGLErrors(int maxNum, unsigned int *errCode, const char **errDesc)
Check for OpenGL errors.
void vtkPrintOpenGLErrors(ostream &os, int maxErrors, int numErrors, unsigned int *errCode, const char **errDesc)
Send a set of errors collected by GetOpenGLErrors to the give stream.