SDL  2.0
SDL_render_gles.c
Go to the documentation of this file.
1 /*
2  Simple DirectMedia Layer
3  Copyright (C) 1997-2019 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_internal.h"
22 
23 #if SDL_VIDEO_RENDER_OGL_ES && !SDL_RENDER_DISABLED
24 
25 #include "SDL_hints.h"
26 #include "SDL_opengles.h"
27 #include "../SDL_sysrender.h"
28 
29 /* To prevent unnecessary window recreation,
30  * these should match the defaults selected in SDL_GL_ResetAttributes
31  */
32 
33 #define RENDERER_CONTEXT_MAJOR 1
34 #define RENDERER_CONTEXT_MINOR 1
35 
36 #if defined(SDL_VIDEO_DRIVER_PANDORA)
37 
38 /* Empty function stub to get OpenGL ES 1.x support without */
39 /* OpenGL ES extension GL_OES_draw_texture supported */
40 GL_API void GL_APIENTRY
41 glDrawTexiOES(GLint x, GLint y, GLint z, GLint width, GLint height)
42 {
43  return;
44 }
45 
46 #endif /* SDL_VIDEO_DRIVER_PANDORA */
47 
48 /* OpenGL ES 1.1 renderer implementation, based on the OpenGL renderer */
49 
50 /* Used to re-create the window with OpenGL ES capability */
52 
53 static const float inv255f = 1.0f / 255.0f;
54 
55 typedef struct GLES_FBOList GLES_FBOList;
56 
57 struct GLES_FBOList
58 {
59  Uint32 w, h;
60  GLuint FBO;
61  GLES_FBOList *next;
62 };
63 
64 typedef struct
65 {
67  SDL_bool viewport_dirty;
70  int drawablew;
71  int drawableh;
72  SDL_BlendMode blend;
73  SDL_bool cliprect_enabled_dirty;
74  SDL_bool cliprect_enabled;
75  SDL_bool cliprect_dirty;
76  SDL_Rect cliprect;
77  SDL_bool texturing;
78  Uint32 color;
79  Uint32 clear_color;
80 } GLES_DrawStateCache;
81 
82 typedef struct
83 {
85 
86 #define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
87 #define SDL_PROC_OES SDL_PROC
88 #include "SDL_glesfuncs.h"
89 #undef SDL_PROC
90 #undef SDL_PROC_OES
91  SDL_bool GL_OES_framebuffer_object_supported;
92  GLES_FBOList *framebuffers;
93  GLuint window_framebuffer;
94 
95  SDL_bool GL_OES_blend_func_separate_supported;
96  SDL_bool GL_OES_blend_equation_separate_supported;
97  SDL_bool GL_OES_blend_subtract_supported;
98 
99  GLES_DrawStateCache drawstate;
100 } GLES_RenderData;
101 
102 typedef struct
103 {
104  GLuint texture;
105  GLenum type;
106  GLfloat texw;
107  GLfloat texh;
108  GLenum format;
109  GLenum formattype;
110  void *pixels;
111  int pitch;
112  GLES_FBOList *fbo;
113 } GLES_TextureData;
114 
115 static int
116 GLES_SetError(const char *prefix, GLenum result)
117 {
118  const char *error;
119 
120  switch (result) {
121  case GL_NO_ERROR:
122  error = "GL_NO_ERROR";
123  break;
124  case GL_INVALID_ENUM:
125  error = "GL_INVALID_ENUM";
126  break;
127  case GL_INVALID_VALUE:
128  error = "GL_INVALID_VALUE";
129  break;
131  error = "GL_INVALID_OPERATION";
132  break;
133  case GL_STACK_OVERFLOW:
134  error = "GL_STACK_OVERFLOW";
135  break;
136  case GL_STACK_UNDERFLOW:
137  error = "GL_STACK_UNDERFLOW";
138  break;
139  case GL_OUT_OF_MEMORY:
140  error = "GL_OUT_OF_MEMORY";
141  break;
142  default:
143  error = "UNKNOWN";
144  break;
145  }
146  return SDL_SetError("%s: %s", prefix, error);
147 }
148 
149 static int GLES_LoadFunctions(GLES_RenderData * data)
150 {
151 #if SDL_VIDEO_DRIVER_UIKIT
152 #define __SDL_NOGETPROCADDR__
153 #elif SDL_VIDEO_DRIVER_ANDROID
154 #define __SDL_NOGETPROCADDR__
155 #elif SDL_VIDEO_DRIVER_PANDORA
156 #define __SDL_NOGETPROCADDR__
157 #endif
158 
159 #ifdef __SDL_NOGETPROCADDR__
160 #define SDL_PROC(ret,func,params) data->func=func;
161 #define SDL_PROC_OES(ret,func,params) data->func=func;
162 #else
163 #define SDL_PROC(ret,func,params) \
164  do { \
165  data->func = SDL_GL_GetProcAddress(#func); \
166  if ( ! data->func ) { \
167  return SDL_SetError("Couldn't load GLES function %s: %s", #func, SDL_GetError()); \
168  } \
169  } while ( 0 );
170 #define SDL_PROC_OES(ret,func,params) \
171  do { \
172  data->func = SDL_GL_GetProcAddress(#func); \
173  } while ( 0 );
174 #endif /* __SDL_NOGETPROCADDR__ */
175 
176 #include "SDL_glesfuncs.h"
177 #undef SDL_PROC
178 #undef SDL_PROC_OES
179  return 0;
180 }
181 
182 static GLES_FBOList *
183 GLES_GetFBO(GLES_RenderData *data, Uint32 w, Uint32 h)
184 {
185  GLES_FBOList *result = data->framebuffers;
186  while ((result) && ((result->w != w) || (result->h != h)) ) {
187  result = result->next;
188  }
189  if (result == NULL) {
190  result = SDL_malloc(sizeof(GLES_FBOList));
191  result->w = w;
192  result->h = h;
193  data->glGenFramebuffersOES(1, &result->FBO);
194  result->next = data->framebuffers;
195  data->framebuffers = result;
196  }
197  return result;
198 }
199 
200 
201 static int
202 GLES_ActivateRenderer(SDL_Renderer * renderer)
203 {
204  GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
205 
206  if (SDL_GL_GetCurrentContext() != data->context) {
207  if (SDL_GL_MakeCurrent(renderer->window, data->context) < 0) {
208  return -1;
209  }
210  }
211 
212  return 0;
213 }
214 
215 static void
216 GLES_WindowEvent(SDL_Renderer * renderer, const SDL_WindowEvent *event)
217 {
218  GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
219 
220  if (event->event == SDL_WINDOWEVENT_MINIMIZED) {
221  /* According to Apple documentation, we need to finish drawing NOW! */
222  data->glFinish();
223  }
224 }
225 
226 static int
227 GLES_GetOutputSize(SDL_Renderer * renderer, int *w, int *h)
228 {
230  return 0;
231 }
232 
233 static GLenum GetBlendFunc(SDL_BlendFactor factor)
234 {
235  switch (factor) {
237  return GL_ZERO;
238  case SDL_BLENDFACTOR_ONE:
239  return GL_ONE;
241  return GL_SRC_COLOR;
243  return GL_ONE_MINUS_SRC_COLOR;
245  return GL_SRC_ALPHA;
247  return GL_ONE_MINUS_SRC_ALPHA;
249  return GL_DST_COLOR;
251  return GL_ONE_MINUS_DST_COLOR;
253  return GL_DST_ALPHA;
255  return GL_ONE_MINUS_DST_ALPHA;
256  default:
257  return GL_INVALID_ENUM;
258  }
259 }
260 
261 static GLenum GetBlendEquation(SDL_BlendOperation operation)
262 {
263  switch (operation) {
265  return GL_FUNC_ADD_OES;
267  return GL_FUNC_SUBTRACT_OES;
269  return GL_FUNC_REVERSE_SUBTRACT_OES;
270  default:
271  return GL_INVALID_ENUM;
272  }
273 }
274 
275 static SDL_bool
276 GLES_SupportsBlendMode(SDL_Renderer * renderer, SDL_BlendMode blendMode)
277 {
278  GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
285 
286  if (GetBlendFunc(srcColorFactor) == GL_INVALID_ENUM ||
287  GetBlendFunc(srcAlphaFactor) == GL_INVALID_ENUM ||
288  GetBlendEquation(colorOperation) == GL_INVALID_ENUM ||
289  GetBlendFunc(dstColorFactor) == GL_INVALID_ENUM ||
290  GetBlendFunc(dstAlphaFactor) == GL_INVALID_ENUM ||
291  GetBlendEquation(alphaOperation) == GL_INVALID_ENUM) {
292  return SDL_FALSE;
293  }
294  if ((srcColorFactor != srcAlphaFactor || dstColorFactor != dstAlphaFactor) && !data->GL_OES_blend_func_separate_supported) {
295  return SDL_FALSE;
296  }
297  if (colorOperation != alphaOperation && !data->GL_OES_blend_equation_separate_supported) {
298  return SDL_FALSE;
299  }
300  if (colorOperation != SDL_BLENDOPERATION_ADD && !data->GL_OES_blend_subtract_supported) {
301  return SDL_FALSE;
302  }
303  return SDL_TRUE;
304 }
305 
306 static SDL_INLINE int
307 power_of_2(int input)
308 {
309  int value = 1;
310 
311  while (value < input) {
312  value <<= 1;
313  }
314  return value;
315 }
316 
317 static int
318 GLES_CreateTexture(SDL_Renderer * renderer, SDL_Texture * texture)
319 {
320  GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
321  GLES_TextureData *data;
323  GLenum format, type;
324  int texture_w, texture_h;
325  GLenum scaleMode;
326  GLenum result;
327 
328  GLES_ActivateRenderer(renderer);
329 
330  switch (texture->format) {
333  format = GL_RGBA;
335  break;
336  default:
337  return SDL_SetError("Texture format not supported");
338  }
339 
340  data = (GLES_TextureData *) SDL_calloc(1, sizeof(*data));
341  if (!data) {
342  return SDL_OutOfMemory();
343  }
344 
345  if (texture->access == SDL_TEXTUREACCESS_STREAMING) {
346  data->pitch = texture->w * SDL_BYTESPERPIXEL(texture->format);
347  data->pixels = SDL_calloc(1, texture->h * data->pitch);
348  if (!data->pixels) {
349  SDL_free(data);
350  return SDL_OutOfMemory();
351  }
352  }
353 
354 
355  if (texture->access == SDL_TEXTUREACCESS_TARGET) {
356  if (!renderdata->GL_OES_framebuffer_object_supported) {
357  SDL_free(data);
358  return SDL_SetError("GL_OES_framebuffer_object not supported");
359  }
360  data->fbo = GLES_GetFBO(renderer->driverdata, texture->w, texture->h);
361  } else {
362  data->fbo = NULL;
363  }
364 
365 
366  renderdata->glGetError();
367  renderdata->glEnable(GL_TEXTURE_2D);
368  renderdata->glGenTextures(1, &data->texture);
369  result = renderdata->glGetError();
370  if (result != GL_NO_ERROR) {
371  SDL_free(data);
372  return GLES_SetError("glGenTextures()", result);
373  }
374 
375  data->type = GL_TEXTURE_2D;
376  /* no NPOV textures allowed in OpenGL ES (yet) */
377  texture_w = power_of_2(texture->w);
378  texture_h = power_of_2(texture->h);
379  data->texw = (GLfloat) texture->w / texture_w;
380  data->texh = (GLfloat) texture->h / texture_h;
381 
382  data->format = format;
383  data->formattype = type;
384  scaleMode = (texture->scaleMode == SDL_ScaleModeNearest) ? GL_NEAREST : GL_LINEAR;
385  renderdata->glBindTexture(data->type, data->texture);
386  renderdata->glTexParameteri(data->type, GL_TEXTURE_MIN_FILTER, scaleMode);
387  renderdata->glTexParameteri(data->type, GL_TEXTURE_MAG_FILTER, scaleMode);
388  renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);
389  renderdata->glTexParameteri(data->type, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE);
390 
391  renderdata->glTexImage2D(data->type, 0, internalFormat, texture_w,
392  texture_h, 0, format, type, NULL);
393  renderdata->glDisable(GL_TEXTURE_2D);
394  renderdata->drawstate.texture = texture;
395  renderdata->drawstate.texturing = SDL_FALSE;
396 
397  result = renderdata->glGetError();
398  if (result != GL_NO_ERROR) {
399  SDL_free(data);
400  return GLES_SetError("glTexImage2D()", result);
401  }
402 
403  texture->driverdata = data;
404  return 0;
405 }
406 
407 static int
408 GLES_UpdateTexture(SDL_Renderer * renderer, SDL_Texture * texture,
409  const SDL_Rect * rect, const void *pixels, int pitch)
410 {
411  GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
412  GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
413  Uint8 *blob = NULL;
414  Uint8 *src;
415  int srcPitch;
416  int y;
417 
418  GLES_ActivateRenderer(renderer);
419 
420  /* Bail out if we're supposed to update an empty rectangle */
421  if (rect->w <= 0 || rect->h <= 0) {
422  return 0;
423  }
424 
425  /* Reformat the texture data into a tightly packed array */
426  srcPitch = rect->w * SDL_BYTESPERPIXEL(texture->format);
427  src = (Uint8 *)pixels;
428  if (pitch != srcPitch) {
429  blob = (Uint8 *)SDL_malloc(srcPitch * rect->h);
430  if (!blob) {
431  return SDL_OutOfMemory();
432  }
433  src = blob;
434  for (y = 0; y < rect->h; ++y) {
435  SDL_memcpy(src, pixels, srcPitch);
436  src += srcPitch;
437  pixels = (Uint8 *)pixels + pitch;
438  }
439  src = blob;
440  }
441 
442  /* Create a texture subimage with the supplied data */
443  renderdata->glGetError();
444  renderdata->glEnable(data->type);
445  renderdata->glBindTexture(data->type, data->texture);
446  renderdata->glPixelStorei(GL_UNPACK_ALIGNMENT, 1);
447  renderdata->glTexSubImage2D(data->type,
448  0,
449  rect->x,
450  rect->y,
451  rect->w,
452  rect->h,
453  data->format,
454  data->formattype,
455  src);
456  renderdata->glDisable(data->type);
457  SDL_free(blob);
458 
459  renderdata->drawstate.texture = texture;
460  renderdata->drawstate.texturing = SDL_FALSE;
461 
462  if (renderdata->glGetError() != GL_NO_ERROR) {
463  return SDL_SetError("Failed to update texture");
464  }
465  return 0;
466 }
467 
468 static int
469 GLES_LockTexture(SDL_Renderer * renderer, SDL_Texture * texture,
470  const SDL_Rect * rect, void **pixels, int *pitch)
471 {
472  GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
473 
474  *pixels =
475  (void *) ((Uint8 *) data->pixels + rect->y * data->pitch +
476  rect->x * SDL_BYTESPERPIXEL(texture->format));
477  *pitch = data->pitch;
478  return 0;
479 }
480 
481 static void
482 GLES_UnlockTexture(SDL_Renderer * renderer, SDL_Texture * texture)
483 {
484  GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
485  SDL_Rect rect;
486 
487  /* We do whole texture updates, at least for now */
488  rect.x = 0;
489  rect.y = 0;
490  rect.w = texture->w;
491  rect.h = texture->h;
492  GLES_UpdateTexture(renderer, texture, &rect, data->pixels, data->pitch);
493 }
494 
495 static int
496 GLES_SetRenderTarget(SDL_Renderer * renderer, SDL_Texture * texture)
497 {
498  GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
499  GLES_TextureData *texturedata = NULL;
500  GLenum status;
501 
502  if (!data->GL_OES_framebuffer_object_supported) {
503  return SDL_SetError("Can't enable render target support in this renderer");
504  }
505 
506  data->drawstate.viewport_dirty = SDL_TRUE;
507 
508  if (texture == NULL) {
509  data->glBindFramebufferOES(GL_FRAMEBUFFER_OES, data->window_framebuffer);
510  return 0;
511  }
512 
513  texturedata = (GLES_TextureData *) texture->driverdata;
514  data->glBindFramebufferOES(GL_FRAMEBUFFER_OES, texturedata->fbo->FBO);
515  /* TODO: check if texture pixel format allows this operation */
516  data->glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, texturedata->type, texturedata->texture, 0);
517  /* Check FBO status */
518  status = data->glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
519  if (status != GL_FRAMEBUFFER_COMPLETE_OES) {
520  return SDL_SetError("glFramebufferTexture2DOES() failed");
521  }
522  return 0;
523 }
524 
525 
526 static int
527 GLES_QueueSetViewport(SDL_Renderer * renderer, SDL_RenderCommand *cmd)
528 {
529  return 0; /* nothing to do in this backend. */
530 }
531 
532 static int
533 GLES_QueueDrawPoints(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FPoint * points, int count)
534 {
535  GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, count * 2 * sizeof (GLfloat), 0, &cmd->data.draw.first);
536  int i;
537 
538  if (!verts) {
539  return -1;
540  }
541 
542  cmd->data.draw.count = count;
543  for (i = 0; i < count; i++) {
544  *(verts++) = 0.5f + points[i].x;
545  *(verts++) = 0.5f + points[i].y;
546  }
547 
548  return 0;
549 }
550 
551 static int
552 GLES_QueueFillRects(SDL_Renderer * renderer, SDL_RenderCommand *cmd, const SDL_FRect * rects, int count)
553 {
554  GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, count * 8 * sizeof (GLfloat), 0, &cmd->data.draw.first);
555  int i;
556 
557  if (!verts) {
558  return -1;
559  }
560 
561  cmd->data.draw.count = count;
562 
563  for (i = 0; i < count; i++) {
564  const SDL_FRect *rect = &rects[i];
565  const GLfloat minx = rect->x;
566  const GLfloat maxx = rect->x + rect->w;
567  const GLfloat miny = rect->y;
568  const GLfloat maxy = rect->y + rect->h;
569  *(verts++) = minx;
570  *(verts++) = miny;
571  *(verts++) = maxx;
572  *(verts++) = miny;
573  *(verts++) = minx;
574  *(verts++) = maxy;
575  *(verts++) = maxx;
576  *(verts++) = maxy;
577  }
578 
579  return 0;
580 }
581 
582 static int
583 GLES_QueueCopy(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
584  const SDL_Rect * srcrect, const SDL_FRect * dstrect)
585 {
586  GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata;
587  GLfloat minx, miny, maxx, maxy;
588  GLfloat minu, maxu, minv, maxv;
589  GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, 16 * sizeof (GLfloat), 0, &cmd->data.draw.first);
590 
591  if (!verts) {
592  return -1;
593  }
594 
595  cmd->data.draw.count = 1;
596 
597  minx = dstrect->x;
598  miny = dstrect->y;
599  maxx = dstrect->x + dstrect->w;
600  maxy = dstrect->y + dstrect->h;
601 
602  minu = (GLfloat) srcrect->x / texture->w;
603  minu *= texturedata->texw;
604  maxu = (GLfloat) (srcrect->x + srcrect->w) / texture->w;
605  maxu *= texturedata->texw;
606  minv = (GLfloat) srcrect->y / texture->h;
607  minv *= texturedata->texh;
608  maxv = (GLfloat) (srcrect->y + srcrect->h) / texture->h;
609  maxv *= texturedata->texh;
610 
611  *(verts++) = minx;
612  *(verts++) = miny;
613  *(verts++) = maxx;
614  *(verts++) = miny;
615  *(verts++) = minx;
616  *(verts++) = maxy;
617  *(verts++) = maxx;
618  *(verts++) = maxy;
619 
620  *(verts++) = minu;
621  *(verts++) = minv;
622  *(verts++) = maxu;
623  *(verts++) = minv;
624  *(verts++) = minu;
625  *(verts++) = maxv;
626  *(verts++) = maxu;
627  *(verts++) = maxv;
628 
629  return 0;
630 }
631 
632 static int
633 GLES_QueueCopyEx(SDL_Renderer * renderer, SDL_RenderCommand *cmd, SDL_Texture * texture,
634  const SDL_Rect * srcquad, const SDL_FRect * dstrect,
635  const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
636 {
637  GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata;
638  GLfloat minx, miny, maxx, maxy;
639  GLfloat centerx, centery;
640  GLfloat minu, maxu, minv, maxv;
641  GLfloat *verts = (GLfloat *) SDL_AllocateRenderVertices(renderer, 19 * sizeof (GLfloat), 0, &cmd->data.draw.first);
642 
643  if (!verts) {
644  return -1;
645  }
646 
647  centerx = center->x;
648  centery = center->y;
649 
650  if (flip & SDL_FLIP_HORIZONTAL) {
651  minx = dstrect->w - centerx;
652  maxx = -centerx;
653  }
654  else {
655  minx = -centerx;
656  maxx = dstrect->w - centerx;
657  }
658 
659  if (flip & SDL_FLIP_VERTICAL) {
660  miny = dstrect->h - centery;
661  maxy = -centery;
662  }
663  else {
664  miny = -centery;
665  maxy = dstrect->h - centery;
666  }
667 
668  minu = (GLfloat) srcquad->x / texture->w;
669  minu *= texturedata->texw;
670  maxu = (GLfloat) (srcquad->x + srcquad->w) / texture->w;
671  maxu *= texturedata->texw;
672  minv = (GLfloat) srcquad->y / texture->h;
673  minv *= texturedata->texh;
674  maxv = (GLfloat) (srcquad->y + srcquad->h) / texture->h;
675  maxv *= texturedata->texh;
676 
677  cmd->data.draw.count = 1;
678 
679  *(verts++) = minx;
680  *(verts++) = miny;
681  *(verts++) = maxx;
682  *(verts++) = miny;
683  *(verts++) = minx;
684  *(verts++) = maxy;
685  *(verts++) = maxx;
686  *(verts++) = maxy;
687 
688  *(verts++) = minu;
689  *(verts++) = minv;
690  *(verts++) = maxu;
691  *(verts++) = minv;
692  *(verts++) = minu;
693  *(verts++) = maxv;
694  *(verts++) = maxu;
695  *(verts++) = maxv;
696 
697  *(verts++) = (GLfloat) dstrect->x + centerx;
698  *(verts++) = (GLfloat) dstrect->y + centery;
699  *(verts++) = (GLfloat) angle;
700 
701  return 0;
702 }
703 
704 static void
705 SetDrawState(GLES_RenderData *data, const SDL_RenderCommand *cmd)
706 {
707  const SDL_BlendMode blend = cmd->data.draw.blend;
708  const Uint8 r = cmd->data.draw.r;
709  const Uint8 g = cmd->data.draw.g;
710  const Uint8 b = cmd->data.draw.b;
711  const Uint8 a = cmd->data.draw.a;
712  const Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
713 
714  if (color != data->drawstate.color) {
715  const GLfloat fr = ((GLfloat) r) * inv255f;
716  const GLfloat fg = ((GLfloat) g) * inv255f;
717  const GLfloat fb = ((GLfloat) b) * inv255f;
718  const GLfloat fa = ((GLfloat) a) * inv255f;
719  data->glColor4f(fr, fg, fb, fa);
720  data->drawstate.color = color;
721  }
722 
723  if (data->drawstate.viewport_dirty) {
724  const SDL_Rect *viewport = &data->drawstate.viewport;
725  const SDL_bool istarget = (data->drawstate.target != NULL);
726  data->glMatrixMode(GL_PROJECTION);
727  data->glLoadIdentity();
728  data->glViewport(viewport->x,
729  istarget ? viewport->y : (data->drawstate.drawableh - viewport->y - viewport->h),
730  viewport->w, viewport->h);
731  if (viewport->w && viewport->h) {
732  data->glOrthof((GLfloat) 0, (GLfloat) viewport->w,
733  (GLfloat) (istarget ? 0 : viewport->h),
734  (GLfloat) (istarget ? viewport->h : 0),
735  0.0, 1.0);
736  }
737  data->glMatrixMode(GL_MODELVIEW);
738  data->drawstate.viewport_dirty = SDL_FALSE;
739  }
740 
741  if (data->drawstate.cliprect_enabled_dirty) {
742  if (data->drawstate.cliprect_enabled) {
743  data->glEnable(GL_SCISSOR_TEST);
744  } else {
745  data->glDisable(GL_SCISSOR_TEST);
746  }
747  data->drawstate.cliprect_enabled_dirty = SDL_FALSE;
748  }
749 
750  if (data->drawstate.cliprect_enabled && data->drawstate.cliprect_dirty) {
751  const SDL_Rect *viewport = &data->drawstate.viewport;
752  const SDL_Rect *rect = &data->drawstate.cliprect;
753  const SDL_bool istarget = (data->drawstate.target != NULL);
754  data->glScissor(viewport->x + rect->x,
755  istarget ? viewport->y + rect->y : data->drawstate.drawableh - viewport->y - rect->y - rect->h,
756  rect->w, rect->h);
757  data->drawstate.cliprect_dirty = SDL_FALSE;
758  }
759 
760  if (blend != data->drawstate.blend) {
761  if (blend == SDL_BLENDMODE_NONE) {
762  data->glDisable(GL_BLEND);
763  } else {
764  data->glEnable(GL_BLEND);
765  if (data->GL_OES_blend_func_separate_supported) {
766  data->glBlendFuncSeparateOES(GetBlendFunc(SDL_GetBlendModeSrcColorFactor(blend)),
767  GetBlendFunc(SDL_GetBlendModeDstColorFactor(blend)),
768  GetBlendFunc(SDL_GetBlendModeSrcAlphaFactor(blend)),
769  GetBlendFunc(SDL_GetBlendModeDstAlphaFactor(blend)));
770  } else {
771  data->glBlendFunc(GetBlendFunc(SDL_GetBlendModeSrcColorFactor(blend)),
772  GetBlendFunc(SDL_GetBlendModeDstColorFactor(blend)));
773  }
774  if (data->GL_OES_blend_equation_separate_supported) {
775  data->glBlendEquationSeparateOES(GetBlendEquation(SDL_GetBlendModeColorOperation(blend)),
776  GetBlendEquation(SDL_GetBlendModeAlphaOperation(blend)));
777  } else if (data->GL_OES_blend_subtract_supported) {
778  data->glBlendEquationOES(GetBlendEquation(SDL_GetBlendModeColorOperation(blend)));
779  }
780  }
781  data->drawstate.blend = blend;
782  }
783 
784  if ((cmd->data.draw.texture != NULL) != data->drawstate.texturing) {
785  if (cmd->data.draw.texture == NULL) {
786  data->glDisable(GL_TEXTURE_2D);
787  data->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
788  data->drawstate.texturing = SDL_FALSE;
789  } else {
790  data->glEnable(GL_TEXTURE_2D);
791  data->glEnableClientState(GL_TEXTURE_COORD_ARRAY);
792  data->drawstate.texturing = SDL_TRUE;
793  }
794  }
795 }
796 
797 static void
798 SetCopyState(GLES_RenderData *data, const SDL_RenderCommand *cmd)
799 {
800  SDL_Texture *texture = cmd->data.draw.texture;
801  SetDrawState(data, cmd);
802 
803  if (texture != data->drawstate.texture) {
804  GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata;
805  data->glBindTexture(GL_TEXTURE_2D, texturedata->texture);
806  data->drawstate.texture = texture;
807  }
808 }
809 
810 static int
811 GLES_RunCommandQueue(SDL_Renderer * renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
812 {
813  GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
814  size_t i;
815 
816  if (GLES_ActivateRenderer(renderer) < 0) {
817  return -1;
818  }
819 
820  data->drawstate.target = renderer->target;
821 
822  if (!renderer->target) {
823  SDL_GL_GetDrawableSize(renderer->window, &data->drawstate.drawablew, &data->drawstate.drawableh);
824  }
825 
826  while (cmd) {
827  switch (cmd->command) {
829  break; /* not used in this render backend. */
830  }
831 
833  SDL_Rect *viewport = &data->drawstate.viewport;
834  if (SDL_memcmp(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect)) != 0) {
835  SDL_memcpy(viewport, &cmd->data.viewport.rect, sizeof (SDL_Rect));
836  data->drawstate.viewport_dirty = SDL_TRUE;
837  }
838  break;
839  }
840 
842  const SDL_Rect *rect = &cmd->data.cliprect.rect;
843  if (data->drawstate.cliprect_enabled != cmd->data.cliprect.enabled) {
844  data->drawstate.cliprect_enabled = cmd->data.cliprect.enabled;
845  data->drawstate.cliprect_enabled_dirty = SDL_TRUE;
846  }
847  if (SDL_memcmp(&data->drawstate.cliprect, rect, sizeof (SDL_Rect)) != 0) {
848  SDL_memcpy(&data->drawstate.cliprect, rect, sizeof (SDL_Rect));
849  data->drawstate.cliprect_dirty = SDL_TRUE;
850  }
851  break;
852  }
853 
854  case SDL_RENDERCMD_CLEAR: {
855  const Uint8 r = cmd->data.color.r;
856  const Uint8 g = cmd->data.color.g;
857  const Uint8 b = cmd->data.color.b;
858  const Uint8 a = cmd->data.color.a;
859  const Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
860  if (color != data->drawstate.clear_color) {
861  const GLfloat fr = ((GLfloat) r) * inv255f;
862  const GLfloat fg = ((GLfloat) g) * inv255f;
863  const GLfloat fb = ((GLfloat) b) * inv255f;
864  const GLfloat fa = ((GLfloat) a) * inv255f;
865  data->glClearColor(fr, fg, fb, fa);
866  data->drawstate.clear_color = color;
867  }
868 
869  if (data->drawstate.cliprect_enabled) {
870  data->glDisable(GL_SCISSOR_TEST);
871  data->drawstate.cliprect_enabled_dirty = SDL_TRUE;
872  }
873 
874  data->glClear(GL_COLOR_BUFFER_BIT);
875 
876  break;
877  }
878 
880  const size_t count = cmd->data.draw.count;
881  const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
882  SetDrawState(data, cmd);
883  data->glVertexPointer(2, GL_FLOAT, 0, verts);
884  data->glDrawArrays(GL_POINTS, 0, (GLsizei) count);
885  break;
886  }
887 
889  const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
890  const size_t count = cmd->data.draw.count;
891  SetDrawState(data, cmd);
892  data->glVertexPointer(2, GL_FLOAT, 0, verts);
893  if (count > 2 && (verts[0] == verts[(count-1)*2]) && (verts[1] == verts[(count*2)-1])) {
894  /* GL_LINE_LOOP takes care of the final segment */
895  data->glDrawArrays(GL_LINE_LOOP, 0, (GLsizei) (count - 1));
896  } else {
897  data->glDrawArrays(GL_LINE_STRIP, 0, (GLsizei) count);
898  /* We need to close the endpoint of the line */
899  data->glDrawArrays(GL_POINTS, (GLsizei) (count - 1), 1);
900  }
901  break;
902  }
903 
905  const size_t count = cmd->data.draw.count;
906  const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
907  GLsizei offset = 0;
908  SetDrawState(data, cmd);
909  data->glVertexPointer(2, GL_FLOAT, 0, verts);
910  for (i = 0; i < count; ++i, offset += 4) {
911  data->glDrawArrays(GL_TRIANGLE_STRIP, offset, 4);
912  }
913  break;
914  }
915 
916  case SDL_RENDERCMD_COPY: {
917  const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
918  SetCopyState(data, cmd);
919  data->glVertexPointer(2, GL_FLOAT, 0, verts);
920  data->glTexCoordPointer(2, GL_FLOAT, 0, verts + 8);
921  data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
922  break;
923  }
924 
925  case SDL_RENDERCMD_COPY_EX: {
926  const GLfloat *verts = (GLfloat *) (((Uint8 *) vertices) + cmd->data.draw.first);
927  const GLfloat translatex = verts[16];
928  const GLfloat translatey = verts[17];
929  const GLfloat angle = verts[18];
930  SetCopyState(data, cmd);
931  data->glVertexPointer(2, GL_FLOAT, 0, verts);
932  data->glTexCoordPointer(2, GL_FLOAT, 0, verts + 8);
933 
934  /* Translate to flip, rotate, translate to position */
935  data->glPushMatrix();
936  data->glTranslatef(translatex, translatey, 0.0f);
937  data->glRotatef(angle, 0.0, 0.0, 1.0);
938  data->glDrawArrays(GL_TRIANGLE_STRIP, 0, 4);
939  data->glPopMatrix();
940  break;
941  }
942 
943  case SDL_RENDERCMD_NO_OP:
944  break;
945  }
946 
947  cmd = cmd->next;
948  }
949 
950  return 0;
951 }
952 
953 static int
954 GLES_RenderReadPixels(SDL_Renderer * renderer, const SDL_Rect * rect,
955  Uint32 pixel_format, void * pixels, int pitch)
956 {
957  GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
959  void *temp_pixels;
960  int temp_pitch;
961  Uint8 *src, *dst, *tmp;
962  int w, h, length, rows;
963  int status;
964 
965  GLES_ActivateRenderer(renderer);
966 
967  temp_pitch = rect->w * SDL_BYTESPERPIXEL(temp_format);
968  temp_pixels = SDL_malloc(rect->h * temp_pitch);
969  if (!temp_pixels) {
970  return SDL_OutOfMemory();
971  }
972 
974 
975  data->glPixelStorei(GL_PACK_ALIGNMENT, 1);
976 
977  data->glReadPixels(rect->x, renderer->target ? rect->y : (h-rect->y)-rect->h,
978  rect->w, rect->h, GL_RGBA, GL_UNSIGNED_BYTE, temp_pixels);
979 
980  /* Flip the rows to be top-down if necessary */
981  if (!renderer->target) {
982  SDL_bool isstack;
983  length = rect->w * SDL_BYTESPERPIXEL(temp_format);
984  src = (Uint8*)temp_pixels + (rect->h-1)*temp_pitch;
985  dst = (Uint8*)temp_pixels;
986  tmp = SDL_small_alloc(Uint8, length, &isstack);
987  rows = rect->h / 2;
988  while (rows--) {
989  SDL_memcpy(tmp, dst, length);
991  SDL_memcpy(src, tmp, length);
992  dst += temp_pitch;
993  src -= temp_pitch;
994  }
995  SDL_small_free(tmp, isstack);
996  }
997 
998  status = SDL_ConvertPixels(rect->w, rect->h,
999  temp_format, temp_pixels, temp_pitch,
1000  pixel_format, pixels, pitch);
1001  SDL_free(temp_pixels);
1002 
1003  return status;
1004 }
1005 
1006 static void
1007 GLES_RenderPresent(SDL_Renderer * renderer)
1008 {
1009  GLES_ActivateRenderer(renderer);
1010 
1012 }
1013 
1014 static void
1015 GLES_DestroyTexture(SDL_Renderer * renderer, SDL_Texture * texture)
1016 {
1017  GLES_RenderData *renderdata = (GLES_RenderData *) renderer->driverdata;
1018 
1019  GLES_TextureData *data = (GLES_TextureData *) texture->driverdata;
1020 
1021  GLES_ActivateRenderer(renderer);
1022 
1023  if (renderdata->drawstate.texture == texture) {
1024  renderdata->drawstate.texture = NULL;
1025  }
1026  if (renderdata->drawstate.target == texture) {
1027  renderdata->drawstate.target = NULL;
1028  }
1029 
1030  if (!data) {
1031  return;
1032  }
1033  if (data->texture) {
1034  renderdata->glDeleteTextures(1, &data->texture);
1035  }
1036  SDL_free(data->pixels);
1037  SDL_free(data);
1038  texture->driverdata = NULL;
1039 }
1040 
1041 static void
1042 GLES_DestroyRenderer(SDL_Renderer * renderer)
1043 {
1044  GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
1045 
1046  if (data) {
1047  if (data->context) {
1048  while (data->framebuffers) {
1049  GLES_FBOList *nextnode = data->framebuffers->next;
1050  data->glDeleteFramebuffersOES(1, &data->framebuffers->FBO);
1051  SDL_free(data->framebuffers);
1052  data->framebuffers = nextnode;
1053  }
1054  SDL_GL_DeleteContext(data->context);
1055  }
1056  SDL_free(data);
1057  }
1058  SDL_free(renderer);
1059 }
1060 
1061 static int GLES_BindTexture (SDL_Renderer * renderer, SDL_Texture *texture, float *texw, float *texh)
1062 {
1063  GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
1064  GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata;
1065  GLES_ActivateRenderer(renderer);
1066 
1067  data->glEnable(GL_TEXTURE_2D);
1068  data->glBindTexture(texturedata->type, texturedata->texture);
1069 
1070  data->drawstate.texture = texture;
1071  data->drawstate.texturing = SDL_TRUE;
1072 
1073  if (texw) {
1074  *texw = (float)texturedata->texw;
1075  }
1076  if (texh) {
1077  *texh = (float)texturedata->texh;
1078  }
1079 
1080  return 0;
1081 }
1082 
1083 static int GLES_UnbindTexture (SDL_Renderer * renderer, SDL_Texture *texture)
1084 {
1085  GLES_RenderData *data = (GLES_RenderData *) renderer->driverdata;
1086  GLES_TextureData *texturedata = (GLES_TextureData *) texture->driverdata;
1087  GLES_ActivateRenderer(renderer);
1088  data->glDisable(texturedata->type);
1089 
1090  data->drawstate.texture = NULL;
1091  data->drawstate.texturing = SDL_FALSE;
1092 
1093  return 0;
1094 }
1095 
1096 static SDL_Renderer *
1097 GLES_CreateRenderer(SDL_Window * window, Uint32 flags)
1098 {
1100  GLES_RenderData *data;
1101  GLint value;
1102  Uint32 window_flags;
1103  int profile_mask = 0, major = 0, minor = 0;
1104  SDL_bool changed_window = SDL_FALSE;
1105 
1109 
1110  window_flags = SDL_GetWindowFlags(window);
1111  if (!(window_flags & SDL_WINDOW_OPENGL) ||
1112  profile_mask != SDL_GL_CONTEXT_PROFILE_ES || major != RENDERER_CONTEXT_MAJOR || minor != RENDERER_CONTEXT_MINOR) {
1113 
1114  changed_window = SDL_TRUE;
1116  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MAJOR_VERSION, RENDERER_CONTEXT_MAJOR);
1117  SDL_GL_SetAttribute(SDL_GL_CONTEXT_MINOR_VERSION, RENDERER_CONTEXT_MINOR);
1118 
1119  if (SDL_RecreateWindow(window, window_flags | SDL_WINDOW_OPENGL) < 0) {
1120  goto error;
1121  }
1122  }
1123 
1124  renderer = (SDL_Renderer *) SDL_calloc(1, sizeof(*renderer));
1125  if (!renderer) {
1126  SDL_OutOfMemory();
1127  goto error;
1128  }
1129 
1130  data = (GLES_RenderData *) SDL_calloc(1, sizeof(*data));
1131  if (!data) {
1132  GLES_DestroyRenderer(renderer);
1133  SDL_OutOfMemory();
1134  goto error;
1135  }
1136 
1137  renderer->WindowEvent = GLES_WindowEvent;
1138  renderer->GetOutputSize = GLES_GetOutputSize;
1139  renderer->SupportsBlendMode = GLES_SupportsBlendMode;
1140  renderer->CreateTexture = GLES_CreateTexture;
1141  renderer->UpdateTexture = GLES_UpdateTexture;
1142  renderer->LockTexture = GLES_LockTexture;
1143  renderer->UnlockTexture = GLES_UnlockTexture;
1144  renderer->SetRenderTarget = GLES_SetRenderTarget;
1145  renderer->QueueSetViewport = GLES_QueueSetViewport;
1146  renderer->QueueSetDrawColor = GLES_QueueSetViewport; /* SetViewport and SetDrawColor are (currently) no-ops. */
1147  renderer->QueueDrawPoints = GLES_QueueDrawPoints;
1148  renderer->QueueDrawLines = GLES_QueueDrawPoints; /* lines and points queue vertices the same way. */
1149  renderer->QueueFillRects = GLES_QueueFillRects;
1150  renderer->QueueCopy = GLES_QueueCopy;
1151  renderer->QueueCopyEx = GLES_QueueCopyEx;
1152  renderer->RunCommandQueue = GLES_RunCommandQueue;
1153  renderer->RenderReadPixels = GLES_RenderReadPixels;
1154  renderer->RenderPresent = GLES_RenderPresent;
1155  renderer->DestroyTexture = GLES_DestroyTexture;
1156  renderer->DestroyRenderer = GLES_DestroyRenderer;
1157  renderer->GL_BindTexture = GLES_BindTexture;
1158  renderer->GL_UnbindTexture = GLES_UnbindTexture;
1162  renderer->window = window;
1163 
1164  data->context = SDL_GL_CreateContext(window);
1165  if (!data->context) {
1166  GLES_DestroyRenderer(renderer);
1167  goto error;
1168  }
1169  if (SDL_GL_MakeCurrent(window, data->context) < 0) {
1170  GLES_DestroyRenderer(renderer);
1171  goto error;
1172  }
1173 
1174  if (GLES_LoadFunctions(data) < 0) {
1175  GLES_DestroyRenderer(renderer);
1176  goto error;
1177  }
1178 
1181  } else {
1183  }
1184  if (SDL_GL_GetSwapInterval() > 0) {
1186  }
1187 
1188  value = 0;
1189  data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
1191  value = 0;
1192  data->glGetIntegerv(GL_MAX_TEXTURE_SIZE, &value);
1194 
1195  /* Android does not report GL_OES_framebuffer_object but the functionality seems to be there anyway */
1196  if (SDL_GL_ExtensionSupported("GL_OES_framebuffer_object") || data->glGenFramebuffersOES) {
1197  data->GL_OES_framebuffer_object_supported = SDL_TRUE;
1199 
1200  value = 0;
1201  data->glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &value);
1202  data->window_framebuffer = (GLuint)value;
1203  }
1204  data->framebuffers = NULL;
1205 
1206  if (SDL_GL_ExtensionSupported("GL_OES_blend_func_separate")) {
1207  data->GL_OES_blend_func_separate_supported = SDL_TRUE;
1208  }
1209  if (SDL_GL_ExtensionSupported("GL_OES_blend_equation_separate")) {
1210  data->GL_OES_blend_equation_separate_supported = SDL_TRUE;
1211  }
1212  if (SDL_GL_ExtensionSupported("GL_OES_blend_subtract")) {
1213  data->GL_OES_blend_subtract_supported = SDL_TRUE;
1214  }
1215 
1216  /* Set up parameters for rendering */
1217  data->glDisable(GL_DEPTH_TEST);
1218  data->glDisable(GL_CULL_FACE);
1219 
1220  data->glMatrixMode(GL_MODELVIEW);
1221  data->glLoadIdentity();
1222 
1223  data->glEnableClientState(GL_VERTEX_ARRAY);
1224  data->glDisableClientState(GL_TEXTURE_COORD_ARRAY);
1225 
1226  data->glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
1227 
1228  data->drawstate.blend = SDL_BLENDMODE_INVALID;
1229  data->drawstate.color = 0xFFFFFFFF;
1230  data->drawstate.clear_color = 0xFFFFFFFF;
1231 
1232  return renderer;
1233 
1234 error:
1235  if (changed_window) {
1236  /* Uh oh, better try to put it back... */
1240  SDL_RecreateWindow(window, window_flags);
1241  }
1242  return NULL;
1243 }
1244 
1246  GLES_CreateRenderer,
1247  {
1248  "opengles",
1250  1,
1252  0,
1253  0
1254  }
1255 };
1256 
1257 #endif /* SDL_VIDEO_RENDER_OGL_ES && !SDL_RENDER_DISABLED */
1258 
1259 /* vi: set ts=4 sw=4 expandtab: */
format
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
Definition: SDL_opengl.h:1571
points
GLfixed GLfixed GLint GLint GLfixed points
Definition: SDL_opengl_glext.h:4558
GL_ONE
#define GL_ONE
Definition: SDL_opengl.h:400
SDL_Renderer::GL_UnbindTexture
int(* GL_UnbindTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:164
GL_POINTS
#define GL_POINTS
Definition: SDL_opengl.h:215
SDL_small_free
#define SDL_small_free(ptr, isstack)
Definition: SDL_internal.h:40
SDL_GL_CONTEXT_PROFILE_MASK
Definition: SDL_video.h:221
offset
GLintptr offset
Definition: SDL_opengl_glext.h:538
target
GLenum target
Definition: SDL_opengl_glext.h:1551
blendMode
static SDL_BlendMode blendMode
Definition: testdraw2.c:34
SDL_RecreateWindow
int SDL_RecreateWindow(SDL_Window *window, Uint32 flags)
Definition: SDL_video.c:1614
SDL_RenderCommand::color
struct SDL_RenderCommand::@30::@34 color
GL_TEXTURE_2D
#define GL_TEXTURE_2D
Definition: SDL_opengl.h:670
SDL_Renderer::QueueCopyEx
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)
Definition: SDL_sysrender.h:140
SDL_BLENDOPERATION_SUBTRACT
Definition: SDL_blendmode.h:65
SDL_AllocateRenderVertices
void * SDL_AllocateRenderVertices(SDL_Renderer *renderer, const size_t numbytes, const size_t alignment, size_t *offset)
Definition: SDL_render.c:284
SDL_Renderer::RunCommandQueue
int(* RunCommandQueue)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
Definition: SDL_sysrender.h:143
SDL_FPoint::x
float x
Definition: SDL_rect.h:62
SDL_FRect::h
float h
Definition: SDL_rect.h:92
NULL
#define NULL
Definition: begin_code.h:167
SDL_ScaleModeNearest
Definition: SDL_sysrender.h:37
GL_NEAREST
#define GL_NEAREST
Definition: SDL_opengl.h:703
b
GLboolean GLboolean GLboolean b
Definition: SDL_opengl_glext.h:1109
SDL_Renderer::SetRenderTarget
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:155
width
GLint GLint GLsizei width
Definition: SDL_opengl.h:1571
GL_STACK_UNDERFLOW
#define GL_STACK_UNDERFLOW
Definition: SDL_opengl.h:723
g
GLboolean GLboolean g
Definition: SDL_opengl_glext.h:1109
GL_MAX_TEXTURE_SIZE
#define GL_MAX_TEXTURE_SIZE
Definition: SDL_opengl.h:535
SDL_BLENDFACTOR_ZERO
Definition: SDL_blendmode.h:77
SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR
Definition: SDL_blendmode.h:84
SDL_GL_CreateContext
#define SDL_GL_CreateContext
Definition: SDL_dynapi_overrides.h:559
SDL_GLContext
void * SDL_GLContext
An opaque handle to an OpenGL context.
Definition: SDL_video.h:193
count
GLuint GLuint GLsizei count
Definition: SDL_opengl.h:1570
SDL_GetWindowFlags
#define SDL_GetWindowFlags
Definition: SDL_dynapi_overrides.h:518
SDL_RenderCommand::next
struct SDL_RenderCommand * next
Definition: SDL_sysrender.h:110
GL_ONE_MINUS_DST_ALPHA
#define GL_ONE_MINUS_DST_ALPHA
Definition: SDL_opengl.h:406
r
GLdouble GLdouble GLdouble r
Definition: SDL_opengl.h:2078
SDL_WINDOW_OPENGL
Definition: SDL_video.h:101
viewport
SDL_Rect viewport
Definition: testviewport.c:28
z
GLdouble GLdouble z
Definition: SDL_opengl_glext.h:404
SDL_RenderDriver
Definition: SDL_sysrender.h:236
SDL_FRect::x
float x
Definition: SDL_rect.h:89
GL_COLOR_BUFFER_BIT
#define GL_COLOR_BUFFER_BIT
Definition: SDL_opengl.h:741
SDL_RenderCommand::data
union SDL_RenderCommand::@30 data
SDL_Renderer::WindowEvent
void(* WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event)
Definition: SDL_sysrender.h:126
input
GLenum GLenum GLenum input
Definition: SDL_opengl_glext.h:9374
SDL_BLENDOPERATION_REV_SUBTRACT
Definition: SDL_blendmode.h:66
GL_UNPACK_ALIGNMENT
#define GL_UNPACK_ALIGNMENT
Definition: SDL_opengl.h:657
GLES_RenderDriver
SDL_RenderDriver GLES_RenderDriver
SDL_FPoint::y
float y
Definition: SDL_rect.h:63
a
GLboolean GLboolean GLboolean GLboolean a
Definition: SDL_opengl_glext.h:1109
h
GLfloat GLfloat GLfloat GLfloat h
Definition: SDL_opengl_glext.h:1946
SDL_opengles.h
SDL_small_alloc
#define SDL_small_alloc(type, count, pisstack)
Definition: SDL_internal.h:39
length
GLuint GLsizei GLsizei * length
Definition: SDL_opengl_glext.h:669
SDL_Rect::x
int x
Definition: SDL_rect.h:79
SDL_RENDERCMD_COPY
Definition: SDL_sysrender.h:82
GL_BLEND
#define GL_BLEND
Definition: SDL_opengl.h:396
SDL_RENDERCMD_SETCLIPRECT
Definition: SDL_sysrender.h:76
result
GLuint64EXT * result
Definition: SDL_opengl_glext.h:9432
GL_CULL_FACE
#define GL_CULL_FACE
Definition: SDL_opengl.h:301
data
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
Definition: SDL_opengl.h:1973
SDL_Rect::w
int w
Definition: SDL_rect.h:80
GL_TEXTURE_WRAP_T
#define GL_TEXTURE_WRAP_T
Definition: SDL_opengl.h:672
GL_ZERO
#define GL_ZERO
Definition: SDL_opengl.h:399
SDL_Window
The type used to identify a window.
Definition: SDL_sysvideo.h:73
SDL_BLENDFACTOR_SRC_COLOR
Definition: SDL_blendmode.h:79
dst
GLenum GLenum dst
Definition: SDL_opengl_glext.h:1737
SDL_BLENDMODE_INVALID
Definition: SDL_blendmode.h:53
GL_LINE_STRIP
#define GL_LINE_STRIP
Definition: SDL_opengl.h:218
SDL_GL_GetDrawableSize
#define SDL_GL_GetDrawableSize
Definition: SDL_dynapi_overrides.h:563
GL_INVALID_OPERATION
#define GL_INVALID_OPERATION
Definition: SDL_opengl.h:721
SDL_BLENDOPERATION_ADD
Definition: SDL_blendmode.h:64
SDL_memcpy
#define SDL_memcpy
Definition: SDL_dynapi_overrides.h:387
Uint8
uint8_t Uint8
Definition: SDL_stdinc.h:179
GL_TEXTURE_MIN_FILTER
#define GL_TEXTURE_MIN_FILTER
Definition: SDL_opengl.h:674
event
struct _cl_event * event
Definition: SDL_opengl_glext.h:2649
SDL_Renderer
Definition: SDL_sysrender.h:122
GL_PROJECTION
#define GL_PROJECTION
Definition: SDL_opengl.h:271
context
static screen_context_t context
Definition: video.c:25
SDL_Renderer::QueueSetDrawColor
int(* QueueSetDrawColor)(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
Definition: SDL_sysrender.h:131
SDL_FPoint
The structure that defines a point (floating point)
Definition: SDL_rect.h:60
SDL_Renderer::driverdata
void * driverdata
Definition: SDL_sysrender.h:232
SDL_FRect::y
float y
Definition: SDL_rect.h:90
SDL_FRect::w
float w
Definition: SDL_rect.h:91
GL_VERTEX_ARRAY
#define GL_VERTEX_ARRAY
Definition: SDL_opengl.h:227
x
GLint GLint GLint GLint GLint x
Definition: SDL_opengl.h:1573
color
GLuint color
Definition: SDL_opengl_glext.h:1148
window
EGLSurface EGLNativeWindowType * window
Definition: eglext.h:1025
GL_LINE_LOOP
#define GL_LINE_LOOP
Definition: SDL_opengl.h:217
SDL_RendererInfo::flags
Uint32 flags
Definition: SDL_render.h:81
SDL_GL_SetAttribute
#define SDL_GL_SetAttribute
Definition: SDL_dynapi_overrides.h:557
SDL_RenderCommand::viewport
struct SDL_RenderCommand::@30::@31 viewport
SDL_Rect::y
int y
Definition: SDL_rect.h:79
GL_ONE_MINUS_SRC_COLOR
#define GL_ONE_MINUS_SRC_COLOR
Definition: SDL_opengl.h:402
GL_NO_ERROR
#define GL_NO_ERROR
Definition: SDL_opengl.h:718
SDL_memcmp
#define SDL_memcmp
Definition: SDL_dynapi_overrides.h:389
SDL_INLINE
#define SDL_INLINE
Definition: begin_code.h:134
SDL_Rect::h
int h
Definition: SDL_rect.h:80
SDL_free
#define SDL_free
Definition: SDL_dynapi_overrides.h:377
f
GLfloat f
Definition: SDL_opengl_glext.h:1870
SDL_GL_CONTEXT_MAJOR_VERSION
Definition: SDL_video.h:217
height
GLint GLint GLsizei GLsizei height
Definition: SDL_opengl.h:1571
SDL_Renderer::SupportsBlendMode
SDL_bool(* SupportsBlendMode)(SDL_Renderer *renderer, SDL_BlendMode blendMode)
Definition: SDL_sysrender.h:128
SDL_RENDERCMD_SETVIEWPORT
Definition: SDL_sysrender.h:75
SDL_FLIP_HORIZONTAL
Definition: SDL_render.h:114
SDL_BLENDFACTOR_DST_COLOR
Definition: SDL_blendmode.h:83
SDL_Renderer::QueueDrawLines
int(* QueueDrawLines)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
Definition: SDL_sysrender.h:134
SDL_FALSE
Definition: SDL_stdinc.h:163
SDL_RENDERER_PRESENTVSYNC
Definition: SDL_render.h:69
SDL_RENDERCMD_DRAW_POINTS
Definition: SDL_sysrender.h:79
rect
SDL_Rect rect
Definition: testrelative.c:27
GL_DEPTH_TEST
#define GL_DEPTH_TEST
Definition: SDL_opengl.h:326
SDL_RenderCommand::draw
struct SDL_RenderCommand::@30::@33 draw
SDL_BLENDFACTOR_SRC_ALPHA
Definition: SDL_blendmode.h:81
SDL_BLENDFACTOR_ONE_MINUS_SRC_COLOR
Definition: SDL_blendmode.h:80
SDL_GL_CONTEXT_PROFILE_ES
Definition: SDL_video.h:233
SDL_GL_GetSwapInterval
#define SDL_GL_GetSwapInterval
Definition: SDL_dynapi_overrides.h:565
SetDrawState
static void SetDrawState(SDL_Surface *surface, SW_DrawStateCache *drawstate)
Definition: SDL_render_sw.c:584
SDL_GL_SetSwapInterval
#define SDL_GL_SetSwapInterval
Definition: SDL_dynapi_overrides.h:564
SDL_GetBlendModeDstAlphaFactor
SDL_BlendFactor SDL_GetBlendModeDstAlphaFactor(SDL_BlendMode blendMode)
Definition: SDL_render.c:3370
GL_TEXTURE_MAG_FILTER
#define GL_TEXTURE_MAG_FILTER
Definition: SDL_opengl.h:673
SDL_Renderer::GL_BindTexture
int(* GL_BindTexture)(SDL_Renderer *renderer, SDL_Texture *texture, float *texw, float *texh)
Definition: SDL_sysrender.h:163
SDL_RenderCommand::command
SDL_RenderCommandType command
Definition: SDL_sysrender.h:88
SDL_RENDERCMD_NO_OP
Definition: SDL_sysrender.h:74
SDL_Renderer::QueueSetViewport
int(* QueueSetViewport)(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
Definition: SDL_sysrender.h:130
SDL_BlendFactor
SDL_BlendFactor
The normalized factor used to multiply pixel components.
Definition: SDL_blendmode.h:75
GL_TEXTURE_COORD_ARRAY
#define GL_TEXTURE_COORD_ARRAY
Definition: SDL_opengl.h:231
SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA
Definition: SDL_blendmode.h:86
SDL_GL_GetCurrentContext
#define SDL_GL_GetCurrentContext
Definition: SDL_dynapi_overrides.h:562
SDL_GL_CONTEXT_MINOR_VERSION
Definition: SDL_video.h:218
SDL_WINDOWEVENT_MINIMIZED
Definition: SDL_video.h:159
GL_TEXTURE_WRAP_S
#define GL_TEXTURE_WRAP_S
Definition: SDL_opengl.h:671
SDL_RENDERCMD_DRAW_LINES
Definition: SDL_sysrender.h:80
pixels
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
Definition: SDL_opengl.h:1571
SDL_BlendMode
SDL_BlendMode
The blend mode used in SDL_RenderCopy() and drawing operations.
Definition: SDL_blendmode.h:40
SDL_BlendOperation
SDL_BlendOperation
The blend operation used when combining source and destination pixel components.
Definition: SDL_blendmode.h:62
SDL_Renderer::GetOutputSize
int(* GetOutputSize)(SDL_Renderer *renderer, int *w, int *h)
Definition: SDL_sysrender.h:127
SDL_OutOfMemory
#define SDL_OutOfMemory()
Definition: SDL_error.h:52
SDL_Renderer::CreateTexture
int(* CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:129
SDL_BLENDFACTOR_ONE
Definition: SDL_blendmode.h:78
y
GLint GLint GLint GLint GLint GLint y
Definition: SDL_opengl.h:1573
SDL_Texture::format
Uint32 format
Definition: SDL_sysrender.h:46
SDL_RENDERCMD_FILL_RECTS
Definition: SDL_sysrender.h:81
GL_SCISSOR_TEST
#define GL_SCISSOR_TEST
Definition: SDL_opengl.h:614
SDL_Renderer::DestroyRenderer
void(* DestroyRenderer)(SDL_Renderer *renderer)
Definition: SDL_sysrender.h:161
SDL_Renderer::LockTexture
int(* LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
Definition: SDL_sysrender.h:152
SDL_calloc
#define SDL_calloc
Definition: SDL_dynapi_overrides.h:375
SDL_GetRendererOutputSize
#define SDL_GetRendererOutputSize
Definition: SDL_dynapi_overrides.h:305
SDL_Renderer::RenderReadPixels
int(* RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect, Uint32 format, void *pixels, int pitch)
Definition: SDL_sysrender.h:156
SDL_GetBlendModeSrcAlphaFactor
SDL_BlendFactor SDL_GetBlendModeSrcAlphaFactor(SDL_BlendMode blendMode)
Definition: SDL_render.c:3363
SDL_GetBlendModeColorOperation
SDL_BlendOperation SDL_GetBlendModeColorOperation(SDL_BlendMode blendMode)
Definition: SDL_render.c:3356
SDL_RENDERCMD_COPY_EX
Definition: SDL_sysrender.h:83
SDL_bool
SDL_bool
Definition: SDL_stdinc.h:161
GL_SRC_COLOR
#define GL_SRC_COLOR
Definition: SDL_opengl.h:401
SDL_RenderCommand
Definition: SDL_sysrender.h:86
src
GLenum src
Definition: SDL_opengl_glext.h:1737
SDL_RendererFlip
SDL_RendererFlip
Flip constants for SDL_RenderCopyEx.
Definition: SDL_render.h:111
renderer
static SDL_Renderer * renderer
Definition: testaudiocapture.c:21
GL_DST_ALPHA
#define GL_DST_ALPHA
Definition: SDL_opengl.h:405
GL_MODELVIEW
#define GL_MODELVIEW
Definition: SDL_opengl.h:270
SDL_FLIP_VERTICAL
Definition: SDL_render.h:115
GL_STACK_OVERFLOW
#define GL_STACK_OVERFLOW
Definition: SDL_opengl.h:722
SDL_GetBlendModeDstColorFactor
SDL_BlendFactor SDL_GetBlendModeDstColorFactor(SDL_BlendMode blendMode)
Definition: SDL_render.c:3349
SDL_Renderer::info
SDL_RendererInfo info
Definition: SDL_sysrender.h:170
value
GLsizei const GLfloat * value
Definition: SDL_opengl_glext.h:698
SDL_RENDERER_TARGETTEXTURE
Definition: SDL_render.h:71
SDL_SetError
#define SDL_SetError
Definition: SDL_dynapi_overrides.h:30
SDL_Renderer::RenderPresent
void(* RenderPresent)(SDL_Renderer *renderer)
Definition: SDL_sysrender.h:158
SDL_BYTESPERPIXEL
#define SDL_BYTESPERPIXEL(X)
Definition: SDL_pixels.h:128
SDL_glesfuncs.h
SDL_Rect
A rectangle, with the origin at the upper left (integer).
Definition: SDL_rect.h:77
SDL_RendererInfo::max_texture_width
int max_texture_width
Definition: SDL_render.h:84
SDL_TRUE
Definition: SDL_stdinc.h:164
GL_RGBA
#define GL_RGBA
Definition: SDL_opengl.h:528
SDL_Texture
Definition: SDL_sysrender.h:43
SDL_Renderer::QueueFillRects
int(* QueueFillRects)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FRect *rects, int count)
Definition: SDL_sysrender.h:136
SDL_Renderer::UpdateTexture
int(* UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
Definition: SDL_sysrender.h:144
SDL_hints.h
GLsizei
int GLsizei
Definition: SDL_opengl.h:185
SDL_RenderCommand::cliprect
struct SDL_RenderCommand::@30::@32 cliprect
SDL_GL_MakeCurrent
#define SDL_GL_MakeCurrent
Definition: SDL_dynapi_overrides.h:560
SDL_TEXTUREACCESS_TARGET
Definition: SDL_render.h:95
GLenum
unsigned int GLenum
Definition: SDL_opengl.h:175
GL_PACK_ALIGNMENT
#define GL_PACK_ALIGNMENT
Definition: SDL_opengl.h:651
SDL_WindowEvent
Window state change event data (event.window.*)
Definition: SDL_events.h:195
GL_LINEAR
#define GL_LINEAR
Definition: SDL_opengl.h:446
SDL_GL_GetAttribute
#define SDL_GL_GetAttribute
Definition: SDL_dynapi_overrides.h:558
SDL_FRect
A rectangle, with the origin at the upper left (floating point).
Definition: SDL_rect.h:87
SDL_RenderDriver::info
SDL_RendererInfo info
Definition: SDL_sysrender.h:241
SDL_ConvertPixels
#define SDL_ConvertPixels
Definition: SDL_dynapi_overrides.h:465
angle
GLfloat angle
Definition: SDL_opengl_glext.h:6097
GL_INVALID_VALUE
#define GL_INVALID_VALUE
Definition: SDL_opengl.h:720
Uint32
uint32_t Uint32
Definition: SDL_stdinc.h:203
SDL_BLENDMODE_NONE
Definition: SDL_blendmode.h:42
GL_OUT_OF_MEMORY
#define GL_OUT_OF_MEMORY
Definition: SDL_opengl.h:724
GL_CLAMP_TO_EDGE
#define GL_CLAMP_TO_EDGE
Definition: SDL_opengl.h:1506
GL_APIENTRY
#define GL_APIENTRY
Definition: SDL_opengles2_gl2platform.h:27
SDL_Renderer::QueueDrawPoints
int(* QueueDrawPoints)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
Definition: SDL_sysrender.h:132
GLuint
unsigned int GLuint
Definition: SDL_opengl.h:184
SDL_GL_SwapWindow
#define SDL_GL_SwapWindow
Definition: SDL_dynapi_overrides.h:566
internalFormat
GLenum internalFormat
Definition: SDL_opengl_glext.h:5063
SDL_malloc
#define SDL_malloc
Definition: SDL_dynapi_overrides.h:374
SDL_RENDERER_ACCELERATED
Definition: SDL_render.h:67
GL_ONE_MINUS_SRC_ALPHA
#define GL_ONE_MINUS_SRC_ALPHA
Definition: SDL_opengl.h:404
SDL_BLENDFACTOR_DST_ALPHA
Definition: SDL_blendmode.h:85
framebuffers
const GLuint * framebuffers
Definition: SDL_opengl_glext.h:1175
SDL_RendererInfo::max_texture_height
int max_texture_height
Definition: SDL_render.h:85
SDL_RENDERCMD_SETDRAWCOLOR
Definition: SDL_sysrender.h:77
flags
GLbitfield flags
Definition: SDL_opengl_glext.h:1480
SDL_Renderer::QueueCopy
int(* QueueCopy)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
Definition: SDL_sysrender.h:138
SDL_Renderer::window
SDL_Window * window
Definition: SDL_sysrender.h:173
SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA
Definition: SDL_blendmode.h:82
SDL_TEXTUREACCESS_STREAMING
Definition: SDL_render.h:94
SDL_Renderer::target
SDL_Texture * target
Definition: SDL_sysrender.h:206
texture
GLenum GLenum GLuint texture
Definition: SDL_opengl_glext.h:1178
GL_SRC_ALPHA
#define GL_SRC_ALPHA
Definition: SDL_opengl.h:403
GL_INVALID_ENUM
#define GL_INVALID_ENUM
Definition: SDL_opengl.h:719
GL_DST_COLOR
#define GL_DST_COLOR
Definition: SDL_opengl.h:407
GL_ONE_MINUS_DST_COLOR
#define GL_ONE_MINUS_DST_COLOR
Definition: SDL_opengl.h:408
rects
EGLSurface EGLint * rects
Definition: eglext.h:282
SDL_PIXELFORMAT_ABGR8888
Definition: SDL_pixels.h:254
SDL_GetBlendModeAlphaOperation
SDL_BlendOperation SDL_GetBlendModeAlphaOperation(SDL_BlendMode blendMode)
Definition: SDL_render.c:3377
type
GLuint GLuint GLsizei GLenum type
Definition: SDL_opengl.h:1570
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 in i)
Definition: SDL_x11sym.h:50
GL_UNSIGNED_BYTE
#define GL_UNSIGNED_BYTE
Definition: SDL_opengl.h:203
SDL_GL_DeleteContext
#define SDL_GL_DeleteContext
Definition: SDL_dynapi_overrides.h:567
SDL_GetBlendModeSrcColorFactor
SDL_BlendFactor SDL_GetBlendModeSrcColorFactor(SDL_BlendMode blendMode)
Definition: SDL_render.c:3342
GL_TRIANGLE_STRIP
#define GL_TRIANGLE_STRIP
Definition: SDL_opengl.h:220
GLint
int GLint
Definition: SDL_opengl.h:181
GLfloat
float GLfloat
Definition: SDL_opengl.h:186
SDL_RENDERCMD_CLEAR
Definition: SDL_sysrender.h:78
GL_FLOAT
#define GL_FLOAT
Definition: SDL_opengl.h:208
SDL_Renderer::UnlockTexture
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:154
SDL_Renderer::DestroyTexture
void(* DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
Definition: SDL_sysrender.h:159
w
GLubyte GLubyte GLubyte GLubyte w
Definition: SDL_opengl_glext.h:731
SDL_GL_ExtensionSupported
#define SDL_GL_ExtensionSupported
Definition: SDL_dynapi_overrides.h:556