# HG changeset patch # User Sam Lantinga # Date 1296979213 28800 # Node ID 523409574510003ac7a8c7c2623cc18f4162fa5d # Parent 01bced9a4cc107c8deb16bf57764a1da6a129150 Added an OpenGL ES 2.0 renderer, contributed by itsnotabigtruck This compiles, but it untested. diff -r 01bced9a4cc1 -r 523409574510 Xcode-iPhoneOS/SDL/SDLiPhoneOS.xcodeproj/project.pbxproj --- a/Xcode-iPhoneOS/SDL/SDLiPhoneOS.xcodeproj/project.pbxproj Sat Feb 05 20:02:37 2011 -0800 +++ b/Xcode-iPhoneOS/SDL/SDLiPhoneOS.xcodeproj/project.pbxproj Sun Feb 06 00:00:13 2011 -0800 @@ -62,6 +62,9 @@ 0098A5631195B4D900343137 /* OpenGLES.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0098A5621195B4D900343137 /* OpenGLES.framework */; }; 0098A5651195B4D900343137 /* UIKit.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0098A5641195B4D900343137 /* UIKit.framework */; }; 0098A5851195B5E200343137 /* QuartzCore.framework in Frameworks */ = {isa = PBXBuildFile; fileRef = 0098A5841195B5E200343137 /* QuartzCore.framework */; }; + 0402A85812FE70C600CECEE3 /* SDL_render_gles2.c in Sources */ = {isa = PBXBuildFile; fileRef = 0402A85512FE70C600CECEE3 /* SDL_render_gles2.c */; }; + 0402A85912FE70C600CECEE3 /* SDL_shaders_gles2.c in Sources */ = {isa = PBXBuildFile; fileRef = 0402A85612FE70C600CECEE3 /* SDL_shaders_gles2.c */; }; + 0402A85A12FE70C600CECEE3 /* SDL_shaders_gles2.h in Headers */ = {isa = PBXBuildFile; fileRef = 0402A85712FE70C600CECEE3 /* SDL_shaders_gles2.h */; }; 041B2CD912FA0E9E0087D585 /* SDL_render.h in Headers */ = {isa = PBXBuildFile; fileRef = 041B2CD812FA0E9E0087D585 /* SDL_render.h */; settings = {ATTRIBUTES = (Public, ); }; }; 041B2CF112FA0F680087D585 /* SDL_render.c in Sources */ = {isa = PBXBuildFile; fileRef = 041B2CEA12FA0F680087D585 /* SDL_render.c */; }; 041B2CF212FA0F680087D585 /* SDL_sysrender.h in Headers */ = {isa = PBXBuildFile; fileRef = 041B2CEB12FA0F680087D585 /* SDL_sysrender.h */; }; @@ -324,6 +327,9 @@ 0098A5621195B4D900343137 /* OpenGLES.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = OpenGLES.framework; path = System/Library/Frameworks/OpenGLES.framework; sourceTree = SDKROOT; }; 0098A5641195B4D900343137 /* UIKit.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = UIKit.framework; path = System/Library/Frameworks/UIKit.framework; sourceTree = SDKROOT; }; 0098A5841195B5E200343137 /* QuartzCore.framework */ = {isa = PBXFileReference; lastKnownFileType = wrapper.framework; name = QuartzCore.framework; path = System/Library/Frameworks/QuartzCore.framework; sourceTree = SDKROOT; }; + 0402A85512FE70C600CECEE3 /* SDL_render_gles2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_render_gles2.c; sourceTree = ""; }; + 0402A85612FE70C600CECEE3 /* SDL_shaders_gles2.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_shaders_gles2.c; sourceTree = ""; }; + 0402A85712FE70C600CECEE3 /* SDL_shaders_gles2.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_shaders_gles2.h; sourceTree = ""; }; 041B2CD812FA0E9E0087D585 /* SDL_render.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = SDL_render.h; path = ../../include/SDL_render.h; sourceTree = SOURCE_ROOT; }; 041B2CEA12FA0F680087D585 /* SDL_render.c */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.c; path = SDL_render.c; sourceTree = ""; }; 041B2CEB12FA0F680087D585 /* SDL_sysrender.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; path = SDL_sysrender.h; sourceTree = ""; }; @@ -669,10 +675,21 @@ path = cocoa; sourceTree = ""; }; + 0402A85412FE70C600CECEE3 /* opengles2 */ = { + isa = PBXGroup; + children = ( + 0402A85512FE70C600CECEE3 /* SDL_render_gles2.c */, + 0402A85612FE70C600CECEE3 /* SDL_shaders_gles2.c */, + 0402A85712FE70C600CECEE3 /* SDL_shaders_gles2.h */, + ); + path = opengles2; + sourceTree = ""; + }; 041B2CE312FA0F680087D585 /* render */ = { isa = PBXGroup; children = ( 041B2CE812FA0F680087D585 /* opengles */, + 0402A85412FE70C600CECEE3 /* opengles2 */, 041B2CEC12FA0F680087D585 /* software */, 04409BA212FA989600FB9AA8 /* mmx.h */, 041B2CEA12FA0F680087D585 /* SDL_render.c */, @@ -1249,6 +1266,7 @@ 04F7808412FB753F00FC43C0 /* SDL_nullframebuffer_c.h in Headers */, 0442EC4B12FE1BFF004C9285 /* SDL_hints.h in Headers */, 0442EC5012FE1C1E004C9285 /* SDL_render_sw_c.h in Headers */, + 0402A85A12FE70C600CECEE3 /* SDL_shaders_gles2.h in Headers */, ); runOnlyForDeploymentPostprocessing = 0; }; @@ -1497,6 +1515,8 @@ 0442EC5112FE1C1E004C9285 /* SDL_render_sw.c in Sources */, 0442EC5312FE1C28004C9285 /* SDL_render_gles.c in Sources */, 0442EC5512FE1C3F004C9285 /* SDL_hints.c in Sources */, + 0402A85812FE70C600CECEE3 /* SDL_render_gles2.c in Sources */, + 0402A85912FE70C600CECEE3 /* SDL_shaders_gles2.c in Sources */, ); runOnlyForDeploymentPostprocessing = 0; }; diff -r 01bced9a4cc1 -r 523409574510 include/SDL_config_iphoneos.h --- a/include/SDL_config_iphoneos.h Sat Feb 05 20:02:37 2011 -0800 +++ b/include/SDL_config_iphoneos.h Sun Feb 06 00:00:13 2011 -0800 @@ -145,6 +145,7 @@ /* enable OpenGL ES */ #define SDL_VIDEO_OPENGL_ES 1 #define SDL_VIDEO_RENDER_OGL_ES 1 +#define SDL_VIDEO_RENDER_OGL_ES2 1 /* Enable system power support */ #define SDL_POWER_UIKIT 1 diff -r 01bced9a4cc1 -r 523409574510 src/render/SDL_render.c --- a/src/render/SDL_render.c Sat Feb 05 20:02:37 2011 -0800 +++ b/src/render/SDL_render.c Sun Feb 06 00:00:13 2011 -0800 @@ -51,7 +51,10 @@ &GL_RenderDriver, #endif #if SDL_VIDEO_RENDER_OGL_ES - &GL_ES_RenderDriver, + &GLES_RenderDriver, +#endif +#if SDL_VIDEO_RENDER_OGL_ES2 + &GLES2_RenderDriver, #endif #if SDL_VIDEO_RENDER_DIRECTFB &DirectFB_RenderDriver, diff -r 01bced9a4cc1 -r 523409574510 src/render/SDL_sysrender.h --- a/src/render/SDL_sysrender.h Sat Feb 05 20:02:37 2011 -0800 +++ b/src/render/SDL_sysrender.h Sun Feb 06 00:00:13 2011 -0800 @@ -125,7 +125,10 @@ extern SDL_RenderDriver GL_RenderDriver; #endif #if SDL_VIDEO_RENDER_OGL_ES -extern SDL_RenderDriver GL_ES_RenderDriver; +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; diff -r 01bced9a4cc1 -r 523409574510 src/render/opengles/SDL_render_gles.c --- a/src/render/opengles/SDL_render_gles.c Sat Feb 05 20:02:37 2011 -0800 +++ b/src/render/opengles/SDL_render_gles.c Sun Feb 06 00:00:13 2011 -0800 @@ -71,7 +71,7 @@ static void GLES_DestroyRenderer(SDL_Renderer * renderer); -SDL_RenderDriver GL_ES_RenderDriver = { +SDL_RenderDriver GLES_RenderDriver = { GLES_CreateRenderer, { "opengl_es", @@ -201,7 +201,7 @@ renderer->RenderPresent = GLES_RenderPresent; renderer->DestroyTexture = GLES_DestroyTexture; renderer->DestroyRenderer = GLES_DestroyRenderer; - renderer->info = GL_ES_RenderDriver.info; + renderer->info = GLES_RenderDriver.info; renderer->driverdata = data; renderer->info.flags = SDL_RENDERER_ACCELERATED; @@ -265,7 +265,6 @@ static int GLES_ActivateRenderer(SDL_Renderer * renderer) { - GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata; SDL_Window *window = renderer->window; @@ -390,13 +389,6 @@ return 0; } -static void -SetupTextureUpdate(GLES_RenderData * renderdata, SDL_Texture * texture, - int pitch) -{ - renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); -} - static int GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture, const SDL_Rect * rect, const void *pixels, int pitch) @@ -412,7 +404,7 @@ GLES_ActivateRenderer(renderer); renderdata->glGetError(); - SetupTextureUpdate(renderdata, texture, pitch); + renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); renderdata->glEnable(data->type); renderdata->glBindTexture(data->type, data->texture); @@ -467,7 +459,7 @@ GLES_ActivateRenderer(renderer); - SetupTextureUpdate(renderdata, texture, data->pitch); + renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1); renderdata->glEnable(data->type); renderdata->glBindTexture(data->type, data->texture); renderdata->glTexSubImage2D(data->type, 0, 0, 0, texture->w, diff -r 01bced9a4cc1 -r 523409574510 src/render/opengles2/SDL_render_gles2.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/render/opengles2/SDL_render_gles2.c Sun Feb 06 00:00:13 2011 -0800 @@ -0,0 +1,1240 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 2010 itsnotabigtruck. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "SDL_config.h" + +#if SDL_VIDEO_RENDER_OGL_ES2 + +#ifdef __IPHONEOS__ +#include +#include +#else +#include +#include +#endif +#include "../SDL_sysrender.h" +#include "SDL_shaders_gles2.h" + +/************************************************************************************************* + * Bootstrap data * + *************************************************************************************************/ + +static SDL_Renderer *GLES2_CreateRenderer(SDL_Window *window, Uint32 flags); + +SDL_RenderDriver GLES2_RenderDriver = { + GLES2_CreateRenderer, + { + "opengles2", + (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC), +#if GLES2_ASSUME_BGRA + 11, + { + SDL_PIXELFORMAT_ABGR8888, + SDL_PIXELFORMAT_ABGR4444, + SDL_PIXELFORMAT_ABGR1555, + SDL_PIXELFORMAT_BGR565, + SDL_PIXELFORMAT_BGR24, + SDL_PIXELFORMAT_ARGB8888, + SDL_PIXELFORMAT_ARGB4444, + SDL_PIXELFORMAT_ARGB1555, + SDL_PIXELFORMAT_RGB565, + SDL_PIXELFORMAT_RGB24 + }, +#elif GLES2_ASSUME_BGRA8888 + 7, + { + SDL_PIXELFORMAT_ABGR8888, + SDL_PIXELFORMAT_ABGR4444, + SDL_PIXELFORMAT_ABGR1555, + SDL_PIXELFORMAT_BGR565, + SDL_PIXELFORMAT_BGR24, + SDL_PIXELFORMAT_ARGB8888 + }, +#else + 6, + { + SDL_PIXELFORMAT_ABGR8888, + SDL_PIXELFORMAT_ABGR4444, + SDL_PIXELFORMAT_ABGR1555, + SDL_PIXELFORMAT_BGR565, + SDL_PIXELFORMAT_BGR24 + }, +#endif + 0, + 0 + } +}; + +/************************************************************************************************* + * Context structures * + *************************************************************************************************/ + +typedef struct GLES2_TextureData +{ + GLenum texture; + GLenum texture_type; + GLenum pixel_format; + GLenum pixel_type; + void *pixel_data; + size_t pitch; +} GLES2_TextureData; + +typedef struct GLES2_ShaderCacheEntry +{ + GLuint id; + GLES2_ShaderType type; + const GLES2_ShaderInstance *instance; + int references; + struct GLES2_ShaderCacheEntry *prev; + struct GLES2_ShaderCacheEntry *next; +} GLES2_ShaderCacheEntry; + +typedef struct GLES2_ShaderCache +{ + int count; + GLES2_ShaderCacheEntry *head; +} GLES2_ShaderCache; + +typedef struct GLES2_ProgramCacheEntry +{ + GLuint id; + SDL_BlendMode blend_mode; + GLES2_ShaderCacheEntry *vertex_shader; + GLES2_ShaderCacheEntry *fragment_shader; + GLuint uniform_locations[16]; + struct GLES2_ProgramCacheEntry *prev; + struct GLES2_ProgramCacheEntry *next; +} GLES2_ProgramCacheEntry; + +typedef struct GLES2_ProgramCache +{ + int count; + GLES2_ProgramCacheEntry *head; + GLES2_ProgramCacheEntry *tail; +} GLES2_ProgramCache; + +typedef enum +{ + GLES2_ATTRIBUTE_POSITION = 0, + GLES2_ATTRIBUTE_TEXCOORD = 1 +} GLES2_Attribute; + +typedef enum +{ + GLES2_UNIFORM_PROJECTION, + GLES2_UNIFORM_TEXTURE, + GLES2_UNIFORM_MODULATION, + GLES2_UNIFORM_COLOR, + GLES2_UNIFORM_COLORTABLE +} GLES2_Uniform; + +typedef enum +{ + GLES2_IMAGESOURCE_SOLID, + GLES2_IMAGESOURCE_TEXTURE +} GLES2_ImageSource; + +typedef struct GLES2_DriverContext +{ + SDL_GLContext *context; + int shader_format_count; + GLenum *shader_formats; + GLES2_ShaderCache shader_cache; + GLES2_ProgramCache program_cache; + GLES2_ProgramCacheEntry *current_program; + SDL_bool updateSize; +} GLES2_DriverContext; + +#define GLES2_MAX_CACHED_PROGRAMS 8 + +/************************************************************************************************* + * Renderer state APIs * + *************************************************************************************************/ + +static void GLES2_WindowEvent(SDL_Renderer * renderer, + const SDL_WindowEvent *event); +static int GLES2_ActivateRenderer(SDL_Renderer *renderer); +static int GLES2_DisplayModeChanged(SDL_Renderer *renderer); +static void GLES2_DestroyRenderer(SDL_Renderer *renderer); + +static SDL_GLContext SDL_CurrentContext = NULL; + +static int +GLES2_ActivateRenderer(SDL_Renderer * renderer) +{ + GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; + SDL_Window *window = renderer->window; + + if (SDL_CurrentContext != rdata->context) { + /* Null out the current program to ensure we set it again */ + rdata->current_program = NULL; + + if (SDL_GL_MakeCurrent(window, rdata->context) < 0) { + return -1; + } + SDL_CurrentContext = rdata->context; + } + if (rdata->updateSize) { + int w, h; + + SDL_GetWindowSize(window, &w, &h); + glViewport(0, 0, w, h); + rdata->updateSize = SDL_FALSE; + } + return 0; +} + +static void +GLES2_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event) +{ + GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; + + if (event->event == SDL_WINDOWEVENT_RESIZED) { + /* Rebind the context to the window area */ + SDL_CurrentContext = NULL; + rdata->updateSize = SDL_TRUE; + } +} + +static void +GLES2_DestroyRenderer(SDL_Renderer *renderer) +{ + GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; + GLES2_ProgramCacheEntry *entry; + GLES2_ProgramCacheEntry *next; + + 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; + } + SDL_GL_DeleteContext(rdata->context); + SDL_free(rdata->shader_formats); + SDL_free(renderer->driverdata); + SDL_free(renderer); +} + +/************************************************************************************************* + * Texture APIs * + *************************************************************************************************/ + +#define GL_BGR_EXT 0x80E0 +#define GL_BGRA_EXT 0x80E1 + +static int GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture); +static void GLES2_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture); +static int GLES2_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, + void **pixels, int *pitch); +static void GLES2_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture); +static int GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, + const void *pixels, int pitch); + +static int +GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture) +{ + GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; + GLES2_TextureData *tdata; + GLenum format; + GLenum type; + + GLES2_ActivateRenderer(renderer); + + /* Determine the corresponding GLES texture format params */ + switch (texture->format) + { + case SDL_PIXELFORMAT_BGR24: + format = GL_RGB; + type = GL_UNSIGNED_BYTE; + break; + case SDL_PIXELFORMAT_ABGR8888: + format = GL_RGBA; + type = GL_UNSIGNED_BYTE; + break; + case SDL_PIXELFORMAT_BGR565: + format = GL_RGB; + type = GL_UNSIGNED_SHORT_5_6_5; + break; + case SDL_PIXELFORMAT_ABGR1555: + format = GL_RGBA; + type = GL_UNSIGNED_SHORT_5_5_5_1; + break; + case SDL_PIXELFORMAT_ABGR4444: + format = GL_RGBA; + type = GL_UNSIGNED_SHORT_4_4_4_4; + break; +#if GLES2_ASSUME_BGRA || GLES2_ASSUME_BGRA8888 + case SDL_PIXELFORMAT_ARGB8888: + format = GL_BGRA_EXT; + type = GL_UNSIGNED_BYTE; + break; +#endif /* GLES2_ASSUME_BGRA || GLES2_ASSUME_BGRA8888 */ +#if GLES2_ASSUME_BGRA + case SDL_PIXELFORMAT_RGB24: + format = GL_BGR_EXT; + type = GL_UNSIGNED_BYTE; + break; + case SDL_PIXELFORMAT_RGB565: + format = GL_BGR_EXT; + type = GL_UNSIGNED_SHORT_5_6_5; + break; + case SDL_PIXELFORMAT_ARGB1555: + format = GL_BGRA_EXT; + type = GL_UNSIGNED_SHORT_5_5_5_1; + break; + case SDL_PIXELFORMAT_ARGB4444: + format = GL_BGRA_EXT; + type = GL_UNSIGNED_SHORT_4_4_4_4; + break; +#endif /* GLES2_ASSUME_BGRA */ + default: + SDL_SetError("Texture format not supported"); + return -1; + } + + /* Allocate a texture struct */ + tdata = (GLES2_TextureData *)SDL_calloc(1, sizeof(GLES2_TextureData)); + if (!tdata) + { + SDL_OutOfMemory(); + return -1; + } + tdata->texture = 0; + tdata->texture_type = GL_TEXTURE_2D; + tdata->pixel_format = format; + tdata->pixel_type = type; + + /* Allocate a blob for image data */ + if (texture->access == SDL_TEXTUREACCESS_STREAMING) + { + tdata->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format); + tdata->pixel_data = SDL_malloc(tdata->pitch * texture->h); + if (!tdata->pixel_data) + { + SDL_OutOfMemory(); + SDL_free(tdata); + return -1; + } + } + + /* Allocate the texture */ + glGetError(); + glGenTextures(1, &tdata->texture); + glActiveTexture(GL_TEXTURE0); + glBindTexture(tdata->texture_type, tdata->texture); + glTexParameteri(tdata->texture_type, GL_TEXTURE_MIN_FILTER, GL_LINEAR); + glTexParameteri(tdata->texture_type, GL_TEXTURE_MAG_FILTER, GL_LINEAR); + glTexParameteri(tdata->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); + glTexParameteri(tdata->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); + glTexImage2D(tdata->texture_type, 0, format, texture->w, texture->h, 0, format, type, NULL); + if (glGetError() != GL_NO_ERROR) + { + SDL_SetError("Texture creation failed"); + glDeleteTextures(1, &tdata->texture); + SDL_free(tdata); + return -1; + } + texture->driverdata = tdata; + return 0; +} + +static void +GLES2_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture) +{ + GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata; + + GLES2_ActivateRenderer(renderer); + + /* Destroy the texture */ + if (tdata) + { + glDeleteTextures(1, &tdata->texture); + SDL_free(tdata->pixel_data); + SDL_free(tdata); + texture->driverdata = NULL; + } +} + +static int +GLES2_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, + void **pixels, int *pitch) +{ + GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata; + + /* Retrieve the buffer/pitch for the specified region */ + *pixels = (Uint8 *)tdata->pixel_data + + (tdata->pitch * rect->y) + + (rect->x * SDL_BYTESPERPIXEL(texture->format)); + *pitch = tdata->pitch; + + return 0; +} + +static void +GLES2_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture) +{ + GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata; + + GLES2_ActivateRenderer(renderer); + + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glActiveTexture(GL_TEXTURE0); + glBindTexture(tdata->texture_type, tdata->texture); + glTexSubImage2D(tdata->texture_type, 0, 0, 0, texture->w, texture->h, + tdata->pixel_format, tdata->pixel_type, tdata->pixel_data); +} + +static int +GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, + const void *pixels, int pitch) +{ + GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata; + Uint8 *blob = NULL; + Uint8 *src; + int srcPitch; + Uint8 *dest; + int y; + + GLES2_ActivateRenderer(renderer); + + /* Bail out if we're supposed to update an empty rectangle */ + if (rect->w <= 0 || rect->h <= 0) + return 0; + + /* Reformat the texture data into a tightly packed array */ + srcPitch = rect->w * SDL_BYTESPERPIXEL(texture->format); + src = (Uint8 *)pixels; + if (pitch != srcPitch) + { + blob = (Uint8 *)SDL_malloc(srcPitch * rect->h); + if (!blob) + { + SDL_OutOfMemory(); + return -1; + } + src = blob; + for (y = 0; y < rect->h; ++y) + { + SDL_memcpy(src, pixels, srcPitch); + src += srcPitch; + pixels = (Uint8 *)pixels + pitch; + } + src = blob; + } + + /* Create a texture subimage with the supplied data */ + glGetError(); + glActiveTexture(GL_TEXTURE0); + glBindTexture(tdata->texture_type, tdata->texture); + glPixelStorei(GL_UNPACK_ALIGNMENT, 1); + glTexSubImage2D(tdata->texture_type, + 0, + rect->x, + rect->y, + rect->w, + rect->h, + tdata->pixel_format, + tdata->pixel_type, + src); + if (glGetError() != GL_NO_ERROR) + { + SDL_SetError("Failed to update texture"); + return -1; + } + + /* Update the (streaming) texture buffer, in one pass if possible */ + if (tdata->pixel_data) + { + dest = (Uint8 *)tdata->pixel_data + + (tdata->pitch * rect->y) + + (SDL_BYTESPERPIXEL(texture->format) * rect->x); + if (rect->w == texture->w) + { + SDL_memcpy(dest, src, srcPitch * rect->h); + } + else + { + for (y = 0; y < rect->h; ++y) + { + SDL_memcpy(dest, src, srcPitch); + src += srcPitch; + dest += tdata->pitch; + } + } + } + + /* Clean up and return */ + SDL_free(blob); + return 0; +} + +/************************************************************************************************* + * Shader management functions * + *************************************************************************************************/ + +static GLES2_ShaderCacheEntry *GLES2_CacheShader(SDL_Renderer *renderer, GLES2_ShaderType type, + SDL_BlendMode blendMode); +static void GLES2_EvictShader(SDL_Renderer *renderer, GLES2_ShaderCacheEntry *entry); +static GLES2_ProgramCacheEntry *GLES2_CacheProgram(SDL_Renderer *renderer, + GLES2_ShaderCacheEntry *vertex, + GLES2_ShaderCacheEntry *fragment, + SDL_BlendMode blendMode); +static int GLES2_SelectProgram(SDL_Renderer *renderer, GLES2_ImageSource source, + SDL_BlendMode blendMode); +static int GLES2_SetOrthographicProjection(SDL_Renderer *renderer); + +static GLES2_ProgramCacheEntry * +GLES2_CacheProgram(SDL_Renderer *renderer, GLES2_ShaderCacheEntry *vertex, + GLES2_ShaderCacheEntry *fragment, SDL_BlendMode blendMode) +{ + GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; + GLES2_ProgramCacheEntry *entry; + GLES2_ShaderCacheEntry *shaderEntry; + GLint linkSuccessful; + + /* Check if we've already cached this program */ + entry = rdata->program_cache.head; + while (entry) + { + if (entry->vertex_shader == vertex && entry->fragment_shader == fragment) + break; + entry = entry->next; + } + if (entry) + { + if (rdata->program_cache.count > 1) + { + if (entry->next) + entry->next->prev = entry->prev; + if (entry->prev) + entry->prev->next = entry->next; + entry->prev = NULL; + entry->next = rdata->program_cache.head; + rdata->program_cache.head->prev = entry; + rdata->program_cache.head = entry; + } + return entry; + } + + /* Create a program cache entry */ + entry = (GLES2_ProgramCacheEntry *)SDL_calloc(1, sizeof(GLES2_ProgramCacheEntry)); + if (!entry) + { + SDL_OutOfMemory(); + return NULL; + } + entry->vertex_shader = vertex; + entry->fragment_shader = fragment; + entry->blend_mode = blendMode; + + /* Create the program and link it */ + glGetError(); + entry->id = glCreateProgram(); + glAttachShader(entry->id, vertex->id); + glAttachShader(entry->id, fragment->id); + glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_POSITION, "a_position"); + glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_TEXCOORD, "a_texCoord"); + glLinkProgram(entry->id); + glGetProgramiv(entry->id, GL_LINK_STATUS, &linkSuccessful); + if (glGetError() != GL_NO_ERROR || !linkSuccessful) + { + SDL_SetError("Failed to link shader program"); + glDeleteProgram(entry->id); + SDL_free(entry); + return NULL; + } + + /* Predetermine locations of uniform variables */ + entry->uniform_locations[GLES2_UNIFORM_PROJECTION] = + glGetUniformLocation(entry->id, "u_projection"); + entry->uniform_locations[GLES2_UNIFORM_TEXTURE] = + glGetUniformLocation(entry->id, "u_texture"); + entry->uniform_locations[GLES2_UNIFORM_MODULATION] = + glGetUniformLocation(entry->id, "u_modulation"); + entry->uniform_locations[GLES2_UNIFORM_COLOR] = + glGetUniformLocation(entry->id, "u_color"); + entry->uniform_locations[GLES2_UNIFORM_COLORTABLE] = + glGetUniformLocation(entry->id, "u_colorTable"); + + /* Cache the linked program */ + if (rdata->program_cache.head) + { + entry->next = rdata->program_cache.head; + rdata->program_cache.head->prev = entry; + } + else + { + rdata->program_cache.tail = entry; + } + rdata->program_cache.head = entry; + ++rdata->program_cache.count; + + /* Increment the refcount of the shaders we're using */ + ++vertex->references; + ++fragment->references; + + /* Evict the last entry from the cache if we exceed the limit */ + if (rdata->program_cache.count > GLES2_MAX_CACHED_PROGRAMS) + { + shaderEntry = rdata->program_cache.tail->vertex_shader; + if (--shaderEntry->references <= 0) + GLES2_EvictShader(renderer, shaderEntry); + shaderEntry = rdata->program_cache.tail->fragment_shader; + if (--shaderEntry->references <= 0) + GLES2_EvictShader(renderer, shaderEntry); + glDeleteProgram(rdata->program_cache.tail->id); + rdata->program_cache.tail = rdata->program_cache.tail->prev; + SDL_free(rdata->program_cache.tail->next); + rdata->program_cache.tail->next = NULL; + --rdata->program_cache.count; + } + return entry; +} + +static GLES2_ShaderCacheEntry * +GLES2_CacheShader(SDL_Renderer *renderer, GLES2_ShaderType type, SDL_BlendMode blendMode) +{ + GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; + const GLES2_Shader *shader; + const GLES2_ShaderInstance *instance = NULL; + GLES2_ShaderCacheEntry *entry = NULL; + GLint compileSuccessful = GL_FALSE; + int i, j; + + /* Find the corresponding shader */ + shader = GLES2_GetShader(type, blendMode); + if (!shader) + { + SDL_SetError("No shader matching the requested characteristics was found"); + return NULL; + } + + /* Find a matching shader instance that's supported on this hardware */ + for (i = 0; i < shader->instance_count; ++i) + { + for (j = 0; j < rdata->shader_format_count; ++j) + { + if (!shader->instances) + continue; + if (shader->instances[i]->format != rdata->shader_formats[j]) + continue; + instance = shader->instances[i]; + break; + } + } + if (!instance) + { + SDL_SetError("The specified shader cannot be loaded on the current platform"); + return NULL; + } + + /* Check if we've already cached this shader */ + entry = rdata->shader_cache.head; + while (entry) + { + if (entry->instance == instance) + break; + entry = entry->next; + } + if (entry) + return entry; + + /* Create a shader cache entry */ + entry = (GLES2_ShaderCacheEntry *)SDL_calloc(1, sizeof(GLES2_ShaderCacheEntry)); + if (!entry) + { + SDL_OutOfMemory(); + return NULL; + } + entry->type = type; + entry->instance = instance; + + /* Compile or load the selected shader instance */ + glGetError(); + entry->id = glCreateShader(instance->type); + if (instance->format == (GLenum)-1) + { + glShaderSource(entry->id, 1, (const char **)&instance->data, &instance->length); + glCompileShader(entry->id); + glGetShaderiv(entry->id, GL_COMPILE_STATUS, &compileSuccessful); + } + else + { + glShaderBinary(1, &entry->id, instance->format, instance->data, instance->length); + compileSuccessful = GL_TRUE; + } + if (glGetError() != GL_NO_ERROR || !compileSuccessful) + { + SDL_SetError("Failed to load the specified shader"); + glDeleteShader(entry->id); + SDL_free(entry); + return NULL; + } + + /* Link the shader entry in at the front of the cache */ + if (rdata->shader_cache.head) + { + entry->next = rdata->shader_cache.head; + rdata->shader_cache.head->prev = entry; + } + rdata->shader_cache.head = entry; + ++rdata->shader_cache.count; + return entry; +} + +static void +GLES2_EvictShader(SDL_Renderer *renderer, GLES2_ShaderCacheEntry *entry) +{ + GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; + + /* Unlink the shader from the cache */ + if (entry->next) + entry->next->prev = entry->prev; + if (entry->prev) + entry->prev->next = entry->next; + if (rdata->shader_cache.head == entry) + rdata->shader_cache.head = entry->next; + --rdata->shader_cache.count; + + /* Deallocate the shader */ + glDeleteShader(entry->id); + SDL_free(entry); +} + +static int +GLES2_SelectProgram(SDL_Renderer *renderer, GLES2_ImageSource source, SDL_BlendMode blendMode) +{ + GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; + GLES2_ShaderCacheEntry *vertex = NULL; + GLES2_ShaderCacheEntry *fragment = NULL; + GLES2_ShaderType vtype, ftype; + GLES2_ProgramCacheEntry *program; + + /* Select an appropriate shader pair for the specified modes */ + vtype = GLES2_SHADER_VERTEX_DEFAULT; + switch (source) + { + case GLES2_IMAGESOURCE_SOLID: + ftype = GLES2_SHADER_FRAGMENT_SOLID_SRC; + break; + case GLES2_IMAGESOURCE_TEXTURE: + ftype = GLES2_SHADER_FRAGMENT_TEXTURE_SRC; + break; + } + + /* Load the requested shaders */ + vertex = GLES2_CacheShader(renderer, vtype, blendMode); + if (!vertex) + goto fault; + fragment = GLES2_CacheShader(renderer, ftype, blendMode); + if (!fragment) + goto fault; + + /* Check if we need to change programs at all */ + if (rdata->current_program && + rdata->current_program->vertex_shader == vertex && + rdata->current_program->fragment_shader == fragment) + return 0; + + /* Generate a matching program */ + program = GLES2_CacheProgram(renderer, vertex, fragment, blendMode); + if (!program) + goto fault; + + /* Select that program in OpenGL */ + glGetError(); + glUseProgram(program->id); + if (glGetError() != GL_NO_ERROR) + { + SDL_SetError("Failed to select program"); + goto fault; + } + + /* Set the current program */ + rdata->current_program = program; + + /* Activate an orthographic projection */ + if (GLES2_SetOrthographicProjection(renderer) < 0) + goto fault; + + /* Clean up and return */ + return 0; +fault: + if (vertex && vertex->references <= 0) + GLES2_EvictShader(renderer, vertex); + if (fragment && fragment->references <= 0) + GLES2_EvictShader(renderer, fragment); + rdata->current_program = NULL; + return -1; +} + +static int +GLES2_SetOrthographicProjection(SDL_Renderer *renderer) +{ + GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; + SDL_Window *window = renderer->window; + int w, h; + GLfloat projection[4][4]; + GLuint locProjection; + + /* Get the window width and height */ + SDL_GetWindowSize(window, &w, &h); + + /* Prepare an orthographic projection */ + projection[0][0] = 2.0f / w; + projection[0][1] = 0.0f; + projection[0][2] = 0.0f; + projection[0][3] = 0.0f; + projection[1][0] = 0.0f; + projection[1][1] = -2.0f / h; + projection[1][2] = 0.0f; + projection[1][3] = 0.0f; + projection[2][0] = 0.0f; + projection[2][1] = 0.0f; + projection[2][2] = 1.0f; + projection[2][3] = 0.0f; + projection[3][0] = -1.0f; + projection[3][1] = 1.0f; + projection[3][2] = 0.0f; + projection[3][3] = 1.0f; + + /* Set the projection matrix */ + locProjection = rdata->current_program->uniform_locations[GLES2_UNIFORM_PROJECTION]; + glGetError(); + glUniformMatrix4fv(locProjection, 1, GL_FALSE, (GLfloat *)projection); + if (glGetError() != GL_NO_ERROR) + { + SDL_SetError("Failed to set orthographic projection"); + return -1; + } + return 0; +} + +/************************************************************************************************* + * Rendering functions * + *************************************************************************************************/ + +static int GLES2_RenderClear(SDL_Renderer *renderer); +static int GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points, int count); +static int GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_Point *points, int count); +static int GLES2_RenderDrawRects(SDL_Renderer *renderer, const SDL_Rect **rects, int count); +static int GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_Rect **rects, int count); +static int GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, + const SDL_Rect *dstrect); +static void GLES2_RenderPresent(SDL_Renderer *renderer); + +static int +GLES2_RenderClear(SDL_Renderer *renderer) +{ + float r = (float)renderer->r / 255.0f; + float g = (float)renderer->g / 255.0f; + float b = (float)renderer->b / 255.0f; + float a = (float)renderer->a / 255.0f; + + GLES2_ActivateRenderer(renderer); + + /* Clear the backbuffer with the selected color */ + glClearColor(r, g, b, a); + glClear(GL_COLOR_BUFFER_BIT); + return 0; +} + +static void +GLES2_SetBlendMode(int blendMode) +{ + switch (blendMode) + { + case SDL_BLENDMODE_NONE: + default: + glDisable(GL_BLEND); + break; + case SDL_BLENDMODE_BLEND: + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA); + break; + case SDL_BLENDMODE_ADD: + glEnable(GL_BLEND); + glBlendFunc(GL_SRC_ALPHA, GL_ONE); + break; + case SDL_BLENDMODE_MOD: + glEnable(GL_BLEND); + glBlendFunc(GL_ZERO, GL_SRC_COLOR); + break; + } +} + +static int +GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_Point *points, int count) +{ + GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; + GLfloat *vertices; + SDL_BlendMode blendMode; + int alpha; + GLuint locColor; + int idx; + + GLES2_ActivateRenderer(renderer); + + blendMode = renderer->blendMode; + alpha = renderer->a; + + /* Activate an appropriate shader and set the projection matrix */ + if (GLES2_SelectProgram(renderer, GLES2_IMAGESOURCE_SOLID, blendMode) < 0) + return -1; + + /* Select the color to draw with */ + locColor = rdata->current_program->uniform_locations[GLES2_UNIFORM_COLOR]; + glGetError(); + glUniform4f(locColor, + renderer->r / 255.0f, + renderer->g / 255.0f, + renderer->b / 255.0f, + alpha / 255.0f); + + /* Configure the correct blend mode */ + GLES2_SetBlendMode(blendMode); + + /* Emit the specified vertices as points */ + vertices = SDL_stack_alloc(GLfloat, count * 2); + for (idx = 0; idx < count; ++idx) + { + GLfloat x = (GLfloat)points[idx].x + 0.5f; + GLfloat y = (GLfloat)points[idx].y + 0.5f; + + vertices[idx * 2] = x; + vertices[(idx * 2) + 1] = y; + } + glEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION); + glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices); + glDrawArrays(GL_POINTS, 0, count); + glDisableVertexAttribArray(GLES2_ATTRIBUTE_POSITION); + SDL_stack_free(vertices); + if (glGetError() != GL_NO_ERROR) + { + SDL_SetError("Failed to render lines"); + return -1; + } + return 0; +} + +static int +GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_Point *points, int count) +{ + GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; + GLfloat *vertices; + SDL_BlendMode blendMode; + int alpha; + GLuint locColor; + int idx; + + GLES2_ActivateRenderer(renderer); + + blendMode = renderer->blendMode; + alpha = renderer->a; + + /* Activate an appropriate shader and set the projection matrix */ + if (GLES2_SelectProgram(renderer, GLES2_IMAGESOURCE_SOLID, blendMode) < 0) + return -1; + + /* Select the color to draw with */ + locColor = rdata->current_program->uniform_locations[GLES2_UNIFORM_COLOR]; + glGetError(); + glUniform4f(locColor, + renderer->r / 255.0f, + renderer->g / 255.0f, + renderer->b / 255.0f, + alpha / 255.0f); + + /* Configure the correct blend mode */ + GLES2_SetBlendMode(blendMode); + + /* Emit a line strip including the specified vertices */ + vertices = SDL_stack_alloc(GLfloat, count * 2); + for (idx = 0; idx < count; ++idx) + { + GLfloat x = (GLfloat)points[idx].x + 0.5f; + GLfloat y = (GLfloat)points[idx].y + 0.5f; + + vertices[idx * 2] = x; + vertices[(idx * 2) + 1] = y; + } + glEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION); + glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices); + glDrawArrays(GL_LINE_STRIP, 0, count); + glDisableVertexAttribArray(GLES2_ATTRIBUTE_POSITION); + SDL_stack_free(vertices); + if (glGetError() != GL_NO_ERROR) + { + SDL_SetError("Failed to render lines"); + return -1; + } + return 0; +} + +static int +GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_Rect **rects, int count) +{ + GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; + GLfloat vertices[8]; + SDL_BlendMode blendMode; + int alpha; + GLuint locColor; + int idx; + + GLES2_ActivateRenderer(renderer); + + blendMode = renderer->blendMode; + alpha = renderer->a; + + /* Activate an appropriate shader and set the projection matrix */ + if (GLES2_SelectProgram(renderer, GLES2_IMAGESOURCE_SOLID, blendMode) < 0) + return -1; + + /* Select the color to draw with */ + locColor = rdata->current_program->uniform_locations[GLES2_UNIFORM_COLOR]; + glGetError(); + glUniform4f(locColor, + renderer->r / 255.0f, + renderer->g / 255.0f, + renderer->b / 255.0f, + alpha / 255.0f); + + /* Configure the correct blend mode */ + GLES2_SetBlendMode(blendMode); + + /* Emit a line loop for each rectangle */ + glEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION); + for (idx = 0; idx < count; ++idx) + { + GLfloat xMin = (GLfloat)rects[idx]->x; + GLfloat xMax = (GLfloat)(rects[idx]->x + rects[idx]->w); + GLfloat yMin = (GLfloat)rects[idx]->y; + GLfloat yMax = (GLfloat)(rects[idx]->y + rects[idx]->h); + + vertices[0] = xMin; + vertices[1] = yMin; + vertices[2] = xMax; + vertices[3] = yMin; + vertices[4] = xMin; + vertices[5] = yMax; + vertices[6] = xMax; + vertices[7] = yMax; + glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + } + glDisableVertexAttribArray(GLES2_ATTRIBUTE_POSITION); + if (glGetError() != GL_NO_ERROR) + { + SDL_SetError("Failed to render lines"); + return -1; + } + return 0; +} + +static int +GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, + const SDL_Rect *dstrect) +{ + GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata; + GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata; + GLES2_ImageSource sourceType; + SDL_BlendMode blendMode; + int alpha; + GLfloat vertices[8]; + GLfloat texCoords[8]; + GLuint locTexture; + GLuint locModulation; + GLuint locColorTable; + + GLES2_ActivateRenderer(renderer); + + /* Activate an appropriate shader and set the projection matrix */ + blendMode = texture->blendMode; + alpha = texture->a; + sourceType = GLES2_IMAGESOURCE_TEXTURE; + if (GLES2_SelectProgram(renderer, sourceType, blendMode) < 0) + return -1; + + /* Select the target texture */ + locTexture = rdata->current_program->uniform_locations[GLES2_UNIFORM_TEXTURE]; + glGetError(); + glActiveTexture(GL_TEXTURE0); + glBindTexture(tdata->texture_type, tdata->texture); + glUniform1i(locTexture, 0); + + /* Configure texture blending */ + GLES2_SetBlendMode(blendMode); + + /* Configure color modulation */ + locModulation = rdata->current_program->uniform_locations[GLES2_UNIFORM_MODULATION]; + glUniform4f(locModulation, + texture->r / 255.0f, + texture->g / 255.0f, + texture->b / 255.0f, + alpha / 255.0f); + + /* Emit the textured quad */ + glEnableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD); + glEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION); + vertices[0] = (GLfloat)dstrect->x; + vertices[1] = (GLfloat)dstrect->y; + vertices[2] = (GLfloat)(dstrect->x + dstrect->w); + vertices[3] = (GLfloat)dstrect->y; + vertices[4] = (GLfloat)dstrect->x; + vertices[5] = (GLfloat)(dstrect->y + dstrect->h); + vertices[6] = (GLfloat)(dstrect->x + dstrect->w); + vertices[7] = (GLfloat)(dstrect->y + dstrect->h); + glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices); + texCoords[0] = srcrect->x / (GLfloat)texture->w; + texCoords[1] = srcrect->y / (GLfloat)texture->h; + texCoords[2] = (srcrect->x + srcrect->w) / (GLfloat)texture->w; + texCoords[3] = srcrect->y / (GLfloat)texture->h; + texCoords[4] = srcrect->x / (GLfloat)texture->w; + texCoords[5] = (srcrect->y + srcrect->h) / (GLfloat)texture->h; + texCoords[6] = (srcrect->x + srcrect->w) / (GLfloat)texture->w; + texCoords[7] = (srcrect->y + srcrect->h) / (GLfloat)texture->h; + glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, texCoords); + glDrawArrays(GL_TRIANGLE_STRIP, 0, 4); + glDisableVertexAttribArray(GLES2_ATTRIBUTE_POSITION); + glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD); + if (glGetError() != GL_NO_ERROR) + { + SDL_SetError("Failed to render texture"); + return -1; + } + return 0; +} + +static void +GLES2_RenderPresent(SDL_Renderer *renderer) +{ + GLES2_ActivateRenderer(renderer); + + /* Tell the video driver to swap buffers */ + SDL_GL_SwapWindow(renderer->window); +} + +/************************************************************************************************* + * Renderer instantiation * + *************************************************************************************************/ + +#define GL_NVIDIA_PLATFORM_BINARY_NV 0x890B + +static SDL_Renderer * +GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) +{ + SDL_Renderer *renderer; + GLES2_DriverContext *rdata; + GLint nFormats; +#ifndef ZUNE_HD + GLboolean hasCompiler; +#endif + + /* Create the renderer struct */ + renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(SDL_Renderer)); + rdata = (GLES2_DriverContext *)SDL_calloc(1, sizeof(GLES2_DriverContext)); + if (!renderer) + { + SDL_OutOfMemory(); + SDL_free(renderer); + SDL_free(rdata); + return NULL; + } + renderer->info = GLES2_RenderDriver.info; + renderer->window = window; + renderer->driverdata = rdata; + + /* Create the GL context */ + rdata->context = SDL_GL_CreateContext(window); + if (!rdata->context) + { + SDL_free(renderer); + SDL_free(rdata); + return NULL; + } + + /* Determine supported shader formats */ + /* HACK: glGetInteger is broken on the Zune HD's compositor, so we just hardcode this */ + glGetError(); +#ifdef ZUNE_HD + nFormats = 1; +#else /* !ZUNE_HD */ + glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &nFormats); + glGetBooleanv(GL_SHADER_COMPILER, &hasCompiler); + if (hasCompiler) + ++nFormats; +#endif /* ZUNE_HD */ + rdata->shader_formats = (GLenum *)SDL_calloc(nFormats, sizeof(GLenum)); + if (!rdata->shader_formats) + { + SDL_OutOfMemory(); + SDL_free(renderer); + SDL_free(rdata); + return NULL; + } + rdata->shader_format_count = nFormats; +#ifdef ZUNE_HD + rdata->shader_formats[0] = GL_NVIDIA_PLATFORM_BINARY_NV; +#else /* !ZUNE_HD */ + glGetIntegerv(GL_SHADER_BINARY_FORMATS, (GLint *)rdata->shader_formats); + if (glGetError() != GL_NO_ERROR) + { + SDL_SetError("Failed to query supported shader formats"); + SDL_free(renderer); + SDL_free(rdata->shader_formats); + SDL_free(rdata); + return NULL; + } + if (hasCompiler) + rdata->shader_formats[nFormats - 1] = (GLenum)-1; +#endif /* ZUNE_HD */ + + /* Populate the function pointers for the module */ + renderer->WindowEvent = &GLES2_WindowEvent; + renderer->CreateTexture = &GLES2_CreateTexture; + renderer->UpdateTexture = &GLES2_UpdateTexture; + renderer->LockTexture = &GLES2_LockTexture; + renderer->UnlockTexture = &GLES2_UnlockTexture; + renderer->RenderClear = &GLES2_RenderClear; + renderer->RenderDrawPoints = &GLES2_RenderDrawPoints; + renderer->RenderDrawLines = &GLES2_RenderDrawLines; + renderer->RenderFillRects = &GLES2_RenderFillRects; + renderer->RenderCopy = &GLES2_RenderCopy; + renderer->RenderPresent = &GLES2_RenderPresent; + renderer->DestroyTexture = &GLES2_DestroyTexture; + renderer->DestroyRenderer = &GLES2_DestroyRenderer; + return renderer; +} + +#endif /* SDL_VIDEO_RENDER_OGL_ES2 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 01bced9a4cc1 -r 523409574510 src/render/opengles2/SDL_shaders_gles2.c --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/render/opengles2/SDL_shaders_gles2.c Sun Feb 06 00:00:13 2011 -0800 @@ -0,0 +1,550 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 2010 itsnotabigtruck. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "SDL_config.h" + +#if SDL_VIDEO_RENDER_OGL_ES2 + +#ifdef __IPHONEOS__ +#include +#include +#else +#include +#include +#endif +#include "SDL_video.h" +#include "SDL_shaders_gles2.h" +#include "SDL_stdinc.h" + +/************************************************************************************************* + * Vertex/fragment shader source * + *************************************************************************************************/ + +static const Uint8 GLES2_VertexSrc_Default_[] = " \ + uniform mat4 u_projection; \ + attribute vec4 a_position; \ + attribute vec2 a_texCoord; \ + varying vec2 v_texCoord; \ + \ + void main() \ + { \ + v_texCoord = a_texCoord; \ + gl_Position = u_projection * a_position; \ + gl_PointSize = 1.0; \ + } \ +"; + +static const Uint8 GLES2_FragmentSrc_SolidSrc_[] = " \ + precision mediump float; \ + uniform vec4 u_color; \ + \ + void main() \ + { \ + gl_FragColor = u_color; \ + } \ +"; + +static const Uint8 GLES2_FragmentSrc_TextureSrc_[] = " \ + precision mediump float; \ + uniform sampler2D u_texture; \ + uniform vec4 u_modulation; \ + varying vec2 v_texCoord; \ + \ + void main() \ + { \ + gl_FragColor = texture2D(u_texture, v_texCoord); \ + gl_FragColor *= u_modulation; \ + } \ +"; + +static const GLES2_ShaderInstance GLES2_VertexSrc_Default = { + GL_VERTEX_SHADER, + GLES2_SOURCE_SHADER, + sizeof(GLES2_VertexSrc_Default_), + GLES2_VertexSrc_Default_ +}; + +static const GLES2_ShaderInstance GLES2_FragmentSrc_SolidSrc = { + GL_FRAGMENT_SHADER, + GLES2_SOURCE_SHADER, + sizeof(GLES2_FragmentSrc_SolidSrc_), + GLES2_FragmentSrc_SolidSrc_ +}; + +static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureSrc = { + GL_FRAGMENT_SHADER, + GLES2_SOURCE_SHADER, + sizeof(GLES2_FragmentSrc_TextureSrc_), + GLES2_FragmentSrc_TextureSrc_ +}; + +/************************************************************************************************* + * Vertex/fragment shader binaries (NVIDIA Tegra 1/2) * + *************************************************************************************************/ + +#if GLES2_INCLUDE_NVIDIA_SHADERS + +#define GL_NVIDIA_PLATFORM_BINARY_NV 0x890B + +static const Uint8 GLES2_VertexTegra_Default_[] = { + 243, 193, 1, 142, 31, 109, 131, 38, 6, 0, 1, 0, 5, 0, 0, 0, 17, 0, 0, 0, 1, 0, 0, 0, 73, 0, + 0, 0, 46, 0, 0, 0, 48, 0, 0, 0, 2, 0, 0, 0, 85, 0, 0, 0, 2, 0, 0, 0, 24, 0, 0, 0, 3, 0, 0, 0, + 91, 0, 0, 0, 1, 0, 0, 0, 16, 0, 0, 0, 5, 0, 0, 0, 95, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 95, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, + 13, 0, 0, 0, 102, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 16, 0, 0, 0, 104, 0, 0, 0, 1, 0, 0, 0, 32, 0, 0, 0, 17, 0, 0, 0, 112, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 112, 0, 0, 0, 80, 0, 0, 0, 80, 0, 0, 0, 19, 0, 0, 0, 132, 0, + 0, 0, 104, 0, 0, 0, 104, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 110, 70, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 97, + 95, 112, 111, 115, 105, 116, 105, 111, 110, 0, 97, 95, 116, 101, 120, 67, 111, 111, 114, 100, + 0, 118, 95, 116, 101, 120, 67, 111, 111, 114, 100, 0, 117, 95, 112, 114, 111, 106, 101, 99, + 116, 105, 111, 110, 0, 0, 0, 0, 0, 0, 0, 82, 139, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 80, 139, 0, + 0, 1, 0, 0, 0, 22, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 33, 0, 0, 0, 92, 139, 0, 0, + 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 240, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 64, 0, 0, 0, 80, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 193, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 128, 63, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 66, 24, 0, 6, 34, 108, 28, + 0, 0, 42, 16, 128, 0, 195, 192, 6, 129, 252, 255, 65, 96, 108, 28, 0, 0, 0, 0, 0, 1, 195, 192, + 6, 1, 252, 255, 33, 96, 108, 156, 31, 64, 8, 1, 64, 0, 131, 192, 6, 1, 156, 159, 65, 96, 108, + 28, 0, 0, 85, 32, 0, 1, 195, 192, 6, 1, 252, 255, 33, 96, 108, 156, 31, 64, 0, 64, 64, 0, 131, + 192, 134, 1, 152, 31, 65, 96, 108, 156, 31, 64, 127, 48, 0, 1, 195, 192, 6, 129, 129, 255, 33, + 96 +}; + +static const Uint8 GLES2_FragmentTegra_None_SolidSrc_[] = { + 155, 191, 159, 1, 47, 109, 131, 38, 6, 0, 1, 0, 5, 0, 0, 0, 17, 0, 0, 0, 1, 0, 0, 0, 73, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 75, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, + 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 75, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 13, 0, + 0, 0, 82, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 14, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 22, 0, 0, 0, 84, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 23, 0, 0, 0, 92, 0, 0, 0, 1, 0, 0, 0, 4, + 0, 0, 0, 15, 0, 0, 0, 93, 0, 0, 0, 1, 0, 0, 0, 80, 0, 0, 0, 17, 0, 0, 0, 113, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 113, 0, 0, + 0, 108, 0, 0, 0, 108, 0, 0, 0, 20, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, + 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 110, 70, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 117, 95, 99, 111, 108, 111, 114, 0, 0, 0, 0, 0, 82, 139, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 48, 0, 0, 0, 0, 0, 0, 0, 0, 0, 241, 0, 0, 0, 240, 0, 0, + 0, 240, 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 0, 0, + 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 21, 32, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 20, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 82, 50, 48, 45, 66, 73, 78, 1, + 0, 0, 0, 1, 0, 0, 0, 1, 0, 65, 37, 0, 0, 0, 0, 1, 0, 0, 21, 0, 0, 0, 0, 1, 0, 1, 38, 0, 0, 0, + 0, 1, 0, 1, 39, 0, 0, 0, 0, 1, 0, 1, 40, 1, 0, 0, 0, 8, 0, 4, 40, 0, 40, 0, 0, 0, 242, 65, 63, + 192, 200, 0, 0, 0, 242, 65, 63, 128, 168, 0, 0, 0, 242, 65, 63, 64, 72, 0, 0, 0, 242, 65, 63, + 1, 0, 6, 40, 0, 0, 0, 0, 1, 0, 1, 41, 5, 0, 2, 0 +}; + +static const Uint8 GLES2_FragmentTegra_Alpha_SolidSrc_[] = { + 169, 153, 195, 28, 47, 109, 131, 38, 6, 0, 1, 0, 5, 0, 0, 0, 17, 0, 0, 0, 1, 0, 0, 0, 73, 0, + 0, 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 75, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, + 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 75, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 13, 0, + 0, 0, 82, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 14, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 22, 0, 0, 0, 84, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 23, 0, 0, 0, 92, 0, 0, 0, 1, 0, 0, 0, 4, + 0, 0, 0, 15, 0, 0, 0, 93, 0, 0, 0, 1, 0, 0, 0, 80, 0, 0, 0, 17, 0, 0, 0, 113, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 113, 0, 0, + 0, 220, 0, 0, 0, 220, 0, 0, 0, 20, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, + 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 110, 70, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 117, 95, 99, 111, 108, 111, 114, 0, 0, 0, 0, 0, 82, 139, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 48, 0, 0, 0, 0, 0, 0, 118, 118, 17, 241, 0, 0, 0, 240, 0, + 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 3, 0, 0, 0, 21, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 82, 50, 48, 45, 66, 73, 78, + 1, 0, 0, 0, 3, 0, 0, 0, 3, 0, 65, 37, 8, 0, 129, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 21, 0, + 0, 0, 0, 3, 0, 1, 38, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 39, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 3, 0, 1, 40, 1, 0, 0, 0, 5, 0, 0, 0, 9, 0, 0, 0, 24, 0, 4, 40, 232, 231, 15, + 0, 0, 242, 65, 62, 194, 72, 1, 0, 0, 250, 65, 63, 194, 40, 1, 0, 0, 250, 65, 63, 192, 168, 1, + 0, 0, 242, 1, 64, 192, 168, 1, 0, 0, 242, 1, 68, 168, 32, 0, 0, 0, 50, 64, 0, 192, 168, 15, + 0, 0, 242, 1, 66, 168, 64, 0, 16, 0, 242, 65, 1, 232, 231, 15, 0, 0, 242, 65, 62, 168, 160, + 0, 0, 0, 50, 64, 2, 104, 192, 0, 0, 36, 48, 66, 4, 232, 231, 15, 0, 0, 242, 65, 62, 3, 0, 6, + 40, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 3, 0, 1, 41, 0, 0, 0, 0, 0, 0, 0, 0, 5, 0, 2, 0 +}; + +static const Uint8 GLES2_FragmentTegra_Additive_SolidSrc_[] = { + 59, 71, 42, 17, 47, 109, 131, 38, 6, 0, 1, 0, 5, 0, 0, 0, 17, 0, 0, 0, 1, 0, 0, 0, 73, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 75, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, + 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 75, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 13, 0, + 0, 0, 82, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 14, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 22, 0, 0, 0, 84, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 23, 0, 0, 0, 92, 0, 0, 0, 1, 0, 0, 0, 4, + 0, 0, 0, 15, 0, 0, 0, 93, 0, 0, 0, 1, 0, 0, 0, 80, 0, 0, 0, 17, 0, 0, 0, 113, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 113, 0, 0, + 0, 108, 0, 0, 0, 108, 0, 0, 0, 20, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, + 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 110, 70, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 117, 95, 99, 111, 108, 111, 114, 0, 0, 0, 0, 0, 82, 139, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 48, 0, 0, 0, 0, 0, 0, 22, 22, 17, 241, 0, 0, 0, 240, 0, + 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 21, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 82, 50, 48, 45, 66, 73, 78, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 65, 37, 8, 0, 129, 0, 1, 0, 0, 21, 0, 0, 0, 0, 1, 0, 1, 38, 0, + 0, 0, 0, 1, 0, 1, 39, 0, 0, 0, 0, 1, 0, 1, 40, 1, 0, 0, 0, 8, 0, 4, 40, 192, 200, 0, 0, 0, 26, + 0, 70, 192, 40, 0, 0, 0, 2, 0, 64, 192, 72, 0, 0, 0, 10, 0, 66, 192, 168, 0, 0, 0, 18, 0, 68, + 1, 0, 6, 40, 0, 0, 0, 0, 1, 0, 1, 41, 5, 0, 2, 0 +}; + +static const Uint8 GLES2_FragmentTegra_Modulated_SolidSrc_[] = { + 37, 191, 49, 17, 47, 109, 131, 38, 6, 0, 1, 0, 5, 0, 0, 0, 17, 0, 0, 0, 1, 0, 0, 0, 73, 0, 0, + 0, 8, 0, 0, 0, 8, 0, 0, 0, 2, 0, 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, 75, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 6, 0, 0, 0, 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, 0, 0, + 75, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 75, 0, 0, 0, 1, 0, 0, 0, 28, 0, 0, 0, 13, 0, + 0, 0, 82, 0, 0, 0, 2, 0, 0, 0, 8, 0, 0, 0, 14, 0, 0, 0, 84, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 22, 0, 0, 0, 84, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 23, 0, 0, 0, 92, 0, 0, 0, 1, 0, 0, 0, 4, + 0, 0, 0, 15, 0, 0, 0, 93, 0, 0, 0, 1, 0, 0, 0, 80, 0, 0, 0, 17, 0, 0, 0, 113, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 113, 0, 0, + 0, 108, 0, 0, 0, 108, 0, 0, 0, 20, 0, 0, 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, 0, 0, + 0, 113, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 110, 70, 73, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 117, 95, 99, 111, 108, 111, 114, 0, 0, 0, 0, 0, 82, 139, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 5, 48, 0, 0, 0, 0, 0, 0, 32, 32, 17, 241, 0, 0, 0, 240, 0, + 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 0, + 0, 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 2, 0, 0, 0, 1, 0, 0, 0, 1, 0, 0, 0, 21, 32, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 20, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 65, 82, 50, 48, 45, 66, 73, 78, + 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 65, 37, 8, 0, 129, 0, 1, 0, 0, 21, 0, 0, 0, 0, 1, 0, 1, 38, 0, + 0, 0, 0, 1, 0, 1, 39, 0, 0, 0, 0, 1, 0, 1, 40, 1, 0, 0, 0, 8, 0, 4, 40, 104, 192, 0, 0, 0, 242, + 1, 70, 8, 32, 0, 0, 0, 242, 1, 64, 40, 64, 0, 0, 0, 242, 1, 66, 72, 160, 0, 0, 0, 242, 1, 68, + 1, 0, 6, 40, 0, 0, 0, 0, 1, 0, 1, 41, 5, 0, 2, 0 +}; + +static const Uint8 GLES2_FragmentTegra_None_TextureSrc_[] = { + 220, 217, 41, 211, 47, 109, 131, 38, 6, 0, 1, 0, 5, 0, 0, 0, 17, 0, 0, 0, 1, 0, 0, 0, 73, 0, + 0, 0, 34, 0, 0, 0, 36, 0, 0, 0, 2, 0, 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, + 82, 0, 0, 0, 1, 0, 0, 0, 20, 0, 0, 0, 6, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, + 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 87, 0, 0, 0, 2, 0, 0, 0, 56, 0, 0, 0, + 13, 0, 0, 0, 101, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 14, 0, 0, 0, 105, 0, 0, 0, 1, 0, 0, 0, 4, + 0, 0, 0, 22, 0, 0, 0, 106, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 23, 0, 0, 0, 114, 0, 0, 0, 1, 0, + 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 115, 0, 0, 0, 1, 0, 0, 0, 80, 0, 0, 0, 17, 0, 0, 0, 135, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 135, + 0, 0, 0, 120, 0, 0, 0, 120, 0, 0, 0, 20, 0, 0, 0, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, + 0, 0, 0, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 110, 70, 73, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 118, 95, 116, 101, 120, 67, 111, 111, 114, 100, 0, 117, 95, 109, 111, 100, 117, 108, + 97, 116, 105, 111, 110, 0, 117, 95, 116, 101, 120, 116, 117, 114, 101, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 82, 139, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 94, 139, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 5, 48, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 0, 0, 0, 241, 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 240, + 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 0, 0, 0, 0, 1, 0, + 0, 0, 1, 0, 0, 0, 21, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 65, 82, 50, 48, 45, 66, 73, 78, 1, 0, 0, 0, 1, 0, 0, 0, 1, 0, 65, 37, 0, 0, 0, 0, 1, 0, + 0, 21, 0, 0, 0, 0, 1, 0, 1, 38, 1, 0, 0, 0, 2, 0, 4, 38, 186, 81, 78, 16, 2, 1, 0, 0, 1, 0, + 1, 39, 0, 4, 0, 0, 1, 0, 1, 40, 1, 0, 0, 0, 8, 0, 4, 40, 104, 192, 0, 0, 0, 242, 1, 70, 8, 32, + 0, 0, 0, 242, 1, 64, 40, 64, 0, 0, 0, 242, 1, 66, 72, 160, 0, 0, 0, 242, 1, 68, 1, 0, 6, 40, + 0, 0, 0, 0, 1, 0, 1, 41, 5, 0, 2, 0 +}; + +static const Uint8 GLES2_FragmentTegra_Alpha_TextureSrc_[] = { + 71, 202, 114, 229, 47, 109, 131, 38, 6, 0, 1, 0, 5, 0, 0, 0, 17, 0, 0, 0, 1, 0, 0, 0, 73, 0, + 0, 0, 34, 0, 0, 0, 36, 0, 0, 0, 2, 0, 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, + 82, 0, 0, 0, 1, 0, 0, 0, 20, 0, 0, 0, 6, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, + 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 87, 0, 0, 0, 2, 0, 0, 0, 56, 0, 0, 0, + 13, 0, 0, 0, 101, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 14, 0, 0, 0, 105, 0, 0, 0, 1, 0, 0, 0, 4, + 0, 0, 0, 22, 0, 0, 0, 106, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 23, 0, 0, 0, 114, 0, 0, 0, 1, 0, + 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 115, 0, 0, 0, 1, 0, 0, 0, 80, 0, 0, 0, 17, 0, 0, 0, 135, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 135, + 0, 0, 0, 176, 0, 0, 0, 176, 0, 0, 0, 20, 0, 0, 0, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, + 0, 0, 0, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 110, 70, 73, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 118, 95, 116, 101, 120, 67, 111, 111, 114, 100, 0, 117, 95, 109, 111, 100, 117, 108, + 97, 116, 105, 111, 110, 0, 117, 95, 116, 101, 120, 116, 117, 114, 101, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 82, 139, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 94, 139, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 5, 48, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 118, 118, 17, 241, 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, + 240, 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 2, 0, 0, 0, + 1, 0, 0, 0, 2, 0, 0, 0, 21, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 16, 0, 0, 0, 16, + 0, 0, 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 0, 65, 82, 50, 48, 45, 66, 73, 78, 1, 0, 0, 0, 2, 0, 0, 0, 2, 0, 65, 37, 0, 0, 0, 0, + 8, 0, 129, 0, 1, 0, 0, 21, 0, 0, 0, 0, 2, 0, 1, 38, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 38, 186, + 81, 78, 16, 2, 1, 0, 0, 2, 0, 1, 39, 0, 4, 0, 0, 0, 0, 0, 0, 2, 0, 1, 40, 1, 0, 0, 0, 5, 0, + 0, 0, 16, 0, 4, 40, 40, 160, 1, 0, 0, 242, 1, 66, 8, 192, 1, 0, 0, 242, 1, 64, 104, 32, 1, 0, + 0, 242, 1, 70, 72, 64, 1, 0, 0, 242, 1, 68, 154, 192, 0, 0, 37, 34, 64, 3, 8, 32, 0, 0, 5, 58, + 208, 4, 40, 64, 0, 0, 5, 50, 208, 4, 72, 160, 0, 0, 37, 42, 208, 4, 2, 0, 6, 40, 0, 0, 0, 0, + 0, 0, 0, 0, 2, 0, 1, 41, 0, 0, 0, 0, 5, 0, 2, 0 +}; + +static const Uint8 GLES2_FragmentTegra_Additive_TextureSrc_[] = { + 161, 234, 193, 234, 47, 109, 131, 38, 6, 0, 1, 0, 5, 0, 0, 0, 17, 0, 0, 0, 1, 0, 0, 0, 73, 0, + 0, 0, 34, 0, 0, 0, 36, 0, 0, 0, 2, 0, 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, + 82, 0, 0, 0, 1, 0, 0, 0, 20, 0, 0, 0, 6, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, + 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 87, 0, 0, 0, 2, 0, 0, 0, 56, 0, 0, 0, + 13, 0, 0, 0, 101, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 14, 0, 0, 0, 105, 0, 0, 0, 1, 0, 0, 0, 4, + 0, 0, 0, 22, 0, 0, 0, 106, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 23, 0, 0, 0, 114, 0, 0, 0, 1, 0, + 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 115, 0, 0, 0, 1, 0, 0, 0, 80, 0, 0, 0, 17, 0, 0, 0, 135, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 135, + 0, 0, 0, 176, 0, 0, 0, 176, 0, 0, 0, 20, 0, 0, 0, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, + 0, 0, 0, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 110, 70, 73, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 118, 95, 116, 101, 120, 67, 111, 111, 114, 100, 0, 117, 95, 109, 111, 100, 117, 108, + 97, 116, 105, 111, 110, 0, 117, 95, 116, 101, 120, 116, 117, 114, 101, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 82, 139, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 94, 139, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 5, 48, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 22, 22, 17, 241, 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 240, + 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 2, 0, 0, 0, 1, 0, + 0, 0, 2, 0, 0, 0, 21, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 65, 82, 50, 48, 45, 66, 73, 78, 1, 0, 0, 0, 2, 0, 0, 0, 2, 0, 65, 37, 0, 0, 0, 0, 8, 0, + 129, 0, 1, 0, 0, 21, 0, 0, 0, 0, 2, 0, 1, 38, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 38, 186, 81, + 78, 16, 2, 1, 0, 0, 2, 0, 1, 39, 0, 4, 0, 0, 0, 0, 0, 0, 2, 0, 1, 40, 1, 0, 0, 0, 5, 0, 0, 0, + 16, 0, 4, 40, 40, 160, 1, 0, 0, 242, 1, 66, 104, 32, 1, 0, 0, 242, 1, 70, 8, 192, 1, 0, 0, 242, + 1, 64, 72, 64, 1, 0, 0, 242, 1, 68, 136, 192, 0, 0, 0, 26, 64, 4, 136, 32, 0, 0, 0, 2, 64, 7, + 136, 64, 0, 0, 0, 10, 64, 6, 136, 160, 0, 0, 0, 18, 64, 5, 2, 0, 6, 40, 0, 0, 0, 0, 0, 0, 0, + 0, 2, 0, 1, 41, 0, 0, 0, 0, 5, 0, 2, 0 +}; + +static const Uint8 GLES2_FragmentTegra_Modulated_TextureSrc_[] = { + 75, 132, 201, 227, 47, 109, 131, 38, 6, 0, 1, 0, 5, 0, 0, 0, 17, 0, 0, 0, 1, 0, 0, 0, 73, 0, + 0, 0, 34, 0, 0, 0, 36, 0, 0, 0, 2, 0, 0, 0, 82, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 0, 0, 0, + 82, 0, 0, 0, 1, 0, 0, 0, 20, 0, 0, 0, 6, 0, 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 7, 0, + 0, 0, 87, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 8, 0, 0, 0, 87, 0, 0, 0, 2, 0, 0, 0, 56, 0, 0, 0, + 13, 0, 0, 0, 101, 0, 0, 0, 4, 0, 0, 0, 16, 0, 0, 0, 14, 0, 0, 0, 105, 0, 0, 0, 1, 0, 0, 0, 4, + 0, 0, 0, 22, 0, 0, 0, 106, 0, 0, 0, 8, 0, 0, 0, 32, 0, 0, 0, 23, 0, 0, 0, 114, 0, 0, 0, 1, 0, + 0, 0, 4, 0, 0, 0, 15, 0, 0, 0, 115, 0, 0, 0, 1, 0, 0, 0, 80, 0, 0, 0, 17, 0, 0, 0, 135, 0, 0, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 18, 0, 0, 0, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 19, 0, 0, 0, 135, + 0, 0, 0, 176, 0, 0, 0, 176, 0, 0, 0, 20, 0, 0, 0, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 21, + 0, 0, 0, 135, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 109, 97, 110, 70, 73, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 0, 118, 95, 116, 101, 120, 67, 111, 111, 114, 100, 0, 117, 95, 109, 111, 100, 117, 108, + 97, 116, 105, 111, 110, 0, 117, 95, 116, 101, 120, 116, 117, 114, 101, 0, 0, 0, 0, 0, 0, 0, + 2, 0, 0, 0, 0, 0, 0, 0, 220, 0, 0, 0, 0, 0, 0, 0, 11, 0, 0, 0, 82, 139, 0, 0, 1, 0, 0, 0, 1, + 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 94, 139, 0, 0, 1, 0, 0, 0, 1, 0, 0, + 0, 2, 0, 0, 0, 16, 0, 0, 0, 0, 0, 0, 0, 5, 48, 0, 0, 0, 0, 0, 0, 3, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 1, 32, 32, 17, 241, 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 240, + 0, 0, 0, 240, 0, 0, 0, 240, 0, 0, 0, 0, 0, 0, 0, 0, 1, 0, 0, 0, 7, 0, 0, 0, 2, 0, 0, 0, 1, 0, + 0, 0, 2, 0, 0, 0, 21, 32, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 24, 0, 0, 0, 16, 0, 0, 0, 16, 0, 0, + 0, 0, 0, 0, 0, 2, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, + 0, 0, 65, 82, 50, 48, 45, 66, 73, 78, 1, 0, 0, 0, 2, 0, 0, 0, 2, 0, 65, 37, 0, 0, 0, 0, 8, 0, + 129, 0, 1, 0, 0, 21, 0, 0, 0, 0, 2, 0, 1, 38, 1, 0, 0, 0, 0, 0, 0, 0, 2, 0, 4, 38, 186, 81, + 78, 16, 2, 1, 0, 0, 2, 0, 1, 39, 0, 4, 0, 0, 0, 0, 0, 0, 2, 0, 1, 40, 1, 0, 0, 0, 5, 0, 0, 0, + 16, 0, 4, 40, 40, 160, 1, 0, 0, 242, 1, 66, 8, 192, 1, 0, 0, 242, 1, 64, 104, 32, 1, 0, 0, 242, + 1, 70, 72, 64, 1, 0, 0, 242, 1, 68, 104, 192, 0, 0, 0, 242, 65, 4, 232, 32, 0, 0, 0, 242, 65, + 0, 40, 64, 0, 0, 0, 242, 65, 6, 72, 160, 0, 0, 0, 242, 65, 5, 2, 0, 6, 40, 0, 0, 0, 0, 0, 0, + 0, 0, 2, 0, 1, 41, 0, 0, 0, 0, 5, 0, 2, 0 +}; + +static const GLES2_ShaderInstance GLES2_VertexTegra_Default = { + GL_VERTEX_SHADER, + GL_NVIDIA_PLATFORM_BINARY_NV, + sizeof(GLES2_VertexTegra_Default_), + GLES2_VertexTegra_Default_ +}; + +static const GLES2_ShaderInstance GLES2_FragmentTegra_None_SolidSrc = { + GL_FRAGMENT_SHADER, + GL_NVIDIA_PLATFORM_BINARY_NV, + sizeof(GLES2_FragmentTegra_None_SolidSrc_), + GLES2_FragmentTegra_None_SolidSrc_ +}; + +static const GLES2_ShaderInstance GLES2_FragmentTegra_Alpha_SolidSrc = { + GL_FRAGMENT_SHADER, + GL_NVIDIA_PLATFORM_BINARY_NV, + sizeof(GLES2_FragmentTegra_Alpha_SolidSrc_), + GLES2_FragmentTegra_Alpha_SolidSrc_ +}; + +static const GLES2_ShaderInstance GLES2_FragmentTegra_Additive_SolidSrc = { + GL_FRAGMENT_SHADER, + GL_NVIDIA_PLATFORM_BINARY_NV, + sizeof(GLES2_FragmentTegra_Additive_SolidSrc_), + GLES2_FragmentTegra_Additive_SolidSrc_ +}; + +static const GLES2_ShaderInstance GLES2_FragmentTegra_Modulated_SolidSrc = { + GL_FRAGMENT_SHADER, + GL_NVIDIA_PLATFORM_BINARY_NV, + sizeof(GLES2_FragmentTegra_Modulated_SolidSrc_), + GLES2_FragmentTegra_Modulated_SolidSrc_ +}; + +static const GLES2_ShaderInstance GLES2_FragmentTegra_None_TextureSrc = { + GL_FRAGMENT_SHADER, + GL_NVIDIA_PLATFORM_BINARY_NV, + sizeof(GLES2_FragmentTegra_None_TextureSrc_), + GLES2_FragmentTegra_None_TextureSrc_ +}; + +static const GLES2_ShaderInstance GLES2_FragmentTegra_Alpha_TextureSrc = { + GL_FRAGMENT_SHADER, + GL_NVIDIA_PLATFORM_BINARY_NV, + sizeof(GLES2_FragmentTegra_Alpha_TextureSrc_), + GLES2_FragmentTegra_Alpha_TextureSrc_ +}; + +static const GLES2_ShaderInstance GLES2_FragmentTegra_Additive_TextureSrc = { + GL_FRAGMENT_SHADER, + GL_NVIDIA_PLATFORM_BINARY_NV, + sizeof(GLES2_FragmentTegra_Additive_TextureSrc_), + GLES2_FragmentTegra_Additive_TextureSrc_ +}; + +static const GLES2_ShaderInstance GLES2_FragmentTegra_Modulated_TextureSrc = { + GL_FRAGMENT_SHADER, + GL_NVIDIA_PLATFORM_BINARY_NV, + sizeof(GLES2_FragmentTegra_Modulated_TextureSrc_), + GLES2_FragmentTegra_Modulated_TextureSrc_ +}; + +#endif /* GLES2_INCLUDE_NVIDIA_SHADERS */ + +/************************************************************************************************* + * Vertex/fragment shader definitions * + *************************************************************************************************/ + +static GLES2_Shader GLES2_VertexShader_Default = { + 2, + { +#if GLES2_INCLUDE_NVIDIA_SHADERS + &GLES2_VertexTegra_Default, +#endif + &GLES2_VertexSrc_Default + } +}; + +static GLES2_Shader GLES2_FragmentShader_None_SolidSrc = { + 2, + { +#if GLES2_INCLUDE_NVIDIA_SHADERS + &GLES2_FragmentTegra_None_SolidSrc, +#endif + &GLES2_FragmentSrc_SolidSrc + } +}; + +static GLES2_Shader GLES2_FragmentShader_Alpha_SolidSrc = { + 2, + { +#if GLES2_INCLUDE_NVIDIA_SHADERS + &GLES2_FragmentTegra_Alpha_SolidSrc, +#endif + &GLES2_FragmentSrc_SolidSrc + } +}; + +static GLES2_Shader GLES2_FragmentShader_Additive_SolidSrc = { + 2, + { +#if GLES2_INCLUDE_NVIDIA_SHADERS + &GLES2_FragmentTegra_Additive_SolidSrc, +#endif + &GLES2_FragmentSrc_SolidSrc + } +}; + +static GLES2_Shader GLES2_FragmentShader_Modulated_SolidSrc = { + 2, + { +#if GLES2_INCLUDE_NVIDIA_SHADERS + &GLES2_FragmentTegra_Modulated_SolidSrc, +#endif + &GLES2_FragmentSrc_SolidSrc + } +}; + +static GLES2_Shader GLES2_FragmentShader_None_TextureSrc = { + 2, + { +#if GLES2_INCLUDE_NVIDIA_SHADERS + &GLES2_FragmentTegra_None_TextureSrc, +#endif + &GLES2_FragmentSrc_TextureSrc + } +}; + +static GLES2_Shader GLES2_FragmentShader_Alpha_TextureSrc = { + 2, + { +#if GLES2_INCLUDE_NVIDIA_SHADERS + &GLES2_FragmentTegra_Alpha_TextureSrc, +#endif + &GLES2_FragmentSrc_TextureSrc + } +}; + +static GLES2_Shader GLES2_FragmentShader_Additive_TextureSrc = { + 2, + { +#if GLES2_INCLUDE_NVIDIA_SHADERS + &GLES2_FragmentTegra_Additive_TextureSrc, +#endif + &GLES2_FragmentSrc_TextureSrc + } +}; + +static GLES2_Shader GLES2_FragmentShader_Modulated_TextureSrc = { + 2, + { +#if GLES2_INCLUDE_NVIDIA_SHADERS + &GLES2_FragmentTegra_Modulated_TextureSrc, +#endif + &GLES2_FragmentSrc_TextureSrc + } +}; + +/************************************************************************************************* + * Shader selector * + *************************************************************************************************/ + +const GLES2_Shader *GLES2_GetShader(GLES2_ShaderType type, SDL_BlendMode blendMode) +{ + switch (type) + { + case GLES2_SHADER_VERTEX_DEFAULT: + return &GLES2_VertexShader_Default; + case GLES2_SHADER_FRAGMENT_SOLID_SRC: + switch (blendMode) + { + case SDL_BLENDMODE_NONE: + return &GLES2_FragmentShader_None_SolidSrc; + case SDL_BLENDMODE_BLEND: + return &GLES2_FragmentShader_Alpha_SolidSrc; + case SDL_BLENDMODE_ADD: + return &GLES2_FragmentShader_Additive_SolidSrc; + case SDL_BLENDMODE_MOD: + return &GLES2_FragmentShader_Modulated_SolidSrc; + default: + return NULL; + } + case GLES2_SHADER_FRAGMENT_TEXTURE_SRC: + switch (blendMode) + { + case SDL_BLENDMODE_NONE: + return &GLES2_FragmentShader_None_TextureSrc; + case SDL_BLENDMODE_BLEND: + return &GLES2_FragmentShader_Alpha_TextureSrc; + case SDL_BLENDMODE_ADD: + return &GLES2_FragmentShader_Additive_TextureSrc; + case SDL_BLENDMODE_MOD: + return &GLES2_FragmentShader_Modulated_TextureSrc; + default: + return NULL; + } + default: + return NULL; + } +} + +#endif /* SDL_VIDEO_RENDER_OGL_ES2 */ + +/* vi: set ts=4 sw=4 expandtab: */ diff -r 01bced9a4cc1 -r 523409574510 src/render/opengles2/SDL_shaders_gles2.h --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/render/opengles2/SDL_shaders_gles2.h Sun Feb 06 00:00:13 2011 -0800 @@ -0,0 +1,66 @@ +/* + SDL - Simple DirectMedia Layer + Copyright (C) 2010 itsnotabigtruck. + + Permission is hereby granted, free of charge, to any person obtaining a + copy of this software and associated documentation files (the "Software"), + to deal in the Software without restriction, including without limitation + the rights to use, copy, modify, merge, publish, distribute, sublicense, + and/or sell copies of the Software, and to permit persons to whom the + Software is furnished to do so, subject to the following conditions: + + The above copyright notice and this permission notice shall be included in + all copies or substantial portions of the Software. + + THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER + DEALINGS IN THE SOFTWARE. +*/ + +#include "SDL_config.h" + +#if SDL_VIDEO_RENDER_OGL_ES2 + +#ifndef SDL_shaderdata_h_ +#define SDL_shaderdata_h_ + +#ifdef __IPHONEOS__ +#include +#else +#include +#endif + +typedef struct GLES2_ShaderInstance +{ + GLenum type; + GLenum format; + int length; + const void *data; +} GLES2_ShaderInstance; + +typedef struct GLES2_Shader +{ + int instance_count; + const GLES2_ShaderInstance *instances[4]; +} GLES2_Shader; + +typedef enum +{ + GLES2_SHADER_VERTEX_DEFAULT, + GLES2_SHADER_FRAGMENT_SOLID_SRC, + GLES2_SHADER_FRAGMENT_TEXTURE_SRC +} GLES2_ShaderType; + +#define GLES2_SOURCE_SHADER (GLenum)-1 + +const GLES2_Shader *GLES2_GetShader(GLES2_ShaderType type, SDL_BlendMode blendMode); + +#endif /* SDL_shaderdata_h_ */ + +#endif /* SDL_VIDEO_RENDER_OGL_ES2 */ + +/* vi: set ts=4 sw=4 expandtab: */