GLES2 SDL_Renderer: remove old ZUNE_HD defines and simplify shader cache

This commit is contained in:
Sylvain Becker 2021-01-25 22:17:11 +01:00
parent aa4a6b0b88
commit f40551c5f6
4 changed files with 128 additions and 511 deletions

View file

@ -41,7 +41,6 @@ SDL_PROC(void, glEnableVertexAttribArray, (GLuint))
SDL_PROC(void, glFinish, (void)) SDL_PROC(void, glFinish, (void))
SDL_PROC(void, glGenFramebuffers, (GLsizei, GLuint *)) SDL_PROC(void, glGenFramebuffers, (GLsizei, GLuint *))
SDL_PROC(void, glGenTextures, (GLsizei, GLuint *)) SDL_PROC(void, glGenTextures, (GLsizei, GLuint *))
SDL_PROC(void, glGetBooleanv, (GLenum, GLboolean *))
SDL_PROC(const GLubyte *, glGetString, (GLenum)) SDL_PROC(const GLubyte *, glGetString, (GLenum))
SDL_PROC(GLenum, glGetError, (void)) SDL_PROC(GLenum, glGetError, (void))
SDL_PROC(void, glGetIntegerv, (GLenum, GLint *)) SDL_PROC(void, glGetIntegerv, (GLenum, GLint *))

View file

