Fixed bug 1584 - Improved glError checks in the opengl renderer

Martin Gerhardy 2012-08-27 02:42:25 PDT

I've extended the gl error checks.

This is needed because on my system there are errors in the renderer that are
hard to find.

Also glError can return multiple errors. Even if SDL_SetError would only
contain the last one of course, the SDL log facilities are able to get the
output for each error.
This commit is contained in:
Sam Lantinga 2012-09-28 03:49:27 -07:00
parent 400b953d29
commit c328979f60

View file

@ -150,43 +150,51 @@ typedef struct
GL_FBOList *fbo; GL_FBOList *fbo;
} GL_TextureData; } GL_TextureData;
static inline const char*
static void GL_TranslateError (GLenum error)
GL_SetError(const char *prefix, GLenum result)
{ {
const char *error; #define GL_ERROR_TRANSLATE(e) case e: return #e;
switch (error) {
switch (result) { GL_ERROR_TRANSLATE(GL_INVALID_ENUM)
case GL_NO_ERROR: GL_ERROR_TRANSLATE(GL_INVALID_VALUE)
error = "GL_NO_ERROR"; GL_ERROR_TRANSLATE(GL_INVALID_OPERATION)
break; GL_ERROR_TRANSLATE(GL_OUT_OF_MEMORY)
case GL_INVALID_ENUM: GL_ERROR_TRANSLATE(GL_NO_ERROR)
error = "GL_INVALID_ENUM"; GL_ERROR_TRANSLATE(GL_STACK_OVERFLOW)
break; GL_ERROR_TRANSLATE(GL_STACK_UNDERFLOW)
case GL_INVALID_VALUE: GL_ERROR_TRANSLATE(GL_TABLE_TOO_LARGE)
error = "GL_INVALID_VALUE";
break;
case GL_INVALID_OPERATION:
error = "GL_INVALID_OPERATION";
break;
case GL_STACK_OVERFLOW:
error = "GL_STACK_OVERFLOW";
break;
case GL_STACK_UNDERFLOW:
error = "GL_STACK_UNDERFLOW";
break;
case GL_OUT_OF_MEMORY:
error = "GL_OUT_OF_MEMORY";
break;
case GL_TABLE_TOO_LARGE:
error = "GL_TABLE_TOO_LARGE";
break;
default: default:
error = "UNKNOWN"; return "UNKNOWN";
break;
}
SDL_SetError("%s: %s", prefix, error);
} }
#undef GL_ERROR_TRANSLATE
}
static __inline__ int
GL_CheckAllErrors (const char *prefix, SDL_Renderer * renderer, const char *file, int line, const char *function)
{
GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
int ret = 0;
/* check gl errors (can return multiple errors) */
for (;;) {
GLenum error = data->glGetError();
if (error != GL_NO_ERROR) {
if (prefix == NULL || prefix[0] == '\0') {
prefix = "generic";
}
SDL_SetError("%s: %s (%d): %s %s (0x%X)", prefix, file, line, function, GL_TranslateError(error), error);
ret++;
} else {
break;
}
}
return ret;
}
#if 1
#define GL_CheckError(prefix, renderer) GL_CheckAllErrors(prefix, renderer, __FILE__, __LINE__, __PRETTY_FUNCTION__)
#else
#define GL_CheckError(prefix, renderer)
#endif
static int static int
GL_LoadFunctions(GL_RenderData * data) GL_LoadFunctions(GL_RenderData * data)
@ -250,6 +258,8 @@ GL_ResetState(SDL_Renderer *renderer)
data->glMatrixMode(GL_MODELVIEW); data->glMatrixMode(GL_MODELVIEW);
data->glLoadIdentity(); data->glLoadIdentity();
GL_CheckError("", renderer);
} }
@ -483,7 +493,6 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
GLenum format, type; GLenum format, type;
int texture_w, texture_h; int texture_w, texture_h;
GLenum scaleMode; GLenum scaleMode;
GLenum result;
GL_ActivateRenderer(renderer); GL_ActivateRenderer(renderer);
@ -525,7 +534,7 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
data->fbo = NULL; data->fbo = NULL;
} }
renderdata->glGetError(); GL_CheckError("", renderer);
renderdata->glGenTextures(1, &data->texture); renderdata->glGenTextures(1, &data->texture);
if ((renderdata->GL_ARB_texture_rectangle_supported) if ((renderdata->GL_ARB_texture_rectangle_supported)
/*&& texture->access != SDL_TEXTUREACCESS_TARGET*/){ /*&& texture->access != SDL_TEXTUREACCESS_TARGET*/){
@ -593,9 +602,7 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
texture_h, 0, format, type, NULL); texture_h, 0, format, type, NULL);
} }
renderdata->glDisable(data->type); renderdata->glDisable(data->type);
result = renderdata->glGetError(); if (GL_CheckError("glTexImage2D()", renderer) > 0) {
if (result != GL_NO_ERROR) {
GL_SetError("glTexImage2D()", result);
return -1; return -1;
} }
@ -633,6 +640,8 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
renderdata->glDisable(data->type); renderdata->glDisable(data->type);
} }
GL_CheckError("", renderer);
return 0; return 0;
} }
@ -642,11 +651,10 @@ GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
{ {
GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata; GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
GL_TextureData *data = (GL_TextureData *) texture->driverdata; GL_TextureData *data = (GL_TextureData *) texture->driverdata;
GLenum result;
GL_ActivateRenderer(renderer); GL_ActivateRenderer(renderer);
renderdata->glGetError(); GL_CheckError("", renderer);
renderdata->glEnable(data->type); renderdata->glEnable(data->type);
renderdata->glBindTexture(data->type, data->texture); renderdata->glBindTexture(data->type, data->texture);
renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
@ -681,9 +689,7 @@ GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
data->format, data->formattype, pixels); data->format, data->formattype, pixels);
} }
renderdata->glDisable(data->type); renderdata->glDisable(data->type);
result = renderdata->glGetError(); if (GL_CheckError("glTexSubImage2D()", renderer) > 0) {
if (result != GL_NO_ERROR) {
GL_SetError("glTexSubImage2D()", result);
return -1; return -1;
} }
return 0; return 0;
@ -754,6 +760,11 @@ GL_UpdateViewport(SDL_Renderer * renderer)
return 0; return 0;
} }
if (!renderer->viewport.w || !renderer->viewport.h) {
/* The viewport isn't set up yet, ignore it */
return -1;
}
data->glViewport(renderer->viewport.x, renderer->viewport.y, data->glViewport(renderer->viewport.x, renderer->viewport.y,
renderer->viewport.w, renderer->viewport.h); renderer->viewport.w, renderer->viewport.h);
@ -772,6 +783,7 @@ GL_UpdateViewport(SDL_Renderer * renderer)
(GLdouble) 0, (GLdouble) 0,
0.0, 1.0); 0.0, 1.0);
} }
GL_CheckError("", renderer);
return 0; return 0;
} }
@ -939,6 +951,7 @@ GL_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points,
#endif #endif
data->glEnd(); data->glEnd();
} }
GL_CheckError("", renderer);
return 0; return 0;
} }
@ -956,6 +969,7 @@ GL_RenderFillRects(SDL_Renderer * renderer, const SDL_Rect * rects, int count)
data->glRecti(rect->x, rect->y, rect->x + rect->w, rect->y + rect->h); data->glRecti(rect->x, rect->y, rect->x + rect->w, rect->y + rect->h);
} }
GL_CheckError("", renderer);
return 0; return 0;
} }
@ -1024,6 +1038,8 @@ GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture,
data->glDisable(texturedata->type); data->glDisable(texturedata->type);
GL_CheckError("", renderer);
return 0; return 0;
} }
@ -1114,6 +1130,8 @@ GL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
data->glDisable(texturedata->type); data->glDisable(texturedata->type);
GL_CheckError("", renderer);
return 0; return 0;
} }
@ -1152,6 +1170,8 @@ GL_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
data->glReadPixels(rect->x, (h-rect->y)-rect->h, rect->w, rect->h, data->glReadPixels(rect->x, (h-rect->y)-rect->h, rect->w, rect->h,
format, type, temp_pixels); format, type, temp_pixels);
GL_CheckError("", renderer);
/* Flip the rows to be top-down */ /* Flip the rows to be top-down */
length = rect->w * SDL_BYTESPERPIXEL(temp_format); length = rect->w * SDL_BYTESPERPIXEL(temp_format);
src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch; src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch;
@ -1222,6 +1242,7 @@ GL_DestroyRenderer(SDL_Renderer * renderer)
GL_FBOList *nextnode = data->framebuffers->next; GL_FBOList *nextnode = data->framebuffers->next;
/* delete the framebuffer object */ /* delete the framebuffer object */
data->glDeleteFramebuffersEXT(1, &data->framebuffers->FBO); data->glDeleteFramebuffersEXT(1, &data->framebuffers->FBO);
GL_CheckError("", renderer);
SDL_free(data->framebuffers); SDL_free(data->framebuffers);
data->framebuffers = nextnode; data->framebuffers = nextnode;
} }