21 #include "../../SDL_internal.h" 23 #if SDL_VIDEO_RENDER_OGL_ES2 && !SDL_RENDER_DISABLED 27 #include "../SDL_sysrender.h" 28 #include "../../video/SDL_blit.h" 39 #define SDL_GLES2_USE_VBOS 1 41 #define SDL_GLES2_USE_VBOS 0 47 #define RENDERER_CONTEXT_MAJOR 2 48 #define RENDERER_CONTEXT_MINOR 0 80 typedef struct GLES2_FBOList GLES2_FBOList;
89 typedef struct GLES2_TextureData
105 typedef struct GLES2_ShaderCacheEntry
108 GLES2_ShaderType
type;
109 const GLES2_ShaderInstance *instance;
111 Uint8 modulation_r, modulation_g, modulation_b, modulation_a;
112 struct GLES2_ShaderCacheEntry *prev;
113 struct GLES2_ShaderCacheEntry *next;
114 } GLES2_ShaderCacheEntry;
116 typedef struct GLES2_ShaderCache
119 GLES2_ShaderCacheEntry *
head;
122 typedef struct GLES2_ProgramCacheEntry
126 GLES2_ShaderCacheEntry *vertex_shader;
127 GLES2_ShaderCacheEntry *fragment_shader;
128 GLuint uniform_locations[16];
129 Uint8 color_r, color_g, color_b, color_a;
130 Uint8 modulation_r, modulation_g, modulation_b, modulation_a;
132 struct GLES2_ProgramCacheEntry *prev;
133 struct GLES2_ProgramCacheEntry *next;
134 } GLES2_ProgramCacheEntry;
136 typedef struct GLES2_ProgramCache
139 GLES2_ProgramCacheEntry *
head;
140 GLES2_ProgramCacheEntry *
tail;
141 } GLES2_ProgramCache;
145 GLES2_ATTRIBUTE_POSITION = 0,
146 GLES2_ATTRIBUTE_TEXCOORD = 1,
147 GLES2_ATTRIBUTE_ANGLE = 2,
148 GLES2_ATTRIBUTE_CENTER = 3,
153 GLES2_UNIFORM_PROJECTION,
154 GLES2_UNIFORM_TEXTURE,
155 GLES2_UNIFORM_MODULATION,
157 GLES2_UNIFORM_TEXTURE_U,
158 GLES2_UNIFORM_TEXTURE_V
163 GLES2_IMAGESOURCE_SOLID,
164 GLES2_IMAGESOURCE_TEXTURE_ABGR,
165 GLES2_IMAGESOURCE_TEXTURE_ARGB,
166 GLES2_IMAGESOURCE_TEXTURE_RGB,
167 GLES2_IMAGESOURCE_TEXTURE_BGR,
168 GLES2_IMAGESOURCE_TEXTURE_YUV,
169 GLES2_IMAGESOURCE_TEXTURE_NV12,
170 GLES2_IMAGESOURCE_TEXTURE_NV21
173 typedef struct GLES2_DriverContext
184 #define SDL_PROC(ret,func,params) ret (APIENTRY *func) params; 188 GLuint window_framebuffer;
190 int shader_format_count;
192 GLES2_ShaderCache shader_cache;
193 GLES2_ProgramCache program_cache;
194 GLES2_ProgramCacheEntry *current_program;
195 Uint8 clear_r, clear_g, clear_b, clear_a;
197 #if SDL_GLES2_USE_VBOS 201 } GLES2_DriverContext;
203 #define GLES2_MAX_CACHED_PROGRAMS 8 207 GL_TranslateError (
GLenum error)
209 #define GL_ERROR_TRANSLATE(e) case e: return #e; 219 #undef GL_ERROR_TRANSLATE 225 GLES2_DriverContext *
data = (GLES2_DriverContext *) renderer->
driverdata;
227 if (!data->debug_enabled) {
236 GL_CheckAllErrors (
const char *prefix,
SDL_Renderer *renderer,
const char *file,
int line,
const char *
function)
238 GLES2_DriverContext *data = (GLES2_DriverContext *) renderer->
driverdata;
241 if (!data->debug_enabled) {
246 GLenum error = data->glGetError();
248 if (prefix ==
NULL || prefix[0] ==
'\0') {
251 SDL_SetError(
"%s: %s (%d): %s %s (0x%X)", prefix, file, line,
function, GL_TranslateError(error), error);
261 #define GL_CheckError(prefix, renderer) 262 #elif defined(_MSC_VER) 263 #define GL_CheckError(prefix, renderer) GL_CheckAllErrors(prefix, renderer, __FILE__, __LINE__, __FUNCTION__) 265 #define GL_CheckError(prefix, renderer) GL_CheckAllErrors(prefix, renderer, __FILE__, __LINE__, __PRETTY_FUNCTION__) 273 static int GLES2_ActivateRenderer(
SDL_Renderer *renderer);
276 static int GLES2_UpdateViewport(
SDL_Renderer * renderer);
277 static void GLES2_DestroyRenderer(
SDL_Renderer *renderer);
278 static int GLES2_SetOrthographicProjection(
SDL_Renderer *renderer);
283 static int GLES2_LoadFunctions(GLES2_DriverContext * data)
285 #if SDL_VIDEO_DRIVER_UIKIT 286 #define __SDL_NOGETPROCADDR__ 287 #elif SDL_VIDEO_DRIVER_ANDROID 288 #define __SDL_NOGETPROCADDR__ 289 #elif SDL_VIDEO_DRIVER_PANDORA 290 #define __SDL_NOGETPROCADDR__ 293 #if defined __SDL_NOGETPROCADDR__ 294 #define SDL_PROC(ret,func,params) data->func=func; 296 #define SDL_PROC(ret,func,params) \ 298 data->func = SDL_GL_GetProcAddress(#func); \ 299 if ( ! data->func ) { \ 300 return SDL_SetError("Couldn't load GLES2 function %s: %s\n", #func, SDL_GetError()); \ 313 GLES2_FBOList *
result = data->framebuffers;
314 while ((result) && ((result->w != w) || (result->h != h)) ) {
315 result = result->next;
317 if (result ==
NULL) {
321 data->glGenFramebuffers(1, &result->FBO);
322 result->next = data->framebuffers;
323 data->framebuffers =
result;
331 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
333 if (SDL_CurrentContext != data->context) {
335 data->current_program =
NULL;
340 SDL_CurrentContext = data->context;
342 GLES2_UpdateViewport(renderer);
345 GL_ClearErrors(renderer);
353 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
359 SDL_CurrentContext =
NULL;
369 GLES2_GetOutputSize(
SDL_Renderer * renderer,
int *w,
int *h)
378 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
380 if (SDL_CurrentContext != data->context) {
396 if (data->current_program) {
397 GLES2_SetOrthographicProjection(renderer);
399 return GL_CheckError(
"", renderer);
405 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
407 if (SDL_CurrentContext != data->context) {
421 data->glScissor(renderer->
viewport.
x + rect->
x, h - renderer->
viewport.
y - rect->
y - rect->
h, rect->
w, rect->
h);
432 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
436 GLES2_ActivateRenderer(renderer);
439 GLES2_ShaderCacheEntry *entry;
440 GLES2_ShaderCacheEntry *next;
441 entry = data->shader_cache.head;
443 data->glDeleteShader(entry->id);
450 GLES2_ProgramCacheEntry *entry;
451 GLES2_ProgramCacheEntry *next;
452 entry = data->program_cache.head;
454 data->glDeleteProgram(entry->id);
461 while (data->framebuffers) {
462 GLES2_FBOList *nextnode = data->framebuffers->next;
463 data->glDeleteFramebuffers(1, &data->framebuffers->FBO);
464 GL_CheckError(
"", renderer);
466 data->framebuffers = nextnode;
482 const void *
pixels,
int pitch);
485 const Uint8 *Yplane,
int Ypitch,
486 const Uint8 *Uplane,
int Upitch,
487 const Uint8 *Vplane,
int Vpitch);
489 void **
pixels,
int *pitch);
499 if (!hint || *hint ==
'0' ||
SDL_strcasecmp(hint,
"nearest") == 0) {
509 GLES2_DriverContext *renderdata = (GLES2_DriverContext *)renderer->
driverdata;
510 GLES2_TextureData *data;
515 GLES2_ActivateRenderer(renderer);
539 data = (GLES2_TextureData *)
SDL_calloc(1,
sizeof(GLES2_TextureData));
545 data->pixel_format =
format;
546 data->pixel_type =
type;
557 size = texture->
h * data->pitch;
560 size += (2 * (texture->
h * data->pitch) / 4);
564 size += ((texture->
h * data->pitch) / 2);
567 if (!data->pixel_data) {
574 GL_CheckError(
"", renderer);
577 renderdata->glGenTextures(1, &data->texture_v);
578 if (GL_CheckError(
"glGenTexures()", renderer) < 0) {
582 renderdata->glBindTexture(data->texture_type, data->texture_v);
587 renderdata->glTexImage2D(data->texture_type, 0,
format, texture->
w / 2, texture->
h / 2, 0,
format,
type,
NULL);
589 renderdata->glGenTextures(1, &data->texture_u);
590 if (GL_CheckError(
"glGenTexures()", renderer) < 0) {
594 renderdata->glBindTexture(data->texture_type, data->texture_u);
599 renderdata->glTexImage2D(data->texture_type, 0,
format, texture->
w / 2, texture->
h / 2, 0,
format,
type,
NULL);
600 if (GL_CheckError(
"glTexImage2D()", renderer) < 0) {
606 renderdata->glGenTextures(1, &data->texture_u);
607 if (GL_CheckError(
"glGenTexures()", renderer) < 0) {
611 renderdata->glBindTexture(data->texture_type, data->texture_u);
617 if (GL_CheckError(
"glTexImage2D()", renderer) < 0) {
622 renderdata->glGenTextures(1, &data->texture);
623 if (GL_CheckError(
"glGenTexures()", renderer) < 0) {
628 renderdata->glBindTexture(data->texture_type, data->texture);
634 if (GL_CheckError(
"glTexImage2D()", renderer) < 0) {
639 data->fbo = GLES2_GetFBO(renderer->
driverdata, texture->
w, texture->
h);
644 return GL_CheckError(
"", renderer);
648 GLES2_TexSubImage2D(GLES2_DriverContext *data,
GLenum target,
GLint xoffset,
GLint yoffset,
GLsizei width,
GLsizei height,
GLenum format,
GLenum type,
const GLvoid *
pixels,
GLint pitch,
GLint bpp)
656 src_pitch = width * bpp;
657 src = (
Uint8 *)pixels;
658 if (pitch != src_pitch) {
668 pixels = (
Uint8 *)pixels + pitch;
673 data->glTexSubImage2D(target, 0, xoffset, yoffset, width, height, format, type, src);
682 const void *pixels,
int pitch)
684 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
685 GLES2_TextureData *tdata = (GLES2_TextureData *)texture->
driverdata;
687 GLES2_ActivateRenderer(renderer);
690 if (rect->
w <= 0 || rect->
h <= 0) {
695 data->glBindTexture(tdata->texture_type, tdata->texture);
696 GLES2_TexSubImage2D(data, tdata->texture_type,
707 pixels = (
const void*)((
const Uint8*)pixels + rect->
h * pitch);
709 data->glBindTexture(tdata->texture_type, tdata->texture_v);
711 data->glBindTexture(tdata->texture_type, tdata->texture_u);
713 GLES2_TexSubImage2D(data, tdata->texture_type,
720 pixels, pitch / 2, 1);
723 pixels = (
const void*)((
const Uint8*)pixels + (rect->
h * pitch)/4);
725 data->glBindTexture(tdata->texture_type, tdata->texture_u);
727 data->glBindTexture(tdata->texture_type, tdata->texture_v);
729 GLES2_TexSubImage2D(data, tdata->texture_type,
736 pixels, pitch / 2, 1);
741 pixels = (
const void*)((
const Uint8*)pixels + rect->
h * pitch);
742 data->glBindTexture(tdata->texture_type, tdata->texture_u);
743 GLES2_TexSubImage2D(data, tdata->texture_type,
753 return GL_CheckError(
"glTexSubImage2D()", renderer);
759 const Uint8 *Yplane,
int Ypitch,
760 const Uint8 *Uplane,
int Upitch,
761 const Uint8 *Vplane,
int Vpitch)
763 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
764 GLES2_TextureData *tdata = (GLES2_TextureData *)texture->
driverdata;
766 GLES2_ActivateRenderer(renderer);
769 if (rect->
w <= 0 || rect->
h <= 0) {
773 data->glBindTexture(tdata->texture_type, tdata->texture_v);
774 GLES2_TexSubImage2D(data, tdata->texture_type,
783 data->glBindTexture(tdata->texture_type, tdata->texture_u);
784 GLES2_TexSubImage2D(data, tdata->texture_type,
793 data->glBindTexture(tdata->texture_type, tdata->texture);
794 GLES2_TexSubImage2D(data, tdata->texture_type,
803 return GL_CheckError(
"glTexSubImage2D()", renderer);
808 void **pixels,
int *pitch)
810 GLES2_TextureData *tdata = (GLES2_TextureData *)texture->
driverdata;
813 *pixels = (
Uint8 *)tdata->pixel_data +
814 (tdata->pitch * rect->
y) +
816 *pitch = tdata->pitch;
824 GLES2_TextureData *tdata = (GLES2_TextureData *)texture->
driverdata;
832 GLES2_UpdateTexture(renderer, texture, &rect, tdata->pixel_data, tdata->pitch);
838 GLES2_DriverContext *data = (GLES2_DriverContext *) renderer->
driverdata;
839 GLES2_TextureData *texturedata =
NULL;
842 if (texture ==
NULL) {
843 data->glBindFramebuffer(
GL_FRAMEBUFFER, data->window_framebuffer);
845 texturedata = (GLES2_TextureData *) texture->
driverdata;
861 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
862 GLES2_TextureData *tdata = (GLES2_TextureData *)texture->
driverdata;
864 GLES2_ActivateRenderer(renderer);
868 data->glDeleteTextures(1, &tdata->texture);
869 if (tdata->texture_v) {
870 data->glDeleteTextures(1, &tdata->texture_v);
872 if (tdata->texture_u) {
873 data->glDeleteTextures(1, &tdata->texture_u);
885 static GLES2_ShaderCacheEntry *GLES2_CacheShader(
SDL_Renderer *renderer, GLES2_ShaderType type,
887 static void GLES2_EvictShader(
SDL_Renderer *renderer, GLES2_ShaderCacheEntry *entry);
888 static GLES2_ProgramCacheEntry *GLES2_CacheProgram(
SDL_Renderer *renderer,
889 GLES2_ShaderCacheEntry *vertex,
890 GLES2_ShaderCacheEntry *fragment,
895 static GLES2_ProgramCacheEntry *
896 GLES2_CacheProgram(
SDL_Renderer *renderer, GLES2_ShaderCacheEntry *vertex,
899 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
900 GLES2_ProgramCacheEntry *entry;
901 GLES2_ShaderCacheEntry *shaderEntry;
902 GLint linkSuccessful;
905 entry = data->program_cache.head;
907 if (entry->vertex_shader == vertex && entry->fragment_shader == fragment) {
913 if (data->program_cache.head != entry) {
915 entry->next->prev = entry->prev;
918 entry->prev->next = entry->next;
921 entry->next = data->program_cache.head;
922 data->program_cache.head->prev = entry;
923 data->program_cache.head = entry;
929 entry = (GLES2_ProgramCacheEntry *)
SDL_calloc(1,
sizeof(GLES2_ProgramCacheEntry));
934 entry->vertex_shader = vertex;
935 entry->fragment_shader = fragment;
939 entry->id = data->glCreateProgram();
940 data->glAttachShader(entry->id, vertex->id);
941 data->glAttachShader(entry->id, fragment->id);
942 data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_POSITION,
"a_position");
943 data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_TEXCOORD,
"a_texCoord");
944 data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_ANGLE,
"a_angle");
945 data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_CENTER,
"a_center");
946 data->glLinkProgram(entry->id);
948 if (!linkSuccessful) {
949 data->glDeleteProgram(entry->id);
956 entry->uniform_locations[GLES2_UNIFORM_PROJECTION] =
957 data->glGetUniformLocation(entry->id,
"u_projection");
958 entry->uniform_locations[GLES2_UNIFORM_TEXTURE_V] =
959 data->glGetUniformLocation(entry->id,
"u_texture_v");
960 entry->uniform_locations[GLES2_UNIFORM_TEXTURE_U] =
961 data->glGetUniformLocation(entry->id,
"u_texture_u");
962 entry->uniform_locations[GLES2_UNIFORM_TEXTURE] =
963 data->glGetUniformLocation(entry->id,
"u_texture");
964 entry->uniform_locations[GLES2_UNIFORM_MODULATION] =
965 data->glGetUniformLocation(entry->id,
"u_modulation");
966 entry->uniform_locations[GLES2_UNIFORM_COLOR] =
967 data->glGetUniformLocation(entry->id,
"u_color");
969 entry->modulation_r = entry->modulation_g = entry->modulation_b = entry->modulation_a = 255;
970 entry->color_r = entry->color_g = entry->color_b = entry->color_a = 255;
972 data->glUseProgram(entry->id);
973 data->glUniform1i(entry->uniform_locations[GLES2_UNIFORM_TEXTURE_V], 2);
974 data->glUniform1i(entry->uniform_locations[GLES2_UNIFORM_TEXTURE_U], 1);
975 data->glUniform1i(entry->uniform_locations[GLES2_UNIFORM_TEXTURE], 0);
976 data->glUniformMatrix4fv(entry->uniform_locations[GLES2_UNIFORM_PROJECTION], 1,
GL_FALSE, (
GLfloat *)entry->projection);
977 data->glUniform4f(entry->uniform_locations[GLES2_UNIFORM_MODULATION], 1.0f, 1.0f, 1.0f, 1.0f);
978 data->glUniform4f(entry->uniform_locations[GLES2_UNIFORM_COLOR], 1.0f, 1.0f, 1.0f, 1.0f);
981 if (data->program_cache.head) {
982 entry->next = data->program_cache.head;
983 data->program_cache.head->prev = entry;
985 data->program_cache.tail = entry;
987 data->program_cache.head = entry;
988 ++data->program_cache.count;
991 ++vertex->references;
992 ++fragment->references;
995 if (data->program_cache.count > GLES2_MAX_CACHED_PROGRAMS) {
996 shaderEntry = data->program_cache.tail->vertex_shader;
997 if (--shaderEntry->references <= 0) {
998 GLES2_EvictShader(renderer, shaderEntry);
1000 shaderEntry = data->program_cache.tail->fragment_shader;
1001 if (--shaderEntry->references <= 0) {
1002 GLES2_EvictShader(renderer, shaderEntry);
1004 data->glDeleteProgram(data->program_cache.tail->id);
1005 data->program_cache.tail = data->program_cache.tail->prev;
1006 SDL_free(data->program_cache.tail->next);
1007 data->program_cache.tail->next =
NULL;
1008 --data->program_cache.count;
1013 static GLES2_ShaderCacheEntry *
1016 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1017 const GLES2_Shader *
shader;
1018 const GLES2_ShaderInstance *instance =
NULL;
1019 GLES2_ShaderCacheEntry *entry =
NULL;
1024 shader = GLES2_GetShader(type, blendMode);
1026 SDL_SetError(
"No shader matching the requested characteristics was found");
1031 for (i = 0; i <
shader->instance_count && !instance; ++
i) {
1032 for (
j = 0;
j < data->shader_format_count && !instance; ++
j) {
1033 if (!
shader->instances[i]) {
1036 if (
shader->instances[i]->format != data->shader_formats[
j]) {
1039 instance =
shader->instances[
i];
1043 SDL_SetError(
"The specified shader cannot be loaded on the current platform");
1048 entry = data->shader_cache.head;
1050 if (entry->instance == instance) {
1053 entry = entry->next;
1060 entry = (GLES2_ShaderCacheEntry *)
SDL_calloc(1,
sizeof(GLES2_ShaderCacheEntry));
1066 entry->instance = instance;
1069 entry->id = data->glCreateShader(instance->type);
1070 if (instance->format == (
GLenum)-1) {
1071 data->glShaderSource(entry->id, 1, (
const char **)&instance->data,
NULL);
1072 data->glCompileShader(entry->id);
1075 data->glShaderBinary(1, &entry->id, instance->format, instance->data, instance->length);
1078 if (!compileSuccessful) {
1086 data->glGetShaderInfoLog(entry->id, length, &length, info);
1095 data->glDeleteShader(entry->id);
1101 if (data->shader_cache.head) {
1102 entry->next = data->shader_cache.head;
1103 data->shader_cache.head->prev = entry;
1105 data->shader_cache.head = entry;
1106 ++data->shader_cache.count;
1111 GLES2_EvictShader(
SDL_Renderer *renderer, GLES2_ShaderCacheEntry *entry)
1113 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1117 entry->next->prev = entry->prev;
1120 entry->prev->next = entry->next;
1122 if (data->shader_cache.head == entry) {
1123 data->shader_cache.head = entry->next;
1125 --data->shader_cache.count;
1128 data->glDeleteShader(entry->id);
1135 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1136 GLES2_ShaderCacheEntry *vertex =
NULL;
1137 GLES2_ShaderCacheEntry *fragment =
NULL;
1138 GLES2_ShaderType vtype, ftype;
1139 GLES2_ProgramCacheEntry *
program;
1142 vtype = GLES2_SHADER_VERTEX_DEFAULT;
1144 case GLES2_IMAGESOURCE_SOLID:
1145 ftype = GLES2_SHADER_FRAGMENT_SOLID_SRC;
1147 case GLES2_IMAGESOURCE_TEXTURE_ABGR:
1148 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_ABGR_SRC;
1150 case GLES2_IMAGESOURCE_TEXTURE_ARGB:
1151 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_ARGB_SRC;
1153 case GLES2_IMAGESOURCE_TEXTURE_RGB:
1154 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_RGB_SRC;
1156 case GLES2_IMAGESOURCE_TEXTURE_BGR:
1157 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_BGR_SRC;
1159 case GLES2_IMAGESOURCE_TEXTURE_YUV:
1160 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_YUV_SRC;
1162 case GLES2_IMAGESOURCE_TEXTURE_NV12:
1163 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_SRC;
1165 case GLES2_IMAGESOURCE_TEXTURE_NV21:
1166 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV21_SRC;
1173 vertex = GLES2_CacheShader(renderer, vtype, blendMode);
1177 fragment = GLES2_CacheShader(renderer, ftype, blendMode);
1183 if (data->current_program &&
1184 data->current_program->vertex_shader == vertex &&
1185 data->current_program->fragment_shader == fragment) {
1190 program = GLES2_CacheProgram(renderer, vertex, fragment, blendMode);
1196 data->glUseProgram(
program->id);
1199 data->current_program =
program;
1202 if (GLES2_SetOrthographicProjection(renderer) < 0) {
1209 if (vertex && vertex->references <= 0) {
1210 GLES2_EvictShader(renderer, vertex);
1212 if (fragment && fragment->references <= 0) {
1213 GLES2_EvictShader(renderer, fragment);
1215 data->current_program =
NULL;
1220 GLES2_SetOrthographicProjection(
SDL_Renderer *renderer)
1222 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1230 projection[0][0] = 2.0f / renderer->
viewport.
w;
1231 projection[0][1] = 0.0f;
1232 projection[0][2] = 0.0f;
1233 projection[0][3] = 0.0f;
1234 projection[1][0] = 0.0f;
1236 projection[1][1] = 2.0f / renderer->
viewport.
h;
1238 projection[1][1] = -2.0f / renderer->
viewport.
h;
1240 projection[1][2] = 0.0f;
1241 projection[1][3] = 0.0f;
1242 projection[2][0] = 0.0f;
1243 projection[2][1] = 0.0f;
1244 projection[2][2] = 0.0f;
1245 projection[2][3] = 0.0f;
1246 projection[3][0] = -1.0f;
1248 projection[3][1] = -1.0f;
1250 projection[3][1] = 1.0f;
1252 projection[3][2] = 0.0f;
1253 projection[3][3] = 1.0f;
1256 if (
SDL_memcmp(data->current_program->projection, projection, sizeof (projection)) != 0) {
1257 const GLuint locProjection = data->current_program->uniform_locations[GLES2_UNIFORM_PROJECTION];
1258 data->glUniformMatrix4fv(locProjection, 1,
GL_FALSE, (
GLfloat *)projection);
1259 SDL_memcpy(data->current_program->projection, projection, sizeof (projection));
1269 static const float inv255f = 1.0f / 255.0f;
1282 static void GLES2_RenderPresent(
SDL_Renderer *renderer);
1291 return (Pixel1 == Pixel2);
1299 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1301 GLES2_ActivateRenderer(renderer);
1303 if (!CompareColors(data->clear_r, data->clear_g, data->clear_b, data->clear_a,
1304 renderer->
r, renderer->
g, renderer->
b, renderer->
a)) {
1320 data->glClearColor((
GLfloat) r * inv255f,
1324 data->clear_r = renderer->
r;
1325 data->clear_g = renderer->
g;
1326 data->clear_b = renderer->
b;
1327 data->clear_a = renderer->
a;
1344 GLES2_SetBlendMode(GLES2_DriverContext *data,
int blendMode)
1346 if (blendMode != data->current.blendMode) {
1347 switch (blendMode) {
1372 if (enabled != data->current.tex_coords) {
1374 data->glEnableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
1376 data->glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
1378 data->current.tex_coords =
enabled;
1385 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1386 const int blendMode = renderer->
blendMode;
1387 GLES2_ProgramCacheEntry *
program;
1390 GLES2_ActivateRenderer(renderer);
1392 GLES2_SetBlendMode(data, blendMode);
1397 if (GLES2_SelectProgram(renderer, GLES2_IMAGESOURCE_SOLID, blendMode) < 0) {
1415 program = data->current_program;
1418 data->glUniform4f(
program->uniform_locations[GLES2_UNIFORM_COLOR], r * inv255f, g * inv255f, b * inv255f, a * inv255f);
1429 GLES2_UpdateVertexBuffer(
SDL_Renderer *renderer, GLES2_Attribute attr,
1430 const void *vertexData,
size_t dataSizeInBytes)
1432 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1434 #
if !SDL_GLES2_USE_VBOS
1435 data->glVertexAttribPointer(attr, attr == GLES2_ATTRIBUTE_ANGLE ? 1 : 2,
GL_FLOAT,
GL_FALSE, 0, vertexData);
1437 if (!data->vertex_buffers[attr]) {
1438 data->glGenBuffers(1, &data->vertex_buffers[attr]);
1443 if (data->vertex_buffer_size[attr] < dataSizeInBytes) {
1445 data->vertex_buffer_size[attr] = dataSizeInBytes;
1447 data->glBufferSubData(
GL_ARRAY_BUFFER, 0, dataSizeInBytes, vertexData);
1450 data->glVertexAttribPointer(attr, attr == GLES2_ATTRIBUTE_ANGLE ? 1 : 2,
GL_FLOAT,
GL_FALSE, 0, 0);
1459 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1463 if (GLES2_SetDrawingState(renderer) < 0) {
1469 for (idx = 0; idx <
count; ++idx) {
1473 vertices[idx * 2] =
x;
1474 vertices[(idx * 2) + 1] = y;
1477 GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_POSITION, vertices, count * 2 *
sizeof(
GLfloat));
1478 data->glDrawArrays(
GL_POINTS, 0, count);
1486 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1490 if (GLES2_SetDrawingState(renderer) < 0) {
1496 for (idx = 0; idx <
count; ++idx) {
1500 vertices[idx * 2] =
x;
1501 vertices[(idx * 2) + 1] = y;
1504 GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_POSITION, vertices, count * 2 *
sizeof(
GLfloat));
1509 points[0].
x != points[count-1].
x || points[0].y != points[count-1].y) {
1510 data->glDrawArrays(
GL_POINTS, count-1, 1);
1514 return GL_CheckError(
"", renderer);
1520 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1524 if (GLES2_SetDrawingState(renderer) < 0) {
1529 for (idx = 0; idx <
count; ++idx) {
1546 GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_POSITION, vertices, 8 *
sizeof(
GLfloat));
1549 return GL_CheckError(
"", renderer);
1555 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1556 GLES2_TextureData *tdata = (GLES2_TextureData *)texture->
driverdata;
1557 GLES2_ImageSource sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1559 GLES2_ProgramCacheEntry *
program;
1567 switch (texture->
format) {
1572 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1575 sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1583 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1586 sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1593 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1596 sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
1599 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1606 sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
1609 sourceType = GLES2_IMAGESOURCE_TEXTURE_RGB;
1612 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1618 sourceType = GLES2_IMAGESOURCE_TEXTURE_YUV;
1621 sourceType = GLES2_IMAGESOURCE_TEXTURE_NV12;
1624 sourceType = GLES2_IMAGESOURCE_TEXTURE_NV21;
1630 sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1633 switch (texture->
format) {
1635 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1638 sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1641 sourceType = GLES2_IMAGESOURCE_TEXTURE_RGB;
1644 sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
1648 sourceType = GLES2_IMAGESOURCE_TEXTURE_YUV;
1651 sourceType = GLES2_IMAGESOURCE_TEXTURE_NV12;
1654 sourceType = GLES2_IMAGESOURCE_TEXTURE_NV21;
1661 if (GLES2_SelectProgram(renderer, sourceType, blendMode) < 0) {
1668 data->glBindTexture(tdata->texture_type, tdata->texture_v);
1671 data->glBindTexture(tdata->texture_type, tdata->texture_u);
1677 data->glBindTexture(tdata->texture_type, tdata->texture_u);
1681 data->glBindTexture(tdata->texture_type, tdata->texture);
1697 program = data->current_program;
1699 if (!CompareColors(program->modulation_r, program->modulation_g, program->modulation_b, program->modulation_a, r, g, b, a)) {
1700 data->glUniform4f(program->uniform_locations[GLES2_UNIFORM_MODULATION], r * inv255f, g * inv255f, b * inv255f, a * inv255f);
1701 program->modulation_r =
r;
1702 program->modulation_g =
g;
1703 program->modulation_b =
b;
1704 program->modulation_a =
a;
1708 GLES2_SetBlendMode(data, blendMode);
1710 GLES2_SetTexCoords(data,
SDL_TRUE);
1718 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1722 GLES2_ActivateRenderer(renderer);
1724 if (GLES2_SetupCopy(renderer, texture) < 0) {
1729 vertices[0] = dstrect->
x;
1730 vertices[1] = dstrect->
y;
1731 vertices[2] = (dstrect->
x + dstrect->
w);
1732 vertices[3] = dstrect->
y;
1733 vertices[4] = dstrect->
x;
1734 vertices[5] = (dstrect->
y + dstrect->
h);
1735 vertices[6] = (dstrect->
x + dstrect->
w);
1736 vertices[7] = (dstrect->
y + dstrect->
h);
1738 GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_POSITION, vertices, 8 *
sizeof(
GLfloat));
1739 texCoords[0] = srcrect->
x / (
GLfloat)texture->
w;
1740 texCoords[1] = srcrect->
y / (
GLfloat)texture->
h;
1741 texCoords[2] = (srcrect->
x + srcrect->
w) / (
GLfloat)texture->
w;
1742 texCoords[3] = srcrect->
y / (
GLfloat)texture->
h;
1743 texCoords[4] = srcrect->
x / (
GLfloat)texture->
w;
1744 texCoords[5] = (srcrect->
y + srcrect->
h) / (
GLfloat)texture->
h;
1745 texCoords[6] = (srcrect->
x + srcrect->
w) / (
GLfloat)texture->
w;
1746 texCoords[7] = (srcrect->
y + srcrect->
h) / (
GLfloat)texture->
h;
1748 GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_TEXCOORD, texCoords, 8 *
sizeof(
GLfloat));
1751 return GL_CheckError(
"", renderer);
1758 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1765 GLES2_ActivateRenderer(renderer);
1767 if (GLES2_SetupCopy(renderer, texture) < 0) {
1771 data->glEnableVertexAttribArray(GLES2_ATTRIBUTE_CENTER);
1772 data->glEnableVertexAttribArray(GLES2_ATTRIBUTE_ANGLE);
1773 fAngle[0] = fAngle[1] = fAngle[2] = fAngle[3] = (
GLfloat)(360.0
f - angle);
1775 translate[0] = translate[2] = translate[4] = translate[6] = (center->
x + dstrect->
x);
1776 translate[1] = translate[3] = translate[5] = translate[7] = (center->
y + dstrect->
y);
1779 vertices[0] = dstrect->
x;
1780 vertices[1] = dstrect->
y;
1781 vertices[2] = (dstrect->
x + dstrect->
w);
1782 vertices[3] = dstrect->
y;
1783 vertices[4] = dstrect->
x;
1784 vertices[5] = (dstrect->
y + dstrect->
h);
1785 vertices[6] = (dstrect->
x + dstrect->
w);
1786 vertices[7] = (dstrect->
y + dstrect->
h);
1789 vertices[0] = vertices[4] = vertices[2];
1790 vertices[2] = vertices[6] = tmp;
1794 vertices[1] = vertices[3] = vertices[5];
1795 vertices[5] = vertices[7] = tmp;
1802 GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_ANGLE, fAngle, 4 *
sizeof(
GLfloat));
1803 GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_CENTER, translate, 8 *
sizeof(
GLfloat));
1804 GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_POSITION, vertices, 8 *
sizeof(
GLfloat));
1806 texCoords[0] = srcrect->
x / (
GLfloat)texture->
w;
1807 texCoords[1] = srcrect->
y / (
GLfloat)texture->
h;
1808 texCoords[2] = (srcrect->
x + srcrect->
w) / (
GLfloat)texture->
w;
1809 texCoords[3] = srcrect->
y / (
GLfloat)texture->
h;
1810 texCoords[4] = srcrect->
x / (
GLfloat)texture->
w;
1811 texCoords[5] = (srcrect->
y + srcrect->
h) / (
GLfloat)texture->
h;
1812 texCoords[6] = (srcrect->
x + srcrect->
w) / (
GLfloat)texture->
w;
1813 texCoords[7] = (srcrect->
y + srcrect->
h) / (
GLfloat)texture->
h;
1815 GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_TEXCOORD, texCoords, 8 *
sizeof(
GLfloat));
1817 data->glDisableVertexAttribArray(GLES2_ATTRIBUTE_CENTER);
1818 data->glDisableVertexAttribArray(GLES2_ATTRIBUTE_ANGLE);
1820 return GL_CheckError(
"", renderer);
1827 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1832 int w, h, length, rows;
1835 GLES2_ActivateRenderer(renderer);
1845 data->glReadPixels(rect->
x, renderer->
target ? rect->
y : (h-rect->
y)-rect->
h,
1847 if (GL_CheckError(
"glReadPixels()", renderer) < 0) {
1854 src = (
Uint8*)temp_pixels + (rect->
h-1)*temp_pitch;
1869 temp_format, temp_pixels, temp_pitch,
1870 pixel_format, pixels, pitch);
1879 GLES2_ActivateRenderer(renderer);
1894 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1895 GLES2_TextureData *texturedata = (GLES2_TextureData *)texture->
driverdata;
1896 GLES2_ActivateRenderer(renderer);
1898 data->glBindTexture(texturedata->texture_type, texturedata->texture);
1912 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1913 GLES2_TextureData *texturedata = (GLES2_TextureData *)texture->
driverdata;
1914 GLES2_ActivateRenderer(renderer);
1916 data->glBindTexture(texturedata->texture_type, 0);
1926 #define GL_NVIDIA_PLATFORM_BINARY_NV 0x890B 1931 GLES2_DriverContext *data = (GLES2_DriverContext *) renderer->
driverdata;
1933 if (SDL_CurrentContext == data->context) {
1934 GLES2_UpdateViewport(renderer);
1936 GLES2_ActivateRenderer(renderer);
1939 data->current.blendMode = -1;
1946 data->glClearColor((
GLfloat) data->clear_r * inv255f,
1947 (
GLfloat) data->clear_g * inv255f,
1948 (
GLfloat) data->clear_b * inv255f,
1949 (
GLfloat) data->clear_a * inv255f);
1951 data->glEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION);
1952 data->glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
1954 GL_CheckError(
"", renderer);
1961 GLES2_DriverContext *
data;
1967 GLint window_framebuffer;
1969 int profile_mask = 0, major = 0, minor = 0;
2003 data = (GLES2_DriverContext *)
SDL_calloc(1,
sizeof(GLES2_DriverContext));
2005 GLES2_DestroyRenderer(renderer);
2009 renderer->
info = GLES2_RenderDriver.
info;
2016 if (!data->context) {
2017 GLES2_DestroyRenderer(renderer);
2021 GLES2_DestroyRenderer(renderer);
2025 if (GLES2_LoadFunctions(data) < 0) {
2026 GLES2_DestroyRenderer(renderer);
2072 if (!data->shader_formats) {
2073 GLES2_DestroyRenderer(renderer);
2077 data->shader_format_count = nFormats;
2079 data->shader_formats[0] = GL_NVIDIA_PLATFORM_BINARY_NV;
2083 data->shader_formats[nFormats - 1] = (
GLenum)-1;
2087 data->framebuffers =
NULL;
2089 data->window_framebuffer = (
GLuint)window_framebuffer;
2120 GLES2_ResetState(renderer);
2125 if (changed_window) {
int(* RenderDrawLines)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
int(* RenderDrawPoints)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
int(* LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
#define GL_INVALID_OPERATION
GLdouble GLdouble GLdouble r
GLint GLint GLsizei width
#define SDL_GL_CreateContext
int(* RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect, Uint32 format, void *pixels, int pitch)
const GLuint * framebuffers
#define GL_COLOR_ATTACHMENT0
GLint GLint GLint GLint GLint x
SDL_BlendMode
The blend mode used in SDL_RenderCopy() and drawing operations.
#define GL_COMPILE_STATUS
GLuint GLuint GLsizei count
#define SDL_HINT_RENDER_SCALE_QUALITY
A variable controlling the scaling quality.
static SDL_Window * window
GLenum GLenum GLuint texture
#define GL_SHADER_COMPILER
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Uint32 texture_formats[16]
#define SDL_GetWindowFlags
#define SDL_BYTESPERPIXEL(X)
#define GL_TEXTURE_MAG_FILTER
int(* RenderFillRects)(SDL_Renderer *renderer, const SDL_FRect *rects, int count)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
#define GL_TRIANGLE_STRIP
uint32_t Uint32
An unsigned 32-bit integer type.
GLint GLint GLsizei GLsizei height
#define GL_FRAMEBUFFER_COMPLETE
#define GL_ONE_MINUS_SRC_ALPHA
int(* RenderClear)(SDL_Renderer *renderer)
void(* DestroyRenderer)(SDL_Renderer *renderer)
GLfixed GLfixed GLint GLint GLfixed points
int(* GetOutputSize)(SDL_Renderer *renderer, int *w, int *h)
#define GL_PACK_ALIGNMENT
#define GL_MAX_TEXTURE_SIZE
static SDL_BlendMode blendMode
int(* UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
int(* UpdateTextureYUV)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const Uint8 *Yplane, int Ypitch, const Uint8 *Uplane, int Upitch, const Uint8 *Vplane, int Vpitch)
#define SDL_GL_SetAttribute
#define SDL_GL_GetDrawableSize
GLuint GLuint GLsizei GLenum type
void * SDL_calloc(size_t nmemb, size_t size)
void * SDL_GLContext
An opaque handle to an OpenGL context.
#define SDL_GL_GetSwapInterval
GLint GLint GLint GLint GLint GLint y
int SDL_RecreateWindow(SDL_Window *window, Uint32 flags)
GLsizei const GLfloat * value
static int GetScaleQuality(void)
static SDL_Renderer * renderer
uint8_t Uint8
An unsigned 8-bit integer type.
#define SDL_stack_alloc(type, count)
#define SDL_GL_SetSwapInterval
#define GL_TEXTURE_WRAP_T
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int int in j)
#define GL_LUMINANCE_ALPHA
int(* GL_BindTexture)(SDL_Renderer *renderer, SDL_Texture *texture, float *texw, float *texh)
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
GLsizei GLsizei GLchar * source
#define RGBA8888_FROM_RGBA(Pixel, r, g, b, a)
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* UpdateViewport)(SDL_Renderer *renderer)
#define GL_COLOR_BUFFER_BIT
int(* GL_UnbindTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
SDL_RendererFlip
Flip constants for SDL_RenderCopyEx.
GLenum GLenum GLsizei const GLuint GLboolean enabled
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
int(* RenderCopy)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
Window state change event data (event.window.*)
#define GL_FRAMEBUFFER_BINDING
#define SDL_OutOfMemory()
int(* RenderCopyEx)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcquad, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
#define SDL_GL_MakeCurrent
#define SDL_GetRendererOutputSize
GLint GLint GLint yoffset
The type used to identify a window.
GLbitfield GLuint program
SDL_Rect rects[MAX_RECTS]
void(* WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event)
#define GL_SHADER_BINARY_FORMATS
Uint32 num_texture_formats
#define GL_NUM_SHADER_BINARY_FORMATS
#define SDL_GL_GetAttribute
GLubyte GLubyte GLubyte GLubyte w
#define SDL_ConvertPixels
void(* DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
void(* RenderPresent)(SDL_Renderer *renderer)
#define SDL_GL_DeleteContext
#define SDL_stack_free(data)
#define GL_TEXTURE_WRAP_S
GLuint GLsizei GLsizei * length
#define GL_TEXTURE_MIN_FILTER
GLboolean GLboolean GLboolean GLboolean a
#define GL_UNPACK_ALIGNMENT
int(* UpdateClipRect)(SDL_Renderer *renderer)
GLboolean GLboolean GLboolean b
#define SDL_GL_SwapWindow
GLfloat GLfloat GLfloat GLfloat h
SDL_bool clipping_enabled
A rectangle, with the origin at the upper left.
#define GL_INFO_LOG_LENGTH