21 #include "../../SDL_internal.h"
23 #if SDL_VIDEO_RENDER_OGL_ES2 && !SDL_RENDER_DISABLED
28 #include "../SDL_sysrender.h"
29 #include "../../video/SDL_blit.h"
40 #define SDL_GLES2_USE_VBOS 1
42 #define SDL_GLES2_USE_VBOS 0
48 #define RENDERER_CONTEXT_MAJOR 2
49 #define RENDERER_CONTEXT_MINOR 0
81 typedef struct GLES2_FBOList GLES2_FBOList;
90 typedef struct GLES2_TextureData
106 typedef struct GLES2_ShaderCacheEntry
109 GLES2_ShaderType
type;
110 const GLES2_ShaderInstance *instance;
112 Uint8 modulation_r, modulation_g, modulation_b, modulation_a;
113 struct GLES2_ShaderCacheEntry *prev;
114 struct GLES2_ShaderCacheEntry *next;
115 } GLES2_ShaderCacheEntry;
117 typedef struct GLES2_ShaderCache
120 GLES2_ShaderCacheEntry *
head;
123 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,
171 GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES
174 typedef struct GLES2_DriverContext
185 #define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
189 GLuint window_framebuffer;
191 int shader_format_count;
193 GLES2_ShaderCache shader_cache;
194 GLES2_ProgramCache program_cache;
195 GLES2_ProgramCacheEntry *current_program;
196 Uint8 clear_r, clear_g, clear_b, clear_a;
198 #if SDL_GLES2_USE_VBOS
202 } GLES2_DriverContext;
204 #define GLES2_MAX_CACHED_PROGRAMS 8
208 GL_TranslateError (
GLenum error)
210 #define GL_ERROR_TRANSLATE(e) case e: return #e;
220 #undef GL_ERROR_TRANSLATE
226 GLES2_DriverContext *
data = (GLES2_DriverContext *) renderer->
driverdata;
228 if (!data->debug_enabled) {
237 GL_CheckAllErrors (
const char *prefix,
SDL_Renderer *renderer,
const char *file,
int line,
const char *
function)
239 GLES2_DriverContext *data = (GLES2_DriverContext *) renderer->
driverdata;
242 if (!data->debug_enabled) {
247 GLenum error = data->glGetError();
249 if (prefix ==
NULL || prefix[0] ==
'\0') {
252 SDL_SetError(
"%s: %s (%d): %s %s (0x%X)", prefix, file, line,
function, GL_TranslateError(error), error);
262 #define GL_CheckError(prefix, renderer)
264 #define GL_CheckError(prefix, renderer) GL_CheckAllErrors(prefix, renderer, SDL_FILE, SDL_LINE, SDL_FUNCTION)
272 static int GLES2_ActivateRenderer(
SDL_Renderer *renderer);
275 static int GLES2_UpdateViewport(
SDL_Renderer * renderer);
276 static void GLES2_DestroyRenderer(
SDL_Renderer *renderer);
277 static int GLES2_SetOrthographicProjection(
SDL_Renderer *renderer);
282 static int GLES2_LoadFunctions(GLES2_DriverContext * data)
284 #if SDL_VIDEO_DRIVER_UIKIT
285 #define __SDL_NOGETPROCADDR__
286 #elif SDL_VIDEO_DRIVER_ANDROID
287 #define __SDL_NOGETPROCADDR__
288 #elif SDL_VIDEO_DRIVER_PANDORA
289 #define __SDL_NOGETPROCADDR__
292 #if defined __SDL_NOGETPROCADDR__
293 #define SDL_PROC(ret,func,params) data->func=func;
295 #define SDL_PROC(ret,func,params) \
297 data->func = SDL_GL_GetProcAddress(#func); \
298 if ( ! data->func ) { \
299 return SDL_SetError("Couldn't load GLES2 function %s: %s", #func, SDL_GetError()); \
309 static GLES2_FBOList *
312 GLES2_FBOList *
result = data->framebuffers;
313 while ((result) && ((result->w != w) || (result->h != h)) ) {
314 result = result->next;
316 if (result ==
NULL) {
320 data->glGenFramebuffers(1, &result->FBO);
321 result->next = data->framebuffers;
322 data->framebuffers =
result;
330 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
332 if (SDL_CurrentContext != data->context) {
334 data->current_program =
NULL;
339 SDL_CurrentContext = data->context;
341 GLES2_UpdateViewport(renderer);
344 GL_ClearErrors(renderer);
352 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
358 SDL_CurrentContext =
NULL;
368 GLES2_GetOutputSize(
SDL_Renderer * renderer,
int *w,
int *h)
440 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
442 if (SDL_CurrentContext != data->context) {
458 if (data->current_program) {
459 GLES2_SetOrthographicProjection(renderer);
461 return GL_CheckError(
"", renderer);
467 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
469 if (SDL_CurrentContext != data->context) {
483 data->glScissor(renderer->
viewport.
x + rect->
x, h - renderer->
viewport.
y - rect->
y - rect->
h, rect->
w, rect->
h);
494 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
498 GLES2_ActivateRenderer(renderer);
501 GLES2_ShaderCacheEntry *entry;
502 GLES2_ShaderCacheEntry *next;
503 entry = data->shader_cache.head;
505 data->glDeleteShader(entry->id);
512 GLES2_ProgramCacheEntry *entry;
513 GLES2_ProgramCacheEntry *next;
514 entry = data->program_cache.head;
516 data->glDeleteProgram(entry->id);
523 while (data->framebuffers) {
524 GLES2_FBOList *nextnode = data->framebuffers->next;
525 data->glDeleteFramebuffers(1, &data->framebuffers->FBO);
526 GL_CheckError(
"", renderer);
528 data->framebuffers = nextnode;
544 const void *
pixels,
int pitch);
547 const Uint8 *Yplane,
int Ypitch,
548 const Uint8 *Uplane,
int Upitch,
549 const Uint8 *Vplane,
int Vpitch);
551 void **
pixels,
int *pitch);
559 GLES2_DriverContext *renderdata = (GLES2_DriverContext *)renderer->
driverdata;
560 GLES2_TextureData *data;
565 GLES2_ActivateRenderer(renderer);
584 #ifdef GL_TEXTURE_EXTERNAL_OES
596 return SDL_SetError(
"Unsupported texture access for SDL_PIXELFORMAT_EXTERNAL_OES");
600 data = (GLES2_TextureData *)
SDL_calloc(1,
sizeof(GLES2_TextureData));
605 #ifdef GL_TEXTURE_EXTERNAL_OES
610 data->pixel_format =
format;
611 data->pixel_type =
type;
622 size = texture->
h * data->pitch;
625 size += 2 * ((texture->
h + 1) / 2) * ((data->pitch + 1) / 2);
629 size += 2 * ((texture->
h + 1) / 2) * ((data->pitch + 1) / 2);
632 if (!data->pixel_data) {
639 GL_CheckError(
"", renderer);
642 renderdata->glGenTextures(1, &data->texture_v);
643 if (GL_CheckError(
"glGenTexures()", renderer) < 0) {
647 renderdata->glBindTexture(data->texture_type, data->texture_v);
652 renderdata->glTexImage2D(data->texture_type, 0,
format, (texture->
w + 1) / 2, (texture->
h + 1) / 2, 0,
format,
type,
NULL);
654 renderdata->glGenTextures(1, &data->texture_u);
655 if (GL_CheckError(
"glGenTexures()", renderer) < 0) {
659 renderdata->glBindTexture(data->texture_type, data->texture_u);
664 renderdata->glTexImage2D(data->texture_type, 0,
format, (texture->
w + 1) / 2, (texture->
h + 1) / 2, 0,
format,
type,
NULL);
665 if (GL_CheckError(
"glTexImage2D()", renderer) < 0) {
671 renderdata->glGenTextures(1, &data->texture_u);
672 if (GL_CheckError(
"glGenTexures()", renderer) < 0) {
676 renderdata->glBindTexture(data->texture_type, data->texture_u);
682 if (GL_CheckError(
"glTexImage2D()", renderer) < 0) {
687 renderdata->glGenTextures(1, &data->texture);
688 if (GL_CheckError(
"glGenTexures()", renderer) < 0) {
693 renderdata->glBindTexture(data->texture_type, data->texture);
700 if (GL_CheckError(
"glTexImage2D()", renderer) < 0) {
706 data->fbo = GLES2_GetFBO(renderer->
driverdata, texture->
w, texture->
h);
711 return GL_CheckError(
"", renderer);
715 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)
722 if ((width == 0) || (height == 0) || (bpp == 0)) {
727 src_pitch = width * bpp;
728 src = (
Uint8 *)pixels;
729 if (pitch != src_pitch) {
739 pixels = (
Uint8 *)pixels + pitch;
744 data->glTexSubImage2D(target, 0, xoffset, yoffset, width, height, format, type, src);
753 const void *pixels,
int pitch)
755 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
756 GLES2_TextureData *tdata = (GLES2_TextureData *)texture->
driverdata;
758 GLES2_ActivateRenderer(renderer);
761 if (rect->
w <= 0 || rect->
h <= 0) {
766 data->glBindTexture(tdata->texture_type, tdata->texture);
767 GLES2_TexSubImage2D(data, tdata->texture_type,
778 pixels = (
const void*)((
const Uint8*)pixels + rect->
h * pitch);
780 data->glBindTexture(tdata->texture_type, tdata->texture_v);
782 data->glBindTexture(tdata->texture_type, tdata->texture_u);
784 GLES2_TexSubImage2D(data, tdata->texture_type,
791 pixels, (pitch + 1) / 2, 1);
795 pixels = (
const void*)((
const Uint8*)pixels + ((rect->
h + 1) / 2) * ((pitch + 1)/2));
797 data->glBindTexture(tdata->texture_type, tdata->texture_u);
799 data->glBindTexture(tdata->texture_type, tdata->texture_v);
801 GLES2_TexSubImage2D(data, tdata->texture_type,
808 pixels, (pitch + 1) / 2, 1);
813 pixels = (
const void*)((
const Uint8*)pixels + rect->
h * pitch);
814 data->glBindTexture(tdata->texture_type, tdata->texture_u);
815 GLES2_TexSubImage2D(data, tdata->texture_type,
822 pixels, 2 * ((pitch + 1) / 2), 2);
825 return GL_CheckError(
"glTexSubImage2D()", renderer);
831 const Uint8 *Yplane,
int Ypitch,
832 const Uint8 *Uplane,
int Upitch,
833 const Uint8 *Vplane,
int Vpitch)
835 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
836 GLES2_TextureData *tdata = (GLES2_TextureData *)texture->
driverdata;
838 GLES2_ActivateRenderer(renderer);
841 if (rect->
w <= 0 || rect->
h <= 0) {
845 data->glBindTexture(tdata->texture_type, tdata->texture_v);
846 GLES2_TexSubImage2D(data, tdata->texture_type,
855 data->glBindTexture(tdata->texture_type, tdata->texture_u);
856 GLES2_TexSubImage2D(data, tdata->texture_type,
865 data->glBindTexture(tdata->texture_type, tdata->texture);
866 GLES2_TexSubImage2D(data, tdata->texture_type,
875 return GL_CheckError(
"glTexSubImage2D()", renderer);
880 void **pixels,
int *pitch)
882 GLES2_TextureData *tdata = (GLES2_TextureData *)texture->
driverdata;
885 *pixels = (
Uint8 *)tdata->pixel_data +
886 (tdata->pitch * rect->
y) +
888 *pitch = tdata->pitch;
896 GLES2_TextureData *tdata = (GLES2_TextureData *)texture->
driverdata;
904 GLES2_UpdateTexture(renderer, texture, &rect, tdata->pixel_data, tdata->pitch);
910 GLES2_DriverContext *data = (GLES2_DriverContext *) renderer->
driverdata;
911 GLES2_TextureData *texturedata =
NULL;
914 if (texture ==
NULL) {
915 data->glBindFramebuffer(
GL_FRAMEBUFFER, data->window_framebuffer);
917 texturedata = (GLES2_TextureData *) texture->
driverdata;
933 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
934 GLES2_TextureData *tdata = (GLES2_TextureData *)texture->
driverdata;
936 GLES2_ActivateRenderer(renderer);
940 data->glDeleteTextures(1, &tdata->texture);
941 if (tdata->texture_v) {
942 data->glDeleteTextures(1, &tdata->texture_v);
944 if (tdata->texture_u) {
945 data->glDeleteTextures(1, &tdata->texture_u);
957 static GLES2_ShaderCacheEntry *GLES2_CacheShader(
SDL_Renderer *renderer, GLES2_ShaderType type);
958 static void GLES2_EvictShader(
SDL_Renderer *renderer, GLES2_ShaderCacheEntry *entry);
959 static GLES2_ProgramCacheEntry *GLES2_CacheProgram(
SDL_Renderer *renderer,
960 GLES2_ShaderCacheEntry *vertex,
961 GLES2_ShaderCacheEntry *fragment);
962 static int GLES2_SelectProgram(
SDL_Renderer *renderer, GLES2_ImageSource
source,
int w,
int h);
964 static GLES2_ProgramCacheEntry *
965 GLES2_CacheProgram(
SDL_Renderer *renderer, GLES2_ShaderCacheEntry *vertex,
966 GLES2_ShaderCacheEntry *fragment)
968 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
969 GLES2_ProgramCacheEntry *entry;
970 GLES2_ShaderCacheEntry *shaderEntry;
971 GLint linkSuccessful;
974 entry = data->program_cache.head;
976 if (entry->vertex_shader == vertex && entry->fragment_shader == fragment) {
982 if (data->program_cache.head != entry) {
984 entry->next->prev = entry->prev;
987 entry->prev->next = entry->next;
990 entry->next = data->program_cache.head;
991 data->program_cache.head->prev = entry;
992 data->program_cache.head = entry;
998 entry = (GLES2_ProgramCacheEntry *)
SDL_calloc(1,
sizeof(GLES2_ProgramCacheEntry));
1003 entry->vertex_shader = vertex;
1004 entry->fragment_shader = fragment;
1007 entry->id = data->glCreateProgram();
1008 data->glAttachShader(entry->id, vertex->id);
1009 data->glAttachShader(entry->id, fragment->id);
1010 data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_POSITION,
"a_position");
1011 data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_TEXCOORD,
"a_texCoord");
1012 data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_ANGLE,
"a_angle");
1013 data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_CENTER,
"a_center");
1014 data->glLinkProgram(entry->id);
1015 data->glGetProgramiv(entry->id,
GL_LINK_STATUS, &linkSuccessful);
1016 if (!linkSuccessful) {
1017 data->glDeleteProgram(entry->id);
1024 entry->uniform_locations[GLES2_UNIFORM_PROJECTION] =
1025 data->glGetUniformLocation(entry->id,
"u_projection");
1026 entry->uniform_locations[GLES2_UNIFORM_TEXTURE_V] =
1027 data->glGetUniformLocation(entry->id,
"u_texture_v");
1028 entry->uniform_locations[GLES2_UNIFORM_TEXTURE_U] =
1029 data->glGetUniformLocation(entry->id,
"u_texture_u");
1030 entry->uniform_locations[GLES2_UNIFORM_TEXTURE] =
1031 data->glGetUniformLocation(entry->id,
"u_texture");
1032 entry->uniform_locations[GLES2_UNIFORM_MODULATION] =
1033 data->glGetUniformLocation(entry->id,
"u_modulation");
1034 entry->uniform_locations[GLES2_UNIFORM_COLOR] =
1035 data->glGetUniformLocation(entry->id,
"u_color");
1037 entry->modulation_r = entry->modulation_g = entry->modulation_b = entry->modulation_a = 255;
1038 entry->color_r = entry->color_g = entry->color_b = entry->color_a = 255;
1040 data->glUseProgram(entry->id);
1041 data->glUniform1i(entry->uniform_locations[GLES2_UNIFORM_TEXTURE_V], 2);
1042 data->glUniform1i(entry->uniform_locations[GLES2_UNIFORM_TEXTURE_U], 1);
1043 data->glUniform1i(entry->uniform_locations[GLES2_UNIFORM_TEXTURE], 0);
1044 data->glUniformMatrix4fv(entry->uniform_locations[GLES2_UNIFORM_PROJECTION], 1,
GL_FALSE, (
GLfloat *)entry->projection);
1045 data->glUniform4f(entry->uniform_locations[GLES2_UNIFORM_MODULATION], 1.0f, 1.0f, 1.0f, 1.0f);
1046 data->glUniform4f(entry->uniform_locations[GLES2_UNIFORM_COLOR], 1.0f, 1.0f, 1.0f, 1.0f);
1049 if (data->program_cache.head) {
1050 entry->next = data->program_cache.head;
1051 data->program_cache.head->prev = entry;
1053 data->program_cache.tail = entry;
1055 data->program_cache.head = entry;
1056 ++data->program_cache.count;
1059 ++vertex->references;
1060 ++fragment->references;
1063 if (data->program_cache.count > GLES2_MAX_CACHED_PROGRAMS) {
1064 shaderEntry = data->program_cache.tail->vertex_shader;
1065 if (--shaderEntry->references <= 0) {
1066 GLES2_EvictShader(renderer, shaderEntry);
1068 shaderEntry = data->program_cache.tail->fragment_shader;
1069 if (--shaderEntry->references <= 0) {
1070 GLES2_EvictShader(renderer, shaderEntry);
1072 data->glDeleteProgram(data->program_cache.tail->id);
1073 data->program_cache.tail = data->program_cache.tail->prev;
1074 SDL_free(data->program_cache.tail->next);
1075 data->program_cache.tail->next =
NULL;
1076 --data->program_cache.count;
1081 static GLES2_ShaderCacheEntry *
1082 GLES2_CacheShader(
SDL_Renderer *renderer, GLES2_ShaderType type)
1084 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1085 const GLES2_Shader *
shader;
1086 const GLES2_ShaderInstance *instance =
NULL;
1087 GLES2_ShaderCacheEntry *entry =
NULL;
1092 shader = GLES2_GetShader(type);
1094 SDL_SetError(
"No shader matching the requested characteristics was found");
1099 for (i = 0; i <
shader->instance_count && !instance; ++
i) {
1100 for (
j = 0;
j < data->shader_format_count && !instance; ++
j) {
1101 if (!
shader->instances[i]) {
1104 if (
shader->instances[i]->format != data->shader_formats[
j]) {
1107 instance =
shader->instances[
i];
1111 SDL_SetError(
"The specified shader cannot be loaded on the current platform");
1116 entry = data->shader_cache.head;
1118 if (entry->instance == instance) {
1121 entry = entry->next;
1128 entry = (GLES2_ShaderCacheEntry *)
SDL_calloc(1,
sizeof(GLES2_ShaderCacheEntry));
1134 entry->instance = instance;
1137 entry->id = data->glCreateShader(instance->type);
1138 if (instance->format == (
GLenum)-1) {
1139 data->glShaderSource(entry->id, 1, (
const char **)(
char *)&instance->data,
NULL);
1140 data->glCompileShader(entry->id);
1143 data->glShaderBinary(1, &entry->id, instance->format, instance->data, instance->length);
1146 if (!compileSuccessful) {
1154 data->glGetShaderInfoLog(entry->id, length, &length, info);
1163 data->glDeleteShader(entry->id);
1169 if (data->shader_cache.head) {
1170 entry->next = data->shader_cache.head;
1171 data->shader_cache.head->prev = entry;
1173 data->shader_cache.head = entry;
1174 ++data->shader_cache.count;
1179 GLES2_EvictShader(
SDL_Renderer *renderer, GLES2_ShaderCacheEntry *entry)
1181 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1185 entry->next->prev = entry->prev;
1188 entry->prev->next = entry->next;
1190 if (data->shader_cache.head == entry) {
1191 data->shader_cache.head = entry->next;
1193 --data->shader_cache.count;
1196 data->glDeleteShader(entry->id);
1203 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1204 GLES2_ShaderCacheEntry *vertex =
NULL;
1205 GLES2_ShaderCacheEntry *fragment =
NULL;
1206 GLES2_ShaderType vtype, ftype;
1207 GLES2_ProgramCacheEntry *
program;
1210 vtype = GLES2_SHADER_VERTEX_DEFAULT;
1212 case GLES2_IMAGESOURCE_SOLID:
1213 ftype = GLES2_SHADER_FRAGMENT_SOLID_SRC;
1215 case GLES2_IMAGESOURCE_TEXTURE_ABGR:
1216 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_ABGR_SRC;
1218 case GLES2_IMAGESOURCE_TEXTURE_ARGB:
1219 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_ARGB_SRC;
1221 case GLES2_IMAGESOURCE_TEXTURE_RGB:
1222 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_RGB_SRC;
1224 case GLES2_IMAGESOURCE_TEXTURE_BGR:
1225 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_BGR_SRC;
1227 case GLES2_IMAGESOURCE_TEXTURE_YUV:
1230 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_YUV_JPEG_SRC;
1233 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601_SRC;
1236 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT709_SRC;
1243 case GLES2_IMAGESOURCE_TEXTURE_NV12:
1246 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_JPEG_SRC;
1249 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT601_SRC;
1252 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT709_SRC;
1259 case GLES2_IMAGESOURCE_TEXTURE_NV21:
1262 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV21_JPEG_SRC;
1265 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT601_SRC;
1268 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709_SRC;
1275 case GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES:
1276 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES_SRC;
1283 vertex = GLES2_CacheShader(renderer, vtype);
1287 fragment = GLES2_CacheShader(renderer, ftype);
1293 if (data->current_program &&
1294 data->current_program->vertex_shader == vertex &&
1295 data->current_program->fragment_shader == fragment) {
1300 program = GLES2_CacheProgram(renderer, vertex, fragment);
1306 data->glUseProgram(
program->id);
1309 data->current_program =
program;
1312 if (GLES2_SetOrthographicProjection(renderer) < 0) {
1319 if (vertex && vertex->references <= 0) {
1320 GLES2_EvictShader(renderer, vertex);
1322 if (fragment && fragment->references <= 0) {
1323 GLES2_EvictShader(renderer, fragment);
1325 data->current_program =
NULL;
1330 GLES2_SetOrthographicProjection(
SDL_Renderer *renderer)
1332 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1340 projection[0][0] = 2.0f / renderer->
viewport.
w;
1341 projection[0][1] = 0.0f;
1342 projection[0][2] = 0.0f;
1343 projection[0][3] = 0.0f;
1344 projection[1][0] = 0.0f;
1346 projection[1][1] = 2.0f / renderer->
viewport.
h;
1348 projection[1][1] = -2.0f / renderer->
viewport.
h;
1350 projection[1][2] = 0.0f;
1351 projection[1][3] = 0.0f;
1352 projection[2][0] = 0.0f;
1353 projection[2][1] = 0.0f;
1354 projection[2][2] = 0.0f;
1355 projection[2][3] = 0.0f;
1356 projection[3][0] = -1.0f;
1358 projection[3][1] = -1.0f;
1360 projection[3][1] = 1.0f;
1362 projection[3][2] = 0.0f;
1363 projection[3][3] = 1.0f;
1366 if (
SDL_memcmp(data->current_program->projection, projection, sizeof (projection)) != 0) {
1367 const GLuint locProjection = data->current_program->uniform_locations[GLES2_UNIFORM_PROJECTION];
1368 data->glUniformMatrix4fv(locProjection, 1,
GL_FALSE, (
GLfloat *)projection);
1369 SDL_memcpy(data->current_program->projection, projection, sizeof (projection));
1379 static const float inv255f = 1.0f / 255.0f;
1391 Uint32 pixel_format,
void * pixels,
int pitch);
1392 static void GLES2_RenderPresent(
SDL_Renderer *renderer);
1401 return (Pixel1 == Pixel2);
1409 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1411 GLES2_ActivateRenderer(renderer);
1413 if (!CompareColors(data->clear_r, data->clear_g, data->clear_b, data->clear_a,
1414 renderer->
r, renderer->
g, renderer->
b, renderer->
a)) {
1430 data->glClearColor((
GLfloat) r * inv255f,
1434 data->clear_r = renderer->
r;
1435 data->clear_g = renderer->
g;
1436 data->clear_b = renderer->
b;
1437 data->clear_a = renderer->
a;
1454 GLES2_SetBlendMode(GLES2_DriverContext *data,
SDL_BlendMode blendMode)
1456 if (blendMode != data->current.blendMode) {
1475 if (enabled != data->current.tex_coords) {
1477 data->glEnableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
1479 data->glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
1481 data->current.tex_coords =
enabled;
1488 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1489 GLES2_ProgramCacheEntry *
program;
1492 GLES2_ActivateRenderer(renderer);
1494 GLES2_SetBlendMode(data, renderer->
blendMode);
1499 if (GLES2_SelectProgram(renderer, GLES2_IMAGESOURCE_SOLID, 0, 0) < 0) {
1517 program = data->current_program;
1520 data->glUniform4f(
program->uniform_locations[GLES2_UNIFORM_COLOR], r * inv255f, g * inv255f, b * inv255f, a * inv255f);
1531 GLES2_UpdateVertexBuffer(
SDL_Renderer *renderer, GLES2_Attribute attr,
1532 const void *vertexData,
size_t dataSizeInBytes)
1534 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1536 #
if !SDL_GLES2_USE_VBOS
1539 if (!data->vertex_buffers[attr]) {
1540 data->glGenBuffers(1, &data->vertex_buffers[attr]);
1545 if (data->vertex_buffer_size[attr] < dataSizeInBytes) {
1547 data->vertex_buffer_size[attr] = dataSizeInBytes;
1549 data->glBufferSubData(
GL_ARRAY_BUFFER, 0, dataSizeInBytes, vertexData);
1561 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1565 if (GLES2_SetDrawingState(renderer) < 0) {
1571 for (idx = 0; idx <
count; ++idx) {
1575 vertices[idx * 2] =
x;
1576 vertices[(idx * 2) + 1] = y;
1579 GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_POSITION, vertices, count * 2 *
sizeof(
GLfloat));
1580 data->glDrawArrays(
GL_POINTS, 0, count);
1588 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1592 if (GLES2_SetDrawingState(renderer) < 0) {
1598 for (idx = 0; idx <
count; ++idx) {
1602 vertices[idx * 2] =
x;
1603 vertices[(idx * 2) + 1] = y;
1606 GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_POSITION, vertices, count * 2 *
sizeof(
GLfloat));
1611 points[0].
x != points[count-1].
x || points[0].y != points[count-1].y) {
1612 data->glDrawArrays(
GL_POINTS, count-1, 1);
1616 return GL_CheckError(
"", renderer);
1622 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1626 if (GLES2_SetDrawingState(renderer) < 0) {
1631 for (idx = 0; idx <
count; ++idx) {
1648 GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_POSITION, vertices, 8 *
sizeof(
GLfloat));
1651 return GL_CheckError(
"", renderer);
1657 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1658 GLES2_TextureData *tdata = (GLES2_TextureData *)texture->
driverdata;
1659 GLES2_ImageSource sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1660 GLES2_ProgramCacheEntry *
program;
1667 switch (texture->
format) {
1672 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1675 sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1683 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1686 sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1693 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1696 sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
1699 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1706 sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
1709 sourceType = GLES2_IMAGESOURCE_TEXTURE_RGB;
1712 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1718 sourceType = GLES2_IMAGESOURCE_TEXTURE_YUV;
1721 sourceType = GLES2_IMAGESOURCE_TEXTURE_NV12;
1724 sourceType = GLES2_IMAGESOURCE_TEXTURE_NV21;
1727 sourceType = GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES;
1733 sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1736 switch (texture->
format) {
1738 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1741 sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1744 sourceType = GLES2_IMAGESOURCE_TEXTURE_RGB;
1747 sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
1751 sourceType = GLES2_IMAGESOURCE_TEXTURE_YUV;
1754 sourceType = GLES2_IMAGESOURCE_TEXTURE_NV12;
1757 sourceType = GLES2_IMAGESOURCE_TEXTURE_NV21;
1760 sourceType = GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES;
1767 if (GLES2_SelectProgram(renderer, sourceType, texture->
w, texture->
h) < 0) {
1774 data->glBindTexture(tdata->texture_type, tdata->texture_v);
1777 data->glBindTexture(tdata->texture_type, tdata->texture_u);
1783 data->glBindTexture(tdata->texture_type, tdata->texture_u);
1787 data->glBindTexture(tdata->texture_type, tdata->texture);
1803 program = data->current_program;
1805 if (!CompareColors(program->modulation_r, program->modulation_g, program->modulation_b, program->modulation_a, r, g, b, a)) {
1806 data->glUniform4f(program->uniform_locations[GLES2_UNIFORM_MODULATION], r * inv255f, g * inv255f, b * inv255f, a * inv255f);
1807 program->modulation_r =
r;
1808 program->modulation_g =
g;
1809 program->modulation_b =
b;
1810 program->modulation_a =
a;
1814 GLES2_SetBlendMode(data, texture->
blendMode);
1816 GLES2_SetTexCoords(data,
SDL_TRUE);
1824 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1828 GLES2_ActivateRenderer(renderer);
1830 if (GLES2_SetupCopy(renderer, texture) < 0) {
1835 vertices[0] = dstrect->
x;
1836 vertices[1] = dstrect->
y;
1837 vertices[2] = (dstrect->
x + dstrect->
w);
1838 vertices[3] = dstrect->
y;
1839 vertices[4] = dstrect->
x;
1840 vertices[5] = (dstrect->
y + dstrect->
h);
1841 vertices[6] = (dstrect->
x + dstrect->
w);
1842 vertices[7] = (dstrect->
y + dstrect->
h);
1844 GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_POSITION, vertices, 8 *
sizeof(
GLfloat));
1845 texCoords[0] = srcrect->
x / (
GLfloat)texture->
w;
1846 texCoords[1] = srcrect->
y / (
GLfloat)texture->
h;
1847 texCoords[2] = (srcrect->
x + srcrect->
w) / (
GLfloat)texture->
w;
1848 texCoords[3] = srcrect->
y / (
GLfloat)texture->
h;
1849 texCoords[4] = srcrect->
x / (
GLfloat)texture->
w;
1850 texCoords[5] = (srcrect->
y + srcrect->
h) / (
GLfloat)texture->
h;
1851 texCoords[6] = (srcrect->
x + srcrect->
w) / (
GLfloat)texture->
w;
1852 texCoords[7] = (srcrect->
y + srcrect->
h) / (
GLfloat)texture->
h;
1854 GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_TEXCOORD, texCoords, 8 *
sizeof(
GLfloat));
1857 return GL_CheckError(
"", renderer);
1864 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1872 GLES2_ActivateRenderer(renderer);
1874 if (GLES2_SetupCopy(renderer, texture) < 0) {
1878 data->glEnableVertexAttribArray(GLES2_ATTRIBUTE_CENTER);
1879 data->glEnableVertexAttribArray(GLES2_ATTRIBUTE_ANGLE);
1881 radian_angle = (float)(M_PI * (360.0 - angle) / 180.0);
1882 fAngle[0] = fAngle[2] = fAngle[4] = fAngle[6] = (
GLfloat)
SDL_sin(radian_angle);
1884 fAngle[1] = fAngle[3] = fAngle[5] = fAngle[7] = (
GLfloat)
SDL_cos(radian_angle) - 1.0f;
1886 translate[0] = translate[2] = translate[4] = translate[6] = (center->
x + dstrect->
x);
1887 translate[1] = translate[3] = translate[5] = translate[7] = (center->
y + dstrect->
y);
1890 vertices[0] = dstrect->
x;
1891 vertices[1] = dstrect->
y;
1892 vertices[2] = (dstrect->
x + dstrect->
w);
1893 vertices[3] = dstrect->
y;
1894 vertices[4] = dstrect->
x;
1895 vertices[5] = (dstrect->
y + dstrect->
h);
1896 vertices[6] = (dstrect->
x + dstrect->
w);
1897 vertices[7] = (dstrect->
y + dstrect->
h);
1900 vertices[0] = vertices[4] = vertices[2];
1901 vertices[2] = vertices[6] = tmp;
1905 vertices[1] = vertices[3] = vertices[5];
1906 vertices[5] = vertices[7] = tmp;
1913 GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_ANGLE, fAngle, 8 *
sizeof(
GLfloat));
1914 GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_CENTER, translate, 8 *
sizeof(
GLfloat));
1915 GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_POSITION, vertices, 8 *
sizeof(
GLfloat));
1917 texCoords[0] = srcrect->
x / (
GLfloat)texture->
w;
1918 texCoords[1] = srcrect->
y / (
GLfloat)texture->
h;
1919 texCoords[2] = (srcrect->
x + srcrect->
w) / (
GLfloat)texture->
w;
1920 texCoords[3] = srcrect->
y / (
GLfloat)texture->
h;
1921 texCoords[4] = srcrect->
x / (
GLfloat)texture->
w;
1922 texCoords[5] = (srcrect->
y + srcrect->
h) / (
GLfloat)texture->
h;
1923 texCoords[6] = (srcrect->
x + srcrect->
w) / (
GLfloat)texture->
w;
1924 texCoords[7] = (srcrect->
y + srcrect->
h) / (
GLfloat)texture->
h;
1926 GLES2_UpdateVertexBuffer(renderer, GLES2_ATTRIBUTE_TEXCOORD, texCoords, 8 *
sizeof(
GLfloat));
1928 data->glDisableVertexAttribArray(GLES2_ATTRIBUTE_CENTER);
1929 data->glDisableVertexAttribArray(GLES2_ATTRIBUTE_ANGLE);
1931 return GL_CheckError(
"", renderer);
1936 Uint32 pixel_format,
void * pixels,
int pitch)
1938 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
1944 int w, h, length, rows;
1947 GLES2_ActivateRenderer(renderer);
1950 buflen = (
size_t) (rect->
h * temp_pitch);
1962 data->glReadPixels(rect->
x, renderer->
target ? rect->
y : (h-rect->
y)-rect->
h,
1964 if (GL_CheckError(
"glReadPixels()", renderer) < 0) {
1971 src = (
Uint8*)temp_pixels + (rect->
h-1)*temp_pitch;
1986 temp_format, temp_pixels, temp_pitch,
1987 pixel_format, pixels, pitch);
1996 GLES2_ActivateRenderer(renderer);
2011 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
2012 GLES2_TextureData *texturedata = (GLES2_TextureData *)texture->
driverdata;
2013 GLES2_ActivateRenderer(renderer);
2015 data->glBindTexture(texturedata->texture_type, texturedata->texture);
2029 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->
driverdata;
2030 GLES2_TextureData *texturedata = (GLES2_TextureData *)texture->
driverdata;
2031 GLES2_ActivateRenderer(renderer);
2033 data->glBindTexture(texturedata->texture_type, 0);
2044 #define GL_NVIDIA_PLATFORM_BINARY_NV 0x890B
2050 GLES2_DriverContext *data = (GLES2_DriverContext *) renderer->
driverdata;
2052 if (SDL_CurrentContext == data->context) {
2053 GLES2_UpdateViewport(renderer);
2055 GLES2_ActivateRenderer(renderer);
2065 data->glClearColor((
GLfloat) data->clear_r * inv255f,
2066 (
GLfloat) data->clear_g * inv255f,
2067 (
GLfloat) data->clear_b * inv255f,
2068 (
GLfloat) data->clear_a * inv255f);
2070 data->glEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION);
2071 data->glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
2073 GL_CheckError(
"", renderer);
2080 GLES2_DriverContext *
data;
2086 GLint window_framebuffer;
2088 int profile_mask = 0, major = 0, minor = 0;
2123 data = (GLES2_DriverContext *)
SDL_calloc(1,
sizeof(GLES2_DriverContext));
2125 GLES2_DestroyRenderer(renderer);
2129 renderer->
info = GLES2_RenderDriver.
info;
2136 if (!data->context) {
2137 GLES2_DestroyRenderer(renderer);
2141 GLES2_DestroyRenderer(renderer);
2145 if (GLES2_LoadFunctions(data) < 0) {
2146 GLES2_DestroyRenderer(renderer);
2192 if (!data->shader_formats) {
2193 GLES2_DestroyRenderer(renderer);
2197 data->shader_format_count = nFormats;
2199 data->shader_formats[0] = GL_NVIDIA_PLATFORM_BINARY_NV;
2203 data->shader_formats[nFormats - 1] = (
GLenum)-1;
2207 data->framebuffers =
NULL;
2209 data->window_framebuffer = (
GLuint)window_framebuffer;
2240 #ifdef GL_TEXTURE_EXTERNAL_OES
2244 GLES2_ResetState(renderer);
2249 if (changed_window) {
SDL_BlendFactor SDL_GetBlendModeSrcColorFactor(SDL_BlendMode blendMode)
SDL_BlendFactor
The normalized factor used to multiply pixel components.
int(* UpdateClipRect)(SDL_Renderer *renderer)
#define GL_TEXTURE_EXTERNAL_OES
GLdouble GLdouble GLdouble r
#define GL_INVALID_OPERATION
void(* WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event)
#define SDL_GL_CreateContext
const GLuint * framebuffers
#define GL_COLOR_ATTACHMENT0
GLint GLint GLint GLint GLint x
int(* RenderClear)(SDL_Renderer *renderer)
SDL_BlendMode
The blend mode used in SDL_RenderCopy() and drawing operations.
#define GL_COMPILE_STATUS
int(* RenderDrawPoints)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
GLuint GLuint GLsizei count
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
GLfloat GLfloat GLfloat GLfloat h
#define GL_SHADER_COMPILER
Uint32 texture_formats[16]
static screen_context_t context
SDL_BlendFactor SDL_GetBlendModeDstAlphaFactor(SDL_BlendMode blendMode)
#define SDL_GetWindowFlags
SDL_BlendOperation SDL_GetBlendModeColorOperation(SDL_BlendMode blendMode)
#define SDL_BYTESPERPIXEL(X)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
#define GL_TEXTURE_MAG_FILTER
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
#define GL_TRIANGLE_STRIP
#define GL_FRAMEBUFFER_COMPLETE
#define GL_ONE_MINUS_SRC_ALPHA
SDL_BlendOperation
The blend operation used when combining source and destination pixel components.
#define GL_ONE_MINUS_SRC_COLOR
GLint GLint GLsizei width
GLfixed GLfixed GLint GLint GLfixed points
#define GL_PACK_ALIGNMENT
#define GL_MAX_TEXTURE_SIZE
static SDL_BlendMode blendMode
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)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
#define SDL_GL_SetAttribute
int(* LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
#define SDL_GL_GetDrawableSize
#define GL_ONE_MINUS_DST_ALPHA
SDL_RenderDriver GLES2_RenderDriver
GLenum GLenum GLuint texture
SDL_BlendOperation SDL_GetBlendModeAlphaOperation(SDL_BlendMode blendMode)
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)
void * SDL_GLContext
An opaque handle to an OpenGL context.
#define SDL_GL_GetSwapInterval
int(* UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
int SDL_RecreateWindow(SDL_Window *window, Uint32 flags)
static SDL_Renderer * renderer
#define SDL_stack_alloc(type, count)
#define SDL_GL_SetSwapInterval
#define GL_TEXTURE_WRAP_T
int(* RenderDrawLines)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
#define GL_LUMINANCE_ALPHA
GLubyte GLubyte GLubyte GLubyte w
GLsizei const GLfloat * value
GLsizei GLsizei GLchar * source
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)
GLint GLint GLint GLint GLint GLint y
#define RGBA8888_FROM_RGBA(Pixel, r, g, b, a)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
#define GL_COLOR_BUFFER_BIT
void(* DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* RenderCopy)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
SDL_RendererFlip
Flip constants for SDL_RenderCopyEx.
GLenum GLenum GLsizei const GLuint GLboolean enabled
Window state change event data (event.window.*)
#define GL_FRAMEBUFFER_BINDING
#define SDL_OutOfMemory()
SDL_BlendFactor SDL_GetBlendModeSrcAlphaFactor(SDL_BlendMode blendMode)
int(* GetOutputSize)(SDL_Renderer *renderer, int *w, int *h)
int(* GL_BindTexture)(SDL_Renderer *renderer, SDL_Texture *texture, float *texw, float *texh)
GLint GLint GLsizei GLsizei height
int(* RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect, Uint32 format, void *pixels, int pitch)
#define SDL_GL_MakeCurrent
int(* GL_UnbindTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
EGLSurface EGLNativeWindowType * window
#define SDL_GetRendererOutputSize
#define GL_FUNC_REVERSE_SUBTRACT
int(* RenderFillRects)(SDL_Renderer *renderer, const SDL_FRect *rects, int count)
GLint GLint GLint yoffset
The type used to identify a window.
#define GL_ONE_MINUS_DST_COLOR
SDL_BlendFactor SDL_GetBlendModeDstColorFactor(SDL_BlendMode blendMode)
SDL_bool(* SupportsBlendMode)(SDL_Renderer *renderer, SDL_BlendMode blendMode)
#define GL_SHADER_BINARY_FORMATS
Uint32 num_texture_formats
GLuint GLuint GLsizei GLenum type
#define GL_NUM_SHADER_BINARY_FORMATS
#define SDL_GL_GetAttribute
int(* UpdateViewport)(SDL_Renderer *renderer)
GLbitfield GLuint program
#define SDL_ConvertPixels
#define SDL_GL_DeleteContext
EGLSurface EGLint * rects
#define SDL_stack_free(data)
#define SDL_GetYUVConversionModeForResolution
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 GL_TEXTURE_WRAP_S
GLuint GLsizei GLsizei * length
#define GL_TEXTURE_MIN_FILTER
void(* RenderPresent)(SDL_Renderer *renderer)
GLboolean GLboolean GLboolean GLboolean a
void(* DestroyRenderer)(SDL_Renderer *renderer)
#define GL_UNPACK_ALIGNMENT
GLboolean GLboolean GLboolean b
#define SDL_GL_SwapWindow
SDL_bool clipping_enabled
A rectangle, with the origin at the upper left.
#define GL_INFO_LOG_LENGTH