Fixed bug 1584 - Improved glError checks in the opengl renderer
authorSam Lantinga
Fri, 28 Sep 2012 03:49:27 -0700
changeset 6494309599be5c2a
parent 6493 6801ced90deb
child 6495 2bf42c5e897a
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
     1.1 --- a/src/render/opengl/SDL_render_gl.c	Fri Sep 28 03:29:36 2012 -0700
     1.2 +++ b/src/render/opengl/SDL_render_gl.c	Fri Sep 28 03:49:27 2012 -0700
     1.3 @@ -150,44 +150,52 @@
     1.4      GL_FBOList *fbo;
     1.5  } GL_TextureData;
     1.6  
     1.7 -
     1.8 -static void
     1.9 -GL_SetError(const char *prefix, GLenum result)
    1.10 +static inline const char*
    1.11 +GL_TranslateError (GLenum error)
    1.12  {
    1.13 -    const char *error;
    1.14 +#define GL_ERROR_TRANSLATE(e) case e: return #e;
    1.15 +    switch (error) {
    1.16 +    GL_ERROR_TRANSLATE(GL_INVALID_ENUM)
    1.17 +    GL_ERROR_TRANSLATE(GL_INVALID_VALUE)
    1.18 +    GL_ERROR_TRANSLATE(GL_INVALID_OPERATION)
    1.19 +    GL_ERROR_TRANSLATE(GL_OUT_OF_MEMORY)
    1.20 +    GL_ERROR_TRANSLATE(GL_NO_ERROR)
    1.21 +    GL_ERROR_TRANSLATE(GL_STACK_OVERFLOW)
    1.22 +    GL_ERROR_TRANSLATE(GL_STACK_UNDERFLOW)
    1.23 +    GL_ERROR_TRANSLATE(GL_TABLE_TOO_LARGE)
    1.24 +    default:
    1.25 +        return "UNKNOWN";
    1.26 +}
    1.27 +#undef GL_ERROR_TRANSLATE
    1.28 +}
    1.29  
    1.30 -    switch (result) {
    1.31 -    case GL_NO_ERROR:
    1.32 -        error = "GL_NO_ERROR";
    1.33 -        break;
    1.34 -    case GL_INVALID_ENUM:
    1.35 -        error = "GL_INVALID_ENUM";
    1.36 -        break;
    1.37 -    case GL_INVALID_VALUE:
    1.38 -        error = "GL_INVALID_VALUE";
    1.39 -        break;
    1.40 -    case GL_INVALID_OPERATION:
    1.41 -        error = "GL_INVALID_OPERATION";
    1.42 -        break;
    1.43 -    case GL_STACK_OVERFLOW:
    1.44 -        error = "GL_STACK_OVERFLOW";
    1.45 -        break;
    1.46 -    case GL_STACK_UNDERFLOW:
    1.47 -        error = "GL_STACK_UNDERFLOW";
    1.48 -        break;
    1.49 -    case GL_OUT_OF_MEMORY:
    1.50 -        error = "GL_OUT_OF_MEMORY";
    1.51 -        break;
    1.52 -    case GL_TABLE_TOO_LARGE:
    1.53 -        error = "GL_TABLE_TOO_LARGE";
    1.54 -        break;
    1.55 -    default:
    1.56 -        error = "UNKNOWN";
    1.57 -        break;
    1.58 +static __inline__ int
    1.59 +GL_CheckAllErrors (const char *prefix, SDL_Renderer * renderer, const char *file, int line, const char *function)
    1.60 +{
    1.61 +    GL_RenderData *data = (GL_RenderData *) renderer->driverdata;
    1.62 +    int ret = 0;
    1.63 +    /* check gl errors (can return multiple errors) */
    1.64 +    for (;;) {
    1.65 +        GLenum error = data->glGetError();
    1.66 +        if (error != GL_NO_ERROR) {
    1.67 +            if (prefix == NULL || prefix[0] == '\0') {
    1.68 +                prefix = "generic";
    1.69 +            }
    1.70 +            SDL_SetError("%s: %s (%d): %s %s (0x%X)", prefix, file, line, function, GL_TranslateError(error), error);
    1.71 +            ret++;
    1.72 +        } else {
    1.73 +            break;
    1.74 +        }
    1.75      }
    1.76 -    SDL_SetError("%s: %s", prefix, error);
    1.77 +    return ret;
    1.78  }
    1.79  
    1.80 +#if 1
    1.81 +#define GL_CheckError(prefix, renderer) GL_CheckAllErrors(prefix, renderer, __FILE__, __LINE__, __PRETTY_FUNCTION__)
    1.82 +#else
    1.83 +#define GL_CheckError(prefix, renderer)
    1.84 +#endif
    1.85 +
    1.86  static int
    1.87  GL_LoadFunctions(GL_RenderData * data)
    1.88  {
    1.89 @@ -250,6 +258,8 @@
    1.90  
    1.91      data->glMatrixMode(GL_MODELVIEW);
    1.92      data->glLoadIdentity();
    1.93 +
    1.94 +    GL_CheckError("", renderer);
    1.95  }
    1.96  
    1.97  
    1.98 @@ -483,7 +493,6 @@
    1.99      GLenum format, type;
   1.100      int texture_w, texture_h;
   1.101      GLenum scaleMode;
   1.102 -    GLenum result;
   1.103  
   1.104      GL_ActivateRenderer(renderer);
   1.105  
   1.106 @@ -525,7 +534,7 @@
   1.107          data->fbo = NULL;
   1.108      }
   1.109  
   1.110 -    renderdata->glGetError();
   1.111 +    GL_CheckError("", renderer);
   1.112      renderdata->glGenTextures(1, &data->texture);
   1.113      if ((renderdata->GL_ARB_texture_rectangle_supported)
   1.114          /*&& texture->access != SDL_TEXTUREACCESS_TARGET*/){
   1.115 @@ -593,9 +602,7 @@
   1.116                                   texture_h, 0, format, type, NULL);
   1.117      }
   1.118      renderdata->glDisable(data->type);
   1.119 -    result = renderdata->glGetError();
   1.120 -    if (result != GL_NO_ERROR) {
   1.121 -        GL_SetError("glTexImage2D()", result);
   1.122 +    if (GL_CheckError("glTexImage2D()", renderer) > 0) {
   1.123          return -1;
   1.124      }
   1.125  
   1.126 @@ -633,6 +640,8 @@
   1.127  
   1.128          renderdata->glDisable(data->type);
   1.129      }
   1.130 +
   1.131 +    GL_CheckError("", renderer);
   1.132      return 0;
   1.133  }
   1.134  
   1.135 @@ -642,11 +651,10 @@
   1.136  {
   1.137      GL_RenderData *renderdata = (GL_RenderData *) renderer->driverdata;
   1.138      GL_TextureData *data = (GL_TextureData *) texture->driverdata;
   1.139 -    GLenum result;
   1.140  
   1.141      GL_ActivateRenderer(renderer);
   1.142  
   1.143 -    renderdata->glGetError();
   1.144 +    GL_CheckError("", renderer);
   1.145      renderdata->glEnable(data->type);
   1.146      renderdata->glBindTexture(data->type, data->texture);
   1.147      renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
   1.148 @@ -681,9 +689,7 @@
   1.149                                      data->format, data->formattype, pixels);
   1.150      }
   1.151      renderdata->glDisable(data->type);
   1.152 -    result = renderdata->glGetError();
   1.153 -    if (result != GL_NO_ERROR) {
   1.154 -        GL_SetError("glTexSubImage2D()", result);
   1.155 +    if (GL_CheckError("glTexSubImage2D()", renderer) > 0) {
   1.156          return -1;
   1.157      }
   1.158      return 0;
   1.159 @@ -754,6 +760,11 @@
   1.160          return 0;
   1.161      }
   1.162  
   1.163 +    if (!renderer->viewport.w || !renderer->viewport.h) {
   1.164 +        /* The viewport isn't set up yet, ignore it */
   1.165 +        return -1;
   1.166 +    }
   1.167 +
   1.168      data->glViewport(renderer->viewport.x, renderer->viewport.y,
   1.169                       renderer->viewport.w, renderer->viewport.h);
   1.170  
   1.171 @@ -772,6 +783,7 @@
   1.172                        (GLdouble) 0,
   1.173                         0.0, 1.0);
   1.174      }
   1.175 +    GL_CheckError("", renderer);
   1.176      return 0;
   1.177  }
   1.178  
   1.179 @@ -939,6 +951,7 @@
   1.180  #endif
   1.181          data->glEnd();
   1.182      }
   1.183 +    GL_CheckError("", renderer);
   1.184  
   1.185      return 0;
   1.186  }
   1.187 @@ -956,6 +969,7 @@
   1.188  
   1.189          data->glRecti(rect->x, rect->y, rect->x + rect->w, rect->y + rect->h);
   1.190      }
   1.191 +    GL_CheckError("", renderer);
   1.192  
   1.193      return 0;
   1.194  }
   1.195 @@ -1024,6 +1038,8 @@
   1.196  
   1.197      data->glDisable(texturedata->type);
   1.198  
   1.199 +    GL_CheckError("", renderer);
   1.200 +
   1.201      return 0;
   1.202  }
   1.203  
   1.204 @@ -1114,6 +1130,8 @@
   1.205      
   1.206      data->glDisable(texturedata->type);
   1.207  
   1.208 +    GL_CheckError("", renderer);
   1.209 +
   1.210      return 0;
   1.211  }
   1.212  
   1.213 @@ -1152,6 +1170,8 @@
   1.214      data->glReadPixels(rect->x, (h-rect->y)-rect->h, rect->w, rect->h,
   1.215                         format, type, temp_pixels);
   1.216  
   1.217 +    GL_CheckError("", renderer);
   1.218 +
   1.219      /* Flip the rows to be top-down */
   1.220      length = rect->w * SDL_BYTESPERPIXEL(temp_format);
   1.221      src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch;
   1.222 @@ -1222,6 +1242,7 @@
   1.223                  GL_FBOList *nextnode = data->framebuffers->next;
   1.224                  /* delete the framebuffer object */
   1.225                  data->glDeleteFramebuffersEXT(1, &data->framebuffers->FBO);
   1.226 +                GL_CheckError("", renderer);
   1.227                  SDL_free(data->framebuffers);
   1.228                  data->framebuffers = nextnode;
   1.229              }