@ -68,27 +68,11 @@ typedef struct GLES2_TextureData
GLES2_FBOList *fbo; GLES2_FBOList *fbo;
} GLES2_TextureData; } 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 typedef struct GLES2_ProgramCacheEntry
{ {
GLuint id; GLuint id;
GLES2_ShaderCacheEntry *vertex_shader; GLuint vertex_shader;
GLES2_ShaderCacheEntry *fragment_shader; GLuint fragment_shader;
GLuint uniform_locations[16]; GLuint uniform_locations[16];
Uint32 color; Uint32 color;
GLfloat projection[4][4]; GLfloat projection[4][4];
@ -167,9 +151,8 @@ typedef struct GLES2_RenderData
GLES2_FBOList *framebuffers; GLES2_FBOList *framebuffers;
GLuint window_framebuffer; GLuint window_framebuffer;
int shader_format_count; GLuint shader_id_cache[GLES2_SHADER_COUNT];
GLenum *shader_formats;
GLES2_ShaderCache shader_cache;
GLES2_ProgramCache program_cache; GLES2_ProgramCache program_cache;
Uint8 clear_r, clear_g, clear_b, clear_a; Uint8 clear_r, clear_g, clear_b, clear_a;
@ -395,32 +378,10 @@ GLES2_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode)
} }
static void
GLES2_EvictShader(GLES2_RenderData *data, GLES2_ShaderCacheEntry *entry)
{
/* Unlink the shader from the cache */
if (entry->next) {
entry->next->prev = entry->prev;
}
if (entry->prev) {
entry->prev->next = entry->next;
}
if (data->shader_cache.head == entry) {
data->shader_cache.head = entry->next;
}
--data->shader_cache.count;
/* Deallocate the shader */
data->glDeleteShader(entry->id);
SDL_free(entry);
}
static GLES2_ProgramCacheEntry * static GLES2_ProgramCacheEntry *
GLES2_CacheProgram(GLES2_RenderData *data, GLES2_ShaderCacheEntry *vertex, GLES2_CacheProgram(GLES2_RenderData *data, GLuint vertex, GLuint fragment)
GLES2_ShaderCacheEntry *fragment)
{ {
GLES2_ProgramCacheEntry *entry; GLES2_ProgramCacheEntry *entry;
GLES2_ShaderCacheEntry *shaderEntry;
GLint linkSuccessful; GLint linkSuccessful;
/* Check if we've already cached this program */ /* Check if we've already cached this program */
@ -458,8 +419,8 @@ GLES2_CacheProgram(GLES2_RenderData *data, GLES2_ShaderCacheEntry *vertex,
/* Create the program and link it */ /* Create the program and link it */
entry->id = data->glCreateProgram(); entry->id = data->glCreateProgram();
data->glAttachShader(entry->id, vertex->id); data->glAttachShader(entry->id, vertex);
data->glAttachShader(entry->id, fragment->id); data->glAttachShader(entry->id, fragment);
data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_POSITION, "a_position"); data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_POSITION, "a_position");
data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_TEXCOORD, "a_texCoord"); data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_TEXCOORD, "a_texCoord");
data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_ANGLE, "a_angle"); data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_ANGLE, "a_angle");
@ -514,20 +475,8 @@ GLES2_CacheProgram(GLES2_RenderData *data, GLES2_ShaderCacheEntry *vertex,
data->program_cache.head = entry; data->program_cache.head = entry;
++data->program_cache.count; ++data->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 */ /* Evict the last entry from the cache if we exceed the limit */
if (data->program_cache.count > GLES2_MAX_CACHED_PROGRAMS) { if (data->program_cache.count > GLES2_MAX_CACHED_PROGRAMS) {
shaderEntry = data->program_cache.tail->vertex_shader;
if (--shaderEntry->references <= 0) {
GLES2_EvictShader(data, shaderEntry);
}
shaderEntry = data->program_cache.tail->fragment_shader;
if (--shaderEntry->references <= 0) {
GLES2_EvictShader(data, shaderEntry);
}
data->glDeleteProgram(data->program_cache.tail->id); data->glDeleteProgram(data->program_cache.tail->id);
data->program_cache.tail = data->program_cache.tail->prev; data->program_cache.tail = data->program_cache.tail->prev;
if (data->program_cache.tail != NULL) { if (data->program_cache.tail != NULL) {
@ -539,80 +488,34 @@ GLES2_CacheProgram(GLES2_RenderData *data, GLES2_ShaderCacheEntry *vertex,
return entry; return entry;
} }
static GLES2_ShaderCacheEntry * static GLuint
GLES2_CacheShader(GLES2_RenderData *data, GLES2_ShaderType type) GLES2_CacheShader(GLES2_RenderData *data, GLES2_ShaderType type, GLenum shader_type)
{ {
const GLES2_Shader *shader; GLuint id;
const GLES2_ShaderInstance *instance = NULL;
GLES2_ShaderCacheEntry *entry = NULL;
GLint compileSuccessful = GL_FALSE; GLint compileSuccessful = GL_FALSE;
int i, j; const Uint8 *shader_src = GLES2_GetShader(type);
/* Find the corresponding shader */ if (!shader_src) {
shader = GLES2_GetShader(type); SDL_SetError("No shader src");
if (!shader) { return 0;
SDL_SetError("No shader matching the requested characteristics was found");
return NULL;
} }
/* Find a matching shader instance that's supported on this hardware */ /* Compile */
for (i = 0; i < shader->instance_count && !instance; ++i) { id = data->glCreateShader(shader_type);
for (j = 0; j < data->shader_format_count && !instance; ++j) { data->glShaderSource(id, 1, (const char**)&shader_src, NULL);
if (!shader->instances[i]) { data->glCompileShader(id);
continue; data->glGetShaderiv(id, GL_COMPILE_STATUS, &compileSuccessful);
}
if (shader->instances[i]->format != data->shader_formats[j]) {
continue;
}
instance = shader->instances[i];
}
}
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 = data->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 */
entry->id = data->glCreateShader(instance->type);
if (instance->format == (GLenum)-1) {
data->glShaderSource(entry->id, 1, (const char **)(char *)&instance->data, NULL);
data->glCompileShader(entry->id);
data->glGetShaderiv(entry->id, GL_COMPILE_STATUS, &compileSuccessful);
} else {
data->glShaderBinary(1, &entry->id, instance->format, instance->data, instance->length);
compileSuccessful = GL_TRUE;
}
if (!compileSuccessful) { if (!compileSuccessful) {
SDL_bool isstack = SDL_FALSE; SDL_bool isstack = SDL_FALSE;
char *info = NULL; char *info = NULL;
int length = 0; int length = 0;
data->glGetShaderiv(entry->id, GL_INFO_LOG_LENGTH, &length); data->glGetShaderiv(id, GL_INFO_LOG_LENGTH, &length);
if (length > 0) { if (length > 0) {
info = SDL_small_alloc(char, length, &isstack); info = SDL_small_alloc(char, length, &isstack);
if (info) { if (info) {
data->glGetShaderInfoLog(entry->id, length, &length, info); data->glGetShaderInfoLog(id, length, &length, info);
} }
} }
if (info) { if (info) {
@ -621,26 +524,21 @@ GLES2_CacheShader(GLES2_RenderData *data, GLES2_ShaderType type)
} else { } else {
SDL_SetError("Failed to load the shader"); SDL_SetError("Failed to load the shader");
} }
data->glDeleteShader(entry->id); data->glDeleteShader(id);
SDL_free(entry); return 0;
return NULL;
} }
/* Link the shader entry in at the front of the cache */ /* Cache */
if (data->shader_cache.head) { data->shader_id_cache[(Uint32)type] = id;
entry->next = data->shader_cache.head;
data->shader_cache.head->prev = entry; return id;
}
data->shader_cache.head = entry;
++data->shader_cache.count;
return entry;
} }
static int static int
GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source, int w, int h) GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source, int w, int h)
{ {
GLES2_ShaderCacheEntry *vertex = NULL; GLuint vertex;
GLES2_ShaderCacheEntry *fragment = NULL; GLuint fragment;
GLES2_ShaderType vtype, ftype; GLES2_ShaderType vtype, ftype;
GLES2_ProgramCacheEntry *program; GLES2_ProgramCacheEntry *program;
@ -648,30 +546,30 @@ GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source, int w, int
vtype = GLES2_SHADER_VERTEX_DEFAULT; vtype = GLES2_SHADER_VERTEX_DEFAULT;
switch (source) { switch (source) {
case GLES2_IMAGESOURCE_SOLID: case GLES2_IMAGESOURCE_SOLID:
ftype = GLES2_SHADER_FRAGMENT_SOLID_SRC; ftype = GLES2_SHADER_FRAGMENT_SOLID;
break; break;
case GLES2_IMAGESOURCE_TEXTURE_ABGR: case GLES2_IMAGESOURCE_TEXTURE_ABGR:
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_ABGR_SRC; ftype = GLES2_SHADER_FRAGMENT_TEXTURE_ABGR;
break; break;
case GLES2_IMAGESOURCE_TEXTURE_ARGB: case GLES2_IMAGESOURCE_TEXTURE_ARGB:
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_ARGB_SRC; ftype = GLES2_SHADER_FRAGMENT_TEXTURE_ARGB;
break; break;
case GLES2_IMAGESOURCE_TEXTURE_RGB: case GLES2_IMAGESOURCE_TEXTURE_RGB:
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_RGB_SRC; ftype = GLES2_SHADER_FRAGMENT_TEXTURE_RGB;
break; break;
case GLES2_IMAGESOURCE_TEXTURE_BGR: case GLES2_IMAGESOURCE_TEXTURE_BGR:
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_BGR_SRC; ftype = GLES2_SHADER_FRAGMENT_TEXTURE_BGR;
break; break;
case GLES2_IMAGESOURCE_TEXTURE_YUV: case GLES2_IMAGESOURCE_TEXTURE_YUV:
switch (SDL_GetYUVConversionModeForResolution(w, h)) { switch (SDL_GetYUVConversionModeForResolution(w, h)) {
case SDL_YUV_CONVERSION_JPEG: case SDL_YUV_CONVERSION_JPEG:
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_YUV_JPEG_SRC; ftype = GLES2_SHADER_FRAGMENT_TEXTURE_YUV_JPEG;
break; break;
case SDL_YUV_CONVERSION_BT601: case SDL_YUV_CONVERSION_BT601:
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601_SRC; ftype = GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601;
break; break;
case SDL_YUV_CONVERSION_BT709: case SDL_YUV_CONVERSION_BT709:
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT709_SRC; ftype = GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT709;
break; break;
default: default:
SDL_SetError("Unsupported YUV conversion mode: %d\n", SDL_GetYUVConversionModeForResolution(w, h)); SDL_SetError("Unsupported YUV conversion mode: %d\n", SDL_GetYUVConversionModeForResolution(w, h));
@ -681,13 +579,13 @@ GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source, int w, int
case GLES2_IMAGESOURCE_TEXTURE_NV12: case GLES2_IMAGESOURCE_TEXTURE_NV12:
switch (SDL_GetYUVConversionModeForResolution(w, h)) { switch (SDL_GetYUVConversionModeForResolution(w, h)) {
case SDL_YUV_CONVERSION_JPEG: case SDL_YUV_CONVERSION_JPEG:
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_JPEG_SRC; ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_JPEG;
break; break;
case SDL_YUV_CONVERSION_BT601: case SDL_YUV_CONVERSION_BT601:
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT601_SRC; ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT601;
break; break;
case SDL_YUV_CONVERSION_BT709: case SDL_YUV_CONVERSION_BT709:
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT709_SRC; ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT709;
break; break;
default: default:
SDL_SetError("Unsupported YUV conversion mode: %d\n", SDL_GetYUVConversionModeForResolution(w, h)); SDL_SetError("Unsupported YUV conversion mode: %d\n", SDL_GetYUVConversionModeForResolution(w, h));
@ -697,13 +595,13 @@ GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source, int w, int
case GLES2_IMAGESOURCE_TEXTURE_NV21: case GLES2_IMAGESOURCE_TEXTURE_NV21:
switch (SDL_GetYUVConversionModeForResolution(w, h)) { switch (SDL_GetYUVConversionModeForResolution(w, h)) {
case SDL_YUV_CONVERSION_JPEG: case SDL_YUV_CONVERSION_JPEG:
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV21_JPEG_SRC; ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV21_JPEG;
break; break;
case SDL_YUV_CONVERSION_BT601: case SDL_YUV_CONVERSION_BT601:
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT601_SRC; ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT601;
break; break;
case SDL_YUV_CONVERSION_BT709: case SDL_YUV_CONVERSION_BT709:
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709_SRC; ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709;
break; break;
default: default:
SDL_SetError("Unsupported YUV conversion mode: %d\n", SDL_GetYUVConversionModeForResolution(w, h)); SDL_SetError("Unsupported YUV conversion mode: %d\n", SDL_GetYUVConversionModeForResolution(w, h));
@ -711,20 +609,27 @@ GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source, int w, int
} }
break; break;
case GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES: case GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES:
ftype = GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES_SRC; ftype = GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES;
break; break;
default: default:
goto fault; goto fault;
} }
/* Load the requested shaders */ /* Load the requested shaders */
vertex = GLES2_CacheShader(data, vtype); vertex = data->shader_id_cache[(Uint32)vtype];
if (!vertex) { if (!vertex) {
goto fault; vertex = GLES2_CacheShader(data, vtype, GL_VERTEX_SHADER);
if (!vertex) {
goto fault;
}
} }
fragment = GLES2_CacheShader(data, ftype);
fragment = data->shader_id_cache[(Uint32)ftype];
if (!fragment) { if (!fragment) {
goto fault; fragment = GLES2_CacheShader(data, ftype, GL_FRAGMENT_SHADER);
if (!fragment) {
goto fault;
}
} }
/* Check if we need to change programs at all */ /* Check if we need to change programs at all */
@ -749,12 +654,6 @@ GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource source, int w, int
/* Clean up and return */ /* Clean up and return */
return 0; return 0;
fault: fault:
if (vertex && vertex->references <= 0) {
GLES2_EvictShader(data, vertex);
}
if (fragment && fragment->references <= 0) {
GLES2_EvictShader(data, fragment);
}
data->drawstate.program = NULL; data->drawstate.program = NULL;
return -1; return -1;
} }
@ -907,7 +806,7 @@ GLES2_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture *
const SDL_Rect * srcquad, const SDL_FRect * dstrect, const SDL_Rect * srcquad, const SDL_FRect * dstrect,
const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip) const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
{ {
/* render expects cos value - 1 (see GLES2_VertexSrc_Default_) */ /* render expects cos value - 1 (see GLES2_Vertex_Default) */
const float radian_angle = (float)(M_PI * (360.0 - angle) / 180.0); const float radian_angle = (float)(M_PI * (360.0 - angle) / 180.0);
const GLfloat s = (GLfloat) SDL_sin(radian_angle); const GLfloat s = (GLfloat) SDL_sin(radian_angle);
const GLfloat c = (GLfloat) SDL_cos(radian_angle) - 1.0f; const GLfloat c = (GLfloat) SDL_cos(radian_angle) - 1.0f;
@ -1386,14 +1285,12 @@ GLES2_DestroyRenderer(SDL_Renderer *renderer)
GLES2_ActivateRenderer(renderer); GLES2_ActivateRenderer(renderer);
{ {
GLES2_ShaderCacheEntry *entry; int i;
GLES2_ShaderCacheEntry *next; for (i = 0; i < GLES2_SHADER_COUNT; i++) {
entry = data->shader_cache.head; GLuint id = data->shader_id_cache[i];
while (entry) { if (id) {
data->glDeleteShader(entry->id); data->glDeleteShader(id);
next = entry->next; }
SDL_free(entry);
entry = next;
} }
} }
{ {
@ -1423,7 +1320,6 @@ GLES2_DestroyRenderer(SDL_Renderer *renderer)
SDL_GL_DeleteContext(data->context); SDL_GL_DeleteContext(data->context);
} }
SDL_free(data->shader_formats);
SDL_free(data); SDL_free(data);
} }
SDL_free(renderer); SDL_free(renderer);
@ -2029,20 +1925,11 @@ static int GLES2_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture)
* Renderer instantiation * * Renderer instantiation *
*************************************************************************************************/ *************************************************************************************************/
#ifdef ZUNE_HD
#define GL_NVIDIA_PLATFORM_BINARY_NV 0x890B
#endif
static SDL_Renderer * static SDL_Renderer *
GLES2_CreateRenderer(SDL_Window *window, Uint32 flags) GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
{ {
SDL_Renderer *renderer; SDL_Renderer *renderer;
GLES2_RenderData *data; GLES2_RenderData *data;
GLint nFormats;
#ifndef ZUNE_HD
GLboolean hasCompiler;
#endif
Uint32 window_flags = 0; /* -Wconditional-uninitialized */ Uint32 window_flags = 0; /* -Wconditional-uninitialized */
GLint window_framebuffer; GLint window_framebuffer;
GLint value; GLint value;
@ -2144,33 +2031,6 @@ GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value); data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
renderer->info.max_texture_height = value; renderer->info.max_texture_height = value;
/* Determine supported shader formats */
/* HACK: glGetInteger is broken on the Zune HD's compositor, so we just hardcode this */
#ifdef ZUNE_HD
nFormats = 1;
#else /* !ZUNE_HD */
data->glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &nFormats);
data->glGetBooleanv(GL_SHADER_COMPILER, &hasCompiler);
if (hasCompiler) {
++nFormats;
}
#endif /* ZUNE_HD */
data->shader_formats = (GLenum *)SDL_calloc(nFormats, sizeof(GLenum));
if (!data->shader_formats) {
GLES2_DestroyRenderer(renderer);
SDL_OutOfMemory();
goto error;
}
data->shader_format_count = nFormats;
#ifdef ZUNE_HD
data->shader_formats[0] = GL_NVIDIA_PLATFORM_BINARY_NV;
#else /* !ZUNE_HD */
data->glGetIntegerv(GL_SHADER_BINARY_FORMATS, (GLint *)data->shader_formats);
if (hasCompiler) {
data->shader_formats[nFormats - 1] = (GLenum)-1;
}
#endif /* ZUNE_HD */
/* we keep a few of these and cycle through them, so data can live for a few frames. */ /* we keep a few of these and cycle through them, so data can live for a few frames. */
data->glGenBuffers(SDL_arraysize(data->vertex_buffers), data->vertex_buffers); data->glGenBuffers(SDL_arraysize(data->vertex_buffers), data->vertex_buffers);

View file

@ -36,7 +36,7 @@
value is decremented by 1.0 to get proper output with 0.0 which is value is decremented by 1.0 to get proper output with 0.0 which is
default value default value
*/ */
static const Uint8 GLES2_VertexSrc_Default_[] = " \ static const Uint8 GLES2_Vertex_Default[] = " \
uniform mat4 u_projection; \ uniform mat4 u_projection; \
attribute vec2 a_position; \ attribute vec2 a_position; \
attribute vec2 a_texCoord; \ attribute vec2 a_texCoord; \
@ -56,7 +56,7 @@ static const Uint8 GLES2_VertexSrc_Default_[] = " \
} \ } \
"; ";
static const Uint8 GLES2_FragmentSrc_SolidSrc_[] = " \ static const Uint8 GLES2_Fragment_Solid[] = " \
precision mediump float; \ precision mediump float; \
uniform vec4 u_color; \ uniform vec4 u_color; \
\ \
@ -66,7 +66,7 @@ static const Uint8 GLES2_FragmentSrc_SolidSrc_[] = " \
} \ } \
"; ";
static const Uint8 GLES2_FragmentSrc_TextureABGRSrc_[] = " \ static const Uint8 GLES2_Fragment_TextureABGR[] = " \
precision mediump float; \ precision mediump float; \
uniform sampler2D u_texture; \ uniform sampler2D u_texture; \
uniform vec4 u_color; \ uniform vec4 u_color; \
@ -80,7 +80,7 @@ static const Uint8 GLES2_FragmentSrc_TextureABGRSrc_[] = " \
"; ";
/* ARGB to ABGR conversion */ /* ARGB to ABGR conversion */
static const Uint8 GLES2_FragmentSrc_TextureARGBSrc_[] = " \ static const Uint8 GLES2_Fragment_TextureARGB[] = " \
precision mediump float; \ precision mediump float; \
uniform sampler2D u_texture; \ uniform sampler2D u_texture; \
uniform vec4 u_color; \ uniform vec4 u_color; \
@ -97,7 +97,7 @@ static const Uint8 GLES2_FragmentSrc_TextureARGBSrc_[] = " \
"; ";
/* RGB to ABGR conversion */ /* RGB to ABGR conversion */
static const Uint8 GLES2_FragmentSrc_TextureRGBSrc_[] = " \ static const Uint8 GLES2_Fragment_TextureRGB[] = " \
precision mediump float; \ precision mediump float; \
uniform sampler2D u_texture; \ uniform sampler2D u_texture; \
uniform vec4 u_color; \ uniform vec4 u_color; \
@ -115,7 +115,7 @@ static const Uint8 GLES2_FragmentSrc_TextureRGBSrc_[] = " \
"; ";
/* BGR to ABGR conversion */ /* BGR to ABGR conversion */
static const Uint8 GLES2_FragmentSrc_TextureBGRSrc_[] = " \ static const Uint8 GLES2_Fragment_TextureBGR[] = " \
precision mediump float; \ precision mediump float; \
uniform sampler2D u_texture; \ uniform sampler2D u_texture; \
uniform vec4 u_color; \ uniform vec4 u_color; \
@ -229,58 +229,58 @@ static const Uint8 GLES2_FragmentSrc_TextureBGRSrc_[] = " \
"}" \ "}" \
/* YUV to ABGR conversion */ /* YUV to ABGR conversion */
static const Uint8 GLES2_FragmentSrc_TextureYUVJPEGSrc_[] = \ static const Uint8 GLES2_Fragment_TextureYUVJPEG[] = \
YUV_SHADER_PROLOGUE \ YUV_SHADER_PROLOGUE \
JPEG_SHADER_CONSTANTS \ JPEG_SHADER_CONSTANTS \
YUV_SHADER_BODY \ YUV_SHADER_BODY \
; ;
static const Uint8 GLES2_FragmentSrc_TextureYUVBT601Src_[] = \ static const Uint8 GLES2_Fragment_TextureYUVBT601[] = \
YUV_SHADER_PROLOGUE \ YUV_SHADER_PROLOGUE \
BT601_SHADER_CONSTANTS \ BT601_SHADER_CONSTANTS \
YUV_SHADER_BODY \ YUV_SHADER_BODY \
; ;
static const Uint8 GLES2_FragmentSrc_TextureYUVBT709Src_[] = \ static const Uint8 GLES2_Fragment_TextureYUVBT709[] = \
YUV_SHADER_PROLOGUE \ YUV_SHADER_PROLOGUE \
BT709_SHADER_CONSTANTS \ BT709_SHADER_CONSTANTS \
YUV_SHADER_BODY \ YUV_SHADER_BODY \
; ;
/* NV12 to ABGR conversion */ /* NV12 to ABGR conversion */
static const Uint8 GLES2_FragmentSrc_TextureNV12JPEGSrc_[] = \ static const Uint8 GLES2_Fragment_TextureNV12JPEG[] = \
YUV_SHADER_PROLOGUE \ YUV_SHADER_PROLOGUE \
JPEG_SHADER_CONSTANTS \ JPEG_SHADER_CONSTANTS \
NV12_SHADER_BODY \ NV12_SHADER_BODY \
; ;
static const Uint8 GLES2_FragmentSrc_TextureNV12BT601Src_[] = \ static const Uint8 GLES2_Fragment_TextureNV12BT601[] = \
YUV_SHADER_PROLOGUE \ YUV_SHADER_PROLOGUE \
BT601_SHADER_CONSTANTS \ BT601_SHADER_CONSTANTS \
NV12_SHADER_BODY \ NV12_SHADER_BODY \
; ;
static const Uint8 GLES2_FragmentSrc_TextureNV12BT709Src_[] = \ static const Uint8 GLES2_Fragment_TextureNV12BT709[] = \
YUV_SHADER_PROLOGUE \ YUV_SHADER_PROLOGUE \
BT709_SHADER_CONSTANTS \ BT709_SHADER_CONSTANTS \
NV12_SHADER_BODY \ NV12_SHADER_BODY \
; ;
/* NV21 to ABGR conversion */ /* NV21 to ABGR conversion */
static const Uint8 GLES2_FragmentSrc_TextureNV21JPEGSrc_[] = \ static const Uint8 GLES2_Fragment_TextureNV21JPEG[] = \
YUV_SHADER_PROLOGUE \ YUV_SHADER_PROLOGUE \
JPEG_SHADER_CONSTANTS \ JPEG_SHADER_CONSTANTS \
NV21_SHADER_BODY \ NV21_SHADER_BODY \
; ;
static const Uint8 GLES2_FragmentSrc_TextureNV21BT601Src_[] = \ static const Uint8 GLES2_Fragment_TextureNV21BT601[] = \
YUV_SHADER_PROLOGUE \ YUV_SHADER_PROLOGUE \
BT601_SHADER_CONSTANTS \ BT601_SHADER_CONSTANTS \
NV21_SHADER_BODY \ NV21_SHADER_BODY \
; ;
static const Uint8 GLES2_FragmentSrc_TextureNV21BT709Src_[] = \ static const Uint8 GLES2_Fragment_TextureNV21BT709[] = \
YUV_SHADER_PROLOGUE \ YUV_SHADER_PROLOGUE \
BT709_SHADER_CONSTANTS \ BT709_SHADER_CONSTANTS \
NV21_SHADER_BODY \ NV21_SHADER_BODY \
; ;
/* Custom Android video format texture */ /* Custom Android video format texture */
static const Uint8 GLES2_FragmentSrc_TextureExternalOESSrc_[] = " \ static const Uint8 GLES2_Fragment_TextureExternalOES[] = " \
#extension GL_OES_EGL_image_external : require\n\ #extension GL_OES_EGL_image_external : require\n\
precision mediump float; \ precision mediump float; \
uniform samplerExternalOES u_texture; \ uniform samplerExternalOES u_texture; \
@ -294,275 +294,46 @@ static const Uint8 GLES2_FragmentSrc_TextureExternalOESSrc_[] = " \
} \ } \
"; ";
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_TextureABGRSrc = {
GL_FRAGMENT_SHADER,
GLES2_SOURCE_SHADER,
sizeof(GLES2_FragmentSrc_TextureABGRSrc_),
GLES2_FragmentSrc_TextureABGRSrc_
};
static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureARGBSrc = {
GL_FRAGMENT_SHADER,
GLES2_SOURCE_SHADER,
sizeof(GLES2_FragmentSrc_TextureARGBSrc_),
GLES2_FragmentSrc_TextureARGBSrc_
};
static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureRGBSrc = {
GL_FRAGMENT_SHADER,
GLES2_SOURCE_SHADER,
sizeof(GLES2_FragmentSrc_TextureRGBSrc_),
GLES2_FragmentSrc_TextureRGBSrc_
};
static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureBGRSrc = {
GL_FRAGMENT_SHADER,
GLES2_SOURCE_SHADER,
sizeof(GLES2_FragmentSrc_TextureBGRSrc_),
GLES2_FragmentSrc_TextureBGRSrc_
};
static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureYUVJPEGSrc = {
GL_FRAGMENT_SHADER,
GLES2_SOURCE_SHADER,
sizeof(GLES2_FragmentSrc_TextureYUVJPEGSrc_),
GLES2_FragmentSrc_TextureYUVJPEGSrc_
};
static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureYUVBT601Src = {
GL_FRAGMENT_SHADER,
GLES2_SOURCE_SHADER,
sizeof(GLES2_FragmentSrc_TextureYUVBT601Src_),
GLES2_FragmentSrc_TextureYUVBT601Src_
};
static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureYUVBT709Src = {
GL_FRAGMENT_SHADER,
GLES2_SOURCE_SHADER,
sizeof(GLES2_FragmentSrc_TextureYUVBT709Src_),
GLES2_FragmentSrc_TextureYUVBT709Src_
};
static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureNV12JPEGSrc = {
GL_FRAGMENT_SHADER,
GLES2_SOURCE_SHADER,
sizeof(GLES2_FragmentSrc_TextureNV12JPEGSrc_),
GLES2_FragmentSrc_TextureNV12JPEGSrc_
};
static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureNV12BT601Src = {
GL_FRAGMENT_SHADER,
GLES2_SOURCE_SHADER,
sizeof(GLES2_FragmentSrc_TextureNV12BT601Src_),
GLES2_FragmentSrc_TextureNV12BT601Src_
};
static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureNV21BT709Src = {
GL_FRAGMENT_SHADER,
GLES2_SOURCE_SHADER,
sizeof(GLES2_FragmentSrc_TextureNV21BT709Src_),
GLES2_FragmentSrc_TextureNV21BT709Src_
};
static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureNV21JPEGSrc = {
GL_FRAGMENT_SHADER,
GLES2_SOURCE_SHADER,
sizeof(GLES2_FragmentSrc_TextureNV21JPEGSrc_),
GLES2_FragmentSrc_TextureNV21JPEGSrc_
};
static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureNV21BT601Src = {
GL_FRAGMENT_SHADER,
GLES2_SOURCE_SHADER,
sizeof(GLES2_FragmentSrc_TextureNV21BT601Src_),
GLES2_FragmentSrc_TextureNV21BT601Src_
};
static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureNV12BT709Src = {
GL_FRAGMENT_SHADER,
GLES2_SOURCE_SHADER,
sizeof(GLES2_FragmentSrc_TextureNV12BT709Src_),
GLES2_FragmentSrc_TextureNV12BT709Src_
};
static const GLES2_ShaderInstance GLES2_FragmentSrc_TextureExternalOESSrc = {
GL_FRAGMENT_SHADER,
GLES2_SOURCE_SHADER,
sizeof(GLES2_FragmentSrc_TextureExternalOESSrc_),
GLES2_FragmentSrc_TextureExternalOESSrc_
};
/*************************************************************************************************
* Vertex/fragment shader definitions *
*************************************************************************************************/
static GLES2_Shader GLES2_VertexShader_Default = {
1,
{
&GLES2_VertexSrc_Default
}
};
static GLES2_Shader GLES2_FragmentShader_SolidSrc = {
1,
{
&GLES2_FragmentSrc_SolidSrc
}
};
static GLES2_Shader GLES2_FragmentShader_TextureABGRSrc = {
1,
{
&GLES2_FragmentSrc_TextureABGRSrc
}
};
static GLES2_Shader GLES2_FragmentShader_TextureARGBSrc = {
1,
{
&GLES2_FragmentSrc_TextureARGBSrc
}
};
static GLES2_Shader GLES2_FragmentShader_TextureRGBSrc = {
1,
{
&GLES2_FragmentSrc_TextureRGBSrc
}
};
static GLES2_Shader GLES2_FragmentShader_TextureBGRSrc = {
1,
{
&GLES2_FragmentSrc_TextureBGRSrc
}
};
static GLES2_Shader GLES2_FragmentShader_TextureYUVJPEGSrc = {
1,
{
&GLES2_FragmentSrc_TextureYUVJPEGSrc
}
};
static GLES2_Shader GLES2_FragmentShader_TextureYUVBT601Src = {
1,
{
&GLES2_FragmentSrc_TextureYUVBT601Src
}
};
static GLES2_Shader GLES2_FragmentShader_TextureYUVBT709Src = {
1,
{
&GLES2_FragmentSrc_TextureYUVBT709Src
}
};
static GLES2_Shader GLES2_FragmentShader_TextureNV12JPEGSrc = {
1,
{
&GLES2_FragmentSrc_TextureNV12JPEGSrc
}
};
static GLES2_Shader GLES2_FragmentShader_TextureNV12BT601Src = {
1,
{
&GLES2_FragmentSrc_TextureNV12BT601Src
}
};
static GLES2_Shader GLES2_FragmentShader_TextureNV12BT709Src = {
1,
{
&GLES2_FragmentSrc_TextureNV12BT709Src
}
};
static GLES2_Shader GLES2_FragmentShader_TextureNV21JPEGSrc = {
1,
{
&GLES2_FragmentSrc_TextureNV21JPEGSrc
}
};
static GLES2_Shader GLES2_FragmentShader_TextureNV21BT601Src = {
1,
{
&GLES2_FragmentSrc_TextureNV21BT601Src
}
};
static GLES2_Shader GLES2_FragmentShader_TextureNV21BT709Src = {
1,
{
&GLES2_FragmentSrc_TextureNV21BT709Src
}
};
static GLES2_Shader GLES2_FragmentShader_TextureExternalOESSrc = {
1,
{
&GLES2_FragmentSrc_TextureExternalOESSrc
}
};
/************************************************************************************************* /*************************************************************************************************
* Shader selector * * Shader selector *
*************************************************************************************************/ *************************************************************************************************/
const GLES2_Shader *GLES2_GetShader(GLES2_ShaderType type) const Uint8 *GLES2_GetShader(GLES2_ShaderType type)
{ {
switch (type) { switch (type) {
case GLES2_SHADER_VERTEX_DEFAULT: case GLES2_SHADER_VERTEX_DEFAULT:
return &GLES2_VertexShader_Default; return GLES2_Vertex_Default;
case GLES2_SHADER_FRAGMENT_SOLID_SRC: case GLES2_SHADER_FRAGMENT_SOLID:
return &GLES2_FragmentShader_SolidSrc; return GLES2_Fragment_Solid;
case GLES2_SHADER_FRAGMENT_TEXTURE_ABGR_SRC: case GLES2_SHADER_FRAGMENT_TEXTURE_ABGR:
return &GLES2_FragmentShader_TextureABGRSrc; return GLES2_Fragment_TextureABGR;
case GLES2_SHADER_FRAGMENT_TEXTURE_ARGB_SRC: case GLES2_SHADER_FRAGMENT_TEXTURE_ARGB:
return &GLES2_FragmentShader_TextureARGBSrc; return GLES2_Fragment_TextureARGB;
case GLES2_SHADER_FRAGMENT_TEXTURE_RGB_SRC: case GLES2_SHADER_FRAGMENT_TEXTURE_RGB:
return &GLES2_FragmentShader_TextureRGBSrc; return GLES2_Fragment_TextureRGB;
case GLES2_SHADER_FRAGMENT_TEXTURE_BGR_SRC: case GLES2_SHADER_FRAGMENT_TEXTURE_BGR:
return &GLES2_FragmentShader_TextureBGRSrc; return GLES2_Fragment_TextureBGR;
case GLES2_SHADER_FRAGMENT_TEXTURE_YUV_JPEG_SRC: case GLES2_SHADER_FRAGMENT_TEXTURE_YUV_JPEG:
return &GLES2_FragmentShader_TextureYUVJPEGSrc; return GLES2_Fragment_TextureYUVJPEG;
case GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601_SRC: case GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601:
return &GLES2_FragmentShader_TextureYUVBT601Src; return GLES2_Fragment_TextureYUVBT601;
case GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT709_SRC: case GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT709:
return &GLES2_FragmentShader_TextureYUVBT709Src; return GLES2_Fragment_TextureYUVBT709;
case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_JPEG_SRC: case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_JPEG:
return &GLES2_FragmentShader_TextureNV12JPEGSrc; return GLES2_Fragment_TextureNV12JPEG;
case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT601_SRC: case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT601:
return &GLES2_FragmentShader_TextureNV12BT601Src; return GLES2_Fragment_TextureNV12BT601;
case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT709_SRC: case GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT709:
return &GLES2_FragmentShader_TextureNV12BT709Src; return GLES2_Fragment_TextureNV12BT709;
case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_JPEG_SRC: case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_JPEG:
return &GLES2_FragmentShader_TextureNV21JPEGSrc; return GLES2_Fragment_TextureNV21JPEG;
case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT601_SRC: case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT601:
return &GLES2_FragmentShader_TextureNV21BT601Src; return GLES2_Fragment_TextureNV21BT601;
case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709_SRC: case GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709:
return &GLES2_FragmentShader_TextureNV21BT709Src; return GLES2_Fragment_TextureNV21BT709;
case GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES_SRC: case GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES:
return &GLES2_FragmentShader_TextureExternalOESSrc; return GLES2_Fragment_TextureExternalOES;
default: default:
return NULL; return NULL;
} }

View file

@ -25,43 +25,30 @@
#if SDL_VIDEO_RENDER_OGL_ES2 #if SDL_VIDEO_RENDER_OGL_ES2
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 typedef enum
{ {
GLES2_SHADER_VERTEX_DEFAULT, GLES2_SHADER_VERTEX_DEFAULT = 0,
GLES2_SHADER_FRAGMENT_SOLID_SRC, GLES2_SHADER_FRAGMENT_SOLID,
GLES2_SHADER_FRAGMENT_TEXTURE_ABGR_SRC, GLES2_SHADER_FRAGMENT_TEXTURE_ABGR,
GLES2_SHADER_FRAGMENT_TEXTURE_ARGB_SRC, GLES2_SHADER_FRAGMENT_TEXTURE_ARGB,
GLES2_SHADER_FRAGMENT_TEXTURE_BGR_SRC, GLES2_SHADER_FRAGMENT_TEXTURE_BGR,
GLES2_SHADER_FRAGMENT_TEXTURE_RGB_SRC, GLES2_SHADER_FRAGMENT_TEXTURE_RGB,
GLES2_SHADER_FRAGMENT_TEXTURE_YUV_JPEG_SRC, GLES2_SHADER_FRAGMENT_TEXTURE_YUV_JPEG,
GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601_SRC, GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601,
GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT709_SRC, GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT709,
GLES2_SHADER_FRAGMENT_TEXTURE_NV12_JPEG_SRC, GLES2_SHADER_FRAGMENT_TEXTURE_NV12_JPEG,
GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT601_SRC, GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT601,
GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT709_SRC, GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT709,
GLES2_SHADER_FRAGMENT_TEXTURE_NV21_JPEG_SRC, GLES2_SHADER_FRAGMENT_TEXTURE_NV21_JPEG,
GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT601_SRC, GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT601,
GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709_SRC, GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709,
GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES_SRC GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES
} GLES2_ShaderType; } GLES2_ShaderType;
#define GLES2_SOURCE_SHADER (GLenum)-1 #define GLES2_SHADER_COUNT 16
const GLES2_Shader *GLES2_GetShader(GLES2_ShaderType type); const Uint8 *GLES2_GetShader(GLES2_ShaderType type);
#endif /* SDL_VIDEO_RENDER_OGL_ES2 */ #endif /* SDL_VIDEO_RENDER_OGL_ES2 */