From c328979f60b2d2a27101f8c640032ccdcc7b4c08 Mon Sep 17 00:00:00 2001 From: Sam Lantinga Date: Fri, 28 Sep 2012 03:49:27 -0700 Subject: [PATCH] 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. --- src/render/opengl/SDL_render_gl.c | 109 ++++++++++++++++++------------ 1 file changed, 65 insertions(+), 44 deletions(-) diff --git a/src/render/opengl/SDL_render_gl.c b/src/render/opengl/SDL_render_gl.c index adc1e6ffe..42be944c9 100644 --- a/src/render/opengl/SDL_render_gl.c +++ b/src/render/opengl/SDL_render_gl.c @@ -150,43 +150,51 @@ typedef struct GL_FBOList *fbo; } GL_TextureData; - -static void -GL_SetError(const char *prefix, GLenum result) +static inline const char* +GL_TranslateError (GLenum error) { - const char *error; - - switch (result) { - case GL_NO_ERROR: - error = "GL_NO_ERROR"; - break; - case GL_INVALID_ENUM: - error = "GL_INVALID_ENUM"; - break; - case GL_INVALID_VALUE: - 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; +#define GL_ERROR_TRANSLATE(e) case e: return #e; + switch (error) { + GL_ERROR_TRANSLATE(GL_INVALID_ENUM) + GL_ERROR_TRANSLATE(GL_INVALID_VALUE) + GL_ERROR_TRANSLATE(GL_INVALID_OPERATION) + GL_ERROR_TRANSLATE(GL_OUT_OF_MEMORY) + GL_ERROR_TRANSLATE(GL_NO_ERROR) + GL_ERROR_TRANSLATE(GL_STACK_OVERFLOW) + GL_ERROR_TRANSLATE(GL_STACK_UNDERFLOW) + GL_ERROR_TRANSLATE(GL_TABLE_TOO_LARGE) default: - error = "UNKNOWN"; - break; - } - SDL_SetError("%s: %s", prefix, error); + return "UNKNOWN"; } +#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 GL_LoadFunctions(GL_RenderData * data) @@ -250,6 +258,8 @@ GL_ResetState(SDL_Renderer *renderer) data->glMatrixMode(GL_MODELVIEW); data->glLoadIdentity(); + + GL_CheckError("", renderer); } @@ -483,7 +493,6 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) GLenum format, type; int texture_w, texture_h; GLenum scaleMode; - GLenum result; GL_ActivateRenderer(renderer); @@ -525,7 +534,7 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) data->fbo = NULL; } - renderdata->glGetError(); + GL_CheckError("", renderer); renderdata->glGenTextures(1, &data->texture); if ((renderdata->GL_ARB_texture_rectangle_supported) /*&& texture->access != SDL_TEXTUREACCESS_TARGET*/){ @@ -593,9 +602,7 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) texture_h, 0, format, type, NULL); } renderdata->glDisable(data->type); - result = renderdata->glGetError(); - if (result != GL_NO_ERROR) { - GL_SetError("glTexImage2D()", result); + if (GL_CheckError("glTexImage2D()", renderer) > 0) { return -1; } @@ -633,6 +640,8 @@ GL_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture) renderdata->glDisable(data->type); } + + GL_CheckError("", renderer); return 0; } @@ -642,11 +651,10 @@ GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, { GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata; GL_TextureData *data = (GL_TextureData *) texture->driverdata; - GLenum result; GL_ActivateRenderer(renderer); - renderdata->glGetError(); + GL_CheckError("", renderer); renderdata->glEnable(data->type); renderdata->glBindTexture(data->type, data->texture); renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); @@ -681,9 +689,7 @@ GL_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, data->format, data->formattype, pixels); } renderdata->glDisable(data->type); - result = renderdata->glGetError(); - if (result != GL_NO_ERROR) { - GL_SetError("glTexSubImage2D()", result); + if (GL_CheckError("glTexSubImage2D()", renderer) > 0) { return -1; } return 0; @@ -754,6 +760,11 @@ GL_UpdateViewport(SDL_Renderer * renderer) 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, renderer->viewport.w, renderer->viewport.h); @@ -772,6 +783,7 @@ GL_UpdateViewport(SDL_Renderer * renderer) (GLdouble) 0, 0.0, 1.0); } + GL_CheckError("", renderer); return 0; } @@ -939,6 +951,7 @@ GL_RenderDrawLines(SDL_Renderer * renderer, const SDL_Point * points, #endif data->glEnd(); } + GL_CheckError("", renderer); 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); } + GL_CheckError("", renderer); return 0; } @@ -1024,6 +1038,8 @@ GL_RenderCopy(SDL_Renderer * renderer, SDL_Texture * texture, data->glDisable(texturedata->type); + GL_CheckError("", renderer); + return 0; } @@ -1114,6 +1130,8 @@ GL_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture, data->glDisable(texturedata->type); + GL_CheckError("", renderer); + 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, format, type, temp_pixels); + GL_CheckError("", renderer); + /* Flip the rows to be top-down */ length = rect->w * SDL_BYTESPERPIXEL(temp_format); src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch; @@ -1222,6 +1242,7 @@ GL_DestroyRenderer(SDL_Renderer * renderer) GL_FBOList *nextnode = data->framebuffers->next; /* delete the framebuffer object */ data->glDeleteFramebuffersEXT(1, &data->framebuffers->FBO); + GL_CheckError("", renderer); SDL_free(data->framebuffers); data->framebuffers = nextnode; }