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" 35 #define RENDERER_CONTEXT_MAJOR 2 36 #define RENDERER_CONTEXT_MINOR 0 45 typedef struct GLES2_FBOList GLES2_FBOList;
54 typedef struct GLES2_TextureData
70 typedef struct GLES2_ShaderCacheEntry
73 GLES2_ShaderType
type;
74 const GLES2_ShaderInstance *instance;
76 struct GLES2_ShaderCacheEntry *prev;
77 struct GLES2_ShaderCacheEntry *next;
78 } GLES2_ShaderCacheEntry;
80 typedef struct GLES2_ShaderCache
83 GLES2_ShaderCacheEntry *
head;
86 typedef struct GLES2_ProgramCacheEntry
89 GLES2_ShaderCacheEntry *vertex_shader;
90 GLES2_ShaderCacheEntry *fragment_shader;
91 GLuint uniform_locations[16];
94 struct GLES2_ProgramCacheEntry *prev;
95 struct GLES2_ProgramCacheEntry *next;
96 } GLES2_ProgramCacheEntry;
98 typedef struct GLES2_ProgramCache
101 GLES2_ProgramCacheEntry *
head;
102 GLES2_ProgramCacheEntry *
tail;
103 } GLES2_ProgramCache;
107 GLES2_ATTRIBUTE_POSITION = 0,
108 GLES2_ATTRIBUTE_TEXCOORD = 1,
109 GLES2_ATTRIBUTE_ANGLE = 2,
110 GLES2_ATTRIBUTE_CENTER = 3,
115 GLES2_UNIFORM_PROJECTION,
116 GLES2_UNIFORM_TEXTURE,
118 GLES2_UNIFORM_TEXTURE_U,
119 GLES2_UNIFORM_TEXTURE_V
124 GLES2_IMAGESOURCE_INVALID,
125 GLES2_IMAGESOURCE_SOLID,
126 GLES2_IMAGESOURCE_TEXTURE_ABGR,
127 GLES2_IMAGESOURCE_TEXTURE_ARGB,
128 GLES2_IMAGESOURCE_TEXTURE_RGB,
129 GLES2_IMAGESOURCE_TEXTURE_BGR,
130 GLES2_IMAGESOURCE_TEXTURE_YUV,
131 GLES2_IMAGESOURCE_TEXTURE_NV12,
132 GLES2_IMAGESOURCE_TEXTURE_NV21,
133 GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES
153 GLES2_ProgramCacheEntry *
program;
155 } GLES2_DrawStateCache;
157 typedef struct GLES2_RenderData
163 #define SDL_PROC(ret,func,params) ret (APIENTRY *func) params; 167 GLuint window_framebuffer;
169 int shader_format_count;
171 GLES2_ShaderCache shader_cache;
172 GLES2_ProgramCache program_cache;
173 Uint8 clear_r, clear_g, clear_b, clear_a;
176 size_t vertex_buffer_size[8];
177 int current_vertex_buffer;
178 GLES2_DrawStateCache drawstate;
181 #define GLES2_MAX_CACHED_PROGRAMS 8 183 static const float inv255f = 1.0f / 255.0f;
187 GL_TranslateError (
GLenum error)
189 #define GL_ERROR_TRANSLATE(e) case e: return #e; 199 #undef GL_ERROR_TRANSLATE 205 GLES2_RenderData *
data = (GLES2_RenderData *) renderer->
driverdata;
207 if (!data->debug_enabled) {
216 GL_CheckAllErrors (
const char *prefix,
SDL_Renderer *renderer,
const char *file,
int line,
const char *
function)
218 GLES2_RenderData *data = (GLES2_RenderData *) renderer->
driverdata;
221 if (!data->debug_enabled) {
226 GLenum error = data->glGetError();
228 if (prefix ==
NULL || prefix[0] ==
'\0') {
231 SDL_SetError(
"%s: %s (%d): %s %s (0x%X)", prefix, file, line,
function, GL_TranslateError(error), error);
241 #define GL_CheckError(prefix, renderer) 243 #define GL_CheckError(prefix, renderer) GL_CheckAllErrors(prefix, renderer, SDL_FILE, SDL_LINE, SDL_FUNCTION) 251 static int GLES2_LoadFunctions(GLES2_RenderData * data)
253 #if SDL_VIDEO_DRIVER_UIKIT 254 #define __SDL_NOGETPROCADDR__ 255 #elif SDL_VIDEO_DRIVER_ANDROID 256 #define __SDL_NOGETPROCADDR__ 257 #elif SDL_VIDEO_DRIVER_PANDORA 258 #define __SDL_NOGETPROCADDR__ 261 #if defined __SDL_NOGETPROCADDR__ 262 #define SDL_PROC(ret,func,params) data->func=func; 264 #define SDL_PROC(ret,func,params) \ 266 data->func = SDL_GL_GetProcAddress(#func); \ 267 if ( ! data->func ) { \ 268 return SDL_SetError("Couldn't load GLES2 function %s: %s", #func, SDL_GetError()); \ 278 static GLES2_FBOList *
281 GLES2_FBOList *
result = data->framebuffers;
282 while ((result) && ((result->w != w) || (result->h != h)) ) {
283 result = result->next;
285 if (result ==
NULL) {
289 data->glGenFramebuffers(1, &result->FBO);
290 result->next = data->framebuffers;
291 data->framebuffers =
result;
299 GLES2_RenderData *data = (GLES2_RenderData *)renderer->
driverdata;
303 data->drawstate.program =
NULL;
310 GL_ClearErrors(renderer);
318 GLES2_RenderData *data = (GLES2_RenderData *)renderer->
driverdata;
327 GLES2_GetOutputSize(
SDL_Renderer * renderer,
int *w,
int *h)
398 GLES2_EvictShader(GLES2_RenderData *data, GLES2_ShaderCacheEntry *entry)
402 entry->next->prev = entry->prev;
405 entry->prev->next = entry->next;
407 if (data->shader_cache.head == entry) {
408 data->shader_cache.head = entry->next;
410 --data->shader_cache.count;
413 data->glDeleteShader(entry->id);
417 static GLES2_ProgramCacheEntry *
418 GLES2_CacheProgram(GLES2_RenderData *data, GLES2_ShaderCacheEntry *vertex,
419 GLES2_ShaderCacheEntry *fragment)
421 GLES2_ProgramCacheEntry *entry;
422 GLES2_ShaderCacheEntry *shaderEntry;
423 GLint linkSuccessful;
426 entry = data->program_cache.head;
428 if (entry->vertex_shader == vertex && entry->fragment_shader == fragment) {
434 if (data->program_cache.head != entry) {
436 entry->next->prev = entry->prev;
439 entry->prev->next = entry->next;
442 entry->next = data->program_cache.head;
443 data->program_cache.head->prev = entry;
444 data->program_cache.head = entry;
450 entry = (GLES2_ProgramCacheEntry *)
SDL_calloc(1,
sizeof(GLES2_ProgramCacheEntry));
455 entry->vertex_shader = vertex;
456 entry->fragment_shader = fragment;
459 entry->id = data->glCreateProgram();
460 data->glAttachShader(entry->id, vertex->id);
461 data->glAttachShader(entry->id, fragment->id);
462 data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_POSITION,
"a_position");
463 data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_TEXCOORD,
"a_texCoord");
464 data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_ANGLE,
"a_angle");
465 data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_CENTER,
"a_center");
466 data->glLinkProgram(entry->id);
468 if (!linkSuccessful) {
469 data->glDeleteProgram(entry->id);
476 entry->uniform_locations[GLES2_UNIFORM_PROJECTION] =
477 data->glGetUniformLocation(entry->id,
"u_projection");
478 entry->uniform_locations[GLES2_UNIFORM_TEXTURE_V] =
479 data->glGetUniformLocation(entry->id,
"u_texture_v");
480 entry->uniform_locations[GLES2_UNIFORM_TEXTURE_U] =
481 data->glGetUniformLocation(entry->id,
"u_texture_u");
482 entry->uniform_locations[GLES2_UNIFORM_TEXTURE] =
483 data->glGetUniformLocation(entry->id,
"u_texture");
484 entry->uniform_locations[GLES2_UNIFORM_COLOR] =
485 data->glGetUniformLocation(entry->id,
"u_color");
489 data->glUseProgram(entry->id);
490 if (entry->uniform_locations[GLES2_UNIFORM_TEXTURE_V] != -1) {
491 data->glUniform1i(entry->uniform_locations[GLES2_UNIFORM_TEXTURE_V], 2);
493 if (entry->uniform_locations[GLES2_UNIFORM_TEXTURE_U] != -1) {
494 data->glUniform1i(entry->uniform_locations[GLES2_UNIFORM_TEXTURE_U], 1);
496 if (entry->uniform_locations[GLES2_UNIFORM_TEXTURE] != -1) {
497 data->glUniform1i(entry->uniform_locations[GLES2_UNIFORM_TEXTURE], 0);
499 if (entry->uniform_locations[GLES2_UNIFORM_PROJECTION] != -1) {
500 data->glUniformMatrix4fv(entry->uniform_locations[GLES2_UNIFORM_PROJECTION], 1,
GL_FALSE, (
GLfloat *)entry->projection);
502 if (entry->uniform_locations[GLES2_UNIFORM_COLOR] != -1) {
503 data->glUniform4f(entry->uniform_locations[GLES2_UNIFORM_COLOR], 0.0f, 0.0f, 0.0f, 0.0f);
507 if (data->program_cache.head) {
508 entry->next = data->program_cache.head;
509 data->program_cache.head->prev = entry;
511 data->program_cache.tail = entry;
513 data->program_cache.head = entry;
514 ++data->program_cache.count;
517 ++vertex->references;
518 ++fragment->references;
521 if (data->program_cache.count > GLES2_MAX_CACHED_PROGRAMS) {
522 shaderEntry = data->program_cache.tail->vertex_shader;
523 if (--shaderEntry->references <= 0) {
524 GLES2_EvictShader(data, shaderEntry);
526 shaderEntry = data->program_cache.tail->fragment_shader;
527 if (--shaderEntry->references <= 0) {
528 GLES2_EvictShader(data, shaderEntry);
530 data->glDeleteProgram(data->program_cache.tail->id);
531 data->program_cache.tail = data->program_cache.tail->prev;
532 if (data->program_cache.tail !=
NULL) {
533 SDL_free(data->program_cache.tail->next);
534 data->program_cache.tail->next =
NULL;
536 --data->program_cache.count;
541 static GLES2_ShaderCacheEntry *
542 GLES2_CacheShader(GLES2_RenderData *data, GLES2_ShaderType
type)
544 const GLES2_Shader *
shader;
545 const GLES2_ShaderInstance *instance =
NULL;
546 GLES2_ShaderCacheEntry *entry =
NULL;
551 shader = GLES2_GetShader(type);
553 SDL_SetError(
"No shader matching the requested characteristics was found");
558 for (i = 0; i < shader->instance_count && !instance; ++
i) {
559 for (j = 0; j < data->shader_format_count && !instance; ++
j) {
560 if (!shader->instances[i]) {
563 if (shader->instances[i]->format != data->shader_formats[j]) {
566 instance = shader->instances[
i];
570 SDL_SetError(
"The specified shader cannot be loaded on the current platform");
575 entry = data->shader_cache.head;
577 if (entry->instance == instance) {
587 entry = (GLES2_ShaderCacheEntry *)
SDL_calloc(1,
sizeof(GLES2_ShaderCacheEntry));
593 entry->instance = instance;
596 entry->id = data->glCreateShader(instance->type);
597 if (instance->format == (
GLenum)-1) {
598 data->glShaderSource(entry->id, 1, (
const char **)(
char *)&instance->data,
NULL);
599 data->glCompileShader(entry->id);
602 data->glShaderBinary(1, &entry->id, instance->format, instance->data, instance->length);
605 if (!compileSuccessful) {
614 data->glGetShaderInfoLog(entry->id, length, &length, info);
623 data->glDeleteShader(entry->id);
629 if (data->shader_cache.head) {
630 entry->next = data->shader_cache.head;
631 data->shader_cache.head->prev = entry;
633 data->shader_cache.head = entry;
634 ++data->shader_cache.count;
639 GLES2_SelectProgram(GLES2_RenderData *data, GLES2_ImageSource
source,
int w,
int h)
641 GLES2_ShaderCacheEntry *vertex =
NULL;
642 GLES2_ShaderCacheEntry *fragment =
NULL;
643 GLES2_ShaderType vtype, ftype;
644 GLES2_ProgramCacheEntry *
program;
647 vtype = GLES2_SHADER_VERTEX_DEFAULT;
649 case GLES2_IMAGESOURCE_SOLID:
650 ftype = GLES2_SHADER_FRAGMENT_SOLID_SRC;
652 case GLES2_IMAGESOURCE_TEXTURE_ABGR:
653 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_ABGR_SRC;
655 case GLES2_IMAGESOURCE_TEXTURE_ARGB:
656 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_ARGB_SRC;
658 case GLES2_IMAGESOURCE_TEXTURE_RGB:
659 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_RGB_SRC;
661 case GLES2_IMAGESOURCE_TEXTURE_BGR:
662 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_BGR_SRC;
664 case GLES2_IMAGESOURCE_TEXTURE_YUV:
667 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_YUV_JPEG_SRC;
670 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601_SRC;
673 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT709_SRC;
680 case GLES2_IMAGESOURCE_TEXTURE_NV12:
683 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_JPEG_SRC;
686 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT601_SRC;
689 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT709_SRC;
696 case GLES2_IMAGESOURCE_TEXTURE_NV21:
699 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV21_JPEG_SRC;
702 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT601_SRC;
705 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709_SRC;
712 case GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES:
713 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES_SRC;
720 vertex = GLES2_CacheShader(data, vtype);
724 fragment = GLES2_CacheShader(data, ftype);
730 if (data->drawstate.program &&
731 data->drawstate.program->vertex_shader == vertex &&
732 data->drawstate.program->fragment_shader == fragment) {
737 program = GLES2_CacheProgram(data, vertex, fragment);
743 data->glUseProgram(program->id);
746 data->drawstate.program =
program;
751 if (vertex && vertex->references <= 0) {
752 GLES2_EvictShader(data, vertex);
754 if (fragment && fragment->references <= 0) {
755 GLES2_EvictShader(data, fragment);
757 data->drawstate.program =
NULL;
778 for (i = 0; i <
count; i++) {
779 *(verts++) = 0.5
f + points[i].
x;
780 *(verts++) = 0.5
f + points[i].
y;
798 for (i = 0; i <
count; i++) {
821 GLfloat minx, miny, maxx, maxy;
822 GLfloat minu, maxu, minv, maxv;
833 maxx = dstrect->
x + dstrect->
w;
834 maxy = dstrect->
y + dstrect->
h;
836 minu = (
GLfloat) srcrect->
x / texture->
w;
837 maxu = (
GLfloat) (srcrect->
x + srcrect->
w) / texture->
w;
838 minv = (
GLfloat) srcrect->
y / texture->
h;
839 maxv = (
GLfloat) (srcrect->
y + srcrect->
h) / texture->
h;
868 const float radian_angle = (float)(M_PI * (360.0 - angle) / 180.0);
871 const GLfloat centerx = center->
x + dstrect->
x;
872 const GLfloat centery = center->
y + dstrect->
y;
873 GLfloat minx, miny, maxx, maxy;
874 GLfloat minu, maxu, minv, maxv;
882 minx = dstrect->
x + dstrect->
w;
886 maxx = dstrect->
x + dstrect->
w;
890 miny = dstrect->
y + dstrect->
h;
894 maxy = dstrect->
y + dstrect->
h;
932 *(verts++) = centerx;
933 *(verts++) = centery;
934 *(verts++) = centerx;
935 *(verts++) = centery;
936 *(verts++) = centerx;
937 *(verts++) = centery;
938 *(verts++) = centerx;
939 *(verts++) = centery;
947 const SDL_bool was_copy_ex = data->drawstate.is_copy_ex;
951 GLES2_ProgramCacheEntry *
program;
953 SDL_assert((texture !=
NULL) == (imgsrc != GLES2_IMAGESOURCE_SOLID));
955 if (data->drawstate.viewport_dirty) {
957 data->glViewport(viewport->
x,
958 data->drawstate.target ? viewport->
y : (data->drawstate.drawableh - viewport->
y - viewport->
h),
959 viewport->
w, viewport->
h);
960 if (viewport->
w && viewport->
h) {
961 data->drawstate.projection[0][0] = 2.0f / viewport->
w;
962 data->drawstate.projection[1][1] = (data->drawstate.target ? 2.0f : -2.0f) / viewport->
h;
963 data->drawstate.projection[3][1] = data->drawstate.target ? -1.0f : 1.0f;
965 data->drawstate.viewport_dirty =
SDL_FALSE;
968 if (data->drawstate.cliprect_enabled_dirty) {
969 if (!data->drawstate.cliprect_enabled) {
974 data->drawstate.cliprect_enabled_dirty =
SDL_FALSE;
977 if (data->drawstate.cliprect_enabled && data->drawstate.cliprect_dirty) {
978 const SDL_Rect *viewport = &data->drawstate.viewport;
980 data->glScissor(viewport->
x + rect->
x,
981 data->drawstate.target ? viewport->
y + rect->
y : data->drawstate.drawableh - viewport->
y - rect->
y - rect->
h,
983 data->drawstate.cliprect_dirty =
SDL_FALSE;
986 if (texture != data->drawstate.texture) {
987 if ((texture !=
NULL) != data->drawstate.texturing) {
988 if (texture ==
NULL) {
989 data->glDisableVertexAttribArray((
GLenum) GLES2_ATTRIBUTE_TEXCOORD);
992 data->glEnableVertexAttribArray((
GLenum) GLES2_ATTRIBUTE_TEXCOORD);
993 data->drawstate.texturing =
SDL_TRUE;
998 GLES2_TextureData *tdata = (GLES2_TextureData *) texture->
driverdata;
1001 data->glBindTexture(tdata->texture_type, tdata->texture_v);
1004 data->glBindTexture(tdata->texture_type, tdata->texture_u);
1007 }
else if (tdata->nv12) {
1009 data->glBindTexture(tdata->texture_type, tdata->texture_u);
1013 data->glBindTexture(tdata->texture_type, tdata->texture);
1016 data->drawstate.texture =
texture;
1023 if (GLES2_SelectProgram(data, imgsrc, texture ? texture->
w : 0, texture ? texture->
h : 0) < 0) {
1027 program = data->drawstate.program;
1029 if (program->uniform_locations[GLES2_UNIFORM_PROJECTION] != -1) {
1030 if (
SDL_memcmp(program->projection, data->drawstate.projection, sizeof (data->drawstate.projection)) != 0) {
1031 data->glUniformMatrix4fv(program->uniform_locations[GLES2_UNIFORM_PROJECTION], 1,
GL_FALSE, (
GLfloat *)data->drawstate.projection);
1032 SDL_memcpy(program->projection, data->drawstate.projection, sizeof (data->drawstate.projection));
1036 if (program->uniform_locations[GLES2_UNIFORM_COLOR] != -1) {
1037 if (data->drawstate.color != program->color) {
1038 const Uint8 r = (data->drawstate.color >> 16) & 0xFF;
1039 const Uint8 g = (data->drawstate.color >> 8) & 0xFF;
1040 const Uint8 b = (data->drawstate.color >> 0) & 0xFF;
1041 const Uint8 a = (data->drawstate.color >> 24) & 0xFF;
1042 data->glUniform4f(program->uniform_locations[GLES2_UNIFORM_COLOR], r * inv255f, g * inv255f, b * inv255f, a * inv255f);
1043 program->color = data->drawstate.color;
1047 if (blend != data->drawstate.blend) {
1059 data->drawstate.blend = blend;
1065 if (is_copy_ex != was_copy_ex) {
1067 data->glEnableVertexAttribArray((
GLenum) GLES2_ATTRIBUTE_ANGLE);
1068 data->glEnableVertexAttribArray((
GLenum) GLES2_ATTRIBUTE_CENTER);
1070 data->glDisableVertexAttribArray((
GLenum) GLES2_ATTRIBUTE_ANGLE);
1071 data->glDisableVertexAttribArray((
GLenum) GLES2_ATTRIBUTE_CENTER);
1073 data->drawstate.is_copy_ex = is_copy_ex;
1087 GLES2_RenderData *data = (GLES2_RenderData *) renderer->
driverdata;
1088 GLES2_ImageSource sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1095 switch (texture->
format) {
1100 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1103 sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1111 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1114 sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1121 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1124 sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
1127 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1134 sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
1137 sourceType = GLES2_IMAGESOURCE_TEXTURE_RGB;
1140 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1146 sourceType = GLES2_IMAGESOURCE_TEXTURE_YUV;
1149 sourceType = GLES2_IMAGESOURCE_TEXTURE_NV12;
1152 sourceType = GLES2_IMAGESOURCE_TEXTURE_NV21;
1155 sourceType = GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES;
1161 sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1164 switch (texture->
format) {
1166 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1169 sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1172 sourceType = GLES2_IMAGESOURCE_TEXTURE_RGB;
1175 sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
1179 sourceType = GLES2_IMAGESOURCE_TEXTURE_YUV;
1182 sourceType = GLES2_IMAGESOURCE_TEXTURE_NV12;
1185 sourceType = GLES2_IMAGESOURCE_TEXTURE_NV21;
1188 sourceType = GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES;
1201 GLES2_RenderData *data = (GLES2_RenderData *) renderer->
driverdata;
1203 const int vboidx = data->current_vertex_buffer;
1204 const GLuint vbo = data->vertex_buffers[vboidx];
1207 if (GLES2_ActivateRenderer(renderer) < 0) {
1211 data->drawstate.target = renderer->
target;
1212 if (!data->drawstate.target) {
1218 if (data->vertex_buffer_size[vboidx] < vertsize) {
1220 data->vertex_buffer_size[vboidx] = vertsize;
1226 data->current_vertex_buffer++;
1227 if (data->current_vertex_buffer >=
SDL_arraysize(data->vertex_buffers)) {
1228 data->current_vertex_buffer = 0;
1238 data->drawstate.color = ((a << 24) | (r << 16) | (g << 8) | b);
1243 SDL_Rect *viewport = &data->drawstate.viewport;
1246 data->drawstate.viewport_dirty =
SDL_TRUE;
1253 if (data->drawstate.cliprect_enabled != cmd->
data.
cliprect.enabled) {
1254 data->drawstate.cliprect_enabled = cmd->
data.
cliprect.enabled;
1255 data->drawstate.cliprect_enabled_dirty =
SDL_TRUE;
1260 data->drawstate.cliprect_dirty =
SDL_TRUE;
1270 const Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
1271 if (color != data->drawstate.clear_color) {
1276 data->glClearColor(fr, fg, fb, fa);
1277 data->drawstate.clear_color =
color;
1280 if (data->drawstate.cliprect_enabled) {
1282 data->drawstate.cliprect_enabled_dirty =
SDL_TRUE;
1290 if (
SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID) == 0) {
1298 const size_t count = cmd->
data.
draw.count;
1299 if (
SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID) == 0) {
1300 if (count > 2 && (verts[0] == verts[(count-1)*2]) && (verts[1] == verts[(count*2)-1])) {
1313 const size_t count = cmd->
data.
draw.count;
1315 if (
SetDrawState(data, cmd, GLES2_IMAGESOURCE_SOLID) == 0) {
1316 for (i = 0; i <
count; ++
i, offset += 4) {
1325 if (SetCopyState(renderer, cmd) == 0) {
1338 return GL_CheckError(
"", renderer);
1344 GLES2_RenderData *data = (GLES2_RenderData *)renderer->
driverdata;
1348 GLES2_ActivateRenderer(renderer);
1351 GLES2_ShaderCacheEntry *entry;
1352 GLES2_ShaderCacheEntry *next;
1353 entry = data->shader_cache.head;
1355 data->glDeleteShader(entry->id);
1362 GLES2_ProgramCacheEntry *entry;
1363 GLES2_ProgramCacheEntry *next;
1364 entry = data->program_cache.head;
1366 data->glDeleteProgram(entry->id);
1373 if (data->context) {
1374 while (data->framebuffers) {
1375 GLES2_FBOList *nextnode = data->framebuffers->next;
1376 data->glDeleteFramebuffers(1, &data->framebuffers->FBO);
1377 GL_CheckError(
"", renderer);
1379 data->framebuffers = nextnode;
1382 data->glDeleteBuffers(
SDL_arraysize(data->vertex_buffers), data->vertex_buffers);
1383 GL_CheckError(
"", renderer);
1397 GLES2_RenderData *renderdata = (GLES2_RenderData *)renderer->
driverdata;
1398 GLES2_TextureData *data;
1403 GLES2_ActivateRenderer(renderer);
1405 renderdata->drawstate.texture =
NULL;
1424 #ifdef GL_TEXTURE_EXTERNAL_OES 1436 return SDL_SetError(
"Unsupported texture access for SDL_PIXELFORMAT_EXTERNAL_OES");
1440 data = (GLES2_TextureData *)
SDL_calloc(1,
sizeof(GLES2_TextureData));
1445 #ifdef GL_TEXTURE_EXTERNAL_OES 1450 data->pixel_format =
format;
1451 data->pixel_type =
type;
1454 data->texture_u = 0;
1455 data->texture_v = 0;
1462 size = texture->
h * data->pitch;
1465 size += 2 * ((texture->
h + 1) / 2) * ((data->pitch + 1) / 2);
1466 }
else if (data->nv12) {
1468 size += 2 * ((texture->
h + 1) / 2) * ((data->pitch + 1) / 2);
1471 if (!data->pixel_data) {
1478 GL_CheckError(
"", renderer);
1481 renderdata->glGenTextures(1, &data->texture_v);
1482 if (GL_CheckError(
"glGenTexures()", renderer) < 0) {
1486 renderdata->glBindTexture(data->texture_type, data->texture_v);
1491 renderdata->glTexImage2D(data->texture_type, 0,
format, (texture->
w + 1) / 2, (texture->
h + 1) / 2, 0,
format, type,
NULL);
1493 renderdata->glGenTextures(1, &data->texture_u);
1494 if (GL_CheckError(
"glGenTexures()", renderer) < 0) {
1498 renderdata->glBindTexture(data->texture_type, data->texture_u);
1503 renderdata->glTexImage2D(data->texture_type, 0,
format, (texture->
w + 1) / 2, (texture->
h + 1) / 2, 0,
format, type,
NULL);
1504 if (GL_CheckError(
"glTexImage2D()", renderer) < 0) {
1507 }
else if (data->nv12) {
1508 renderdata->glGenTextures(1, &data->texture_u);
1509 if (GL_CheckError(
"glGenTexures()", renderer) < 0) {
1513 renderdata->glBindTexture(data->texture_type, data->texture_u);
1519 if (GL_CheckError(
"glTexImage2D()", renderer) < 0) {
1524 renderdata->glGenTextures(1, &data->texture);
1525 if (GL_CheckError(
"glGenTexures()", renderer) < 0) {
1530 renderdata->glBindTexture(data->texture_type, data->texture);
1536 renderdata->glTexImage2D(data->texture_type, 0,
format, texture->
w, texture->
h, 0,
format, type,
NULL);
1537 if (GL_CheckError(
"glTexImage2D()", renderer) < 0) {
1543 data->fbo = GLES2_GetFBO(renderer->
driverdata, texture->
w, texture->
h);
1548 return GL_CheckError(
"", renderer);
1552 GLES2_TexSubImage2D(GLES2_RenderData *data,
GLenum target,
GLint xoffset,
GLint yoffset,
GLsizei width,
GLsizei height,
GLenum format,
GLenum type,
const GLvoid *
pixels,
GLint pitch,
GLint bpp)
1559 if ((width == 0) || (height == 0) || (bpp == 0)) {
1564 src_pitch = width * bpp;
1565 src = (
Uint8 *)pixels;
1566 if (pitch != src_pitch) {
1576 pixels = (
Uint8 *)pixels + pitch;
1581 data->glTexSubImage2D(target, 0, xoffset, yoffset, width, height, format, type, src);
1590 const void *pixels,
int pitch)
1592 GLES2_RenderData *data = (GLES2_RenderData *)renderer->
driverdata;
1593 GLES2_TextureData *tdata = (GLES2_TextureData *)texture->
driverdata;
1595 GLES2_ActivateRenderer(renderer);
1598 if (rect->
w <= 0 || rect->
h <= 0) {
1602 data->drawstate.texture =
NULL;
1605 data->glBindTexture(tdata->texture_type, tdata->texture);
1606 GLES2_TexSubImage2D(data, tdata->texture_type,
1611 tdata->pixel_format,
1617 pixels = (
const void*)((
const Uint8*)pixels + rect->
h * pitch);
1619 data->glBindTexture(tdata->texture_type, tdata->texture_v);
1621 data->glBindTexture(tdata->texture_type, tdata->texture_u);
1623 GLES2_TexSubImage2D(data, tdata->texture_type,
1628 tdata->pixel_format,
1630 pixels, (pitch + 1) / 2, 1);
1634 pixels = (
const void*)((
const Uint8*)pixels + ((rect->
h + 1) / 2) * ((pitch + 1)/2));
1636 data->glBindTexture(tdata->texture_type, tdata->texture_u);
1638 data->glBindTexture(tdata->texture_type, tdata->texture_v);
1640 GLES2_TexSubImage2D(data, tdata->texture_type,
1645 tdata->pixel_format,
1647 pixels, (pitch + 1) / 2, 1);
1648 }
else if (tdata->nv12) {
1650 pixels = (
const void*)((
const Uint8*)pixels + rect->
h * pitch);
1651 data->glBindTexture(tdata->texture_type, tdata->texture_u);
1652 GLES2_TexSubImage2D(data, tdata->texture_type,
1659 pixels, 2 * ((pitch + 1) / 2), 2);
1662 return GL_CheckError(
"glTexSubImage2D()", renderer);
1668 const Uint8 *Yplane,
int Ypitch,
1669 const Uint8 *Uplane,
int Upitch,
1670 const Uint8 *Vplane,
int Vpitch)
1672 GLES2_RenderData *data = (GLES2_RenderData *)renderer->
driverdata;
1673 GLES2_TextureData *tdata = (GLES2_TextureData *)texture->
driverdata;
1675 GLES2_ActivateRenderer(renderer);
1678 if (rect->
w <= 0 || rect->
h <= 0) {
1682 data->drawstate.texture =
NULL;
1684 data->glBindTexture(tdata->texture_type, tdata->texture_v);
1685 GLES2_TexSubImage2D(data, tdata->texture_type,
1690 tdata->pixel_format,
1694 data->glBindTexture(tdata->texture_type, tdata->texture_u);
1695 GLES2_TexSubImage2D(data, tdata->texture_type,
1700 tdata->pixel_format,
1704 data->glBindTexture(tdata->texture_type, tdata->texture);
1705 GLES2_TexSubImage2D(data, tdata->texture_type,
1710 tdata->pixel_format,
1714 return GL_CheckError(
"glTexSubImage2D()", renderer);
1719 void **pixels,
int *pitch)
1721 GLES2_TextureData *tdata = (GLES2_TextureData *)texture->
driverdata;
1724 *pixels = (
Uint8 *)tdata->pixel_data +
1725 (tdata->pitch * rect->
y) +
1727 *pitch = tdata->pitch;
1735 GLES2_TextureData *tdata = (GLES2_TextureData *)texture->
driverdata;
1741 rect.
w = texture->
w;
1742 rect.
h = texture->
h;
1743 GLES2_UpdateTexture(renderer, texture, &rect, tdata->pixel_data, tdata->pitch);
1749 GLES2_RenderData *data = (GLES2_RenderData *) renderer->
driverdata;
1750 GLES2_TextureData *texturedata =
NULL;
1753 data->drawstate.viewport_dirty =
SDL_TRUE;
1755 if (texture ==
NULL) {
1756 data->glBindFramebuffer(
GL_FRAMEBUFFER, data->window_framebuffer);
1758 texturedata = (GLES2_TextureData *) texture->
driverdata;
1765 return SDL_SetError(
"glFramebufferTexture2D() failed");
1774 GLES2_RenderData *data = (GLES2_RenderData *)renderer->
driverdata;
1775 GLES2_TextureData *tdata = (GLES2_TextureData *)texture->
driverdata;
1777 GLES2_ActivateRenderer(renderer);
1779 if (data->drawstate.texture == texture) {
1780 data->drawstate.texture =
NULL;
1782 if (data->drawstate.target == texture) {
1783 data->drawstate.target =
NULL;
1788 data->glDeleteTextures(1, &tdata->texture);
1789 if (tdata->texture_v) {
1790 data->glDeleteTextures(1, &tdata->texture_v);
1792 if (tdata->texture_u) {
1793 data->glDeleteTextures(1, &tdata->texture_u);
1803 Uint32 pixel_format,
void * pixels,
int pitch)
1805 GLES2_RenderData *data = (GLES2_RenderData *)renderer->
driverdata;
1811 int w, h, length, rows;
1815 buflen = (
size_t) (rect->
h * temp_pitch);
1827 data->glReadPixels(rect->
x, renderer->
target ? rect->
y : (h-rect->
y)-rect->
h,
1829 if (GL_CheckError(
"glReadPixels()", renderer) < 0) {
1837 src = (
Uint8*)temp_pixels + (rect->
h-1)*temp_pitch;
1852 temp_format, temp_pixels, temp_pitch,
1853 pixel_format, pixels, pitch);
1875 GLES2_RenderData *data = (GLES2_RenderData *)renderer->
driverdata;
1876 GLES2_TextureData *texturedata = (GLES2_TextureData *)texture->
driverdata;
1877 GLES2_ActivateRenderer(renderer);
1879 data->glBindTexture(texturedata->texture_type, texturedata->texture);
1880 data->drawstate.texture =
texture;
1894 GLES2_RenderData *data = (GLES2_RenderData *)renderer->
driverdata;
1895 GLES2_TextureData *texturedata = (GLES2_TextureData *)texture->
driverdata;
1896 GLES2_ActivateRenderer(renderer);
1898 data->glBindTexture(texturedata->texture_type, 0);
1899 data->drawstate.texture =
NULL;
1910 #define GL_NVIDIA_PLATFORM_BINARY_NV 0x890B 1918 GLES2_RenderData *
data;
1924 GLint window_framebuffer;
1926 int profile_mask = 0, major = 0, minor = 0;
1962 data = (GLES2_RenderData *)
SDL_calloc(1,
sizeof(GLES2_RenderData));
1975 if (!data->context) {
1987 if (GLES2_LoadFunctions(data) < 0) {
2036 if (!data->shader_formats) {
2037 GLES2_DestroyRenderer(renderer);
2041 data->shader_format_count = nFormats;
2043 data->shader_formats[0] = GL_NVIDIA_PLATFORM_BINARY_NV;
2047 data->shader_formats[nFormats - 1] = (
GLenum)-1;
2052 data->glGenBuffers(
SDL_arraysize(data->vertex_buffers), data->vertex_buffers);
2054 data->framebuffers =
NULL;
2056 data->window_framebuffer = (
GLuint)window_framebuffer;
2087 #ifdef GL_TEXTURE_EXTERNAL_OES 2096 data->glEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION);
2097 data->glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
2099 data->glClearColor(1.0
f, 1.0
f, 1.0
f, 1.0
f);
2102 data->drawstate.color = 0xFFFFFFFF;
2103 data->drawstate.clear_color = 0xFFFFFFFF;
2104 data->drawstate.projection[3][0] = -1.0f;
2105 data->drawstate.projection[3][3] = 1.0f;
2107 GL_CheckError(
"", renderer);
2112 if (changed_window) {
2123 GLES2_CreateRenderer,
SDL_BlendFactor SDL_GetBlendModeSrcColorFactor(SDL_BlendMode blendMode)
SDL_BlendFactor
The normalized factor used to multiply pixel components.
#define GL_TEXTURE_EXTERNAL_OES
GLdouble GLdouble GLdouble r
int(* LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
struct SDL_RenderCommand::@30::@31 viewport
#define GL_INVALID_OPERATION
static void SetDrawState(SDL_Surface *surface, SW_DrawStateCache *drawstate)
#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
struct SDL_RenderCommand::@30::@32 cliprect
SDL_BlendMode
The blend mode used in SDL_RenderCopy() and drawing operations.
#define GL_COMPILE_STATUS
SDL_bool(* SupportsBlendMode)(SDL_Renderer *renderer, SDL_BlendMode blendMode)
GLuint GLuint GLsizei count
void * SDL_AllocateRenderVertices(SDL_Renderer *renderer, const size_t numbytes, const size_t alignment, size_t *offset)
struct SDL_RenderCommand::@30::@34 color
GLfloat GLfloat GLfloat GLfloat h
int(* QueueSetDrawColor)(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
#define GL_SHADER_COMPILER
Uint32 texture_formats[16]
static screen_context_t context
SDL_BlendFactor SDL_GetBlendModeDstAlphaFactor(SDL_BlendMode blendMode)
#define SDL_GetWindowFlags
int(* QueueCopyEx)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const SDL_Rect *srcquad, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
SDL_BlendOperation SDL_GetBlendModeColorOperation(SDL_BlendMode blendMode)
SDL_RendererFlip
Flip constants for SDL_RenderCopyEx.
#define SDL_BYTESPERPIXEL(X)
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
#define GL_TEXTURE_MAG_FILTER
#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
void(* DestroyRenderer)(SDL_Renderer *renderer)
GLint GLint GLsizei width
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
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
int(* UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
#define SDL_small_alloc(type, count, pisstack)
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
int(* QueueCopy)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
#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)
void * SDL_GLContext
An opaque handle to an OpenGL context.
#define SDL_GL_GetSwapInterval
struct SDL_RenderCommand::@30::@33 draw
int SDL_RecreateWindow(SDL_Window *window, Uint32 flags)
static SDL_Renderer * renderer
#define SDL_GL_SetSwapInterval
int(* QueueSetViewport)(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
#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)
GLubyte GLubyte GLubyte GLubyte w
GLsizei const GLfloat * value
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
GLsizei GLsizei GLchar * source
GLint GLint GLint GLint GLint GLint y
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
#define GL_COLOR_BUFFER_BIT
int(* QueueDrawLines)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
int(* GL_UnbindTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* RunCommandQueue)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
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)
Window state change event data (event.window.*)
#define SDL_assert(condition)
#define GL_FRAMEBUFFER_BINDING
#define SDL_OutOfMemory()
#define SDL_GL_GetCurrentContext
SDL_BlendFactor SDL_GetBlendModeSrcAlphaFactor(SDL_BlendMode blendMode)
GLint GLint GLsizei GLsizei height
#define SDL_GL_MakeCurrent
int(* QueueDrawPoints)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
EGLSurface EGLNativeWindowType * window
#define SDL_GetRendererOutputSize
#define GL_FUNC_REVERSE_SUBTRACT
SDL_RenderCommandType command
GLint GLint GLint yoffset
The type used to identify a window.
union SDL_RenderCommand::@30 data
#define GL_ONE_MINUS_DST_COLOR
SDL_BlendFactor SDL_GetBlendModeDstColorFactor(SDL_BlendMode blendMode)
#define SDL_small_free(ptr, isstack)
int(* QueueFillRects)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FRect *rects, int count)
void(* WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event)
#define GL_SHADER_BINARY_FORMATS
Uint32 num_texture_formats
GLuint GLuint GLsizei GLenum type
#define SDL_arraysize(array)
#define GL_NUM_SHADER_BINARY_FORMATS
#define SDL_GL_GetAttribute
GLbitfield GLuint program
#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
EGLSurface EGLint * rects
#define SDL_GetYUVConversionModeForResolution
#define GL_TEXTURE_WRAP_S
GLuint GLsizei GLsizei * length
#define GL_TEXTURE_MIN_FILTER
struct SDL_RenderCommand * next
GLboolean GLboolean GLboolean GLboolean a
#define GL_UNPACK_ALIGNMENT
GLboolean GLboolean GLboolean b
#define SDL_GL_SwapWindow
A rectangle, with the origin at the upper left (floating point).
The structure that defines a point (floating point)
A rectangle, with the origin at the upper left (integer).
#define GL_INFO_LOG_LENGTH