21 #include "../../SDL_internal.h" 23 #if SDL_VIDEO_RENDER_OGL_ES && !SDL_RENDER_DISABLED 27 #include "../SDL_sysrender.h" 33 #define RENDERER_CONTEXT_MAJOR 1 34 #define RENDERER_CONTEXT_MINOR 1 36 #if defined(SDL_VIDEO_DRIVER_PANDORA) 53 static const float inv255f = 1.0f / 255.0f;
93 typedef struct GLES_FBOList GLES_FBOList;
123 #define SDL_PROC(ret,func,params) ret (APIENTRY *func) params; 124 #define SDL_PROC_OES SDL_PROC 128 SDL_bool GL_OES_framebuffer_object_supported;
130 GLuint window_framebuffer;
132 SDL_bool GL_OES_blend_func_separate_supported;
155 error =
"GL_NO_ERROR";
158 error =
"GL_INVALID_ENUM";
161 error =
"GL_INVALID_VALUE";
164 error =
"GL_INVALID_OPERATION";
167 error =
"GL_STACK_OVERFLOW";
170 error =
"GL_STACK_UNDERFLOW";
173 error =
"GL_OUT_OF_MEMORY";
182 static int GLES_LoadFunctions(GLES_RenderData *
data)
184 #if SDL_VIDEO_DRIVER_UIKIT 185 #define __SDL_NOGETPROCADDR__ 186 #elif SDL_VIDEO_DRIVER_ANDROID 187 #define __SDL_NOGETPROCADDR__ 188 #elif SDL_VIDEO_DRIVER_PANDORA 189 #define __SDL_NOGETPROCADDR__ 192 #ifdef __SDL_NOGETPROCADDR__ 193 #define SDL_PROC(ret,func,params) data->func=func; 194 #define SDL_PROC_OES(ret,func,params) data->func=func; 196 #define SDL_PROC(ret,func,params) \ 198 data->func = SDL_GL_GetProcAddress(#func); \ 199 if ( ! data->func ) { \ 200 return SDL_SetError("Couldn't load GLES function %s: %s\n", #func, SDL_GetError()); \ 203 #define SDL_PROC_OES(ret,func,params) \ 205 data->func = SDL_GL_GetProcAddress(#func); \ 220 GLES_FBOList *result = data->framebuffers;
221 while ((result) && ((result->w != w) || (result->h != h)) ) {
222 result = result->next;
224 if (result ==
NULL) {
228 data->glGenFramebuffersOES(1, &result->FBO);
229 result->next = data->framebuffers;
230 data->framebuffers =
result;
239 GLES_RenderData *data = (GLES_RenderData *) renderer->
driverdata;
241 if (SDL_CurrentContext != data->context) {
245 SDL_CurrentContext = data->context;
247 GLES_UpdateViewport(renderer);
256 GLES_RenderData *data = (GLES_RenderData *) renderer->
driverdata;
258 if (SDL_CurrentContext == data->context) {
259 GLES_UpdateViewport(renderer);
261 GLES_ActivateRenderer(renderer);
264 data->current.color = 0;
265 data->current.blendMode = -1;
272 data->glLoadIdentity();
283 GLES_RenderData *
data;
286 int profile_mask = 0, major = 0, minor = 0;
313 data = (GLES_RenderData *)
SDL_calloc(1,
sizeof(*data));
315 GLES_DestroyRenderer(renderer);
341 renderer->
info = GLES_RenderDriver.
info;
347 if (!data->context) {
348 GLES_DestroyRenderer(renderer);
352 GLES_DestroyRenderer(renderer);
356 if (GLES_LoadFunctions(data) < 0) {
357 GLES_DestroyRenderer(renderer);
379 data->GL_OES_framebuffer_object_supported =
SDL_TRUE;
383 data->glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &value);
384 data->window_framebuffer = (
GLuint)value;
386 data->framebuffers =
NULL;
389 data->GL_OES_blend_func_separate_supported =
SDL_TRUE;
393 GLES_ResetState(renderer);
398 if (changed_window) {
411 GLES_RenderData *data = (GLES_RenderData *) renderer->
driverdata;
417 SDL_CurrentContext =
NULL;
427 GLES_GetOutputSize(
SDL_Renderer * renderer,
int *w,
int *h)
434 power_of_2(
int input)
438 while (value < input) {
449 if (!hint || *hint ==
'0' ||
SDL_strcasecmp(hint,
"nearest") == 0) {
459 GLES_RenderData *renderdata = (GLES_RenderData *) renderer->
driverdata;
460 GLES_TextureData *data;
463 int texture_w, texture_h;
467 GLES_ActivateRenderer(renderer);
469 switch (texture->
format) {
479 data = (GLES_TextureData *)
SDL_calloc(1,
sizeof(*data));
486 data->pixels =
SDL_calloc(1, texture->
h * data->pitch);
495 if (!renderdata->GL_OES_framebuffer_object_supported) {
497 return SDL_SetError(
"GL_OES_framebuffer_object not supported");
499 data->fbo = GLES_GetFBO(renderer->
driverdata, texture->
w, texture->
h);
505 renderdata->glGetError();
507 renderdata->glGenTextures(1, &data->texture);
508 result = renderdata->glGetError();
511 return GLES_SetError(
"glGenTextures()", result);
516 texture_w = power_of_2(texture->
w);
517 texture_h = power_of_2(texture->
h);
518 data->texw = (
GLfloat) texture->
w / texture_w;
519 data->texh = (
GLfloat) texture->
h / texture_h;
522 data->formattype =
type;
524 renderdata->glBindTexture(data->type, data->texture);
530 renderdata->glTexImage2D(data->type, 0,
internalFormat, texture_w,
534 result = renderdata->glGetError();
537 return GLES_SetError(
"glTexImage2D()", result);
548 GLES_RenderData *renderdata = (GLES_RenderData *) renderer->
driverdata;
549 GLES_TextureData *data = (GLES_TextureData *) texture->
driverdata;
555 GLES_ActivateRenderer(renderer);
558 if (rect->
w <= 0 || rect->
h <= 0) {
564 src = (
Uint8 *)pixels;
565 if (pitch != srcPitch) {
571 for (y = 0; y < rect->
h; ++
y) {
574 pixels = (
Uint8 *)pixels + pitch;
580 renderdata->glGetError();
581 renderdata->glEnable(data->type);
582 renderdata->glBindTexture(data->type, data->texture);
584 renderdata->glTexSubImage2D(data->type,
593 renderdata->glDisable(data->type);
604 const SDL_Rect * rect,
void **pixels,
int *pitch)
606 GLES_TextureData *data = (GLES_TextureData *) texture->
driverdata;
609 (
void *) ((
Uint8 *) data->pixels + rect->
y * data->pitch +
611 *pitch = data->pitch;
618 GLES_TextureData *data = (GLES_TextureData *) texture->
driverdata;
626 GLES_UpdateTexture(renderer, texture, &rect, data->pixels, data->pitch);
632 GLES_RenderData *data = (GLES_RenderData *) renderer->
driverdata;
633 GLES_TextureData *texturedata =
NULL;
636 GLES_ActivateRenderer(renderer);
638 if (!data->GL_OES_framebuffer_object_supported) {
639 return SDL_SetError(
"Can't enable render target support in this renderer");
642 if (texture ==
NULL) {
643 data->glBindFramebufferOES(GL_FRAMEBUFFER_OES, data->window_framebuffer);
647 texturedata = (GLES_TextureData *) texture->
driverdata;
648 data->glBindFramebufferOES(GL_FRAMEBUFFER_OES, texturedata->fbo->FBO);
650 data->glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, texturedata->type, texturedata->texture, 0);
652 status = data->glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
653 if (status != GL_FRAMEBUFFER_COMPLETE_OES) {
654 return SDL_SetError(
"glFramebufferTexture2DOES() failed");
662 GLES_RenderData *data = (GLES_RenderData *) renderer->
driverdata;
664 if (SDL_CurrentContext != data->context) {
681 data->glLoadIdentity();
703 GLES_RenderData *data = (GLES_RenderData *) renderer->
driverdata;
705 if (SDL_CurrentContext != data->context) {
719 data->glScissor(renderer->
viewport.
x + rect->
x, h - renderer->
viewport.
y - rect->
y - rect->
h, rect->
w, rect->
h);
730 Uint32 color = ((a << 24) | (r << 16) | (g << 8) | b);
732 if (color != data->current.color) {
733 data->glColor4f((
GLfloat) r * inv255f,
737 data->current.color =
color;
742 GLES_SetBlendMode(GLES_RenderData * data,
int blendMode)
744 if (blendMode != data->current.blendMode) {
751 if (data->GL_OES_blend_func_separate_supported) {
759 if (data->GL_OES_blend_func_separate_supported) {
767 if (data->GL_OES_blend_func_separate_supported) {
781 if (enabled != data->current.tex_coords) {
787 data->current.tex_coords =
enabled;
794 GLES_RenderData *data = (GLES_RenderData *) renderer->
driverdata;
796 GLES_ActivateRenderer(renderer);
798 GLES_SetColor(data, (
GLfloat) renderer->
r,
803 GLES_SetBlendMode(data, renderer->
blendMode);
811 GLES_RenderData *data = (GLES_RenderData *) renderer->
driverdata;
813 GLES_ActivateRenderer(renderer);
815 data->glClearColor((
GLfloat) renderer->
r * inv255f,
837 GLES_RenderData *data = (GLES_RenderData *) renderer->
driverdata;
841 GLES_SetDrawingState(renderer);
849 vertices[
idx * 2] =
x;
850 vertices[(
idx * 2) + 1] = y;
853 data->glVertexPointer(2,
GL_FLOAT, 0, vertices);
863 GLES_RenderData *data = (GLES_RenderData *) renderer->
driverdata;
867 GLES_SetDrawingState(renderer);
875 vertices[
idx * 2] =
x;
876 vertices[(
idx * 2) + 1] = y;
879 data->glVertexPointer(2,
GL_FLOAT, 0, vertices);
881 points[0].
x == points[count-1].
x && points[0].y == points[count-1].y) {
888 data->glDrawArrays(
GL_POINTS, count-1, 1);
899 GLES_RenderData *data = (GLES_RenderData *) renderer->
driverdata;
902 GLES_SetDrawingState(renderer);
920 data->glVertexPointer(2,
GL_FLOAT, 0, vertices);
931 GLES_RenderData *data = (GLES_RenderData *) renderer->
driverdata;
932 GLES_TextureData *texturedata = (GLES_TextureData *) texture->
driverdata;
933 GLfloat minx, miny, maxx, maxy;
934 GLfloat minu, maxu, minv, maxv;
938 GLES_ActivateRenderer(renderer);
942 data->glBindTexture(texturedata->type, texturedata->texture);
945 GLES_SetColor(data, texture->
r, texture->
g, texture->
b, texture->
a);
947 GLES_SetColor(data, 255, 255, 255, 255);
950 GLES_SetBlendMode(data, texture->
blendMode);
956 maxx = dstrect->
x + dstrect->
w;
957 maxy = dstrect->
y + dstrect->
h;
959 minu = (
GLfloat) srcrect->
x / texture->
w;
960 minu *= texturedata->texw;
961 maxu = (
GLfloat) (srcrect->
x + srcrect->
w) / texture->
w;
962 maxu *= texturedata->texw;
963 minv = (
GLfloat) srcrect->
y / texture->
h;
964 minv *= texturedata->texh;
965 maxv = (
GLfloat) (srcrect->
y + srcrect->
h) / texture->
h;
966 maxv *= texturedata->texh;
986 data->glVertexPointer(2,
GL_FLOAT, 0, vertices);
987 data->glTexCoordPointer(2,
GL_FLOAT, 0, texCoords);
1001 GLES_RenderData *data = (GLES_RenderData *) renderer->
driverdata;
1002 GLES_TextureData *texturedata = (GLES_TextureData *) texture->
driverdata;
1003 GLfloat minx, miny, maxx, maxy;
1004 GLfloat minu, maxu, minv, maxv;
1010 GLES_ActivateRenderer(renderer);
1014 data->glBindTexture(texturedata->type, texturedata->texture);
1017 GLES_SetColor(data, texture->
r, texture->
g, texture->
b, texture->
a);
1019 GLES_SetColor(data, 255, 255, 255, 255);
1022 GLES_SetBlendMode(data, texture->
blendMode);
1026 centerx = center->
x;
1027 centery = center->
y;
1030 data->glPushMatrix();
1031 data->glTranslatef(dstrect->
x + centerx, dstrect->
y + centery, 0.0f);
1032 data->glRotatef((
GLfloat)angle, 0.0
f, 0.0
f, 1.0
f);
1035 minx = dstrect->
w - centerx;
1039 maxx = dstrect->
w - centerx;
1043 miny = dstrect->
h - centery;
1047 maxy = dstrect->
h - centery;
1050 minu = (
GLfloat) srcrect->
x / texture->
w;
1051 minu *= texturedata->texw;
1052 maxu = (
GLfloat) (srcrect->
x + srcrect->
w) / texture->
w;
1053 maxu *= texturedata->texw;
1054 minv = (
GLfloat) srcrect->
y / texture->
h;
1055 minv *= texturedata->texh;
1056 maxv = (
GLfloat) (srcrect->
y + srcrect->
h) / texture->
h;
1057 maxv *= texturedata->texh;
1068 texCoords[0] = minu;
1069 texCoords[1] = minv;
1070 texCoords[2] = maxu;
1071 texCoords[3] = minv;
1072 texCoords[4] = minu;
1073 texCoords[5] = maxv;
1074 texCoords[6] = maxu;
1075 texCoords[7] = maxv;
1076 data->glVertexPointer(2,
GL_FLOAT, 0, vertices);
1077 data->glTexCoordPointer(2,
GL_FLOAT, 0, texCoords);
1079 data->glPopMatrix();
1089 GLES_RenderData *data = (GLES_RenderData *) renderer->
driverdata;
1097 GLES_ActivateRenderer(renderer);
1109 data->glReadPixels(rect->
x, renderer->
target ? rect->
y : (h-rect->
y)-rect->
h,
1115 src = (
Uint8*)temp_pixels + (rect->
h-1)*temp_pitch;
1130 temp_format, temp_pixels, temp_pitch,
1131 pixel_format, pixels, pitch);
1140 GLES_ActivateRenderer(renderer);
1148 GLES_RenderData *renderdata = (GLES_RenderData *) renderer->
driverdata;
1150 GLES_TextureData *data = (GLES_TextureData *) texture->
driverdata;
1152 GLES_ActivateRenderer(renderer);
1157 if (data->texture) {
1158 renderdata->glDeleteTextures(1, &data->texture);
1168 GLES_RenderData *data = (GLES_RenderData *) renderer->
driverdata;
1171 if (data->context) {
1172 while (data->framebuffers) {
1173 GLES_FBOList *nextnode = data->framebuffers->next;
1174 data->glDeleteFramebuffersOES(1, &data->framebuffers->FBO);
1176 data->framebuffers = nextnode;
1187 GLES_RenderData *data = (GLES_RenderData *) renderer->
driverdata;
1188 GLES_TextureData *texturedata = (GLES_TextureData *) texture->
driverdata;
1189 GLES_ActivateRenderer(renderer);
1192 data->glBindTexture(texturedata->type, texturedata->texture);
1195 *texw = (float)texturedata->texw;
1198 *texh = (float)texturedata->texh;
1206 GLES_RenderData *data = (GLES_RenderData *) renderer->
driverdata;
1207 GLES_TextureData *texturedata = (GLES_TextureData *) texture->
driverdata;
1208 GLES_ActivateRenderer(renderer);
1209 data->glDisable(texturedata->type);
int(* RenderDrawLines)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
#define GL_STACK_UNDERFLOW
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
#define SDL_GL_ExtensionSupported
int(* RenderDrawPoints)(SDL_Renderer *renderer, const SDL_FPoint *points, int count)
int(* LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
#define GL_INVALID_OPERATION
GLdouble GLdouble GLdouble r
GLint GLint GLsizei width
#define SDL_GL_CreateContext
int(* RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect, Uint32 format, void *pixels, int pitch)
const GLuint * framebuffers
GLint GLint GLint GLint GLint x
GLuint GLuint GLsizei count
#define SDL_HINT_RENDER_SCALE_QUALITY
A variable controlling the scaling quality.
static SDL_Window * window
GLenum GLenum GLuint texture
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d ®2 endm macro vzip8 reg2 vzip d d ®2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld [DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp local skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
#define SDL_GetWindowFlags
#define SDL_BYTESPERPIXEL(X)
#define GL_TEXTURE_MAG_FILTER
int(* RenderFillRects)(SDL_Renderer *renderer, const SDL_FRect *rects, int count)
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
#define GL_TRIANGLE_STRIP
uint32_t Uint32
An unsigned 32-bit integer type.
GLint GLint GLsizei GLsizei height
#define GL_ONE_MINUS_SRC_ALPHA
int(* RenderClear)(SDL_Renderer *renderer)
void(* DestroyRenderer)(SDL_Renderer *renderer)
GLfixed GLfixed GLint GLint GLfixed points
int(* GetOutputSize)(SDL_Renderer *renderer, int *w, int *h)
#define GL_PACK_ALIGNMENT
#define GL_MAX_TEXTURE_SIZE
static SDL_BlendMode blendMode
int(* UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
#define SDL_GL_SetAttribute
#define SDL_GL_GetDrawableSize
GLuint GLuint GLsizei GLenum type
void * SDL_calloc(size_t nmemb, size_t size)
void * SDL_GLContext
An opaque handle to an OpenGL context.
#define SDL_GL_GetSwapInterval
GLenum GLenum GLenum input
GLint GLint GLint GLint GLint GLint y
int SDL_RecreateWindow(SDL_Window *window, Uint32 flags)
GLsizei const GLfloat * value
#define GL_STACK_OVERFLOW
static int GetScaleQuality(void)
static SDL_Renderer * renderer
uint8_t Uint8
An unsigned 8-bit integer type.
#define SDL_stack_alloc(type, count)
#define SDL_GL_SetSwapInterval
#define GL_TEXTURE_WRAP_T
int(* GL_BindTexture)(SDL_Renderer *renderer, SDL_Texture *texture, float *texw, float *texh)
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* UpdateViewport)(SDL_Renderer *renderer)
#define GL_COLOR_BUFFER_BIT
int(* GL_UnbindTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
SDL_RendererFlip
Flip constants for SDL_RenderCopyEx.
GLenum GLenum GLsizei const GLuint GLboolean enabled
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)
int(* RenderCopy)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
Window state change event data (event.window.*)
#define SDL_OutOfMemory()
int(* RenderCopyEx)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *srcquad, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
#define SDL_GL_MakeCurrent
#define SDL_GetRendererOutputSize
The type used to identify a window.
SDL_Rect rects[MAX_RECTS]
void(* WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event)
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 idx
#define GL_TEXTURE_COORD_ARRAY
#define SDL_GL_GetAttribute
GLubyte GLubyte GLubyte GLubyte w
#define SDL_ConvertPixels
void(* DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
void(* RenderPresent)(SDL_Renderer *renderer)
#define SDL_GL_DeleteContext
#define SDL_stack_free(data)
#define GL_TEXTURE_WRAP_S
GLuint GLsizei GLsizei * length
#define GL_TEXTURE_MIN_FILTER
GLboolean GLboolean GLboolean GLboolean a
#define GL_UNPACK_ALIGNMENT
int(* UpdateClipRect)(SDL_Renderer *renderer)
GLboolean GLboolean GLboolean b
#define SDL_GL_SwapWindow
GLfloat GLfloat GLfloat GLfloat h
SDL_bool clipping_enabled
A rectangle, with the origin at the upper left.