[Bug 2042] OpenGL ES renderer tries to load OES functions unconditionally Also, fail more gracefully when creating texture to avoid double free errors.
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
diff --git a/src/render/opengles/SDL_glesfuncs.h b/src/render/opengles/SDL_glesfuncs.h
index 4a6384d..ff5ce76 100644
--- a/src/render/opengles/SDL_glesfuncs.h
+++ b/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: */
diff --git a/src/render/opengles/SDL_render_gles.c b/src/render/opengles/SDL_render_gles.c
index ab0f01d..940bcb1 100644
--- a/src/render/opengles/SDL_render_gles.c
+++ b/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);