IVL was designed to allow applications to achieve maximum performance. One
such area is in the handling of error conditions. The error checking
philosophy of IVL is fairly simple. IVL assumes that correctly working
programs will pass valid parameter values. Exhaustive checking of all
parameter values is usually only helpful when developing and debugging code.
Such error checking would adversely impact the performance of an application
that was fully debugged and working properly. Therefore, primarily for
performance reasons, IVL error checking is kept to a minimum. More exhaustive
error checking can be performed by the application prior to calling IVL
routines.
The goal of the IVL error semantics is to perform the minimum amount of error
checking necessary to ensure that programs can continue to operate in a
reasonable fashion (e.g., the program will not hang or crash the operating
system). When an error is detected by IVL, the error value is recorded. The
current error value is part of the current state and can be queried with the
glGetError routine.
When an error occurs (indicated by setting the error value to something other
than GL_NO_ERROR), no further errors are recorded until glGetError is
called. The act of querying the current error value has the side effect of
resetting the error value to GL_NO_ERROR in preparation for recording the
next error.
If glGetError returns GL_NO_ERROR, then there have been no detectable
errors since the last call to glGetError. The reference pages for each
individual IVL routine describe errors that can be generated by that
particular routine.
The following table describes the defined error values. The results of a
routine are undefined only if the GL_OUT_OF_MEMORY error occurs. For all
other errors, the offending routine is ignored and has no effect on the
current state or the contents of the frame buffer.
If the routine that generates the error returns a value, it will return zero.
If the routine that generates the error modifies values through a pointer
argument, no change is made to these values. The fact that the offending
routine is ignored can sometimes lead to mysterious program behavior. If your
program seems to ignore some routines, insert calls to glGetError to
ensure that no errors are occurring:
If IVL is implemented in a distributed (i.e., client/server) fashion, there
may be more than one error value. To query and reset all the error values, you
should call glGetError within a loop until a value of GL_NO_ERROR is
returned. For each call to glGetError, one error value that is something
other than GL_NO_ERROR will be returned and its value will be reset to
GL_NO_ERROR.
It is a good idea to check the status of the current error value frequently in
order to determine whether any errors have occurred. A good way to do this is
to define a routine that checks for errors and then call this routine at the
end of each rendering loop. For example:
{
/* start of main rendering loop */
/* ... */
/* ... */
/* end of main rendering loop */
CheckForErrors ();
}
/************************************************************************/
static void CheckForErrors(void)
{
int i;
int gotError;
gotError = FALSE;
while (i = glGetError())
{
gotError = TRUE;
fprintf(stderr, "Error: 0x%xn", i);
process_error (i);
}
if (gotError)
exit (1);
}
|
The disadvantage to this approach is that a number of pixel processing
operations may occur before you check for errors. If this happens, it may be
necessary to repeat the rendering operations after detecting and correcting the
error.
Although the goal of IVL is to detect errors that would cause a fatal
exception, there are some conditions under which a fatal exception might
happen. If a sequence of floating point computations occurs (such as in the
image transformation computation) with very large values (e.g.,
MAX_FLOAT), it is possible for an application to produce a floating
point overflow exception.
Since such large data values are not likely to be produced by a properly
working application, and since preventing this type of condition would be
difficult and would penalize the performance of properly working applications,
this condition may result in a floating point exception. It is the
responsibility of the application to provide values that are well within the
range of floating point computation limits.