Prefer the OpenGL ES 2.0 context when it's available, make it possible to create an OpenGL 2.0 context on iPhoneOS
authorSam Lantinga <slouken@libsdl.org>
Sun, 06 Feb 2011 10:22:25 -0800
changeset 5209 115fff0641ee
parent 5208 78db79f5a4e2
child 5210 1be088cec098
Prefer the OpenGL ES 2.0 context when it's available, make it possible to create an OpenGL 2.0 context on iPhoneOS
src/render/SDL_render.c
src/render/SDL_sysrender.h
src/render/opengles/SDL_render_gles.c
src/render/opengles2/SDL_render_gles2.c
src/video/SDL_video.c
src/video/uikit/SDL_uikitopengles.m
src/video/uikit/SDL_uikitopenglview.h
src/video/uikit/SDL_uikitopenglview.m
--- a/src/render/SDL_render.c	Sun Feb 06 09:02:10 2011 -0800
+++ b/src/render/SDL_render.c	Sun Feb 06 10:22:25 2011 -0800
@@ -50,12 +50,12 @@
 #if SDL_VIDEO_RENDER_OGL
     &GL_RenderDriver,
 #endif
+#if SDL_VIDEO_RENDER_OGL_ES2
+    &GLES2_RenderDriver,
+#endif
 #if SDL_VIDEO_RENDER_OGL_ES
     &GLES_RenderDriver,
 #endif
-#if SDL_VIDEO_RENDER_OGL_ES2
-    &GLES2_RenderDriver,
-#endif
 #if SDL_VIDEO_RENDER_DIRECTFB
     &DirectFB_RenderDriver,
 #endif
--- a/src/render/SDL_sysrender.h	Sun Feb 06 09:02:10 2011 -0800
+++ b/src/render/SDL_sysrender.h	Sun Feb 06 10:22:25 2011 -0800
@@ -124,12 +124,12 @@
 #if SDL_VIDEO_RENDER_OGL
 extern SDL_RenderDriver GL_RenderDriver;
 #endif
+#if SDL_VIDEO_RENDER_OGL_ES2
+extern SDL_RenderDriver GLES2_RenderDriver;
+#endif
 #if SDL_VIDEO_RENDER_OGL_ES
 extern SDL_RenderDriver GLES_RenderDriver;
 #endif
-#if SDL_VIDEO_RENDER_OGL_ES2
-extern SDL_RenderDriver GLES2_RenderDriver;
-#endif
 #if SDL_VIDEO_RENDER_DIRECTFB
 extern SDL_RenderDriver DirectFB_RenderDriver;
 #endif
--- a/src/render/opengles/SDL_render_gles.c	Sun Feb 06 09:02:10 2011 -0800
+++ b/src/render/opengles/SDL_render_gles.c	Sun Feb 06 10:22:25 2011 -0800
@@ -184,6 +184,9 @@
 
     renderer->info.flags = SDL_RENDERER_ACCELERATED;
 
