fixed the gles1 issue
[sdlhildon] / sdlgles / src / SDL_gles.c
index c28dfdf..38d92a1 100644 (file)
@@ -55,6 +55,7 @@ static EGLint attrib_list[] = {
        EGL_RED_SIZE,                           0,
        EGL_GREEN_SIZE,                         0,
        EGL_BLUE_SIZE,                          0,
+       EGL_LUMINANCE_SIZE,                     0,
        EGL_ALPHA_SIZE,                         0,
        EGL_CONFIG_CAVEAT,                      EGL_DONT_CARE,
        EGL_CONFIG_ID,                          EGL_DONT_CARE,
@@ -62,6 +63,7 @@ static EGLint attrib_list[] = {
        EGL_LEVEL,                                      0,
        EGL_NATIVE_RENDERABLE,          EGL_DONT_CARE,
        EGL_NATIVE_VISUAL_TYPE,         EGL_DONT_CARE,
+       EGL_RENDERABLE_TYPE,            0,
        EGL_SAMPLE_BUFFERS,                     0,
        EGL_SAMPLES,                            0,
        EGL_STENCIL_SIZE,                       0,
@@ -72,6 +74,12 @@ static EGLint attrib_list[] = {
        EGL_TRANSPARENT_BLUE_VALUE,     EGL_DONT_CARE,
        EGL_NONE
 };
+static EGLint context_attrib_list[] = {
+       EGL_CONTEXT_CLIENT_VERSION,     1,
+       EGL_NONE
+};
+static const int attrib_list_size = (sizeof(attrib_list) / sizeof(EGLint)) / 2;
+static const int context_attrib_list_size = (sizeof(context_attrib_list) / sizeof(EGLint)) / 2;
 static SDL_GLES_ContextPriv *cur_context = NULL;
 
 static const char * get_error_string(int error) {
@@ -111,8 +119,51 @@ static const char * get_error_string(int error) {
     }
 }
 
+static int set_egl_attrib(EGLenum attrib, EGLint value)
+{
+       const EGLint a = attrib;
+       int i;
+       for (i = 0; i < attrib_list_size; i++) {
+               if (attrib_list[i * 2] == a) {
+                       attrib_list[(i*2)+1] = value;
+                       return 0;
+               }
+       }
+
+       return -1;
+}
+
+static EGLint get_egl_attrib(EGLenum attrib)
+{
+       const EGLint a = attrib;
+       int i;
+       for (i = 0; i < attrib_list_size; i++) {
+               if (attrib_list[i * 2] == a) {
+                       return attrib_list[(i*2)+1];
+               }
+       }
+
+       return -1;
+}
+
+static int set_egl_context_attrib(EGLenum attrib, EGLint value)
+{
+       const EGLint a = attrib;
+       int i;
+       for (i = 0; i < context_attrib_list_size; i++) {
+               if (context_attrib_list[i * 2] == a) {
+                       context_attrib_list[(i*2)+1] = value;
+                       return 0;
+               }
+       }
+
+       return -1;
+}
+
 int SDL_GLES_LoadLibrary(const char *path)
 {
+       /* If path is NULL, try first to use path from SDL_VIDEO_GL_DRIVER,
+        * otherwise use a sane default depending on selected GLES version. */
        if (!path) {
                path = getenv("SDL_VIDEO_GL_DRIVER");
                if (!path) {
@@ -155,6 +206,7 @@ int SDL_GLES_Init(SDL_GLES_Version version)
                return -1;
        }
 
+       /* We use the SDL GFX display (we're using the GFX window too after all) */
        display = info.info.x11.gfxdisplay;
 
        egl_display = eglGetDisplay((EGLNativeDisplayType)display);
@@ -170,17 +222,64 @@ int SDL_GLES_Init(SDL_GLES_Version version)
                return -2;
        }
 
+       /* Configure some context attributes and bind the required API now. */
+       EGLenum api_to_bind = EGL_OPENGL_ES_API;
        gl_version = version;
+       switch (gl_version) {
+               case SDL_GLES_VERSION_1_1:
+                       /* OpenGL|ES 1.1 */
+                       api_to_bind = EGL_OPENGL_ES_API;
+                       /* filter non ES 1.0 renderable configurations */
+                       res = set_egl_attrib(EGL_RENDERABLE_TYPE, EGL_OPENGL_ES_BIT) == 0;
+                       assert(res);
+                       /* default egl_context_client_version is OK */
+                       break;
+               case SDL_GLES_VERSION_2_0:
+                       /* OpenGL|ES 2.0 */
+                       api_to_bind = EGL_OPENGL_ES_API; /* Note: no EGL_OPENGL_ES2_API */
+                       /* filter non ES 2.0 renderable configurations */
+                       res = set_egl_attrib(EGL_RENDERABLE_TYPE, EGL_OPENGL_ES2_BIT) == 0;
+                       assert(res);
+                       /* and request GL ES 2.0 contexts */
+                       res = set_egl_context_attrib(EGL_CONTEXT_CLIENT_VERSION, 2) == 0;
+                       assert(res);
+                       break;
+               default:
+                       SDL_SetError("Unsupported API version");
+                       return -1;
+       }
+
+       res = eglBindAPI(api_to_bind);
+       if (!res) {
+               SDL_SetError("EGL failed to bind the required API");
+               return -2;
+       }
+
        return 0;
 }
 
 void SDL_GLES_Quit()
 {
+       /* Close the loaded GL library (if any) */
        if (gl_handle) {
                dlclose(gl_handle);
                gl_handle = NULL;
        }
+       /* Unallocate most stuff we can unallocate. */
        if (egl_display != EGL_NO_DISPLAY) {
+               eglMakeCurrent(egl_display, EGL_NO_SURFACE, EGL_NO_SURFACE,
+                       EGL_NO_CONTEXT);
+
+               if (cur_context) {
+                       eglDestroyContext(egl_display, cur_context->egl_context);
+                       free(cur_context);
+                       cur_context = 0;
+               }
+               if (egl_surface != EGL_NO_SURFACE) {
+                       eglDestroySurface(egl_display, egl_surface);
+                       egl_surface = EGL_NO_SURFACE;
+               }
+
                eglTerminate(egl_display);
                egl_display = EGL_NO_DISPLAY;
        }
@@ -253,12 +352,19 @@ SDL_GLES_Context* SDL_GLES_CreateContext(void)
        if (!res || num_config < 1) {
                SDL_SetError("EGL failed to find any valid config with required attributes: %s",
                        get_error_string(eglGetError()));
+               free(context);
                return NULL;
        }
 
        context->egl_config = configs[0];
        context->egl_context = eglCreateContext(egl_display, configs[0],
-               EGL_NO_CONTEXT, NULL);
+               EGL_NO_CONTEXT, context_attrib_list);
+       if (context->egl_context == EGL_NO_CONTEXT) {
+               SDL_SetError("EGL failed to create context: %s",
+                       get_error_string(eglGetError()));
+               free(context);
+               return NULL;
+       }
 
        return (SDL_GLES_Context*) context;
 }
@@ -292,20 +398,6 @@ int SDL_GLES_MakeCurrent(SDL_GLES_Context* c)
 
        /* TODO Update attrib_list. Make SDL_GLES_GetAttribute work. */
 
-       switch (gl_version) {
-               case SDL_GLES_VERSION_1_1:
-               case SDL_GLES_VERSION_2_0:
-                       res = eglBindAPI(EGL_OPENGL_ES_API);
-                       if (!res) {
-                               SDL_SetError("EGL failed to bind the required API: %s",
-                                       get_error_string(eglGetError()));
-                               return -2;
-                       }
-                       break;
-               default:
-                       break;
-       }
-
        return 0;
 }