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_glew.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_TABLE_TOO_LARGE:
78  return "Table too large";
79  case GL_INVALID_FRAMEBUFFER_OPERATION_EXT:
80  return "Invalid framebuffer operation";
81 #endif
82  }
83  return "Unknown error";
84 }
85 
94 #if defined(VTK_REPORT_OPENGL_ERRORS)
95 inline
97  int maxNum,
98  unsigned int *errCode,
99  const char **errDesc)
100 {
101  int i = 0;
102  GLenum code = glGetError();
103  if (i < maxNum)
104  {
105  errCode[i] = static_cast<unsigned int>(code);
106  errDesc[i] = vtkOpenGLStrError(code);
107  }
108  while (code != GL_NO_ERROR && i < maxNum)
109  {
110  i++;
111  code = glGetError();
112  if (i < maxNum)
113  {
114  errCode[i] = static_cast<unsigned int>(code);
115  errDesc[i] = vtkOpenGLStrError(code);
116  }
117  }
118  return i;
119 }
120 #else
121 inline
123  int maxNum,
124  unsigned int *errCode,
125  const char **errDesc)
126 {
127  (void)maxNum;
128  (void)errCode;
129  (void)errDesc;
130  return 0;
131 }
132 #endif
133 
140 #if defined(VTK_REPORT_OPENGL_ERRORS)
141 inline
143  ostream &os,
144  int maxErrors,
145  int numErrors,
146  unsigned int *errCode,
147  const char **errDesc)
148 {
149  os << numErrors << " OpenGL errors detected" << std::endl;
150  for (int i=0; (i<numErrors)&&(i<maxErrors); ++i)
151  {
152  os << " " << i << " : (" << errCode[i] << ") " << errDesc[i] << std::endl;
153  }
154  if (numErrors>maxErrors)
155  {
156  os
157  << "More than " << maxErrors
158  << " detected! The remainder are not reported"
159  << std::endl;
160  }
161 }
162 #else
163 inline
165  ostream &os,
166  int maxErrors,
167  int numErrors,
168  unsigned int *errCode,
169  const char **errDesc)
170 {
171  (void)os;
172  (void)maxErrors;
173  (void)numErrors;
174  (void)errCode;
175  (void)errDesc;
176 }
177 #endif
178 
184 #if defined(VTK_REPORT_OPENGL_ERRORS)
185 inline
186 bool vtkOpenGLCheckErrors(const char* headerMessage = "")
187 {
188  const int maxNumErrors = 16;
189  unsigned int errCode[maxNumErrors] = {0};
190  const char* errDesc[maxNumErrors] = {nullptr};
191  int numErrors = vtkGetOpenGLErrors(maxNumErrors, errCode, errDesc);
192  if (numErrors > 0)
193  {
194  std::ostringstream oss;
195  vtkPrintOpenGLErrors(oss, maxNumErrors, numErrors, errCode, errDesc);
196  vtkGenericWarningMacro(<< headerMessage << oss.str());
197  return false;
198  }
199  return true;
200 }
201 #else
202 inline
203 bool vtkOpenGLCheckErrors(const char* errorMessage = "")
204 {
205  (void)errorMessage;
206  return true;
207 }
208 #endif
209 
213 #if defined(VTK_REPORT_OPENGL_ERRORS)
214 inline
215 void vtkClearOpenGLErrors(const unsigned int maxErrors = 16)
216 {
217  GLenum glError;
218  unsigned int i = 0;
219  do
220  {
221  glError = glGetError();
222  ++i;
223  }
224  while(i < maxErrors && glError != GL_NO_ERROR);
225 }
226 #else
227 inline
228 void vtkClearOpenGLErrors(const unsigned int maxErrors = 16)
229 {
230  (void) maxErrors;
231 }
232 #endif
233 
234 #if !defined(VTK_REPORT_OPENGL_ERRORS)
235 # define vtkOpenGLClearErrorMacro()
236 # define vtkOpenGLCheckErrorMacro(message)
237 # define vtkOpenGLStaticCheckErrorMacro(message)
238 #else
239 # define vtkOpenGLClearErrorMacro() vtkClearOpenGLErrors(16);
240 # include <sstream> // for error macro
241 # define vtkOpenGLCheckErrorMacroImpl(ostr, message) \
242 do \
243 { \
244  const int maxErrors = 16; \
245  unsigned int errCode[maxErrors] = {0}; \
246  const char *errDesc[maxErrors] = {nullptr}; \
247  \
248  int numErrors \
249  = vtkGetOpenGLErrors( \
250  maxErrors, \
251  errCode, \
252  errDesc); \
253  \
254  if (numErrors) \
255  { \
256  std::ostringstream oss; \
257  vtkPrintOpenGLErrors( \
258  oss, \
259  maxErrors, \
260  numErrors, \
261  errCode, \
262  errDesc); \
263  \
264  ostr(<< message << " " << oss.str()); \
265  } \
266 } while(false)
267 # define vtkOpenGLCheckErrorMacro(message) \
268  vtkOpenGLCheckErrorMacroImpl(vtkErrorMacro, message)
269 # define vtkOpenGLStaticCheckErrorMacro(message) \
270  vtkOpenGLCheckErrorMacroImpl(vtkGenericWarningMacro, message)
271 #endif
272 
273 // Use this macro for fine grained error checking during
274 // debugging. It is removed for Release builds.
275 #ifdef NDEBUG
276 # define vtkOpenGLDebugClearErrorMacro()
277 # define vtkOpenGLDebugCheckErrorMacro(message)
278 #else
279 # define vtkOpenGLDebugClearErrorMacro() \
280  vtkOpenGLClearErrorMacro()
281 # define vtkOpenGLDebugCheckErrorMacro(message) \
282  vtkOpenGLStaticCheckErrorMacro(message)
283 #endif
284 
286 #endif
287 // 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.