Explorar el Código

[Bug 2042] OpenGL ES renderer tries to load OES functions unconditionally

Also, fail more gracefully when creating texture to avoid double free errors.
Gabriel Jacobo hace 12 años
padre
commit
02868b6903
Se han modificado 2 ficheros con 30 adiciones y 11 borrados
  1. 7 7
      src/render/opengles/SDL_glesfuncs.h
  2. 23 4
      src/render/opengles/SDL_render_gles.c

+ 7 - 7
src/render/opengles/SDL_glesfuncs.h

@@ -1,6 +1,6 @@
 SDL_PROC(void, glBindTexture, (GLenum, GLuint))
 SDL_PROC(void, glBlendFunc, (GLenum, GLenum))
-SDL_PROC(void, glBlendFuncSeparateOES, (GLenum, GLenum, GLenum, GLenum))
+SDL_PROC_OES(void, glBlendFuncSeparateOES, (GLenum, GLenum, GLenum, GLenum))
 SDL_PROC(void, glClear, (GLbitfield))
 SDL_PROC(void, glClearColor, (GLclampf, GLclampf, GLclampf, GLclampf))
 SDL_PROC(void, glColor4f, (GLfloat, GLfloat, GLfloat, GLfloat))
@@ -8,11 +8,11 @@ SDL_PROC(void, glDeleteTextures, (GLsizei, const GLuint *))
 SDL_PROC(void, glDisable, (GLenum))
 SDL_PROC(void, glDisableClientState, (GLenum array))
 SDL_PROC(void, glDrawArrays, (GLenum, GLint, GLsizei))
-SDL_PROC(void, glDrawTexfOES, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat))
+SDL_PROC_OES(void, glDrawTexfOES, (GLfloat, GLfloat, GLfloat, GLfloat, GLfloat))
 SDL_PROC(void, glEnable, (GLenum))
 SDL_PROC(void, glEnableClientState, (GLenum))
 SDL_PROC(void, glFinish, (void))
-SDL_PROC(void, glGenFramebuffersOES, (GLsizei, GLuint *))
+SDL_PROC_OES(void, glGenFramebuffersOES, (GLsizei, GLuint *))
 SDL_PROC(void, glGenTextures, (GLsizei, GLuint *))
 SDL_PROC(GLenum, glGetError, (void))
 SDL_PROC(void, glGetIntegerv, (GLenum, GLint *))
@@ -30,13 +30,13 @@ SDL_PROC(void, glTexParameteriv, (GLenum, GLenum, const GLint *))
 SDL_PROC(void, glTexSubImage2D, (GLenum, GLint, GLint, GLint, GLsizei, GLsizei, GLenum, GLenum, const GLvoid *))
 SDL_PROC(void, glVertexPointer, (GLint, GLenum, GLsizei, const GLvoid *))
 SDL_PROC(void, glViewport, (GLint, GLint, GLsizei, GLsizei))
-SDL_PROC(void, glBindFramebufferOES, (GLenum, GLuint))
-SDL_PROC(void, glFramebufferTexture2DOES, (GLenum, GLenum, GLenum, GLuint, GLint))
-SDL_PROC(GLenum, glCheckFramebufferStatusOES, (GLenum))
+SDL_PROC_OES(void, glBindFramebufferOES, (GLenum, GLuint))
+SDL_PROC_OES(void, glFramebufferTexture2DOES, (GLenum, GLenum, GLenum, GLuint, GLint))
+SDL_PROC_OES(GLenum, glCheckFramebufferStatusOES, (GLenum))
 SDL_PROC(void, glPushMatrix, (void))
 SDL_PROC(void, glTranslatef, (GLfloat, GLfloat, GLfloat))
 SDL_PROC(void, glRotatef, (GLfloat, GLfloat, GLfloat, GLfloat))
 SDL_PROC(void, glPopMatrix, (void))
-SDL_PROC(void, glDeleteFramebuffersOES, (GLsizei, const GLuint*))
+SDL_PROC_OES(void, glDeleteFramebuffersOES, (GLsizei, const GLuint*))
 
 /* vi: set ts=4 sw=4 expandtab: */

+ 23 - 4
src/render/opengles/SDL_render_gles.c

@@ -96,7 +96,7 @@ SDL_RenderDriver GLES_RenderDriver = {
     GLES_CreateRenderer,
     {
      "opengles",
-     (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE),
+     (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC ),
      1,
      {SDL_PIXELFORMAT_ABGR8888},
      0,
@@ -113,8 +113,10 @@ typedef struct
     } current;
 
 #define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
+#define SDL_PROC_OES SDL_PROC
 #include "SDL_glesfuncs.h"
 #undef SDL_PROC
+#undef SDL_PROC_OES
     SDL_bool GL_OES_framebuffer_object_supported;
     GLES_FBOList *framebuffers;
     GLuint window_framebuffer;
@@ -191,10 +193,15 @@ static int GLES_LoadFunctions(GLES_RenderData * data)
             return SDL_SetError("Couldn't load GLES function %s: %s\n", #func, SDL_GetError()); \
         } \
     } while ( 0 );
+#define SDL_PROC_OES(ret,func,params) \
+    do { \
+        data->func = SDL_GL_GetProcAddress(#func); \
+    } while ( 0 );    
 #endif /* _SDL_NOGETPROCADDR_ */
 
 #include "SDL_glesfuncs.h"
 #undef SDL_PROC
+#undef SDL_PROC_OES
     return 0;
 }
 
@@ -465,12 +472,17 @@ GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
         }
     }
 
-    texture->driverdata = data;
+    
     if (texture->access == SDL_TEXTUREACCESS_TARGET) {
-       data->fbo = GLES_GetFBO(renderer->driverdata, texture->w, texture->h);
+        if (!renderdata->GL_OES_framebuffer_object_supported) {
+            SDL_free(data);
+            return SDL_SetError("GL_OES_framebuffer_object not supported");
+        }
+        data->fbo = GLES_GetFBO(renderer->driverdata, texture->w, texture->h);
     } else {
-       data->fbo = NULL;
+        data->fbo = NULL;
     }
+    
 
     renderdata->glGetError();
     renderdata->glEnable(GL_TEXTURE_2D);
@@ -503,8 +515,11 @@ GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
 
     result = renderdata->glGetError();
     if (result != GL_NO_ERROR) {
+        SDL_free(data);
         return GLES_SetError("glTexImage2D()", result);
     }
+    
+    texture->driverdata = data;
     return 0;
 }
 
@@ -602,6 +617,10 @@ GLES_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
     GLenum status;
 
     GLES_ActivateRenderer(renderer);
+    
+    if (!data->GL_OES_framebuffer_object_supported) {
+        return SDL_SetError("Can't enable render target support in this renderer");
+    }
 
     if (texture == NULL) {
         data->glBindFramebufferOES(GL_FRAMEBUFFER_OES, data->window_framebuffer);