فهرست منبع

[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 12 سال پیش
والد
کامیت
02868b6903
2فایلهای تغییر یافته به همراه30 افزوده شده و 11 حذف شده
  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);