+    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 1);
+    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 1);
+
     data->context = SDL_GL_CreateContext(window);
     if (!data->context) {
         GLES_DestroyRenderer(renderer);
--- a/src/render/opengles2/SDL_render_gles2.c	Sun Feb 06 09:02:10 2011 -0800
+++ b/src/render/opengles2/SDL_render_gles2.c	Sun Feb 06 10:22:25 2011 -0800
@@ -185,24 +185,29 @@
     GLES2_ProgramCacheEntry *entry;
     GLES2_ProgramCacheEntry *next;
 
-    GLES2_ActivateRenderer(renderer);
+    /* Deallocate everything */
+    if (rdata) {
+        GLES2_ActivateRenderer(renderer);
 
-    /* Deallocate everything */
-    entry = rdata->program_cache.head;
-    while (entry)
-    {
-        glDeleteShader(entry->vertex_shader->id);
-        glDeleteShader(entry->fragment_shader->id);
-        SDL_free(entry->vertex_shader);
-        SDL_free(entry->fragment_shader);
-        glDeleteProgram(entry->id);
-        next = entry->next;
-        SDL_free(entry);
-        entry = next;
+        entry = rdata->program_cache.head;
+        while (entry) {
+            glDeleteShader(entry->vertex_shader->id);
+            glDeleteShader(entry->fragment_shader->id);
+            SDL_free(entry->vertex_shader);
+            SDL_free(entry->fragment_shader);
+            glDeleteProgram(entry->id);
+            next = entry->next;
+            SDL_free(entry);
+            entry = next;
+        }
+        if (rdata->context) {
+            SDL_GL_DeleteContext(rdata->context);
+        }
+        if (rdata->shader_formats) {
+            SDL_free(rdata->shader_formats);
+        }
+        SDL_free(rdata);
     }
-    SDL_GL_DeleteContext(rdata->context);
-    SDL_free(rdata->shader_formats);
-    SDL_free(renderer->driverdata);
     SDL_free(renderer);
 }
 
@@ -1081,12 +1086,15 @@
 
     /* Create the renderer struct */
     renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(SDL_Renderer));
+    if (!renderer) {
+        SDL_OutOfMemory();
+        return NULL;
+    }
+
     rdata = (GLES2_DriverContext *)SDL_calloc(1, sizeof(GLES2_DriverContext));
