zenilib: zenilib/jni/external/sdl/src/render/opengles2/SDL_render_gles2.c Source File

zenilib 0.5.3.0

- Main Page
- Modules
- Namespaces
- Classes
- Files

- File List
- File Members

All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
SDL_render_gles2.c
Go to the documentation of this file.
1 /*
2 Simple DirectMedia Layer
3 Copyright (C) 1997-2013 Sam Lantinga <slouken@libsdl.org>
4
5 This software is provided 'as-is', without any express or implied
6 warranty. In no event will the authors be held liable for any damages
7 arising from the use of this software.
8
9 Permission is granted to anyone to use this software for any purpose,
10 including commercial applications, and to alter it and redistribute it
11 freely, subject to the following restrictions:
12
13 1. The origin of this software must not be misrepresented; you must not
14 claim that you wrote the original software. If you use this software
15 in a product, an acknowledgment in the product documentation would be
16 appreciated but is not required.
17 2. Altered source versions must be plainly marked as such, and must not be
18 misrepresented as being the original software.
19 3. This notice may not be removed or altered from any source distribution.
20 */
21 #include "SDL_config.h"
22
23 #if SDL_VIDEO_RENDER_OGL_ES2 && !SDL_RENDER_DISABLED
24
25 #include "SDL_hints.h"
26 #include "SDL_opengles2.h"
27 #include "../SDL_sysrender.h"
28 #include "SDL_shaders_gles2.h"
29
30 /* Used to re-create the window with OpenGL ES capability */
31 extern int SDL_RecreateWindow(SDL_Window * window, Uint32 flags);
32
33 /*************************************************************************************************
34 * Bootstrap data *
35 *************************************************************************************************/
36
37 static SDL_Renderer *GLES2_CreateRenderer(SDL_Window *window, Uint32 flags);
38
39 SDL_RenderDriver GLES2_RenderDriver = {
40 GLES2_CreateRenderer,
41 {
42 "opengles2",
43 (SDL_RENDERER_ACCELERATED | SDL_RENDERER_PRESENTVSYNC | SDL_RENDERER_TARGETTEXTURE),
44 4,
45 {SDL_PIXELFORMAT_ABGR8888,
46 SDL_PIXELFORMAT_ARGB8888,
47 SDL_PIXELFORMAT_RGB888,
48 SDL_PIXELFORMAT_BGR888},
49 0,
50 0
51 }
52 };
53
54 /*************************************************************************************************
55 * Context structures *
56 *************************************************************************************************/
57
58 typedef struct GLES2_FBOList GLES2_FBOList;
59
60 struct GLES2_FBOList
61 {
62 Uint32 w, h;
63 GLuint FBO;
64 GLES2_FBOList *next;
65 };
66
67 typedef struct GLES2_TextureData
68 {
69 GLenum texture;
70 GLenum texture_type;
71 GLenum pixel_format;
72 GLenum pixel_type;
73 void *pixel_data;
74 size_t pitch;
75 GLES2_FBOList *fbo;
76 } GLES2_TextureData;
77
78 typedef struct GLES2_ShaderCacheEntry
79 {
80 GLuint id;
81 GLES2_ShaderType type;
82 const GLES2_ShaderInstance *instance;
83 int references;
84 struct GLES2_ShaderCacheEntry *prev;
85 struct GLES2_ShaderCacheEntry *next;
86 } GLES2_ShaderCacheEntry;
87
88 typedef struct GLES2_ShaderCache
89 {
90 int count;
91 GLES2_ShaderCacheEntry *head;
92 } GLES2_ShaderCache;
93
94 typedef struct GLES2_ProgramCacheEntry
95 {
96 GLuint id;
97 SDL_BlendMode blend_mode;
98 GLES2_ShaderCacheEntry *vertex_shader;
99 GLES2_ShaderCacheEntry *fragment_shader;
100 GLuint uniform_locations[16];
101 struct GLES2_ProgramCacheEntry *prev;
102 struct GLES2_ProgramCacheEntry *next;
103 } GLES2_ProgramCacheEntry;
104
105 typedef struct GLES2_ProgramCache
106 {
107 int count;
108 GLES2_ProgramCacheEntry *head;
109 GLES2_ProgramCacheEntry *tail;
110 } GLES2_ProgramCache;
111
112 typedef enum
113 {
114 GLES2_ATTRIBUTE_POSITION = 0,
115 GLES2_ATTRIBUTE_TEXCOORD = 1,
116 GLES2_ATTRIBUTE_ANGLE = 2,
117 GLES2_ATTRIBUTE_CENTER = 3,
118 } GLES2_Attribute;
119
120 typedef enum
121 {
122 GLES2_UNIFORM_PROJECTION,
123 GLES2_UNIFORM_TEXTURE,
124 GLES2_UNIFORM_MODULATION,
125 GLES2_UNIFORM_COLOR,
126 GLES2_UNIFORM_COLORTABLE
127 } GLES2_Uniform;
128
129 typedef enum
130 {
131 GLES2_IMAGESOURCE_SOLID,
132 GLES2_IMAGESOURCE_TEXTURE_ABGR,
133 GLES2_IMAGESOURCE_TEXTURE_ARGB,
134 GLES2_IMAGESOURCE_TEXTURE_RGB,
135 GLES2_IMAGESOURCE_TEXTURE_BGR
136 } GLES2_ImageSource;
137
138 typedef struct GLES2_DriverContext
139 {
140 SDL_GLContext *context;
141 struct {
142 int blendMode;
143 SDL_bool tex_coords;
144 } current;
145
146 #define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
147 #include "SDL_gles2funcs.h"
148 #undef SDL_PROC
149 GLES2_FBOList *framebuffers;
150 GLuint window_framebuffer;
151
152 int shader_format_count;
153 GLenum *shader_formats;
154 GLES2_ShaderCache shader_cache;
155 GLES2_ProgramCache program_cache;
156 GLES2_ProgramCacheEntry *current_program;
157 } GLES2_DriverContext;
158
159 #define GLES2_MAX_CACHED_PROGRAMS 8
160
161 /*************************************************************************************************
162 * Renderer state APIs *
163 *************************************************************************************************/
164
165 static int GLES2_ActivateRenderer(SDL_Renderer *renderer);
166 static void GLES2_WindowEvent(SDL_Renderer * renderer,
167 const SDL_WindowEvent *event);
168 static int GLES2_UpdateViewport(SDL_Renderer * renderer);
169 static void GLES2_DestroyRenderer(SDL_Renderer *renderer);
170 static int GLES2_SetOrthographicProjection(SDL_Renderer *renderer);
171
172
173 static SDL_GLContext SDL_CurrentContext = NULL;
174
175 static int GLES2_LoadFunctions(GLES2_DriverContext * data)
176 {
177 #if SDL_VIDEO_DRIVER_UIKIT
178 #define __SDL_NOGETPROCADDR__
179 #elif SDL_VIDEO_DRIVER_ANDROID
180 #define __SDL_NOGETPROCADDR__
181 #elif SDL_VIDEO_DRIVER_PANDORA
182 #define __SDL_NOGETPROCADDR__
183 #endif
184
185 #if defined __SDL_NOGETPROCADDR__
186 #define SDL_PROC(ret,func,params) data->func=func;
187 #else
188 #define SDL_PROC(ret,func,params) \
189 do { \
190 data->func = SDL_GL_GetProcAddress(#func); \
191 if ( ! data->func ) { \
192 return SDL_SetError("Couldn't load GLES2 function %s: %s\n", #func, SDL_GetError()); \
193 } \
194 } while ( 0 );
195 #endif /* _SDL_NOGETPROCADDR_ */
196
197 #include "SDL_gles2funcs.h"
198 #undef SDL_PROC
199 return 0;
200 }
201
202 GLES2_FBOList *
203 GLES2_GetFBO(GLES2_DriverContext *data, Uint32 w, Uint32 h)
204 {
205 GLES2_FBOList *result = data->framebuffers;
206 while ((result) && ((result->w != w) || (result->h != h)) )
207 {
208 result = result->next;
209 }
210 if (result == NULL)
211 {
212 result = SDL_malloc(sizeof(GLES2_FBOList));
213 result->w = w;
214 result->h = h;
215 data->glGenFramebuffers(1, &result->FBO);
216 result->next = data->framebuffers;
217 data->framebuffers = result;
218 }
219 return result;
220 }
221
222 static int
223 GLES2_ActivateRenderer(SDL_Renderer * renderer)
224 {
225 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
226
227 if (SDL_CurrentContext != rdata->context) {
228 /* Null out the current program to ensure we set it again */
229 rdata->current_program = NULL;
230
231 if (SDL_GL_MakeCurrent(renderer->window, rdata->context) < 0) {
232 return -1;
233 }
234 SDL_CurrentContext = rdata->context;
235
236 GLES2_UpdateViewport(renderer);
237 }
238 return 0;
239 }
240
241 static void
242 GLES2_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
243 {
244 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
245
246 if (event->event == SDL_WINDOWEVENT_SIZE_CHANGED ||
247 event->event == SDL_WINDOWEVENT_SHOWN ||
248 event->event == SDL_WINDOWEVENT_HIDDEN) {
249 /* Rebind the context to the window area */
250 SDL_CurrentContext = NULL;
251 }
252
253 if (event->event == SDL_WINDOWEVENT_MINIMIZED) {
254 /* According to Apple documentation, we need to finish drawing NOW! */
255 rdata->glFinish();
256 }
257 }
258
259 static int
260 GLES2_UpdateViewport(SDL_Renderer * renderer)
261 {
262 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
263
264 if (SDL_CurrentContext != rdata->context) {
265 /* We'll update the viewport after we rebind the context */
266 return 0;
267 }
268
269 rdata->glViewport(renderer->viewport.x, renderer->viewport.y,
270 renderer->viewport.w, renderer->viewport.h);
271
272 if (rdata->current_program) {
273 GLES2_SetOrthographicProjection(renderer);
274 }
275 return 0;
276 }
277
278 static int
279 GLES2_UpdateClipRect(SDL_Renderer * renderer)
280 {
281 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
282 const SDL_Rect *rect = &renderer->clip_rect;
283
284 if (SDL_CurrentContext != rdata->context) {
285 /* We'll update the clip rect after we rebind the context */
286 return 0;
287 }
288
289 if (!SDL_RectEmpty(rect)) {
290 rdata->glEnable(GL_SCISSOR_TEST);
291 rdata->glScissor(rect->x, renderer->viewport.h - rect->y - rect->h, rect->w, rect->h);
292 } else {
293 rdata->glDisable(GL_SCISSOR_TEST);
294 }
295 return 0;
296 }
297
298 static void
299 GLES2_DestroyRenderer(SDL_Renderer *renderer)
300 {
301 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
302
303 /* Deallocate everything */
304 if (rdata) {
305 GLES2_ActivateRenderer(renderer);
306
307 {
308 GLES2_ShaderCacheEntry *entry;
309 GLES2_ShaderCacheEntry *next;
310 entry = rdata->shader_cache.head;
311 while (entry)
312 {
313 rdata->glDeleteShader(entry->id);
314 next = entry->next;
315 SDL_free(entry);
316 entry = next;
317 }
318 }
319 {
320 GLES2_ProgramCacheEntry *entry;
321 GLES2_ProgramCacheEntry *next;
322 entry = rdata->program_cache.head;
323 while (entry) {
324 rdata->glDeleteProgram(entry->id);
325 next = entry->next;
326 SDL_free(entry);
327 entry = next;
328 }
329 }
330 if (rdata->context) {
331 while (rdata->framebuffers) {
332 GLES2_FBOList *nextnode = rdata->framebuffers->next;
333 rdata->glDeleteFramebuffers(1, &rdata->framebuffers->FBO);
334 SDL_free(rdata->framebuffers);
335 rdata->framebuffers = nextnode;
336 }
337 SDL_GL_DeleteContext(rdata->context);
338 }
339 SDL_free(rdata->shader_formats);
340 SDL_free(rdata);
341 }
342 SDL_free(renderer);
343 }
344
345 /*************************************************************************************************
346 * Texture APIs *
347 *************************************************************************************************/
348
349 static int GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture);
350 static void GLES2_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture);
351 static int GLES2_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect,
352 void **pixels, int *pitch);
353 static void GLES2_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture);
354 static int GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect,
355 const void *pixels, int pitch);
356 static int GLES2_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture);
357
358 static GLenum
359 GetScaleQuality(void)
360 {
361 const char *hint = SDL_GetHint(SDL_HINT_RENDER_SCALE_QUALITY);
362
363 if (!hint || *hint == '0' || SDL_strcasecmp(hint, "nearest") == 0) {
364 return GL_NEAREST;
365 } else {
366 return GL_LINEAR;
367 }
368 }
369
370 static int
371 GLES2_CreateTexture(SDL_Renderer *renderer, SDL_Texture *texture)
372 {
373 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
374 GLES2_TextureData *tdata;
375 GLenum format;
376 GLenum type;
377 GLenum scaleMode;
378
379 GLES2_ActivateRenderer(renderer);
380
381 /* Determine the corresponding GLES texture format params */
382 switch (texture->format)
383 {
384 case SDL_PIXELFORMAT_ABGR8888:
385 case SDL_PIXELFORMAT_ARGB8888:
386 case SDL_PIXELFORMAT_BGR888:
387 case SDL_PIXELFORMAT_RGB888:
388 format = GL_RGBA;
389 type = GL_UNSIGNED_BYTE;
390 break;
391 default:
392 return SDL_SetError("Texture format not supported");
393 }
394
395 /* Allocate a texture struct */
396 tdata = (GLES2_TextureData *)SDL_calloc(1, sizeof(GLES2_TextureData));
397 if (!tdata) {
398 return SDL_OutOfMemory();
399 }
400 tdata->texture = 0;
401 tdata->texture_type = GL_TEXTURE_2D;
402 tdata->pixel_format = format;
403 tdata->pixel_type = type;
404 scaleMode = GetScaleQuality();
405
406 /* Allocate a blob for image data */
407 if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
408 tdata->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
409 tdata->pixel_data = SDL_calloc(1, tdata->pitch * texture->h);
410 if (!tdata->pixel_data) {
411 SDL_free(tdata);
412 return SDL_OutOfMemory();
413 }
414 }
415
416 /* Allocate the texture */
417 rdata->glGetError();
418 rdata->glGenTextures(1, &tdata->texture);
419 if (rdata->glGetError() != GL_NO_ERROR) {
420 SDL_free(tdata);
421 return SDL_SetError("Texture creation failed in glGenTextures()");
422 }
423 rdata->glActiveTexture(GL_TEXTURE0);
424 rdata->glBindTexture(tdata->texture_type, tdata->texture);
425 rdata->glTexParameteri(tdata->texture_type, GL_TEXTURE_MIN_FILTER, scaleMode);
426 rdata->glTexParameteri(tdata->texture_type, GL_TEXTURE_MAG_FILTER, scaleMode);
427 rdata->glTexParameteri(tdata->texture_type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
428 rdata->glTexParameteri(tdata->texture_type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
429 rdata->glTexImage2D(tdata->texture_type, 0, format, texture->w, texture->h, 0, format, type, NULL);
430 if (rdata->glGetError() != GL_NO_ERROR) {
431 rdata->glDeleteTextures(1, &tdata->texture);
432 SDL_free(tdata);
433 return SDL_SetError("Texture creation failed");
434 }
435 texture->driverdata = tdata;
436
437 if (texture->access == SDL_TEXTUREACCESS_TARGET) {
438 tdata->fbo = GLES2_GetFBO(renderer->driverdata, texture->w, texture->h);
439 } else {
440 tdata->fbo = NULL;
441 }
442
443 return 0;
444 }
445
446 static void
447 GLES2_DestroyTexture(SDL_Renderer *renderer, SDL_Texture *texture)
448 {
449 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
450 GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata;
451
452 GLES2_ActivateRenderer(renderer);
453
454 /* Destroy the texture */
455 if (tdata)
456 {
457 rdata->glDeleteTextures(1, &tdata->texture);
458 SDL_free(tdata->pixel_data);
459 SDL_free(tdata);
460 texture->driverdata = NULL;
461 }
462 }
463
464 static int
465 GLES2_LockTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect,
466 void **pixels, int *pitch)
467 {
468 GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata;
469
470 /* Retrieve the buffer/pitch for the specified region */
471 *pixels = (Uint8 *)tdata->pixel_data +
472 (tdata->pitch * rect->y) +
473 (rect->x * SDL_BYTESPERPIXEL(texture->format));
474 *pitch = tdata->pitch;
475
476 return 0;
477 }
478
479 static void
480 GLES2_UnlockTexture(SDL_Renderer *renderer, SDL_Texture *texture)
481 {
482 GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata;
483 SDL_Rect rect;
484
485 /* We do whole texture updates, at least for now */
486 rect.x = 0;
487 rect.y = 0;
488 rect.w = texture->w;
489 rect.h = texture->h;
490 GLES2_UpdateTexture(renderer, texture, &rect, tdata->pixel_data, tdata->pitch);
491 }
492
493 static int
494 GLES2_UpdateTexture(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect,
495 const void *pixels, int pitch)
496 {
497 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
498 GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata;
499 Uint8 *blob = NULL;
500 Uint8 *src;
501 int srcPitch;
502 int y;
503
504 GLES2_ActivateRenderer(renderer);
505
506 /* Bail out if we're supposed to update an empty rectangle */
507 if (rect->w <= 0 || rect->h <= 0)
508 return 0;
509
510 /* Reformat the texture data into a tightly packed array */
511 srcPitch = rect->w * SDL_BYTESPERPIXEL(texture->format);
512 src = (Uint8 *)pixels;
513 if (pitch != srcPitch) {
514 blob = (Uint8 *)SDL_malloc(srcPitch * rect->h);
515 if (!blob) {
516 return SDL_OutOfMemory();
517 }
518 src = blob;
519 for (y = 0; y < rect->h; ++y)
520 {
521 SDL_memcpy(src, pixels, srcPitch);
522 src += srcPitch;
523 pixels = (Uint8 *)pixels + pitch;
524 }
525 src = blob;
526 }
527
528 /* Create a texture subimage with the supplied data */
529 rdata->glGetError();
530 rdata->glActiveTexture(GL_TEXTURE0);
531 rdata->glBindTexture(tdata->texture_type, tdata->texture);
532 rdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
533 rdata->glTexSubImage2D(tdata->texture_type,
534 0,
535 rect->x,
536 rect->y,
537 rect->w,
538 rect->h,
539 tdata->pixel_format,
540 tdata->pixel_type,
541 src);
542 SDL_free(blob);
543
544 if (rdata->glGetError() != GL_NO_ERROR) {
545 return SDL_SetError("Failed to update texture");
546 }
547 return 0;
548 }
549
550 static int
551 GLES2_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
552 {
553 GLES2_DriverContext *data = (GLES2_DriverContext *) renderer->driverdata;
554 GLES2_TextureData *texturedata = NULL;
555 GLenum status;
556
557 if (texture == NULL) {
558 data->glBindFramebuffer(GL_FRAMEBUFFER, data->window_framebuffer);
559 } else {
560 texturedata = (GLES2_TextureData *) texture->driverdata;
561 data->glBindFramebuffer(GL_FRAMEBUFFER, texturedata->fbo->FBO);
562 /* TODO: check if texture pixel format allows this operation */
563 data->glFramebufferTexture2D(GL_FRAMEBUFFER, GL_COLOR_ATTACHMENT0, texturedata->texture_type, texturedata->texture, 0);
564 /* Check FBO status */
565 status = data->glCheckFramebufferStatus(GL_FRAMEBUFFER);
566 if (status != GL_FRAMEBUFFER_COMPLETE) {
567 return SDL_SetError("glFramebufferTexture2D() failed");
568 }
569 }
570 return 0;
571 }
572
573 /*************************************************************************************************
574 * Shader management functions *
575 *************************************************************************************************/
576
577 static GLES2_ShaderCacheEntry *GLES2_CacheShader(SDL_Renderer *renderer, GLES2_ShaderType type,
578 SDL_BlendMode blendMode);
579 static void GLES2_EvictShader(SDL_Renderer *renderer, GLES2_ShaderCacheEntry *entry);
580 static GLES2_ProgramCacheEntry *GLES2_CacheProgram(SDL_Renderer *renderer,
581 GLES2_ShaderCacheEntry *vertex,
582 GLES2_ShaderCacheEntry *fragment,
583 SDL_BlendMode blendMode);
584 static int GLES2_SelectProgram(SDL_Renderer *renderer, GLES2_ImageSource source,
585 SDL_BlendMode blendMode);
586
587 static GLES2_ProgramCacheEntry *
588 GLES2_CacheProgram(SDL_Renderer *renderer, GLES2_ShaderCacheEntry *vertex,
589 GLES2_ShaderCacheEntry *fragment, SDL_BlendMode blendMode)
590 {
591 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
592 GLES2_ProgramCacheEntry *entry;
593 GLES2_ShaderCacheEntry *shaderEntry;
594 GLint linkSuccessful;
595
596 /* Check if we've already cached this program */
597 entry = rdata->program_cache.head;
598 while (entry)
599 {
600 if (entry->vertex_shader == vertex && entry->fragment_shader == fragment)
601 break;
602 entry = entry->next;
603 }
604 if (entry)
605 {
606 if (rdata->program_cache.head != entry)
607 {
608 if (entry->next)
609 entry->next->prev = entry->prev;
610 if (entry->prev)
611 entry->prev->next = entry->next;
612 entry->prev = NULL;
613 entry->next = rdata->program_cache.head;
614 rdata->program_cache.head->prev = entry;
615 rdata->program_cache.head = entry;
616 }
617 return entry;
618 }
619
620 /* Create a program cache entry */
621 entry = (GLES2_ProgramCacheEntry *)SDL_calloc(1, sizeof(GLES2_ProgramCacheEntry));
622 if (!entry)
623 {
624 SDL_OutOfMemory();
625 return NULL;
626 }
627 entry->vertex_shader = vertex;
628 entry->fragment_shader = fragment;
629 entry->blend_mode = blendMode;
630
631 /* Create the program and link it */
632 rdata->glGetError();
633 entry->id = rdata->glCreateProgram();
634 rdata->glAttachShader(entry->id, vertex->id);
635 rdata->glAttachShader(entry->id, fragment->id);
636 rdata->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_POSITION, "a_position");
637 rdata->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_TEXCOORD, "a_texCoord");
638 rdata->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_ANGLE, "a_angle");
639 rdata->glBindAttribLocation(entry->id, GLES2_ATTRIBUTE_CENTER, "a_center");
640 rdata->glLinkProgram(entry->id);
641 rdata->glGetProgramiv(entry->id, GL_LINK_STATUS, &linkSuccessful);
642 if (rdata->glGetError() != GL_NO_ERROR || !linkSuccessful)
643 {
644 rdata->glDeleteProgram(entry->id);
645 SDL_free(entry);
646 SDL_SetError("Failed to link shader program");
647 return NULL;
648 }
649
650 /* Predetermine locations of uniform variables */
651 entry->uniform_locations[GLES2_UNIFORM_PROJECTION] =
652 rdata->glGetUniformLocation(entry->id, "u_projection");
653 entry->uniform_locations[GLES2_UNIFORM_TEXTURE] =
654 rdata->glGetUniformLocation(entry->id, "u_texture");
655 entry->uniform_locations[GLES2_UNIFORM_MODULATION] =
656 rdata->glGetUniformLocation(entry->id, "u_modulation");
657 entry->uniform_locations[GLES2_UNIFORM_COLOR] =
658 rdata->glGetUniformLocation(entry->id, "u_color");
659 entry->uniform_locations[GLES2_UNIFORM_COLORTABLE] =
660 rdata->glGetUniformLocation(entry->id, "u_colorTable");
661
662 /* Cache the linked program */
663 if (rdata->program_cache.head)
664 {
665 entry->next = rdata->program_cache.head;
666 rdata->program_cache.head->prev = entry;
667 }
668 else
669 {
670 rdata->program_cache.tail = entry;
671 }
672 rdata->program_cache.head = entry;
673 ++rdata->program_cache.count;
674
675 /* Increment the refcount of the shaders we're using */
676 ++vertex->references;
677 ++fragment->references;
678
679 /* Evict the last entry from the cache if we exceed the limit */
680 if (rdata->program_cache.count > GLES2_MAX_CACHED_PROGRAMS)
681 {
682 shaderEntry = rdata->program_cache.tail->vertex_shader;
683 if (--shaderEntry->references <= 0)
684 GLES2_EvictShader(renderer, shaderEntry);
685 shaderEntry = rdata->program_cache.tail->fragment_shader;
686 if (--shaderEntry->references <= 0)
687 GLES2_EvictShader(renderer, shaderEntry);
688 rdata->glDeleteProgram(rdata->program_cache.tail->id);
689 rdata->program_cache.tail = rdata->program_cache.tail->prev;
690 SDL_free(rdata->program_cache.tail->next);
691 rdata->program_cache.tail->next = NULL;
692 --rdata->program_cache.count;
693 }
694 return entry;
695 }
696
697 static GLES2_ShaderCacheEntry *
698 GLES2_CacheShader(SDL_Renderer *renderer, GLES2_ShaderType type, SDL_BlendMode blendMode)
699 {
700 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
701 const GLES2_Shader *shader;
702 const GLES2_ShaderInstance *instance = NULL;
703 GLES2_ShaderCacheEntry *entry = NULL;
704 GLint compileSuccessful = GL_FALSE;
705 int i, j;
706
707 /* Find the corresponding shader */
708 shader = GLES2_GetShader(type, blendMode);
709 if (!shader)
710 {
711 SDL_SetError("No shader matching the requested characteristics was found");
712 return NULL;
713 }
714
715 /* Find a matching shader instance that's supported on this hardware */
716 for (i = 0; i < shader->instance_count && !instance; ++i)
717 {
718 for (j = 0; j < rdata->shader_format_count && !instance; ++j)
719 {
720 if (!shader->instances)
721 continue;
722 if (!shader->instances[i])
723 continue;
724 if (shader->instances[i]->format != rdata->shader_formats[j])
725 continue;
726 instance = shader->instances[i];
727 }
728 }
729 if (!instance)
730 {
731 SDL_SetError("The specified shader cannot be loaded on the current platform");
732 return NULL;
733 }
734
735 /* Check if we've already cached this shader */
736 entry = rdata->shader_cache.head;
737 while (entry)
738 {
739 if (entry->instance == instance)
740 break;
741 entry = entry->next;
742 }
743 if (entry)
744 return entry;
745
746 /* Create a shader cache entry */
747 entry = (GLES2_ShaderCacheEntry *)SDL_calloc(1, sizeof(GLES2_ShaderCacheEntry));
748 if (!entry)
749 {
750 SDL_OutOfMemory();
751 return NULL;
752 }
753 entry->type = type;
754 entry->instance = instance;
755
756 /* Compile or load the selected shader instance */
757 rdata->glGetError();
758 entry->id = rdata->glCreateShader(instance->type);
759 if (instance->format == (GLenum)-1)
760 {
761 rdata->glShaderSource(entry->id, 1, (const char **)&instance->data, NULL);
762 rdata->glCompileShader(entry->id);
763 rdata->glGetShaderiv(entry->id, GL_COMPILE_STATUS, &compileSuccessful);
764 }
765 else
766 {
767 rdata->glShaderBinary(1, &entry->id, instance->format, instance->data, instance->length);
768 compileSuccessful = GL_TRUE;
769 }
770 if (rdata->glGetError() != GL_NO_ERROR || !compileSuccessful)
771 {
772 char *info = NULL;
773 int length = 0;
774
775 rdata->glGetShaderiv(entry->id, GL_INFO_LOG_LENGTH, &length);
776 if (length > 0) {
777 info = SDL_stack_alloc(char, length);
778 if (info) {
779 rdata->glGetShaderInfoLog(entry->id, length, &length, info);
780 }
781 }
782 if (info) {
783 SDL_SetError("Failed to load the shader: %s", info);
784 SDL_stack_free(info);
785 } else {
786 SDL_SetError("Failed to load the shader");
787 }
788 rdata->glDeleteShader(entry->id);
789 SDL_free(entry);
790 return NULL;
791 }
792
793 /* Link the shader entry in at the front of the cache */
794 if (rdata->shader_cache.head)
795 {
796 entry->next = rdata->shader_cache.head;
797 rdata->shader_cache.head->prev = entry;
798 }
799 rdata->shader_cache.head = entry;
800 ++rdata->shader_cache.count;
801 return entry;
802 }
803
804 static void
805 GLES2_EvictShader(SDL_Renderer *renderer, GLES2_ShaderCacheEntry *entry)
806 {
807 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
808
809 /* Unlink the shader from the cache */
810 if (entry->next)
811 entry->next->prev = entry->prev;
812 if (entry->prev)
813 entry->prev->next = entry->next;
814 if (rdata->shader_cache.head == entry)
815 rdata->shader_cache.head = entry->next;
816 --rdata->shader_cache.count;
817
818 /* Deallocate the shader */
819 rdata->glDeleteShader(entry->id);
820 SDL_free(entry);
821 }
822
823 static int
824 GLES2_SelectProgram(SDL_Renderer *renderer, GLES2_ImageSource source, SDL_BlendMode blendMode)
825 {
826 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
827 GLES2_ShaderCacheEntry *vertex = NULL;
828 GLES2_ShaderCacheEntry *fragment = NULL;
829 GLES2_ShaderType vtype, ftype;
830 GLES2_ProgramCacheEntry *program;
831
832 /* Select an appropriate shader pair for the specified modes */
833 vtype = GLES2_SHADER_VERTEX_DEFAULT;
834 switch (source)
835 {
836 case GLES2_IMAGESOURCE_SOLID:
837 ftype = GLES2_SHADER_FRAGMENT_SOLID_SRC;
838 break;
839 case GLES2_IMAGESOURCE_TEXTURE_ABGR:
840 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_ABGR_SRC;
841 break;
842 case GLES2_IMAGESOURCE_TEXTURE_ARGB:
843 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_ARGB_SRC;
844 break;
845 case GLES2_IMAGESOURCE_TEXTURE_RGB:
846 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_RGB_SRC;
847 break;
848 case GLES2_IMAGESOURCE_TEXTURE_BGR:
849 ftype = GLES2_SHADER_FRAGMENT_TEXTURE_BGR_SRC;
850 break;
851 default:
852 goto fault;
853 }
854
855 /* Load the requested shaders */
856 vertex = GLES2_CacheShader(renderer, vtype, blendMode);
857 if (!vertex)
858 goto fault;
859 fragment = GLES2_CacheShader(renderer, ftype, blendMode);
860 if (!fragment)
861 goto fault;
862
863 /* Check if we need to change programs at all */
864 if (rdata->current_program &&
865 rdata->current_program->vertex_shader == vertex &&
866 rdata->current_program->fragment_shader == fragment)
867 return 0;
868
869 /* Generate a matching program */
870 program = GLES2_CacheProgram(renderer, vertex, fragment, blendMode);
871 if (!program)
872 goto fault;
873
874 /* Select that program in OpenGL */
875 rdata->glGetError();
876 rdata->glUseProgram(program->id);
877 if (rdata->glGetError() != GL_NO_ERROR)
878 {
879 SDL_SetError("Failed to select program");
880 goto fault;
881 }
882
883 /* Set the current program */
884 rdata->current_program = program;
885
886 /* Activate an orthographic projection */
887 if (GLES2_SetOrthographicProjection(renderer) < 0)
888 goto fault;
889
890 /* Clean up and return */
891 return 0;
892 fault:
893 if (vertex && vertex->references <= 0)
894 GLES2_EvictShader(renderer, vertex);
895 if (fragment && fragment->references <= 0)
896 GLES2_EvictShader(renderer, fragment);
897 rdata->current_program = NULL;
898 return -1;
899 }
900
901 static int
902 GLES2_SetOrthographicProjection(SDL_Renderer *renderer)
903 {
904 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
905 GLfloat projection[4][4];
906 GLuint locProjection;
907
908 if (!renderer->viewport.w || !renderer->viewport.h) {
909 return 0;
910 }
911
912 /* Prepare an orthographic projection */
913 projection[0][0] = 2.0f / renderer->viewport.w;
914 projection[0][1] = 0.0f;
915 projection[0][2] = 0.0f;
916 projection[0][3] = 0.0f;
917 projection[1][0] = 0.0f;
918 if (renderer->target) {
919 projection[1][1] = 2.0f / renderer->viewport.h;
920 } else {
921 projection[1][1] = -2.0f / renderer->viewport.h;
922 }
923 projection[1][2] = 0.0f;
924 projection[1][3] = 0.0f;
925 projection[2][0] = 0.0f;
926 projection[2][1] = 0.0f;
927 projection[2][2] = 0.0f;
928 projection[2][3] = 0.0f;
929 projection[3][0] = -1.0f;
930 if (renderer->target) {
931 projection[3][1] = -1.0f;
932 } else {
933 projection[3][1] = 1.0f;
934 }
935 projection[3][2] = 0.0f;
936 projection[3][3] = 1.0f;
937
938 /* Set the projection matrix */
939 locProjection = rdata->current_program->uniform_locations[GLES2_UNIFORM_PROJECTION];
940 rdata->glGetError();
941 rdata->glUniformMatrix4fv(locProjection, 1, GL_FALSE, (GLfloat *)projection);
942 if (rdata->glGetError() != GL_NO_ERROR) {
943 return SDL_SetError("Failed to set orthographic projection");
944 }
945 return 0;
946 }
947
948 /*************************************************************************************************
949 * Rendering functions *
950 *************************************************************************************************/
951
952 static const float inv255f = 1.0f / 255.0f;
953
954 static int GLES2_RenderClear(SDL_Renderer *renderer);
955 static int GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_FPoint *points, int count);
956 static int GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_FPoint *points, int count);
957 static int GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_FRect *rects, int count);
958 static int GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect,
959 const SDL_FRect *dstrect);
960 static int GLES2_RenderCopyEx(SDL_Renderer * renderer, SDL_Texture * texture,
961 const SDL_Rect * srcrect, const SDL_FRect * dstrect,
962 const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip);
963 static int GLES2_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
964 Uint32 pixel_format, void * pixels, int pitch);
965 static void GLES2_RenderPresent(SDL_Renderer *renderer);
966
967
968 static int
969 GLES2_RenderClear(SDL_Renderer * renderer)
970 {
971 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
972
973 GLES2_ActivateRenderer(renderer);
974
975 rdata->glClearColor((GLfloat) renderer->r * inv255f,
976 (GLfloat) renderer->g * inv255f,
977 (GLfloat) renderer->b * inv255f,
978 (GLfloat) renderer->a * inv255f);
979
980 rdata->glClear(GL_COLOR_BUFFER_BIT);
981
982 return 0;
983 }
984
985 static void
986 GLES2_SetBlendMode(GLES2_DriverContext *rdata, int blendMode)
987 {
988 if (blendMode != rdata->current.blendMode) {
989 switch (blendMode) {
990 default:
991 case SDL_BLENDMODE_NONE:
992 rdata->glDisable(GL_BLEND);
993 break;
994 case SDL_BLENDMODE_BLEND:
995 rdata->glEnable(GL_BLEND);
996 rdata->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE_MINUS_SRC_ALPHA, GL_ONE, GL_ONE_MINUS_SRC_ALPHA);
997 break;
998 case SDL_BLENDMODE_ADD:
999 rdata->glEnable(GL_BLEND);
1000 rdata->glBlendFuncSeparate(GL_SRC_ALPHA, GL_ONE, GL_ZERO, GL_ONE);
1001 break;
1002 case SDL_BLENDMODE_MOD:
1003 rdata->glEnable(GL_BLEND);
1004 rdata->glBlendFuncSeparate(GL_ZERO, GL_SRC_COLOR, GL_ZERO, GL_ONE);
1005 break;
1006 }
1007 rdata->current.blendMode = blendMode;
1008 }
1009 }
1010
1011 static void
1012 GLES2_SetTexCoords(GLES2_DriverContext * rdata, SDL_bool enabled)
1013 {
1014 if (enabled != rdata->current.tex_coords) {
1015 if (enabled) {
1016 rdata->glEnableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
1017 } else {
1018 rdata->glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
1019 }
1020 rdata->current.tex_coords = enabled;
1021 }
1022 }
1023
1024 static int
1025 GLES2_SetDrawingState(SDL_Renderer * renderer)
1026 {
1027 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
1028 int blendMode = renderer->blendMode;
1029 GLuint locColor;
1030
1031 rdata->glGetError();
1032
1033 GLES2_ActivateRenderer(renderer);
1034
1035 GLES2_SetBlendMode(rdata, blendMode);
1036
1037 GLES2_SetTexCoords(rdata, SDL_FALSE);
1038
1039 /* Activate an appropriate shader and set the projection matrix */
1040 if (GLES2_SelectProgram(renderer, GLES2_IMAGESOURCE_SOLID, blendMode) < 0)
1041 return -1;
1042
1043 /* Select the color to draw with */
1044 locColor = rdata->current_program->uniform_locations[GLES2_UNIFORM_COLOR];
1045 if (renderer->target &&
1046 (renderer->target->format == SDL_PIXELFORMAT_ARGB8888 ||
1047 renderer->target->format == SDL_PIXELFORMAT_RGB888)) {
1048 rdata->glUniform4f(locColor,
1049 renderer->b * inv255f,
1050 renderer->g * inv255f,
1051 renderer->r * inv255f,
1052 renderer->a * inv255f);
1053 } else {
1054 rdata->glUniform4f(locColor,
1055 renderer->r * inv255f,
1056 renderer->g * inv255f,
1057 renderer->b * inv255f,
1058 renderer->a * inv255f);
1059 }
1060 return 0;
1061 }
1062
1063 static int
1064 GLES2_RenderDrawPoints(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
1065 {
1066 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
1067 GLfloat *vertices;
1068 int idx;
1069
1070 if (GLES2_SetDrawingState(renderer) < 0) {
1071 return -1;
1072 }
1073
1074 /* Emit the specified vertices as points */
1075 vertices = SDL_stack_alloc(GLfloat, count * 2);
1076 for (idx = 0; idx < count; ++idx) {
1077 GLfloat x = points[idx].x + 0.5f;
1078 GLfloat y = points[idx].y + 0.5f;
1079
1080 vertices[idx * 2] = x;
1081 vertices[(idx * 2) + 1] = y;
1082 }
1083 rdata->glGetError();
1084 rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
1085 rdata->glDrawArrays(GL_POINTS, 0, count);
1086 SDL_stack_free(vertices);
1087 if (rdata->glGetError() != GL_NO_ERROR) {
1088 return SDL_SetError("Failed to render points");
1089 }
1090 return 0;
1091 }
1092
1093 static int
1094 GLES2_RenderDrawLines(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
1095 {
1096 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
1097 GLfloat *vertices;
1098 int idx;
1099
1100 if (GLES2_SetDrawingState(renderer) < 0) {
1101 return -1;
1102 }
1103
1104 /* Emit a line strip including the specified vertices */
1105 vertices = SDL_stack_alloc(GLfloat, count * 2);
1106 for (idx = 0; idx < count; ++idx) {
1107 GLfloat x = points[idx].x + 0.5f;
1108 GLfloat y = points[idx].y + 0.5f;
1109
1110 vertices[idx * 2] = x;
1111 vertices[(idx * 2) + 1] = y;
1112 }
1113 rdata->glGetError();
1114 rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
1115 rdata->glDrawArrays(GL_LINE_STRIP, 0, count);
1116
1117 /* We need to close the endpoint of the line */
1118 if (count == 2 ||
1119 points[0].x != points[count-1].x || points[0].y != points[count-1].y) {
1120 rdata->glDrawArrays(GL_POINTS, count-1, 1);
1121 }
1122 SDL_stack_free(vertices);
1123 if (rdata->glGetError() != GL_NO_ERROR) {
1124 return SDL_SetError("Failed to render lines");
1125 }
1126 return 0;
1127 }
1128
1129 static int
1130 GLES2_RenderFillRects(SDL_Renderer *renderer, const SDL_FRect *rects, int count)
1131 {
1132 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
1133 GLfloat vertices[8];
1134 int idx;
1135
1136 if (GLES2_SetDrawingState(renderer) < 0) {
1137 return -1;
1138 }
1139
1140 /* Emit a line loop for each rectangle */
1141 rdata->glGetError();
1142 for (idx = 0; idx < count; ++idx) {
1143 const SDL_FRect *rect = &rects[idx];
1144
1145 GLfloat xMin = rect->x;
1146 GLfloat xMax = (rect->x + rect->w);
1147 GLfloat yMin = rect->y;
1148 GLfloat yMax = (rect->y + rect->h);
1149
1150 vertices[0] = xMin;
1151 vertices[1] = yMin;
1152 vertices[2] = xMax;
1153 vertices[3] = yMin;
1154 vertices[4] = xMin;
1155 vertices[5] = yMax;
1156 vertices[6] = xMax;
1157 vertices[7] = yMax;
1158 rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
1159 rdata->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1160 }
1161 if (rdata->glGetError() != GL_NO_ERROR) {
1162 return SDL_SetError("Failed to render filled rects");
1163 }
1164 return 0;
1165 }
1166
1167 static int
1168 GLES2_RenderCopy(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect,
1169 const SDL_FRect *dstrect)
1170 {
1171 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
1172 GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata;
1173 GLES2_ImageSource sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1174 SDL_BlendMode blendMode;
1175 GLfloat vertices[8];
1176 GLfloat texCoords[8];
1177 GLuint locTexture;
1178 GLuint locModulation;
1179
1180 GLES2_ActivateRenderer(renderer);
1181
1182 /* Activate an appropriate shader and set the projection matrix */
1183 blendMode = texture->blendMode;
1184 if (renderer->target) {
1185 /* Check if we need to do color mapping between the source and render target textures */
1186 if (renderer->target->format != texture->format) {
1187 switch (texture->format)
1188 {
1189 case SDL_PIXELFORMAT_ABGR8888:
1190 switch (renderer->target->format)
1191 {
1192 case SDL_PIXELFORMAT_ARGB8888:
1193 case SDL_PIXELFORMAT_RGB888:
1194 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1195 break;
1196 case SDL_PIXELFORMAT_BGR888:
1197 sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1198 break;
1199 }
1200 break;
1201 case SDL_PIXELFORMAT_ARGB8888:
1202 switch (renderer->target->format)
1203 {
1204 case SDL_PIXELFORMAT_ABGR8888:
1205 case SDL_PIXELFORMAT_BGR888:
1206 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1207 break;
1208 case SDL_PIXELFORMAT_RGB888:
1209 sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1210 break;
1211 }
1212 break;
1213 case SDL_PIXELFORMAT_BGR888:
1214 switch (renderer->target->format)
1215 {
1216 case SDL_PIXELFORMAT_ABGR8888:
1217 sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
1218 break;
1219 case SDL_PIXELFORMAT_ARGB8888:
1220 sourceType = GLES2_IMAGESOURCE_TEXTURE_RGB;
1221 break;
1222 case SDL_PIXELFORMAT_RGB888:
1223 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1224 break;
1225 }
1226 break;
1227 case SDL_PIXELFORMAT_RGB888:
1228 switch (renderer->target->format)
1229 {
1230 case SDL_PIXELFORMAT_ABGR8888:
1231 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1232 break;
1233 case SDL_PIXELFORMAT_ARGB8888:
1234 sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
1235 break;
1236 case SDL_PIXELFORMAT_BGR888:
1237 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1238 break;
1239 }
1240 break;
1241 }
1242 }
1243 else sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR; /* Texture formats match, use the non color mapping shader (even if the formats are not ABGR) */
1244 }
1245 else {
1246 switch (texture->format)
1247 {
1248 case SDL_PIXELFORMAT_ABGR8888:
1249 sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1250 break;
1251 case SDL_PIXELFORMAT_ARGB8888:
1252 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1253 break;
1254 case SDL_PIXELFORMAT_BGR888:
1255 sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
1256 break;
1257 case SDL_PIXELFORMAT_RGB888:
1258 sourceType = GLES2_IMAGESOURCE_TEXTURE_RGB;
1259 break;
1260 default:
1261 return -1;
1262 }
1263 }
1264 if (GLES2_SelectProgram(renderer, sourceType, blendMode) < 0)
1265 return -1;
1266
1267 /* Select the target texture */
1268 locTexture = rdata->current_program->uniform_locations[GLES2_UNIFORM_TEXTURE];
1269 rdata->glGetError();
1270 rdata->glActiveTexture(GL_TEXTURE0);
1271 rdata->glBindTexture(tdata->texture_type, tdata->texture);
1272 rdata->glUniform1i(locTexture, 0);
1273
1274 /* Configure color modulation */
1275 locModulation = rdata->current_program->uniform_locations[GLES2_UNIFORM_MODULATION];
1276 if (renderer->target &&
1277 (renderer->target->format == SDL_PIXELFORMAT_ARGB8888 ||
1278 renderer->target->format == SDL_PIXELFORMAT_RGB888)) {
1279 rdata->glUniform4f(locModulation,
1280 texture->b * inv255f,
1281 texture->g * inv255f,
1282 texture->r * inv255f,
1283 texture->a * inv255f);
1284 } else {
1285 rdata->glUniform4f(locModulation,
1286 texture->r * inv255f,
1287 texture->g * inv255f,
1288 texture->b * inv255f,
1289 texture->a * inv255f);
1290 }
1291
1292 /* Configure texture blending */
1293 GLES2_SetBlendMode(rdata, blendMode);
1294
1295 GLES2_SetTexCoords(rdata, SDL_TRUE);
1296
1297 /* Emit the textured quad */
1298 vertices[0] = dstrect->x;
1299 vertices[1] = dstrect->y;
1300 vertices[2] = (dstrect->x + dstrect->w);
1301 vertices[3] = dstrect->y;
1302 vertices[4] = dstrect->x;
1303 vertices[5] = (dstrect->y + dstrect->h);
1304 vertices[6] = (dstrect->x + dstrect->w);
1305 vertices[7] = (dstrect->y + dstrect->h);
1306 rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
1307 texCoords[0] = srcrect->x / (GLfloat)texture->w;
1308 texCoords[1] = srcrect->y / (GLfloat)texture->h;
1309 texCoords[2] = (srcrect->x + srcrect->w) / (GLfloat)texture->w;
1310 texCoords[3] = srcrect->y / (GLfloat)texture->h;
1311 texCoords[4] = srcrect->x / (GLfloat)texture->w;
1312 texCoords[5] = (srcrect->y + srcrect->h) / (GLfloat)texture->h;
1313 texCoords[6] = (srcrect->x + srcrect->w) / (GLfloat)texture->w;
1314 texCoords[7] = (srcrect->y + srcrect->h) / (GLfloat)texture->h;
1315 rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, texCoords);
1316 rdata->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1317 if (rdata->glGetError() != GL_NO_ERROR) {
1318 return SDL_SetError("Failed to render texture");
1319 }
1320 return 0;
1321 }
1322
1323 static int
1324 GLES2_RenderCopyEx(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect,
1325 const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
1326 {
1327 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
1328 GLES2_TextureData *tdata = (GLES2_TextureData *)texture->driverdata;
1329 GLES2_ImageSource sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1330 SDL_BlendMode blendMode;
1331 GLfloat vertices[8];
1332 GLfloat texCoords[8];
1333 GLuint locTexture;
1334 GLuint locModulation;
1335 GLfloat translate[8];
1336 GLfloat fAngle[4];
1337 GLfloat tmp;
1338
1339 GLES2_ActivateRenderer(renderer);
1340
1341 rdata->glEnableVertexAttribArray(GLES2_ATTRIBUTE_CENTER);
1342 rdata->glEnableVertexAttribArray(GLES2_ATTRIBUTE_ANGLE);
1343 fAngle[0] = fAngle[1] = fAngle[2] = fAngle[3] = (GLfloat)(360.0f - angle);
1344 /* Calculate the center of rotation */
1345 translate[0] = translate[2] = translate[4] = translate[6] = (center->x + dstrect->x);
1346 translate[1] = translate[3] = translate[5] = translate[7] = (center->y + dstrect->y);
1347
1348 /* Activate an appropriate shader and set the projection matrix */
1349 blendMode = texture->blendMode;
1350 if (renderer->target) {
1351 /* Check if we need to do color mapping between the source and render target textures */
1352 if (renderer->target->format != texture->format) {
1353 switch (texture->format)
1354 {
1355 case SDL_PIXELFORMAT_ABGR8888:
1356 switch (renderer->target->format)
1357 {
1358 case SDL_PIXELFORMAT_ARGB8888:
1359 case SDL_PIXELFORMAT_RGB888:
1360 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1361 break;
1362 case SDL_PIXELFORMAT_BGR888:
1363 sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1364 break;
1365 }
1366 break;
1367 case SDL_PIXELFORMAT_ARGB8888:
1368 switch (renderer->target->format)
1369 {
1370 case SDL_PIXELFORMAT_ABGR8888:
1371 case SDL_PIXELFORMAT_BGR888:
1372 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1373 break;
1374 case SDL_PIXELFORMAT_RGB888:
1375 sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1376 break;
1377 }
1378 break;
1379 case SDL_PIXELFORMAT_BGR888:
1380 switch (renderer->target->format)
1381 {
1382 case SDL_PIXELFORMAT_ABGR8888:
1383 sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
1384 break;
1385 case SDL_PIXELFORMAT_ARGB8888:
1386 sourceType = GLES2_IMAGESOURCE_TEXTURE_RGB;
1387 break;
1388 case SDL_PIXELFORMAT_RGB888:
1389 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1390 break;
1391 }
1392 break;
1393 case SDL_PIXELFORMAT_RGB888:
1394 switch (renderer->target->format)
1395 {
1396 case SDL_PIXELFORMAT_ABGR8888:
1397 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1398 break;
1399 case SDL_PIXELFORMAT_ARGB8888:
1400 sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
1401 break;
1402 case SDL_PIXELFORMAT_BGR888:
1403 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1404 break;
1405 }
1406 break;
1407 }
1408 }
1409 else sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR; /* Texture formats match, use the non color mapping shader (even if the formats are not ABGR) */
1410 }
1411 else {
1412 switch (texture->format)
1413 {
1414 case SDL_PIXELFORMAT_ABGR8888:
1415 sourceType = GLES2_IMAGESOURCE_TEXTURE_ABGR;
1416 break;
1417 case SDL_PIXELFORMAT_ARGB8888:
1418 sourceType = GLES2_IMAGESOURCE_TEXTURE_ARGB;
1419 break;
1420 case SDL_PIXELFORMAT_BGR888:
1421 sourceType = GLES2_IMAGESOURCE_TEXTURE_BGR;
1422 break;
1423 case SDL_PIXELFORMAT_RGB888:
1424 sourceType = GLES2_IMAGESOURCE_TEXTURE_RGB;
1425 break;
1426 default:
1427 return -1;
1428 }
1429 }
1430 if (GLES2_SelectProgram(renderer, sourceType, blendMode) < 0)
1431 return -1;
1432
1433 /* Select the target texture */
1434 locTexture = rdata->current_program->uniform_locations[GLES2_UNIFORM_TEXTURE];
1435 rdata->glGetError();
1436 rdata->glActiveTexture(GL_TEXTURE0);
1437 rdata->glBindTexture(tdata->texture_type, tdata->texture);
1438 rdata->glUniform1i(locTexture, 0);
1439
1440 /* Configure color modulation */
1441 locModulation = rdata->current_program->uniform_locations[GLES2_UNIFORM_MODULATION];
1442 if (renderer->target &&
1443 (renderer->target->format == SDL_PIXELFORMAT_ARGB8888 ||
1444 renderer->target->format == SDL_PIXELFORMAT_RGB888)) {
1445 rdata->glUniform4f(locModulation,
1446 texture->b * inv255f,
1447 texture->g * inv255f,
1448 texture->r * inv255f,
1449 texture->a * inv255f);
1450 } else {
1451 rdata->glUniform4f(locModulation,
1452 texture->r * inv255f,
1453 texture->g * inv255f,
1454 texture->b * inv255f,
1455 texture->a * inv255f);
1456 }
1457
1458 /* Configure texture blending */
1459 GLES2_SetBlendMode(rdata, blendMode);
1460
1461 GLES2_SetTexCoords(rdata, SDL_TRUE);
1462
1463 /* Emit the textured quad */
1464 vertices[0] = dstrect->x;
1465 vertices[1] = dstrect->y;
1466 vertices[2] = (dstrect->x + dstrect->w);
1467 vertices[3] = dstrect->y;
1468 vertices[4] = dstrect->x;
1469 vertices[5] = (dstrect->y + dstrect->h);
1470 vertices[6] = (dstrect->x + dstrect->w);
1471 vertices[7] = (dstrect->y + dstrect->h);
1472 if (flip & SDL_FLIP_HORIZONTAL) {
1473 tmp = vertices[0];
1474 vertices[0] = vertices[4] = vertices[2];
1475 vertices[2] = vertices[6] = tmp;
1476 }
1477 if (flip & SDL_FLIP_VERTICAL) {
1478 tmp = vertices[1];
1479 vertices[1] = vertices[3] = vertices[5];
1480 vertices[5] = vertices[7] = tmp;
1481 }
1482
1483 rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_ANGLE, 1, GL_FLOAT, GL_FALSE, 0, &fAngle);
1484 rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_CENTER, 2, GL_FLOAT, GL_FALSE, 0, translate);
1485 rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_POSITION, 2, GL_FLOAT, GL_FALSE, 0, vertices);
1486
1487 texCoords[0] = srcrect->x / (GLfloat)texture->w;
1488 texCoords[1] = srcrect->y / (GLfloat)texture->h;
1489 texCoords[2] = (srcrect->x + srcrect->w) / (GLfloat)texture->w;
1490 texCoords[3] = srcrect->y / (GLfloat)texture->h;
1491 texCoords[4] = srcrect->x / (GLfloat)texture->w;
1492 texCoords[5] = (srcrect->y + srcrect->h) / (GLfloat)texture->h;
1493 texCoords[6] = (srcrect->x + srcrect->w) / (GLfloat)texture->w;
1494 texCoords[7] = (srcrect->y + srcrect->h) / (GLfloat)texture->h;
1495 rdata->glVertexAttribPointer(GLES2_ATTRIBUTE_TEXCOORD, 2, GL_FLOAT, GL_FALSE, 0, texCoords);
1496 rdata->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
1497 rdata->glDisableVertexAttribArray(GLES2_ATTRIBUTE_CENTER);
1498 rdata->glDisableVertexAttribArray(GLES2_ATTRIBUTE_ANGLE);
1499 if (rdata->glGetError() != GL_NO_ERROR) {
1500 return SDL_SetError("Failed to render texture");
1501 }
1502 return 0;
1503 }
1504
1505 static int
1506 GLES2_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
1507 Uint32 pixel_format, void * pixels, int pitch)
1508 {
1509 GLES2_DriverContext *rdata = (GLES2_DriverContext *)renderer->driverdata;
1510 Uint32 temp_format = SDL_PIXELFORMAT_ABGR8888;
1511 void *temp_pixels;
1512 int temp_pitch;
1513 Uint8 *src, *dst, *tmp;
1514 int w, h, length, rows;
1515 int status;
1516
1517 GLES2_ActivateRenderer(renderer);
1518
1519 temp_pitch = rect->w * SDL_BYTESPERPIXEL(temp_format);
1520 temp_pixels = SDL_malloc(rect->h * temp_pitch);
1521 if (!temp_pixels) {
1522 return SDL_OutOfMemory();
1523 }
1524
1525 SDL_GetRendererOutputSize(renderer, &w, &h);
1526
1527 rdata->glPixelStorei(GL_PACK_ALIGNMENT, 1);
1528
1529 rdata->glReadPixels(rect->x, (h-rect->y)-rect->h, rect->w, rect->h,
1530 GL_RGBA, GL_UNSIGNED_BYTE, temp_pixels);
1531
1532 /* Flip the rows to be top-down */
1533 length = rect->w * SDL_BYTESPERPIXEL(temp_format);
1534 src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch;
1535 dst = (Uint8*)temp_pixels;
1536 tmp = SDL_stack_alloc(Uint8, length);
1537 rows = rect->h / 2;
1538 while (rows--) {
1539 SDL_memcpy(tmp, dst, length);
1540 SDL_memcpy(dst, src, length);
1541 SDL_memcpy(src, tmp, length);
1542 dst += temp_pitch;
1543 src -= temp_pitch;
1544 }
1545 SDL_stack_free(tmp);
1546
1547 status = SDL_ConvertPixels(rect->w, rect->h,
1548 temp_format, temp_pixels, temp_pitch,
1549 pixel_format, pixels, pitch);
1550 SDL_free(temp_pixels);
1551
1552 return status;
1553 }
1554
1555 static void
1556 GLES2_RenderPresent(SDL_Renderer *renderer)
1557 {
1558 GLES2_ActivateRenderer(renderer);
1559
1560 /* Tell the video driver to swap buffers */
1561 SDL_GL_SwapWindow(renderer->window);
1562 }
1563
1564
1565 /*************************************************************************************************
1566 * Bind/unbinding of textures
1567 *************************************************************************************************/
1568 static int GLES2_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh);
1569 static int GLES2_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture);
1570
1571 static int GLES2_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh) {
1572 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
1573 GLES2_TextureData *texturedata = (GLES2_TextureData *)texture->driverdata;
1574 GLES2_ActivateRenderer(renderer);
1575
1576 data->glBindTexture(texturedata->texture_type, texturedata->texture);
1577
1578 if(texw) *texw = 1.0;
1579 if(texh) *texh = 1.0;
1580
1581 return 0;
1582 }
1583
1584 static int GLES2_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture) {
1585 GLES2_DriverContext *data = (GLES2_DriverContext *)renderer->driverdata;
1586 GLES2_TextureData *texturedata = (GLES2_TextureData *)texture->driverdata;
1587 GLES2_ActivateRenderer(renderer);
1588
1589 data->glBindTexture(texturedata->texture_type, 0);
1590
1591 return 0;
1592 }
1593
1594
1595 /*************************************************************************************************
1596 * Renderer instantiation *
1597 *************************************************************************************************/
1598
1599 #define GL_NVIDIA_PLATFORM_BINARY_NV 0x890B
1600
1601 static void
1602 GLES2_ResetState(SDL_Renderer *renderer)
1603 {
1604 GLES2_DriverContext *rdata = (GLES2_DriverContext *) renderer->driverdata;
1605
1606 if (SDL_CurrentContext == rdata->context) {
1607 GLES2_UpdateViewport(renderer);
1608 } else {
1609 GLES2_ActivateRenderer(renderer);
1610 }
1611
1612 rdata->current.blendMode = -1;
1613 rdata->current.tex_coords = SDL_FALSE;
1614
1615 rdata->glEnableVertexAttribArray(GLES2_ATTRIBUTE_POSITION);
1616 rdata->glDisableVertexAttribArray(GLES2_ATTRIBUTE_TEXCOORD);
1617 }
1618
1619 static SDL_Renderer *
1620 GLES2_CreateRenderer(SDL_Window *window, Uint32 flags)
1621 {
1622 SDL_Renderer *renderer;
1623 GLES2_DriverContext *rdata;
1624 GLint nFormats;
1625 #ifndef ZUNE_HD
1626 GLboolean hasCompiler;
1627 #endif
1628 Uint32 windowFlags;
1629 GLint window_framebuffer;
1630
1631 SDL_GL_SetAttribute(SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES);
1632 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, 2);
1633 SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, 0);
1634
1635 windowFlags = SDL_GetWindowFlags(window);
1636 if (!(windowFlags & SDL_WINDOW_OPENGL)) {
1637 if (SDL_RecreateWindow(window, windowFlags | SDL_WINDOW_OPENGL) < 0) {
1638 /* Uh oh, better try to put it back... */
1639 SDL_RecreateWindow(window, windowFlags);
1640 return NULL;
1641 }
1642 }
1643
1644 /* Create the renderer struct */
1645 renderer = (SDL_Renderer *)SDL_calloc(1, sizeof(SDL_Renderer));
1646 if (!renderer) {
1647 SDL_OutOfMemory();
1648 return NULL;
1649 }
1650
1651 rdata = (GLES2_DriverContext *)SDL_calloc(1, sizeof(GLES2_DriverContext));
1652 if (!rdata) {
1653 GLES2_DestroyRenderer(renderer);
1654 SDL_OutOfMemory();
1655 return NULL;
1656 }
1657 renderer->info = GLES2_RenderDriver.info;
1658 renderer->info.flags = SDL_RENDERER_ACCELERATED | SDL_RENDERER_TARGETTEXTURE;
1659 renderer->driverdata = rdata;
1660 renderer->window = window;
1661
1662 /* Create an OpenGL ES 2.0 context */
1663 rdata->context = SDL_GL_CreateContext(window);
1664 if (!rdata->context)
1665 {
1666 GLES2_DestroyRenderer(renderer);
1667 return NULL;
1668 }
1669 if (SDL_GL_MakeCurrent(window, rdata->context) < 0) {
1670 GLES2_DestroyRenderer(renderer);
1671 return NULL;
1672 }
1673
1674 if (GLES2_LoadFunctions(rdata) < 0) {
1675 GLES2_DestroyRenderer(renderer);
1676 return NULL;
1677 }
1678
1679 if (flags & SDL_RENDERER_PRESENTVSYNC) {
1680 SDL_GL_SetSwapInterval(1);
1681 } else {
1682 SDL_GL_SetSwapInterval(0);
1683 }
1684 if (SDL_GL_GetSwapInterval() > 0) {
1685 renderer->info.flags |= SDL_RENDERER_PRESENTVSYNC;
1686 }
1687
1688 /* Determine supported shader formats */
1689 /* HACK: glGetInteger is broken on the Zune HD's compositor, so we just hardcode this */
1690 rdata->glGetError();
1691 #ifdef ZUNE_HD
1692 nFormats = 1;
1693 #else /* !ZUNE_HD */
1694 rdata->glGetIntegerv(GL_NUM_SHADER_BINARY_FORMATS, &nFormats);
1695 rdata->glGetBooleanv(GL_SHADER_COMPILER, &hasCompiler);
1696 if (hasCompiler)
1697 ++nFormats;
1698 #endif /* ZUNE_HD */
1699 rdata->shader_formats = (GLenum *)SDL_calloc(nFormats, sizeof(GLenum));
1700 if (!rdata->shader_formats)
1701 {
1702 GLES2_DestroyRenderer(renderer);
1703 SDL_OutOfMemory();
1704 return NULL;
1705 }
1706 rdata->shader_format_count = nFormats;
1707 #ifdef ZUNE_HD
1708 rdata->shader_formats[0] = GL_NVIDIA_PLATFORM_BINARY_NV;
1709 #else /* !ZUNE_HD */
1710 rdata->glGetIntegerv(GL_SHADER_BINARY_FORMATS, (GLint *)rdata->shader_formats);
1711 if (rdata->glGetError() != GL_NO_ERROR)
1712 {
1713 GLES2_DestroyRenderer(renderer);
1714 SDL_SetError("Failed to query supported shader formats");
1715 return NULL;
1716 }
1717 if (hasCompiler)
1718 rdata->shader_formats[nFormats - 1] = (GLenum)-1;
1719 #endif /* ZUNE_HD */
1720
1721 rdata->framebuffers = NULL;
1722 rdata->glGetIntegerv(GL_FRAMEBUFFER_BINDING, &window_framebuffer);
1723 rdata->window_framebuffer = (GLuint)window_framebuffer;
1724
1725 /* Populate the function pointers for the module */
1726 renderer->WindowEvent = &GLES2_WindowEvent;
1727 renderer->CreateTexture = &GLES2_CreateTexture;
1728 renderer->UpdateTexture = &GLES2_UpdateTexture;
1729 renderer->LockTexture = &GLES2_LockTexture;
1730 renderer->UnlockTexture = &GLES2_UnlockTexture;
1731 renderer->SetRenderTarget = &GLES2_SetRenderTarget;
1732 renderer->UpdateViewport = &GLES2_UpdateViewport;
1733 renderer->UpdateClipRect = &GLES2_UpdateClipRect;
1734 renderer->RenderClear = &GLES2_RenderClear;
1735 renderer->RenderDrawPoints = &GLES2_RenderDrawPoints;
1736 renderer->RenderDrawLines = &GLES2_RenderDrawLines;
1737 renderer->RenderFillRects = &GLES2_RenderFillRects;
1738 renderer->RenderCopy = &GLES2_RenderCopy;
1739 renderer->RenderCopyEx = &GLES2_RenderCopyEx;
1740 renderer->RenderReadPixels = &GLES2_RenderReadPixels;
1741 renderer->RenderPresent = &GLES2_RenderPresent;
1742 renderer->DestroyTexture = &GLES2_DestroyTexture;
1743 renderer->DestroyRenderer = &GLES2_DestroyRenderer;
1744 renderer->GL_BindTexture = &GLES2_BindTexture;
1745 renderer->GL_UnbindTexture = &GLES2_UnbindTexture;
1746
1747 GLES2_ResetState(renderer);
1748
1749 return renderer;
1750 }
1751
1752 #endif /* SDL_VIDEO_RENDER_OGL_ES2 && !SDL_RENDER_DISABLED */
1753
1754 /* vi: set ts=4 sw=4 expandtab: */
GL_TRUE
#define GL_TRUE
Definition: gl2.h:51
SDL_Renderer::UpdateClipRect
int(* UpdateClipRect)(SDL_Renderer *renderer)
Definition: SDL_sysrender.h:102
SDL_Texture::blendMode
SDL_BlendMode blendMode
Definition: SDL_sysrender.h:57
SDL_FRect::w
float w
Definition: SDL_sysrender.h:44
SDL_FLIP_HORIZONTAL
Definition: SDL_render.h:114
GL_SRC_COLOR
#define GL_SRC_COLOR
Definition: gl2.h:75
GL_LINK_STATUS
#define GL_LINK_STATUS
Definition: gl2.h:270
GL_LINE_STRIP
#define GL_LINE_STRIP
Definition: gl2.h:57
GL_FALSE
#define GL_FALSE
Definition: gl2.h:50
GL_BLEND
#define GL_BLEND
Definition: gl2.h:147
GL_ZERO
#define GL_ZERO
Definition: gl2.h:73
h
GLfloat GLfloat GLfloat GLfloat h
Definition: glew.h:7294
type
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum type
Definition: gl2ext.h:845
SDL_calloc
DECLSPEC void *SDLCALL SDL_calloc(size_t nmemb, size_t size)
GL_CLAMP_TO_EDGE
#define GL_CLAMP_TO_EDGE
Definition: gl2.h:375
SDL_Renderer::WindowEvent
void(* WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event)
Definition: SDL_sysrender.h:80
SDL_PIXELFORMAT_ABGR8888
Definition: SDL_pixels.h:230
SDL_RENDERER_ACCELERATED
Definition: SDL_render.h:67
GLenum
unsigned int GLenum
Definition: gl2.h:23
SDL_GL_CONTEXT_MINOR_VERSION
Definition: SDL_video.h:186
SDL_BlendMode
SDL_BlendMode
The blend mode used in SDL_RenderCopy() and drawing operations.
Definition: SDL_blendmode.h:40
SDL_WINDOWEVENT_MINIMIZED
Definition: SDL_video.h:146
SDL_Renderer::info
SDL_RendererInfo info
Definition: SDL_sysrender.h:126
SDL_GL_CONTEXT_MAJOR_VERSION
Definition: SDL_video.h:185
SDL_GL_GetSwapInterval
DECLSPEC int SDLCALL SDL_GL_GetSwapInterval(void)
Get the swap interval for the current OpenGL context.
Definition: SDL_video.c:2857
SDL_RENDERER_TARGETTEXTURE
Definition: SDL_render.h:71
SDL_RendererInfo::flags
Uint32 flags
Definition: SDL_render.h:81
GL_SRC_ALPHA
#define GL_SRC_ALPHA
Definition: gl2.h:77
SDL_ConvertPixels
DECLSPEC int SDLCALL SDL_ConvertPixels(int width, int height, Uint32 src_format, const void *src, int src_pitch, Uint32 dst_format, void *dst, int dst_pitch)
Copy a block of pixels of one format to another format.
Definition: SDL_surface.c:984
GL_NUM_SHADER_BINARY_FORMATS
#define GL_NUM_SHADER_BINARY_FORMATS
Definition: gl2.h:416
NULL
#define NULL
Definition: ftobjs.h:61
SDL_Renderer::RenderClear
int(* RenderClear)(SDL_Renderer *renderer)
Definition: SDL_sysrender.h:103
f
GLclampf f
Definition: glew.h:3390
GL_COLOR_ATTACHMENT0
#define GL_COLOR_ATTACHMENT0
Definition: gl2.h:452
SDL_stack_free
#define SDL_stack_free(data)
Definition: SDL_stdinc.h:227
GLboolean
unsigned char GLboolean
Definition: gl2.h:24
SDL_GL_CreateContext
DECLSPEC SDL_GLContext SDLCALL SDL_GL_CreateContext(SDL_Window *window)
Create an OpenGL context for use with an OpenGL window, and make it current.
Definition: SDL_video.c:2758
SDL_Texture::g
Uint8 g
Definition: SDL_sysrender.h:58
SDL_Renderer::RenderDrawPoints
int(* RenderDrawPoints)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
Definition: SDL_sysrender.h:104
angle
GLdouble angle
Definition: glew.h:8396
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:116
enabled
GLenum GLsizei const GLuint GLboolean enabled
Definition: glew.h:2538
SDL_Renderer::SetRenderTarget
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:100
SDL_Renderer::CreateTexture
int(* CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:82
GL_TEXTURE_2D
#define GL_TEXTURE_2D
Definition: gl2.h:145
SDL_HINT_RENDER_SCALE_QUALITY
#define SDL_HINT_RENDER_SCALE_QUALITY
A variable controlling the scaling quality.
Definition: SDL_hints.h:118
SDL_RENDERER_PRESENTVSYNC
Definition: SDL_render.h:69
SDL_Renderer::driverdata
void * driverdata
Definition: SDL_sysrender.h:157
SDL_TRUE
Definition: SDL_stdinc.h:119
x
EGLSurface EGLint x
Definition: eglext.h:293
GL_FRAMEBUFFER_COMPLETE
#define GL_FRAMEBUFFER_COMPLETE
Definition: gl2.h:458
SDL_free
DECLSPEC void SDLCALL SDL_free(void *mem)
SDL_Renderer
Definition: SDL_sysrender.h:76
j
int32_t j
Definition: e_log.c:102
SDL_FLIP_VERTICAL
Definition: SDL_render.h:115
GL_INFO_LOG_LENGTH
#define GL_INFO_LOG_LENGTH
Definition: gl2.h:410
SDL_GLContext
void * SDL_GLContext
An opaque handle to an OpenGL context.
Definition: SDL_video.h:161
SDL_BYTESPERPIXEL
#define SDL_BYTESPERPIXEL(X)
Definition: SDL_pixels.h:123
SDL_Renderer::UnlockTexture
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:99
GL_TEXTURE_MAG_FILTER
#define GL_TEXTURE_MAG_FILTER
Definition: gl2.h:319
SDL_GetRendererOutputSize
DECLSPEC int SDLCALL SDL_GetRendererOutputSize(SDL_Renderer *renderer, int *w, int *h)
Get the output size of a rendering context.
Definition: SDL_render.c:338
SDL_Renderer::clip_rect
SDL_Rect clip_rect
Definition: SDL_sysrender.h:143
switch
switch(yytype)
Definition: glslang_tab.cpp:1918
if
if(!yyg->yy_init)
Definition: glslang_lex.cpp:1037
SDL_FALSE
Definition: SDL_stdinc.h:118
id
GLuint id
Definition: gl2ext.h:1142
GL_SHADER_COMPILER
#define GL_SHADER_COMPILER
Definition: gl2.h:412
SDL_WINDOWEVENT_SIZE_CHANGED
Definition: SDL_video.h:145
yMin
bbox yMin
Definition: ftbbox.c:603
GL_TRIANGLE_STRIP
#define GL_TRIANGLE_STRIP
Definition: gl2.h:59
SDL_RectEmpty
SDL_FORCE_INLINE SDL_bool SDL_RectEmpty(const SDL_Rect *r)
Returns true if the rectangle has no area.
Definition: SDL_rect.h:72
SDL_FRect::y
float y
Definition: SDL_sysrender.h:43
SDL_Renderer::window
SDL_Window * window
Definition: SDL_sysrender.h:129
SDL_RenderDriver::info
SDL_RendererInfo info
Definition: SDL_sysrender.h:166
SDL_config.h
SDL_GL_CONTEXT_PROFILE_MASK
Definition: SDL_video.h:189
SDL_Texture::a
Uint8 a
Definition: SDL_sysrender.h:58
SDL_WINDOWEVENT_HIDDEN
Definition: SDL_video.h:139
SDL_Texture
Definition: SDL_sysrender.h:49
SDL_BLENDMODE_NONE
Definition: SDL_blendmode.h:42
Uint32
uint32_t Uint32
An unsigned 32-bit integer type.
Definition: SDL_stdinc.h:145
framebuffers
const GLuint * framebuffers
Definition: glew.h:4126
SDL_GL_MakeCurrent
DECLSPEC int SDLCALL SDL_GL_MakeCurrent(SDL_Window *window, SDL_GLContext context)
Set up an OpenGL context for rendering into an OpenGL window.
Definition: SDL_video.c:2781
SDL_Renderer::LockTexture
int(* LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
Definition: SDL_sysrender.h:97
SDL_GL_SetAttribute
DECLSPEC int SDLCALL SDL_GL_SetAttribute(SDL_GLattr attr, int value)
Set an OpenGL window attribute before window creation.
Definition: SDL_video.c:2469
GL_COLOR_BUFFER_BIT
#define GL_COLOR_BUFFER_BIT
Definition: gl2.h:47
SDL_gles2funcs.h
GL_NO_ERROR
#define GL_NO_ERROR
Definition: gl2.h:157
result
GLuint64EXT * result
Definition: glew.h:12708
shader
GLuint shader
Definition: glew.h:1799
GL_TEXTURE_MIN_FILTER
#define GL_TEXTURE_MIN_FILTER
Definition: gl2.h:320
SDL_GL_SetSwapInterval
DECLSPEC int SDLCALL SDL_GL_SetSwapInterval(int interval)
Set the swap interval for the current OpenGL context.
Definition: SDL_video.c:2843
SDL_Renderer::UpdateTexture
int(* UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
Definition: SDL_sysrender.h:89
dst
GLenum GLenum dst
Definition: glew.h:2396
idx
FT_UInt idx
Definition: cffcmap.c:125
SDL_Renderer::target
SDL_Texture * target
Definition: SDL_sysrender.h:152
length
GLsizei GLsizei * length
Definition: gl2ext.h:792
SDL_Renderer::g
Uint8 g
Definition: SDL_sysrender.h:154
GL_ONE
#define GL_ONE
Definition: gl2.h:74
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: gl2ext.h:848
SDL_opengles2.h
SDL_RecreateWindow
int SDL_RecreateWindow(SDL_Window *window, Uint32 flags)
Definition: SDL_video.c:1317
GetScaleQuality
static int GetScaleQuality(void)
Definition: SDL_render_sw.c:562
SDL_Renderer::blendMode
SDL_BlendMode blendMode
Definition: SDL_sysrender.h:155
GL_POINTS
#define GL_POINTS
Definition: gl2.h:54
count
GLint GLsizei count
Definition: gl2ext.h:1011
SDL_GL_DeleteContext
DECLSPEC void SDLCALL SDL_GL_DeleteContext(SDL_GLContext context)
Delete an OpenGL context.
Definition: SDL_video.c:2889
SDL_Renderer::RenderDrawLines
int(* RenderDrawLines)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
Definition: SDL_sysrender.h:106
GL_PACK_ALIGNMENT
#define GL_PACK_ALIGNMENT
Definition: gl2.h:198
SDL_Renderer::b
Uint8 b
Definition: SDL_sysrender.h:154
SDL_TEXTUREACCESS_STREAMING
Definition: SDL_render.h:94
SDL_hints.h
SDL_Texture::w
int w
Definition: SDL_sysrender.h:54
format
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum format
Definition: gl2ext.h:845
SDL_SetError
DECLSPEC int SDLCALL SDL_SetError(const char *fmt,...)
Definition: SDL_error.c:53
SDL_malloc
DECLSPEC void *SDLCALL SDL_malloc(size_t size)
SDL_GetWindowFlags
DECLSPEC Uint32 SDLCALL SDL_GetWindowFlags(SDL_Window *window)
Get the window flags.
Definition: SDL_video.c:1409
SDL_Rect::x
int x
Definition: SDL_rect.h:65
SDL_WindowEvent::event
Uint8 event
Definition: SDL_events.h:165
SDL_GetHint
DECLSPEC const char *SDLCALL SDL_GetHint(const char *name)
Get a hint.
Definition: SDL_hints.c:104
SDL_Renderer::DestroyTexture
void(* DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:118
program
GLbitfield GLuint program
Definition: gl2ext.h:1203
SDL_Rect::w
int w
Definition: SDL_rect.h:66
SDL_Renderer::RenderCopy
int(* RenderCopy)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
Definition: SDL_sysrender.h:110
GLfloat
khronos_float_t GLfloat
Definition: gl2.h:33
SDL_FRect::h
float h
Definition: SDL_sysrender.h:45
SDL_RendererFlip
SDL_RendererFlip
Flip constants for SDL_RenderCopyEx.
Definition: SDL_render.h:111
GL_LINEAR
#define GL_LINEAR
Definition: gl2.h:308
GL_COMPILE_STATUS
#define GL_COMPILE_STATUS
Definition: gl2.h:409
SDL_WindowEvent
Window state change event data (event.window.*)
Definition: SDL_events.h:160
SDL_BLENDMODE_MOD
Definition: SDL_blendmode.h:50
GL_RGBA
#define GL_RGBA
Definition: gl2.h:248
y
EGLSurface EGLint EGLint y
Definition: eglext.h:293
SDL_PIXELFORMAT_ARGB8888
Definition: SDL_pixels.h:224
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
tail
SDL_EventEntry * tail
Definition: SDL_events.c:79
SDL_Texture::b
Uint8 b
Definition: SDL_sysrender.h:58
texture
GLenum GLenum GLuint texture
Definition: gl2ext.h:850
pixels
GLint GLenum GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: gl2ext.h:845
SDL_Renderer::GL_BindTexture
int(* GL_BindTexture)(SDL_Renderer *renderer, SDL_Texture *texture, float *texw, float *texh)
Definition: SDL_sysrender.h:122
GLint
int GLint
Definition: gl2.h:28
SDL_RenderDriver
Definition: SDL_sysrender.h:161
GLuint
unsigned int GLuint
Definition: gl2.h:32
SDL_Renderer::RenderReadPixels
int(* RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect, Uint32 format, void *pixels, int pitch)
Definition: SDL_sysrender.h:115
SDL_memcpy
DECLSPEC void *SDLCALL SDL_memcpy(void *dst, const void *src, size_t len)
Definition: SDL_string.c:293
SDL_WINDOWEVENT_SHOWN
Definition: SDL_video.h:138
flags
GLenum GLsizei GLsizei GLsizei GLsizei GLbitfield flags
Definition: glew.h:2767
GL_FRAMEBUFFER_BINDING
#define GL_FRAMEBUFFER_BINDING
Definition: gl2.h:464
SDL_Renderer::GL_UnbindTexture
int(* GL_UnbindTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:123
SDL_Renderer::viewport
SDL_Rect viewport
Definition: SDL_sysrender.h:139
GL_TEXTURE_WRAP_T
#define GL_TEXTURE_WRAP_T
Definition: gl2.h:322
SDL_Renderer::RenderFillRects
int(* RenderFillRects)(SDL_Renderer *renderer, const SDL_FRect *rects, int count)
Definition: SDL_sysrender.h:108
SDL_Rect::h
int h
Definition: SDL_rect.h:66
Uint8
uint8_t Uint8
An unsigned 8-bit integer type.
Definition: SDL_stdinc.h:129
SDL_Window
Definition: SDL_sysvideo.h:71
GL_UNSIGNED_BYTE
#define GL_UNSIGNED_BYTE
Definition: gl2.h:236
GL_TEXTURE_WRAP_S
#define GL_TEXTURE_WRAP_S
Definition: gl2.h:321
GL_ONE_MINUS_SRC_ALPHA
#define GL_ONE_MINUS_SRC_ALPHA
Definition: gl2.h:78
SDL_TEXTUREACCESS_TARGET
Definition: SDL_render.h:95
SDL_Texture::format
Uint32 format
Definition: SDL_sysrender.h:52
w
GLint GLint GLint GLint GLint w
Definition: gl2ext.h:1215
SDL_stack_alloc
#define SDL_stack_alloc(type, count)
Definition: SDL_stdinc.h:226
GL_FRAMEBUFFER
#define GL_FRAMEBUFFER
Definition: gl2.h:427
SDL_PIXELFORMAT_RGB888
Definition: SDL_pixels.h:212
GL_UNPACK_ALIGNMENT
#define GL_UNPACK_ALIGNMENT
Definition: gl2.h:197
SDL_PIXELFORMAT_BGR888
Definition: SDL_pixels.h:218
SDL_Texture::driverdata
void * driverdata
Definition: SDL_sysrender.h:69
SDL_WINDOW_OPENGL
Definition: SDL_video.h:99
SDL_Renderer::UpdateViewport
int(* UpdateViewport)(SDL_Renderer *renderer)
Definition: SDL_sysrender.h:101
points
GLuint GLdouble GLdouble GLint GLint const GLdouble * points
Definition: glew.h:3337
GL_FLOAT
#define GL_FLOAT
Definition: gl2.h:241
src
GLenum src
Definition: glew.h:2396
xMin
bbox xMin
Definition: ftbbox.c:602
context
TParseContext * context
Definition: glslang_tab.cpp:1907
SDL_Renderer::r
Uint8 r
Definition: SDL_sysrender.h:154
i
int i
Definition: pngrutil.c:1377
SDL_FRect::x
float x
Definition: SDL_sysrender.h:42
SDL_BLENDMODE_ADD
Definition: SDL_blendmode.h:47
SDL_Renderer::RenderCopyEx
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)
Definition: SDL_sysrender.h:112
while
while(1)
Definition: glslang_lex.cpp:1063
head
SDL_EventEntry * head
Definition: SDL_events.c:78
SDL_Renderer::RenderPresent
void(* RenderPresent)(SDL_Renderer *renderer)
Definition: SDL_sysrender.h:117
SDL_Renderer::a
Uint8 a
Definition: SDL_sysrender.h:154
GL_SHADER_BINARY_FORMATS
#define GL_SHADER_BINARY_FORMATS
Definition: gl2.h:415
SDL_Renderer::DestroyRenderer
void(* DestroyRenderer)(SDL_Renderer *renderer)
Definition: SDL_sysrender.h:120
vertices
GLfloat vertices[12]
Definition: modern.h:22
SDL_GL_CONTEXT_PROFILE_ES
Definition: SDL_video.h:197
SDL_BLENDMODE_BLEND
Definition: SDL_blendmode.h:44
GL_SCISSOR_TEST
#define GL_SCISSOR_TEST
Definition: gl2.h:151
source
GLsizei GLsizei GLchar * source
Definition: gl2ext.h:994
SDL_Texture::access
int access
Definition: SDL_sysrender.h:53
SDL_Rect::y
int y
Definition: SDL_rect.h:65
SDL_strcasecmp
DECLSPEC int SDLCALL SDL_strcasecmp(const char *str1, const char *str2)
Definition: SDL_string.c:946
SDL_FPoint::x
float x
Definition: SDL_sysrender.h:36
GL_TEXTURE0
#define GL_TEXTURE0
Definition: gl2.h:339
SDL_FRect
Definition: SDL_sysrender.h:40
SDL_FPoint
Definition: SDL_sysrender.h:34
SDL_Rect
A rectangle, with the origin at the upper left.
Definition: SDL_rect.h:63
SDL_shaders_gles2.h
SDL_GL_SwapWindow
DECLSPEC void SDLCALL SDL_GL_SwapWindow(SDL_Window *window)
Swap the OpenGL buffers for a window, if double-buffering is supported.
Definition: SDL_video.c:2871
GL_NEAREST
#define GL_NEAREST
Definition: gl2.h:307
event
cl_event event
Definition: glew.h:3556
SDL_Texture::h
int h
Definition: SDL_sysrender.h:55
SDL_FPoint::y
float y
Definition: SDL_sysrender.h:37
SDL_Texture::r
Uint8 r
Definition: SDL_sysrender.h:58