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"
34 #define RENDERER_CONTEXT_MAJOR 2
35 #define RENDERER_CONTEXT_MINOR 0
44 typedef struct GLES2_FBOList GLES2_FBOList;
53 typedef struct GLES2_TextureData
69 typedef struct GLES2_ShaderCacheEntry
72 GLES2_ShaderType
type;
73 const GLES2_ShaderInstance *instance;
75 struct GLES2_ShaderCacheEntry *prev;
76 struct GLES2_ShaderCacheEntry *next;
77 } GLES2_ShaderCacheEntry;
79 typedef struct GLES2_ShaderCache
82 GLES2_ShaderCacheEntry *
head;
85 typedef struct GLES2_ProgramCacheEntry
88 GLES2_ShaderCacheEntry *vertex_shader;
89 GLES2_ShaderCacheEntry *fragment_shader;
90 GLuint uniform_locations[16];
93 struct GLES2_ProgramCacheEntry *prev;
94 struct GLES2_ProgramCacheEntry *next;
95 } GLES2_ProgramCacheEntry;
97 typedef struct GLES2_ProgramCache
100 GLES2_ProgramCacheEntry *
head;
101 GLES2_ProgramCacheEntry *
tail;
102 } GLES2_ProgramCache;
106 GLES2_ATTRIBUTE_POSITION = 0,
107 GLES2_ATTRIBUTE_TEXCOORD = 1,
108 GLES2_ATTRIBUTE_ANGLE = 2,
109 GLES2_ATTRIBUTE_CENTER = 3,
114 GLES2_UNIFORM_PROJECTION,
115 GLES2_UNIFORM_TEXTURE,
117 GLES2_UNIFORM_TEXTURE_U,
118 GLES2_UNIFORM_TEXTURE_V
123 GLES2_IMAGESOURCE_INVALID,
124 GLES2_IMAGESOURCE_SOLID,
125 GLES2_IMAGESOURCE_TEXTURE_ABGR,
126 GLES2_IMAGESOURCE_TEXTURE_ARGB,
127 GLES2_IMAGESOURCE_TEXTURE_RGB,
128 GLES2_IMAGESOURCE_TEXTURE_BGR,
129 GLES2_IMAGESOURCE_TEXTURE_YUV,
130 GLES2_IMAGESOURCE_TEXTURE_NV12,
131 GLES2_IMAGESOURCE_TEXTURE_NV21,
132 GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES
152 GLES2_ProgramCacheEntry *
program;
154 } GLES2_DrawStateCache;
156 typedef struct GLES2_RenderData
162 #define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
166 GLuint window_framebuffer;
168 int shader_format_count;
170 GLES2_ShaderCache shader_cache;
171 GLES2_ProgramCache program_cache;
172 Uint8 clear_r, clear_g, clear_b, clear_a;
175 size_t vertex_buffer_size[8];
176 int current_vertex_buffer;
177 GLES2_DrawStateCache drawstate;
180 #define GLES2_MAX_CACHED_PROGRAMS 8
182 static const float inv255f = 1.0f / 255.0f;
186 GL_TranslateError (
GLenum error)
188 #define GL_ERROR_TRANSLATE(e) case e: return #e;
198 #undef GL_ERROR_TRANSLATE
206 if (!
data->debug_enabled) {
215 GL_CheckAllErrors (
const char *prefix,
SDL_Renderer *
renderer,
const char *file,
int line,
const char *
function)
220 if (!
data->debug_enabled) {
227 if (prefix ==
NULL || prefix[0] ==
'\0') {
230 SDL_SetError(
"%s: %s (%d): %s %s (0x%X)", prefix, file, line,
function, GL_TranslateError(error), error);
240 #define GL_CheckError(prefix, renderer)
242 #define GL_CheckError(prefix, renderer) GL_CheckAllErrors(prefix, renderer, SDL_FILE, SDL_LINE, SDL_FUNCTION)
250 static int GLES2_LoadFunctions(GLES2_RenderData *
data)
252 #if SDL_VIDEO_DRIVER_UIKIT
253 #define __SDL_NOGETPROCADDR__
254 #elif SDL_VIDEO_DRIVER_ANDROID
255 #define __SDL_NOGETPROCADDR__
256 #elif SDL_VIDEO_DRIVER_PANDORA
257 #define __SDL_NOGETPROCADDR__
260 #if defined __SDL_NOGETPROCADDR__
261 #define SDL_PROC(ret,func,params) data->func=func;
263 #define SDL_PROC(ret,func,params) \
265 data->func = SDL_GL_GetProcAddress(#func); \
266 if ( ! data->func ) { \
267 return SDL_SetError("Couldn't load GLES2 function %s: %s", #func, SDL_GetError()); \
277 static GLES2_FBOList *
397 GLES2_EvictShader(GLES2_RenderData *
data, GLES2_ShaderCacheEntry *entry)
401 entry->next->prev = entry->prev;
404 entry->prev->next = entry->next;
406 if (
data->shader_cache.head == entry) {
407 data->shader_cache.head = entry->next;
409 --
data->shader_cache.count;
412 data->glDeleteShader(entry->id);
416 static GLES2_ProgramCacheEntry *
417 GLES2_CacheProgram(GLES2_RenderData *
data, GLES2_ShaderCacheEntry *vertex,
418 GLES2_ShaderCacheEntry *fragment)
420 GLES2_ProgramCacheEntry *entry;
421 GLES2_ShaderCacheEntry *shaderEntry;
422 GLint linkSuccessful;
425 entry =
data->program_cache.head;
427 if (entry->vertex_shader == vertex && entry->fragment_shader == fragment) {
433 if (
data->program_cache.head != entry) {
435 entry->next->prev = entry->prev;
438 entry->prev->next = entry->next;
441 entry->next =
data->program_cache.head;
442 data->program_cache.head->prev = entry;
443 data->program_cache.head = entry;
449 entry = (GLES2_ProgramCacheEntry *)
SDL_calloc(1,
sizeof(GLES2_ProgramCacheEntry));
454 entry->vertex_shader = vertex;
455 entry->fragment_shader = fragment;
458 entry->id =
data->glCreateProgram();
459 data->glAttachShader(entry->id, vertex->id);
460 data->glAttachShader(entry->id, fragment->id);
461 data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_POSITION,
"a_position");
462 data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_TEXCOORD,
"a_texCoord");
463 data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_ANGLE,
"a_angle");
464 data->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_CENTER,
"a_center");
465 data->glLinkProgram(entry->id);
467 if (!linkSuccessful) {
468 data->glDeleteProgram(entry->id);
475 entry->uniform_locations[GLES2_UNIFORM_PROJECTION] =
476 data->glGetUniformLocation(entry->id,
"u_projection");
477 entry->uniform_locations[GLES2_UNIFORM_TEXTURE_V] =
478 data->glGetUniformLocation(entry->id,
"u_texture_v");
479 entry->uniform_locations[GLES2_UNIFORM_TEXTURE_U] =
480 data->glGetUniformLocation(entry->id,
"u_texture_u");
481 entry->uniform_locations[GLES2_UNIFORM_TEXTURE] =
482 data->glGetUniformLocation(entry->id,
"u_texture");
483 entry->uniform_locations[GLES2_UNIFORM_COLOR] =
484 data->glGetUniformLocation(entry->id,
"u_color");
488 data->glUseProgram(entry->id);
489 if (entry->uniform_locations[GLES2_UNIFORM_TEXTURE_V] != -1) {
490 data->glUniform1i(entry->uniform_locations[GLES2_UNIFORM_TEXTURE_V], 2);
492 if (entry->uniform_locations[GLES2_UNIFORM_TEXTURE_U] != -1) {
493 data->glUniform1i(entry->uniform_locations[GLES2_UNIFORM_TEXTURE_U], 1);
495 if (entry->uniform_locations[GLES2_UNIFORM_TEXTURE] != -1) {
496 data->glUniform1i(entry->uniform_locations[GLES2_UNIFORM_TEXTURE], 0);
498 if (entry->uniform_locations[GLES2_UNIFORM_PROJECTION] != -1) {
499 data->glUniformMatrix4fv(entry->uniform_locations[GLES2_UNIFORM_PROJECTION], 1,
GL_FALSE, (
GLfloat *)entry->projection);
501 if (entry->uniform_locations[GLES2_UNIFORM_COLOR] != -1) {
502 data->glUniform4f(entry->uniform_locations[GLES2_UNIFORM_COLOR], 0.0f, 0.0f, 0.0f, 0.0f);
506 if (
data->program_cache.head) {
507 entry->next =
data->program_cache.head;
508 data->program_cache.head->prev = entry;
510 data->program_cache.tail = entry;
512 data->program_cache.head = entry;
513 ++
data->program_cache.count;
516 ++vertex->references;
517 ++fragment->references;
520 if (
data->program_cache.count > GLES2_MAX_CACHED_PROGRAMS) {
521 shaderEntry =
data->program_cache.tail->vertex_shader;
522 if (--shaderEntry->references <= 0) {
523 GLES2_EvictShader(
data, shaderEntry);
525 shaderEntry =
data->program_cache.tail->fragment_shader;
526 if (--shaderEntry->references <= 0) {
527 GLES2_EvictShader(
data, shaderEntry);
529 data->glDeleteProgram(
data->program_cache.tail->id);
530 data->program_cache.tail =
data->program_cache.tail->prev;
531 if (
data->program_cache.tail !=
NULL) {
533 data->program_cache.tail->next =
NULL;
535 --
data->program_cache.count;
540 static GLES2_ShaderCacheEntry *
541 GLES2_CacheShader(GLES2_RenderData *
data, GLES2_ShaderType
type)
543 const GLES2_Shader *
shader;
544 const GLES2_ShaderInstance *instance =
NULL;
545 GLES2_ShaderCacheEntry *entry =
NULL;
552 SDL_SetError(
"No shader matching the requested characteristics was found");
557 for (
i = 0;
i <
shader->instance_count && !instance; ++
i) {
558 for (
j = 0;
j <
data->shader_format_count && !instance; ++
j) {
562 if (
shader->instances[
i]->format !=
data->shader_formats[
j]) {
565 instance =
shader->instances[
i];
569 SDL_SetError(
"The specified shader cannot be loaded on the current platform");
574 entry =
data->shader_cache.head;
576 if (entry->instance == instance) {
586 entry = (GLES2_ShaderCacheEntry *)
SDL_calloc(1,
sizeof(GLES2_ShaderCacheEntry));
592 entry->instance = instance;
595 entry->id =
data->glCreateShader(instance->type);
596 if (instance->format == (
GLenum)-1) {
597 data->glShaderSource(entry->id, 1, (
const char **)(
char *)&instance->data,
NULL);
598 data->glCompileShader(entry->id);
601 data->glShaderBinary(1, &entry->id, instance->format, instance->data, instance->length);
604 if (!compileSuccessful) {
622 data->glDeleteShader(entry->id);
628 if (
data->shader_cache.head) {
629 entry->next =
data->shader_cache.head;
630 data->shader_cache.head->prev = entry;
632 data->shader_cache.head = entry;
633 ++
data->shader_cache.count;
638 GLES2_SelectProgram(GLES2_RenderData *
data, GLES2_ImageSource
source,
int w,
int h)
640 GLES2_ShaderCacheEntry *vertex =
NULL;
641 GLES2_ShaderCacheEntry *fragment =
NULL;
642 GLES2_ShaderType vtype, ftype;
643 GLES2_ProgramCacheEntry *
program;
646 vtype = GLES2_SHADER_VERTEX_DEFAULT;
648 case GLES2_IMAGESOURCE_SOLID:
649 ftype = GLES2_SHADER_FRAGMENT_SOLID_SRC;
651 case GLES2_IMAGESOURCE_TEXTURE_ABGR:
652 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_ABGR_SRC;
654 case GLES2_IMAGESOURCE_TEXTURE_ARGB:
655 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_ARGB_SRC;
657 case GLES2_IMAGESOURCE_TEXTURE_RGB:
658 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_RGB_SRC;
660 case GLES2_IMAGESOURCE_TEXTURE_BGR:
661 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_BGR_SRC;
663 case GLES2_IMAGESOURCE_TEXTURE_YUV:
666 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_YUV_JPEG_SRC;
669 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT601_SRC;
672 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_YUV_BT709_SRC;
679 case GLES2_IMAGESOURCE_TEXTURE_NV12:
682 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_JPEG_SRC;
685 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT601_SRC;
688 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV12_BT709_SRC;
695 case GLES2_IMAGESOURCE_TEXTURE_NV21:
698 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV21_JPEG_SRC;
701 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT601_SRC;
704 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_NV21_BT709_SRC;
711 case GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES:
712 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_EXTERNAL_OES_SRC;
719 vertex = GLES2_CacheShader(
data, vtype);
723 fragment = GLES2_CacheShader(
data, ftype);
729 if (
data->drawstate.program &&
730 data->drawstate.program->vertex_shader == vertex &&
731 data->drawstate.program->fragment_shader == fragment) {
736 program = GLES2_CacheProgram(
data, vertex, fragment);
750 if (vertex && vertex->references <= 0) {
751 GLES2_EvictShader(
data, vertex);
753 if (fragment && fragment->references <= 0) {
754 GLES2_EvictShader(
data, fragment);
806 const GLfloat xstart = verts[0];
807 const GLfloat ystart = verts[1];
811 if (ystart == yend) {
812 verts[2] += (xend > xstart) ? 1.0f : -1.0f;
813 }
else if (xstart == xend) {
814 verts[3] += (yend > ystart) ? 1.0f : -1.0f;
816 const GLfloat deltax = xend - xstart;
817 const GLfloat deltay = yend - ystart;
862 GLfloat minx, miny, maxx, maxy;
863 GLfloat minu, maxu, minv, maxv;
874 maxx = dstrect->
x + dstrect->
w;
875 maxy = dstrect->
y + dstrect->
h;
909 const float radian_angle = (float)(M_PI * (360.0 -
angle) / 180.0);
912 const GLfloat centerx = center->
x + dstrect->
x;
913 const GLfloat centery = center->
y + dstrect->
y;
914 GLfloat minx, miny, maxx, maxy;
915 GLfloat minu, maxu, minv, maxv;
923 minx = dstrect->
x + dstrect->
w;
927 maxx = dstrect->
x + dstrect->
w;
931 miny = dstrect->
y + dstrect->
h;
935 maxy = dstrect->
y + dstrect->
h;
973 *(verts++) = centerx;
974 *(verts++) = centery;
975 *(verts++) = centerx;
976 *(verts++) = centery;
977 *(verts++) = centerx;
978 *(verts++) = centery;
979 *(verts++) = centerx;
980 *(verts++) = centery;
988 const SDL_bool was_copy_ex =
data->drawstate.is_copy_ex;
992 GLES2_ProgramCacheEntry *
program;
996 if (
data->drawstate.viewport_dirty) {
1003 data->drawstate.projection[1][1] = (
data->drawstate.target ? 2.0f : -2.0f) /
viewport->
h;
1004 data->drawstate.projection[3][1] =
data->drawstate.target ? -1.0f : 1.0f;
1009 if (
data->drawstate.cliprect_enabled_dirty) {
1010 if (!
data->drawstate.cliprect_enabled) {
1018 if (
data->drawstate.cliprect_enabled &&
data->drawstate.cliprect_dirty) {
1030 data->glDisableVertexAttribArray((
GLenum) GLES2_ATTRIBUTE_TEXCOORD);
1033 data->glEnableVertexAttribArray((
GLenum) GLES2_ATTRIBUTE_TEXCOORD);
1039 GLES2_TextureData *tdata = (GLES2_TextureData *)
texture->driverdata;
1042 data->glBindTexture(tdata->texture_type, tdata->texture_v);
1045 data->glBindTexture(tdata->texture_type, tdata->texture_u);
1048 }
else if (tdata->nv12) {
1050 data->glBindTexture(tdata->texture_type, tdata->texture_u);
1054 data->glBindTexture(tdata->texture_type, tdata->texture);
1070 if (
program->uniform_locations[GLES2_UNIFORM_PROJECTION] != -1) {
1077 if (
program->uniform_locations[GLES2_UNIFORM_COLOR] != -1) {
1079 const Uint8 r = (
data->drawstate.color >> 16) & 0xFF;
1080 const Uint8 g = (
data->drawstate.color >> 8) & 0xFF;
1081 const Uint8 b = (
data->drawstate.color >> 0) & 0xFF;
1082 const Uint8 a = (
data->drawstate.color >> 24) & 0xFF;
1083 data->glUniform4f(
program->uniform_locations[GLES2_UNIFORM_COLOR],
r * inv255f,
g * inv255f,
b * inv255f,
a * inv255f);
1088 if (blend !=
data->drawstate.blend) {
1100 data->drawstate.blend = blend;
1106 if (is_copy_ex != was_copy_ex) {
1108 data->glEnableVertexAttribArray((
GLenum) GLES2_ATTRIBUTE_ANGLE);
1109 data->glEnableVertexAttribArray((
GLenum) GLES2_ATTRIBUTE_CENTER);
1111 data->glDisableVertexAttribArray((
GLenum) GLES2_ATTRIBUTE_ANGLE);
1112 data->glDisableVertexAttribArray((
GLenum) GLES2_ATTRIBUTE_CENTER);
1114 data->drawstate.is_copy_ex = is_copy_ex;
1129 GLES2_ImageSource sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1141 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1144 sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1152 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1155 sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1162 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1165 sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
1168 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1175 sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
1178 sourceType = GLES2_IMAGESOURCE_TEXTURE_RGB;
1181 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1187 sourceType = GLES2_IMAGESOURCE_TEXTURE_YUV;
1190 sourceType = GLES2_IMAGESOURCE_TEXTURE_NV12;
1193 sourceType = GLES2_IMAGESOURCE_TEXTURE_NV21;
1196 sourceType = GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES;
1202 sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1207 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1210 sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1213 sourceType = GLES2_IMAGESOURCE_TEXTURE_RGB;
1216 sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
1220 sourceType = GLES2_IMAGESOURCE_TEXTURE_YUV;
1223 sourceType = GLES2_IMAGESOURCE_TEXTURE_NV12;
1226 sourceType = GLES2_IMAGESOURCE_TEXTURE_NV21;
1229 sourceType = GLES2_IMAGESOURCE_TEXTURE_EXTERNAL_OES;
1244 const int vboidx =
data->current_vertex_buffer;
1245 const GLuint vbo =
data->vertex_buffers[vboidx];
1248 if (GLES2_ActivateRenderer(
renderer) < 0) {
1253 if (!
data->drawstate.target) {
1259 if (
data->vertex_buffer_size[vboidx] < vertsize) {
1261 data->vertex_buffer_size[vboidx] = vertsize;
1267 data->current_vertex_buffer++;
1269 data->current_vertex_buffer = 0;
1279 data->drawstate.color = ((
a << 24) | (
r << 16) | (
g << 8) |
b);
1312 if (
color !=
data->drawstate.clear_color) {
1317 data->glClearColor(fr, fg, fb, fa);
1321 if (
data->drawstate.cliprect_enabled ||
data->drawstate.cliprect_enabled_dirty) {
1323 data->drawstate.cliprect_enabled_dirty =
data->drawstate.cliprect_enabled;
1359 if (SetCopyState(
renderer, cmd) == 0) {
1372 return GL_CheckError(
"",
renderer);
1385 GLES2_ShaderCacheEntry *entry;
1386 GLES2_ShaderCacheEntry *next;
1387 entry =
data->shader_cache.head;
1389 data->glDeleteShader(entry->id);
1396 GLES2_ProgramCacheEntry *entry;
1397 GLES2_ProgramCacheEntry *next;
1398 entry =
data->program_cache.head;
1400 data->glDeleteProgram(entry->id);
1407 if (
data->context) {
1408 while (
data->framebuffers) {
1409 GLES2_FBOList *nextnode =
data->framebuffers->next;
1410 data->glDeleteFramebuffers(1, &
data->framebuffers->FBO);
1413 data->framebuffers = nextnode;
1432 GLES2_TextureData *
data;
1439 renderdata->drawstate.texture =
NULL;
1458 #ifdef GL_TEXTURE_EXTERNAL_OES
1470 return SDL_SetError(
"Unsupported texture access for SDL_PIXELFORMAT_EXTERNAL_OES");
1474 data = (GLES2_TextureData *)
SDL_calloc(1,
sizeof(GLES2_TextureData));
1479 #ifdef GL_TEXTURE_EXTERNAL_OES
1488 data->texture_u = 0;
1489 data->texture_v = 0;
1500 }
else if (
data->nv12) {
1505 if (!
data->pixel_data) {
1515 renderdata->glGenTextures(1, &
data->texture_v);
1516 if (GL_CheckError(
"glGenTexures()",
renderer) < 0) {
1520 renderdata->glBindTexture(
data->texture_type,
data->texture_v);
1527 renderdata->glGenTextures(1, &
data->texture_u);
1528 if (GL_CheckError(
"glGenTexures()",
renderer) < 0) {
1532 renderdata->glBindTexture(
data->texture_type,
data->texture_u);
1538 if (GL_CheckError(
"glTexImage2D()",
renderer) < 0) {
1541 }
else if (
data->nv12) {
1542 renderdata->glGenTextures(1, &
data->texture_u);
1543 if (GL_CheckError(
"glGenTexures()",
renderer) < 0) {
1547 renderdata->glBindTexture(
data->texture_type,
data->texture_u);
1553 if (GL_CheckError(
"glTexImage2D()",
renderer) < 0) {
1558 renderdata->glGenTextures(1, &
data->texture);
1559 if (GL_CheckError(
"glGenTexures()",
renderer) < 0) {
1564 renderdata->glBindTexture(
data->texture_type,
data->texture);
1571 if (GL_CheckError(
"glTexImage2D()",
renderer) < 0) {
1582 return GL_CheckError(
"",
renderer);
1586 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)
1600 if (pitch != src_pitch) {
1624 const void *
pixels,
int pitch)
1627 GLES2_TextureData *tdata = (GLES2_TextureData *)
texture->driverdata;
1639 data->glBindTexture(tdata->texture_type, tdata->texture);
1640 GLES2_TexSubImage2D(
data, tdata->texture_type,
1645 tdata->pixel_format,
1653 data->glBindTexture(tdata->texture_type, tdata->texture_v);
1655 data->glBindTexture(tdata->texture_type, tdata->texture_u);
1657 GLES2_TexSubImage2D(
data, tdata->texture_type,
1662 tdata->pixel_format,
1664 pixels, (pitch + 1) / 2, 1);
1670 data->glBindTexture(tdata->texture_type, tdata->texture_u);
1672 data->glBindTexture(tdata->texture_type, tdata->texture_v);
1674 GLES2_TexSubImage2D(
data, tdata->texture_type,
1679 tdata->pixel_format,
1681 pixels, (pitch + 1) / 2, 1);
1682 }
else if (tdata->nv12) {
1685 data->glBindTexture(tdata->texture_type, tdata->texture_u);
1686 GLES2_TexSubImage2D(
data, tdata->texture_type,
1693 pixels, 2 * ((pitch + 1) / 2), 2);
1696 return GL_CheckError(
"glTexSubImage2D()",
renderer);
1702 const Uint8 *Yplane,
int Ypitch,
1703 const Uint8 *Uplane,
int Upitch,
1704 const Uint8 *Vplane,
int Vpitch)
1707 GLES2_TextureData *tdata = (GLES2_TextureData *)
texture->driverdata;
1718 data->glBindTexture(tdata->texture_type, tdata->texture_v);
1719 GLES2_TexSubImage2D(
data, tdata->texture_type,
1724 tdata->pixel_format,
1728 data->glBindTexture(tdata->texture_type, tdata->texture_u);
1729 GLES2_TexSubImage2D(
data, tdata->texture_type,
1734 tdata->pixel_format,
1738 data->glBindTexture(tdata->texture_type, tdata->texture);
1739 GLES2_TexSubImage2D(
data, tdata->texture_type,
1744 tdata->pixel_format,
1748 return GL_CheckError(
"glTexSubImage2D()",
renderer);
1753 void **
pixels,
int *pitch)
1755 GLES2_TextureData *tdata = (GLES2_TextureData *)
texture->driverdata;
1759 (tdata->pitch *
rect->
y) +
1761 *pitch = tdata->pitch;
1769 GLES2_TextureData *tdata = (GLES2_TextureData *)
texture->driverdata;
1784 GLES2_TextureData *
data = (GLES2_TextureData *)
texture->driverdata;
1789 renderdata->glBindTexture(
data->texture_type,
data->texture_v);
1794 renderdata->glBindTexture(
data->texture_type,
data->texture_u);
1797 }
else if (
data->nv12) {
1799 renderdata->glBindTexture(
data->texture_type,
data->texture_u);
1805 renderdata->glBindTexture(
data->texture_type,
data->texture);
1814 GLES2_TextureData *texturedata =
NULL;
1822 texturedata = (GLES2_TextureData *)
texture->driverdata;
1829 return SDL_SetError(
"glFramebufferTexture2D() failed");
1839 GLES2_TextureData *tdata = (GLES2_TextureData *)
texture->driverdata;
1852 data->glDeleteTextures(1, &tdata->texture);
1853 if (tdata->texture_v) {
1854 data->glDeleteTextures(1, &tdata->texture_v);
1856 if (tdata->texture_u) {
1857 data->glDeleteTextures(1, &tdata->texture_u);
1879 buflen =
rect->
h * temp_pitch;
1893 if (GL_CheckError(
"glReadPixels()",
renderer) < 0) {
1916 temp_format, temp_pixels, temp_pitch,
1940 GLES2_TextureData *texturedata = (GLES2_TextureData *)
texture->driverdata;
1943 data->glBindTexture(texturedata->texture_type, texturedata->texture);
1959 GLES2_TextureData *texturedata = (GLES2_TextureData *)
texture->driverdata;
1962 data->glBindTexture(texturedata->texture_type, 0);
1974 #define GL_NVIDIA_PLATFORM_BINARY_NV 0x890B
1982 GLES2_RenderData *
data;
1988 GLint window_framebuffer;
1990 int profile_mask = 0, major = 0, minor = 0;
2026 data = (GLES2_RenderData *)
SDL_calloc(1,
sizeof(GLES2_RenderData));
2039 if (!
data->context) {
2051 if (GLES2_LoadFunctions(
data) < 0) {
2100 if (!
data->shader_formats) {
2105 data->shader_format_count = nFormats;
2107 data->shader_formats[0] = GL_NVIDIA_PLATFORM_BINARY_NV;
2111 data->shader_formats[nFormats - 1] = (
GLenum)-1;
2120 data->window_framebuffer = (
GLuint)window_framebuffer;
2152 #ifdef GL_TEXTURE_EXTERNAL_OES
2161 data->glEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION);
2162 data->glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
2164 data->glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
2167 data->drawstate.color = 0xFFFFFFFF;
2168 data->drawstate.clear_color = 0xFFFFFFFF;
2169 data->drawstate.projection[3][0] = -1.0f;
2170 data->drawstate.projection[3][3] = 1.0f;
2177 if (changed_window) {
2188 GLES2_CreateRenderer,
#define SDL_assert(condition)
SDL_BlendOperation
The blend operation used when combining source and destination pixel components.
@ SDL_BLENDOPERATION_REV_SUBTRACT
@ SDL_BLENDOPERATION_SUBTRACT
SDL_BlendFactor
The normalized factor used to multiply pixel components.
@ SDL_BLENDFACTOR_ONE_MINUS_SRC_COLOR
@ SDL_BLENDFACTOR_SRC_COLOR
@ SDL_BLENDFACTOR_SRC_ALPHA
@ SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR
@ SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA
@ SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA
@ SDL_BLENDFACTOR_DST_ALPHA
@ SDL_BLENDFACTOR_DST_COLOR
SDL_BlendMode
The blend mode used in SDL_RenderCopy() and drawing operations.
#define SDL_GL_SwapWindow
#define SDL_GetWindowFlags
#define SDL_GetYUVConversionModeForResolution
#define SDL_GL_GetAttribute
#define SDL_GL_SetSwapInterval
#define SDL_GL_MakeCurrent
#define SDL_GetRendererOutputSize
#define SDL_GL_SetAttribute
#define SDL_GL_GetSwapInterval
#define SDL_GL_DeleteContext
#define SDL_GL_CreateContext
#define SDL_GL_GetDrawableSize
#define SDL_ConvertPixels
#define SDL_GL_GetCurrentContext
#define SDL_OutOfMemory()
#define SDL_small_alloc(type, count, pisstack)
#define SDL_small_free(ptr, isstack)
int uint32_t uint32_t uint32_t pixel_format
#define GL_MAX_TEXTURE_SIZE
GLint GLint GLint GLint GLint GLint y
#define GL_TEXTURE_MIN_FILTER
#define GL_TEXTURE_WRAP_S
#define GL_LUMINANCE_ALPHA
#define GL_ONE_MINUS_DST_ALPHA
#define GL_PACK_ALIGNMENT
#define GL_ONE_MINUS_DST_COLOR
#define GL_INVALID_OPERATION
GLuint GLuint GLsizei count
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
GLint GLint GLint yoffset
#define GL_FUNC_REVERSE_SUBTRACT
#define GL_UNPACK_ALIGNMENT
#define GL_COLOR_BUFFER_BIT
GLint GLint GLsizei width
#define GL_ONE_MINUS_SRC_ALPHA
GLdouble GLdouble GLdouble r
GLint GLint GLint GLint GLint x
#define GL_TEXTURE_WRAP_T
GLint GLint GLsizei GLsizei height
#define GL_TEXTURE_MAG_FILTER
#define GL_TRIANGLE_STRIP
GLuint GLuint GLsizei GLenum type
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
#define GL_ONE_MINUS_SRC_COLOR
GLboolean GLboolean GLboolean b
#define GL_NUM_SHADER_BINARY_FORMATS
GLfixed GLfixed GLint GLint GLfixed points
#define GL_SHADER_COMPILER
#define GL_COLOR_ATTACHMENT0
GLsizei GLsizei GLchar * source
GLboolean GLboolean GLboolean GLboolean a
#define GL_FRAMEBUFFER_COMPLETE
#define GL_COMPILE_STATUS
const GLuint * framebuffers
GLenum GLenum GLuint texture
#define GL_FRAMEBUFFER_BINDING
GLuint GLsizei GLsizei * length
GLsizei const GLfloat * value
#define GL_SHADER_BINARY_FORMATS
GLbitfield GLuint program
#define GL_INFO_LOG_LENGTH
GLfloat GLfloat GLfloat GLfloat h
GLubyte GLubyte GLubyte GLubyte w
#define GL_TEXTURE_EXTERNAL_OES
#define SDL_BYTESPERPIXEL(X)
@ SDL_PIXELFORMAT_EXTERNAL_OES
@ SDL_PIXELFORMAT_ABGR8888
@ SDL_PIXELFORMAT_ARGB8888
SDL_BlendFactor SDL_GetBlendModeDstColorFactor(SDL_BlendMode blendMode)
SDL_BlendFactor SDL_GetBlendModeSrcColorFactor(SDL_BlendMode blendMode)
void * SDL_AllocateRenderVertices(SDL_Renderer *renderer, const size_t numbytes, const size_t alignment, size_t *offset)
SDL_BlendFactor SDL_GetBlendModeDstAlphaFactor(SDL_BlendMode blendMode)
SDL_BlendFactor SDL_GetBlendModeSrcAlphaFactor(SDL_BlendMode blendMode)
SDL_BlendOperation SDL_GetBlendModeAlphaOperation(SDL_BlendMode blendMode)
SDL_BlendOperation SDL_GetBlendModeColorOperation(SDL_BlendMode blendMode)
@ SDL_RENDERER_ACCELERATED
@ SDL_RENDERER_PRESENTVSYNC
@ SDL_RENDERER_TARGETTEXTURE
SDL_RendererFlip
Flip constants for SDL_RenderCopyEx.
@ SDL_TEXTUREACCESS_STATIC
@ SDL_TEXTUREACCESS_STREAMING
@ SDL_TEXTUREACCESS_TARGET
SDL_ScaleMode
The scaling mode for a texture.
static void SetDrawState(SDL_Surface *surface, SW_DrawStateCache *drawstate)
#define SDL_arraysize(array)
@ SDL_YUV_CONVERSION_BT601
@ SDL_YUV_CONVERSION_JPEG
@ SDL_YUV_CONVERSION_BT709
SDL_RenderDriver GLES2_RenderDriver
@ SDL_RENDERCMD_SETCLIPRECT
@ SDL_RENDERCMD_DRAW_LINES
@ SDL_RENDERCMD_SETVIEWPORT
@ SDL_RENDERCMD_DRAW_POINTS
@ SDL_RENDERCMD_FILL_RECTS
@ SDL_RENDERCMD_SETDRAWCOLOR
int SDL_RecreateWindow(SDL_Window *window, Uint32 flags)
@ SDL_GL_CONTEXT_MAJOR_VERSION
@ SDL_GL_CONTEXT_MINOR_VERSION
@ SDL_GL_CONTEXT_PROFILE_MASK
@ SDL_GL_CONTEXT_DEBUG_FLAG
void * SDL_GLContext
An opaque handle to an OpenGL context.
@ SDL_WINDOWEVENT_MINIMIZED
@ SDL_GL_CONTEXT_PROFILE_ES
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)
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)
EGLSurface EGLNativeWindowType * window
EGLSurface EGLint * rects
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d ®2 endm macro vzip8 reg2 vzip d d ®2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp
The structure that defines a point (floating point)
A rectangle, with the origin at the upper left (floating point).
A rectangle, with the origin at the upper left (integer).
struct SDL_RenderCommand::@38::@42 color
struct SDL_RenderCommand * next
struct SDL_RenderCommand::@38::@39 viewport
struct SDL_RenderCommand::@38::@41 draw
SDL_RenderCommandType command
union SDL_RenderCommand::@38 data
struct SDL_RenderCommand::@38::@40 cliprect
int(* QueueCopy)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
int(* LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, 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)
int(* QueueDrawLines)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
void(* SetTextureScaleMode)(SDL_Renderer *renderer, SDL_Texture *texture, SDL_ScaleMode scaleMode)
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
void(* DestroyRenderer)(SDL_Renderer *renderer)
void(* DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* GL_BindTexture)(SDL_Renderer *renderer, SDL_Texture *texture, float *texw, float *texh)
int(* GetOutputSize)(SDL_Renderer *renderer, int *w, int *h)
SDL_bool(* SupportsBlendMode)(SDL_Renderer *renderer, SDL_BlendMode blendMode)
void(* RenderPresent)(SDL_Renderer *renderer)
int(* RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect, Uint32 format, void *pixels, int pitch)
int(* QueueDrawPoints)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
int(* QueueFillRects)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FRect *rects, int count)
void(* WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event)
int(* RunCommandQueue)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
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)
int(* CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* QueueSetViewport)(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
int(* GL_UnbindTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* QueueSetDrawColor)(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
Uint32 texture_formats[16]
Uint32 num_texture_formats
Window state change event data (event.window.*)
The type used to identify a window.
static SDL_Renderer * renderer
static SDL_BlendMode blendMode
static screen_context_t context