-    if (!renderer)
-    {
+    if (!rdata) {
+        GLES2_DestroyRenderer(renderer);
         SDL_OutOfMemory();
-        SDL_free(renderer);
-        SDL_free(rdata);
         return NULL;
     }
     renderer->info = GLES2_RenderDriver.info;
@@ -1095,17 +1103,18 @@
 
     renderer->info.flags = SDL_RENDERER_ACCELERATED;
 
-    /* Create the GL context */
+    /* Create an OpenGL ES 2.0 context */
+    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
+    SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
+
     rdata->context = SDL_GL_CreateContext(window);
     if (!rdata->context)
     {
-        SDL_free(renderer);
-        SDL_free(rdata);
+        GLES2_DestroyRenderer(renderer);
         return NULL;
     }
     if (SDL_GL_MakeCurrent(window, rdata->context) < 0) {
-        SDL_free(renderer);
-        SDL_free(rdata);
+        GLES2_DestroyRenderer(renderer);
         return NULL;
     }
 
@@ -1132,9 +1141,8 @@
     rdata->shader_formats = (GLenum *)SDL_calloc(nFormats, sizeof(GLenum));
     if (!rdata->shader_formats)
     {
+        GLES2_DestroyRenderer(renderer);
         SDL_OutOfMemory();
-        SDL_free(renderer);
-        SDL_free(rdata);
         return NULL;
     }
     rdata->shader_format_count = nFormats;
@@ -1144,10 +1152,8 @@
     glGetIntegerv(GL_SHADER_BINARY_FORMATS, (GLint *)rdata->shader_formats);
     if (glGetError() != GL_NO_ERROR)
     {
+        GLES2_DestroyRenderer(renderer);
         SDL_SetError("Failed to query supported shader formats");
-        SDL_free(renderer);
-        SDL_free(rdata->shader_formats);
-        SDL_free(rdata);
         return NULL;
     }
     if (hasCompiler)
--- a/src/video/SDL_video.c	Sun Feb 06 09:02:10 2011 -0800
+++ b/src/video/SDL_video.c	Sun Feb 06 10:22:25 2011 -0800
@@ -30,13 +30,17 @@
 #include "SDL_pixels_c.h"
 #include "../events/SDL_events_c.h"
 
+#if SDL_VIDEO_OPENGL
+#include "SDL_opengl.h"
+#endif /* SDL_VIDEO_OPENGL */
+
 #if SDL_VIDEO_OPENGL_ES
 #include "SDL_opengles.h"
 #endif /* SDL_VIDEO_OPENGL_ES */
 
-#if SDL_VIDEO_OPENGL
-#include "SDL_opengl.h"
-#endif /* SDL_VIDEO_OPENGL */
+#if SDL_VIDEO_OPENGL_ES2
+#include "SDL_opengles2.h"
+#endif /* SDL_VIDEO_OPENGL_ES2 */
 
 #include "SDL_syswm.h"
 
@@ -481,8 +485,16 @@
     _this->gl_config.multisamplesamples = 0;
     _this->gl_config.retained_backing = 1;
     _this->gl_config.accelerated = -1;  /* accelerated or not, both are fine */
+#if SDL_VIDEO_OPENGL
     _this->gl_config.major_version = 2;
     _this->gl_config.minor_version = 1;
+#elif SDL_VIDEO_OPENGL_ES2
+    _this->gl_config.major_version = 2;
+    _this->gl_config.minor_version = 0;
+#elif SDL_VIDEO_OPENGL_ES
+    _this->gl_config.major_version = 1;
+    _this->gl_config.minor_version = 1;
+#endif
 
     /* Initialize the video subsystem */
     if (_this->VideoInit(_this) < 0) {
@@ -1897,7 +1909,7 @@
 SDL_bool
 SDL_GL_ExtensionSupported(const char *extension)
 {
-#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES
+#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
     const GLubyte *(APIENTRY * glGetStringFunc) (GLenum);
     const char *extensions;
     const char *start;
@@ -1951,7 +1963,7 @@
 int
 SDL_GL_SetAttribute(SDL_GLattr attr, int value)
 {
-#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES
+#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
     int retval;
 
     if (!_this) {
@@ -2032,7 +2044,7 @@
 int
 SDL_GL_GetAttribute(SDL_GLattr attr, int *value)
 {
-#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES
+#if SDL_VIDEO_OPENGL || SDL_VIDEO_OPENGL_ES || SDL_VIDEO_OPENGL_ES2
     void (APIENTRY * glGetIntegervFunc) (GLenum pname, GLint * params);
     GLenum(APIENTRY * glGetErrorFunc) (void);
     GLenum attrib = 0;
@@ -2068,7 +2080,7 @@
         attrib = GL_ALPHA_BITS;
         break;
     case SDL_GL_DOUBLEBUFFER:
-#ifndef SDL_VIDEO_OPENGL_ES
+#if SDL_VIDEO_OPENGL
         attrib = GL_DOUBLEBUFFER;
         break;
 #else
@@ -2084,7 +2096,7 @@
     case SDL_GL_STENCIL_SIZE:
         attrib = GL_STENCIL_BITS;
         break;
-#ifndef SDL_VIDEO_OPENGL_ES
+#if SDL_VIDEO_OPENGL
     case SDL_GL_ACCUM_RED_SIZE:
         attrib = GL_ACCUM_RED_BITS;
         break;
@@ -2111,14 +2123,14 @@
         return 0;
 #endif
     case SDL_GL_MULTISAMPLEBUFFERS:
-#ifndef SDL_VIDEO_OPENGL_ES
+#if SDL_VIDEO_OPENGL
         attrib = GL_SAMPLE_BUFFERS_ARB;
 #else
         attrib = GL_SAMPLE_BUFFERS;
 #endif
         break;
     case SDL_GL_MULTISAMPLESAMPLES:
-#ifndef SDL_VIDEO_OPENGL_ES
+#if SDL_VIDEO_OPENGL
         attrib = GL_SAMPLES_ARB;
 #else
         attrib = GL_SAMPLES;
--- a/src/video/uikit/SDL_uikitopengles.m	Sun Feb 06 09:02:10 2011 -0800
+++ b/src/video/uikit/SDL_uikitopengles.m	Sun Feb 06 10:22:25 2011 -0800
@@ -113,7 +113,8 @@
                                     gBits: _this->gl_config.green_size \
                                     bBits: _this->gl_config.blue_size \
                                     aBits: _this->gl_config.alpha_size \
-                                    depthBits: _this->gl_config.depth_size];
+                                    depthBits: _this->gl_config.depth_size \
+                                    majorVersion: _this->gl_config.major_version];
     
     data->view = view;
     
--- a/src/video/uikit/SDL_uikitopenglview.h	Sun Feb 06 09:02:10 2011 -0800
+++ b/src/video/uikit/SDL_uikitopenglview.h	Sun Feb 06 10:22:25 2011 -0800
@@ -26,26 +26,26 @@
 #import <OpenGLES/ES1/glext.h>
 #import "SDL_uikitview.h"
 /*
-	This class wraps the CAEAGLLayer from CoreAnimation into a convenient UIView subclass.
-	The view content is basically an EAGL surface you render your OpenGL scene into.
-	Note that setting the view non-opaque will only work if the EAGL surface has an alpha channel.
+    This class wraps the CAEAGLLayer from CoreAnimation into a convenient UIView subclass.
+    The view content is basically an EAGL surface you render your OpenGL scene into.
+    Note that setting the view non-opaque will only work if the EAGL surface has an alpha channel.
  */
 /* *INDENT-OFF* */
 @interface SDL_uikitopenglview : SDL_uikitview {
-	
+    
 @private
-	/* The pixel dimensions of the backbuffer */
-	GLint backingWidth;
-	GLint backingHeight;
-	
-	EAGLContext *context;
-	
-	/* OpenGL names for the renderbuffer and framebuffers used to render to this view */
-	GLuint viewRenderbuffer, viewFramebuffer;
-	
-	/* OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist) */
-	GLuint depthRenderbuffer;
-	
+    /* The pixel dimensions of the backbuffer */
+    GLint backingWidth;
+    GLint backingHeight;
+    
+    EAGLContext *context;
+    
+    /* OpenGL names for the renderbuffer and framebuffers used to render to this view */
+    GLuint viewRenderbuffer, viewFramebuffer;
+    
+    /* OpenGL name for the depth buffer that is attached to viewFramebuffer, if it exists (0 if it does not exist) */
+    GLuint depthRenderbuffer;
+    
 }
 
 @property (nonatomic, retain, readonly) EAGLContext *context;
@@ -54,12 +54,13 @@
 - (void)setCurrentContext;
 
 - (id)initWithFrame:(CGRect)frame
-	retainBacking:(BOOL)retained \
-	rBits:(int)rBits \
-	gBits:(int)gBits \
-	bBits:(int)bBits \
-	aBits:(int)aBits \
-	depthBits:(int)depthBits;
+    retainBacking:(BOOL)retained \
+    rBits:(int)rBits \
+    gBits:(int)gBits \
+    bBits:(int)bBits \
+    aBits:(int)aBits \
+    depthBits:(int)depthBits \
+    majorVersion:(int)majorVersion;
 
 @end
 /* *INDENT-ON* */
--- a/src/video/uikit/SDL_uikitopenglview.m	Sun Feb 06 09:02:10 2011 -0800
+++ b/src/video/uikit/SDL_uikitopenglview.m	Sun Feb 06 10:22:25 2011 -0800
@@ -47,6 +47,7 @@
       bBits:(int)bBits \
       aBits:(int)aBits \
       depthBits:(int)depthBits \
+      majorVersion:(int)majorVersion \
 {
     NSString *colorFormat=nil;
     GLuint depthBufferFormat;
@@ -86,8 +87,11 @@
         eaglLayer.drawableProperties = [NSDictionary dictionaryWithObjectsAndKeys:
                                         [NSNumber numberWithBool: retained], kEAGLDrawablePropertyRetainedBacking, colorFormat, kEAGLDrawablePropertyColorFormat, nil];
         
-        context = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES1];
-        
+        if (majorVersion > 1) {
+            context = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES2];
+        } else {
+            context = [[EAGLContext alloc] initWithAPI: kEAGLRenderingAPIOpenGLES1];
+        }
         if (!context || ![EAGLContext setCurrentContext:context]) {
             [self release];
             return nil;