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;
55 typedef struct GLES_FBOList GLES_FBOList;
80 } GLES_DrawStateCache;
86 #define SDL_PROC(ret,func,params) ret (APIENTRY *func) params;
87 #define SDL_PROC_OES SDL_PROC
91 SDL_bool GL_OES_framebuffer_object_supported;
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;
99 GLES_DrawStateCache drawstate;
122 error =
"GL_NO_ERROR";
125 error =
"GL_INVALID_ENUM";
128 error =
"GL_INVALID_VALUE";
131 error =
"GL_INVALID_OPERATION";
134 error =
"GL_STACK_OVERFLOW";
137 error =
"GL_STACK_UNDERFLOW";
140 error =
"GL_OUT_OF_MEMORY";
149 static int GLES_LoadFunctions(GLES_RenderData *
data)
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__
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;
163 #define SDL_PROC(ret,func,params) \
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()); \
170 #define SDL_PROC_OES(ret,func,params) \
172 data->func = SDL_GL_GetProcAddress(#func); \
182 static GLES_FBOList *
265 return GL_FUNC_ADD_OES;
267 return GL_FUNC_SUBTRACT_OES;
269 return GL_FUNC_REVERSE_SUBTRACT_OES;
294 if ((srcColorFactor != srcAlphaFactor || dstColorFactor != dstAlphaFactor) && !
data->GL_OES_blend_func_separate_supported) {
297 if (colorOperation != alphaOperation && !
data->GL_OES_blend_equation_separate_supported) {
307 power_of_2(
int input)
321 GLES_TextureData *
data;
324 int texture_w, texture_h;
356 if (!renderdata->GL_OES_framebuffer_object_supported) {
358 return SDL_SetError(
"GL_OES_framebuffer_object not supported");
366 renderdata->glGetError();
368 renderdata->glGenTextures(1, &
data->texture);
369 result = renderdata->glGetError();
372 return GLES_SetError(
"glGenTextures()",
result);
377 texture_w = power_of_2(
texture->w);
378 texture_h = power_of_2(
texture->h);
385 renderdata->glBindTexture(
data->type,
data->texture);
394 renderdata->drawstate.texture =
texture;
395 renderdata->drawstate.texturing =
SDL_FALSE;
397 result = renderdata->glGetError();
400 return GLES_SetError(
"glTexImage2D()",
result);
412 GLES_TextureData *
data = (GLES_TextureData *)
texture->driverdata;
428 if (pitch != srcPitch) {
443 renderdata->glGetError();
444 renderdata->glEnable(
data->type);
445 renderdata->glBindTexture(
data->type,
data->texture);
447 renderdata->glTexSubImage2D(
data->type,
456 renderdata->glDisable(
data->type);
459 renderdata->drawstate.texture =
texture;
460 renderdata->drawstate.texturing =
SDL_FALSE;
472 GLES_TextureData *
data = (GLES_TextureData *)
texture->driverdata;
477 *pitch =
data->pitch;
484 GLES_TextureData *
data = (GLES_TextureData *)
texture->driverdata;
499 GLES_TextureData *
data = (GLES_TextureData *)
texture->driverdata;
502 renderdata->glBindTexture(
data->type,
data->texture);
511 GLES_TextureData *texturedata =
NULL;
514 if (!
data->GL_OES_framebuffer_object_supported) {
515 return SDL_SetError(
"Can't enable render target support in this renderer");
521 data->glBindFramebufferOES(GL_FRAMEBUFFER_OES,
data->window_framebuffer);
525 texturedata = (GLES_TextureData *)
texture->driverdata;
526 data->glBindFramebufferOES(GL_FRAMEBUFFER_OES, texturedata->fbo->FBO);
528 data->glFramebufferTexture2DOES(GL_FRAMEBUFFER_OES, GL_COLOR_ATTACHMENT0_OES, texturedata->type, texturedata->texture, 0);
530 status =
data->glCheckFramebufferStatusOES(GL_FRAMEBUFFER_OES);
531 if (status != GL_FRAMEBUFFER_COMPLETE_OES) {
532 return SDL_SetError(
"glFramebufferTexture2DOES() failed");
584 const GLfloat xstart = verts[0];
585 const GLfloat ystart = verts[1];
589 if (ystart == yend) {
590 verts[2] += (xend > xstart) ? 1.0f : -1.0f;
591 }
else if (xstart == xend) {
592 verts[3] += (yend > ystart) ? 1.0f : -1.0f;
594 const GLfloat deltax = xend - xstart;
595 const GLfloat deltay = yend - ystart;
640 GLES_TextureData *texturedata = (GLES_TextureData *)
texture->driverdata;
641 GLfloat minx, miny, maxx, maxy;
642 GLfloat minu, maxu, minv, maxv;
653 maxx = dstrect->
x + dstrect->
w;
654 maxy = dstrect->
y + dstrect->
h;
657 minu *= texturedata->texw;
659 maxu *= texturedata->texw;
661 minv *= texturedata->texh;
663 maxv *= texturedata->texh;
691 GLES_TextureData *texturedata = (GLES_TextureData *)
texture->driverdata;
692 GLfloat minx, miny, maxx, maxy;
694 GLfloat minu, maxu, minv, maxv;
705 minx = dstrect->
w - centerx;
710 maxx = dstrect->
w - centerx;
714 miny = dstrect->
h - centery;
719 maxy = dstrect->
h - centery;
723 minu *= texturedata->texw;
725 maxu *= texturedata->texw;
727 minv *= texturedata->texh;
729 maxv *= texturedata->texh;
751 *(verts++) = (
GLfloat) dstrect->
x + centerx;
752 *(verts++) = (
GLfloat) dstrect->
y + centery;
773 data->glColor4f(fr, fg, fb, fa);
777 if (
data->drawstate.viewport_dirty) {
781 data->glLoadIdentity();
795 if (
data->drawstate.cliprect_enabled_dirty) {
796 if (
data->drawstate.cliprect_enabled) {
804 if (
data->drawstate.cliprect_enabled &&
data->drawstate.cliprect_dirty) {
814 if (blend !=
data->drawstate.blend) {
819 if (
data->GL_OES_blend_func_separate_supported) {
828 if (
data->GL_OES_blend_equation_separate_supported) {
831 }
else if (
data->GL_OES_blend_subtract_supported) {
835 data->drawstate.blend = blend;
858 GLES_TextureData *texturedata = (GLES_TextureData *)
texture->driverdata;
914 if (
color !=
data->drawstate.clear_color) {
919 data->glClearColor(fr, fg, fb, fa);
923 if (
data->drawstate.cliprect_enabled ||
data->drawstate.cliprect_enabled_dirty) {
925 data->drawstate.cliprect_enabled_dirty =
data->drawstate.cliprect_enabled;
966 SetCopyState(
data, cmd);
975 const GLfloat translatex = verts[16];
976 const GLfloat translatey = verts[17];
978 SetCopyState(
data, cmd);
983 data->glPushMatrix();
984 data->glTranslatef(translatex, translatey, 0.0f);
1047 temp_format, temp_pixels, temp_pitch,
1067 GLES_TextureData *
data = (GLES_TextureData *)
texture->driverdata;
1071 if (renderdata->drawstate.texture ==
texture) {
1072 renderdata->drawstate.texture =
NULL;
1074 if (renderdata->drawstate.target ==
texture) {
1075 renderdata->drawstate.target =
NULL;
1081 if (
data->texture) {
1082 renderdata->glDeleteTextures(1, &
data->texture);
1095 if (
data->context) {
1096 while (
data->framebuffers) {
1097 GLES_FBOList *nextnode =
data->framebuffers->next;
1098 data->glDeleteFramebuffersOES(1, &
data->framebuffers->FBO);
1100 data->framebuffers = nextnode;
1112 GLES_TextureData *texturedata = (GLES_TextureData *)
texture->driverdata;
1116 data->glBindTexture(texturedata->type, texturedata->texture);
1122 *texw = (float)texturedata->texw;
1125 *texh = (float)texturedata->texh;
1134 GLES_TextureData *texturedata = (GLES_TextureData *)
texture->driverdata;
1136 data->glDisable(texturedata->type);
1148 GLES_RenderData *
data;
1151 int profile_mask = 0, major = 0, minor = 0;
1214 if (!
data->context) {
1223 if (GLES_LoadFunctions(
data) < 0) {
1250 data->glGetIntegerv(GL_FRAMEBUFFER_BINDING_OES, &
value);
1259 data->GL_OES_blend_equation_separate_supported =
SDL_TRUE;
1270 data->glLoadIdentity();
1275 data->glClearColor(1.0f, 1.0f, 1.0f, 1.0f);
1278 data->drawstate.color = 0xFFFFFFFF;
1279 data->drawstate.clear_color = 0xFFFFFFFF;
1284 if (changed_window) {
1295 GLES_CreateRenderer,
#define SDL_assert(condition)
SDL_BlendOperation
The blend operation used when combining source and destination pixel components.
@ SDL_BLENDOPERATION_REV_SUBTRACT
@ SDL_BLENDOPERATION_SUBTRACT
SDL_BlendFactor
The normalized factor used to multiply pixel components.
@ SDL_BLENDFACTOR_ONE_MINUS_SRC_COLOR
@ SDL_BLENDFACTOR_SRC_COLOR
@ SDL_BLENDFACTOR_SRC_ALPHA
@ SDL_BLENDFACTOR_ONE_MINUS_DST_COLOR
@ SDL_BLENDFACTOR_ONE_MINUS_DST_ALPHA
@ SDL_BLENDFACTOR_ONE_MINUS_SRC_ALPHA
@ SDL_BLENDFACTOR_DST_ALPHA
@ SDL_BLENDFACTOR_DST_COLOR
SDL_BlendMode
The blend mode used in SDL_RenderCopy() and drawing operations.
#define SDL_GL_SwapWindow
#define SDL_GetWindowFlags
#define SDL_GL_GetAttribute
#define SDL_GL_SetSwapInterval
#define SDL_GL_MakeCurrent
#define SDL_GetRendererOutputSize
#define SDL_GL_SetAttribute
#define SDL_GL_GetSwapInterval
#define SDL_GL_DeleteContext
#define SDL_GL_CreateContext
#define SDL_GL_ExtensionSupported
#define SDL_GL_GetDrawableSize
#define SDL_ConvertPixels
#define SDL_GL_GetCurrentContext
#define SDL_OutOfMemory()
#define SDL_small_alloc(type, count, pisstack)
#define SDL_small_free(ptr, isstack)
int uint32_t uint32_t uint32_t pixel_format
#define GL_TEXTURE_COORD_ARRAY
#define GL_MAX_TEXTURE_SIZE
GLint GLint GLint GLint GLint GLint y
#define GL_TEXTURE_MIN_FILTER
#define GL_TEXTURE_WRAP_S
#define GL_ONE_MINUS_DST_ALPHA
#define GL_PACK_ALIGNMENT
#define GL_ONE_MINUS_DST_COLOR
#define GL_INVALID_OPERATION
GLuint GLuint GLsizei count
GLint GLint GLsizei GLsizei GLsizei GLint GLenum GLenum const GLvoid * pixels
#define GL_STACK_OVERFLOW
GLint GLenum GLsizei GLsizei GLsizei GLint GLsizei const GLvoid * data
#define GL_UNPACK_ALIGNMENT
#define GL_COLOR_BUFFER_BIT
GLint GLint GLsizei width
#define GL_ONE_MINUS_SRC_ALPHA
GLdouble GLdouble GLdouble r
GLint GLint GLint GLint GLint x
#define GL_TEXTURE_WRAP_T
GLint GLint GLsizei GLsizei height
#define GL_TEXTURE_MAG_FILTER
#define GL_TRIANGLE_STRIP
GLuint GLuint GLsizei GLenum type
#define GL_STACK_UNDERFLOW
GLint GLint GLsizei GLsizei GLsizei GLint GLenum format
#define GL_ONE_MINUS_SRC_COLOR
GLboolean GLboolean GLboolean b
GLfixed GLfixed GLint GLint GLfixed points
GLboolean GLboolean GLboolean GLboolean a
const GLuint * framebuffers
GLenum GLenum GLuint texture
GLuint GLsizei GLsizei * length
GLsizei const GLfloat * value
GLenum GLenum GLenum input
GLfloat GLfloat GLfloat GLfloat h
GLubyte GLubyte GLubyte GLubyte w
#define SDL_BYTESPERPIXEL(X)
@ SDL_PIXELFORMAT_ABGR8888
SDL_BlendFactor SDL_GetBlendModeDstColorFactor(SDL_BlendMode blendMode)
SDL_BlendFactor SDL_GetBlendModeSrcColorFactor(SDL_BlendMode blendMode)
void * SDL_AllocateRenderVertices(SDL_Renderer *renderer, const size_t numbytes, const size_t alignment, size_t *offset)
SDL_BlendFactor SDL_GetBlendModeDstAlphaFactor(SDL_BlendMode blendMode)
SDL_BlendFactor SDL_GetBlendModeSrcAlphaFactor(SDL_BlendMode blendMode)
SDL_BlendOperation SDL_GetBlendModeAlphaOperation(SDL_BlendMode blendMode)
SDL_BlendOperation SDL_GetBlendModeColorOperation(SDL_BlendMode blendMode)
@ SDL_RENDERER_ACCELERATED
@ SDL_RENDERER_PRESENTVSYNC
@ SDL_RENDERER_TARGETTEXTURE
SDL_RendererFlip
Flip constants for SDL_RenderCopyEx.
@ SDL_TEXTUREACCESS_STREAMING
@ SDL_TEXTUREACCESS_TARGET
SDL_ScaleMode
The scaling mode for a texture.
static void SetDrawState(SDL_Surface *surface, SW_DrawStateCache *drawstate)
SDL_RenderDriver GLES_RenderDriver
@ SDL_RENDERCMD_SETCLIPRECT
@ SDL_RENDERCMD_DRAW_LINES
@ SDL_RENDERCMD_SETVIEWPORT
@ SDL_RENDERCMD_DRAW_POINTS
@ SDL_RENDERCMD_FILL_RECTS
@ SDL_RENDERCMD_SETDRAWCOLOR
int SDL_RecreateWindow(SDL_Window *window, Uint32 flags)
@ SDL_GL_CONTEXT_MAJOR_VERSION
@ SDL_GL_CONTEXT_MINOR_VERSION
@ SDL_GL_CONTEXT_PROFILE_MASK
void * SDL_GLContext
An opaque handle to an OpenGL context.
@ SDL_WINDOWEVENT_MINIMIZED
@ SDL_GL_CONTEXT_PROFILE_ES
return Display return Display Bool Bool int int int return Display XEvent Bool(*) XPointer return Display return Display Drawable _Xconst char unsigned int unsigned int return Display Pixmap Pixmap XColor XColor unsigned int unsigned int return Display _Xconst char char int char return Display Visual unsigned int int int char unsigned int unsigned int in i)
EGLSurface EGLNativeWindowType * window
EGLSurface EGLint * rects
set set set set set set set macro pixldst1 abits if abits op else op endif endm macro pixldst2 abits if abits op else op endif endm macro pixldst4 abits if abits op else op endif endm macro pixldst0 abits op endm macro pixldst3 mem_operand op endm macro pixldst30 mem_operand op endm macro pixldst abits if abits elseif abits elseif abits elseif abits elseif abits pixldst0 abits else pixldst0 abits pixldst0 abits pixldst0 abits pixldst0 abits endif elseif abits else pixldst0 abits pixldst0 abits endif elseif abits else error unsupported bpp *numpix else pixst endif endm macro pixld1_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl mov asr adds SRC_WIDTH_FIXED bpl add asl else error unsupported endif endm macro pixld2_s mem_operand if mov asr add asl add asl mov asr sub UNIT_X add asl mov asr add asl add asl mov asr add UNIT_X add asl else pixld1_s mem_operand pixld1_s mem_operand endif endm macro pixld0_s mem_operand if asr adds SRC_WIDTH_FIXED bpl add asl elseif asr adds SRC_WIDTH_FIXED bpl add asl endif endm macro pixld_s_internal mem_operand if mem_operand pixld2_s mem_operand pixdeinterleave basereg elseif mem_operand elseif mem_operand elseif mem_operand elseif mem_operand pixld0_s mem_operand else pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else pixld0_s mem_operand pixld0_s mem_operand endif elseif mem_operand else error unsupported mem_operand if bpp mem_operand endif endm macro vuzp8 reg2 vuzp d d ®2 endm macro vzip8 reg2 vzip d d ®2 endm macro pixdeinterleave basereg basereg basereg basereg basereg endif endm macro pixinterleave basereg basereg basereg basereg basereg endif endm macro PF boost_increment endif if endif PF tst PF addne PF subne PF cmp ORIG_W if endif if endif if endif PF subge ORIG_W PF subges if endif if endif if endif endif endm macro cache_preload_simple endif if dst_r_bpp pld[DST_R, #(PREFETCH_DISTANCE_SIMPLE *dst_r_bpp/8)] endif if mask_bpp pld if[MASK, #(PREFETCH_DISTANCE_SIMPLE *mask_bpp/8)] endif endif endm macro fetch_mask_pixblock pixld mask_basereg pixblock_size MASK endm macro ensure_destination_ptr_alignment process_pixblock_tail_head if beq irp skip1(dst_w_bpp<=(lowbit *8)) &&((lowbit *8)<(pixblock_size *dst_w_bpp)) .if lowbit< 16 tst DST_R
The structure that defines a point (floating point)
A rectangle, with the origin at the upper left (floating point).
A rectangle, with the origin at the upper left (integer).
struct SDL_RenderCommand::@38::@42 color
struct SDL_RenderCommand * next
struct SDL_RenderCommand::@38::@39 viewport
struct SDL_RenderCommand::@38::@41 draw
SDL_RenderCommandType command
union SDL_RenderCommand::@38 data
struct SDL_RenderCommand::@38::@40 cliprect
int(* QueueCopy)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const SDL_Rect *srcrect, const SDL_FRect *dstrect)
int(* LockTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, void **pixels, int *pitch)
int(* QueueDrawLines)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
void(* SetTextureScaleMode)(SDL_Renderer *renderer, SDL_Texture *texture, SDL_ScaleMode scaleMode)
void(* UnlockTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* UpdateTexture)(SDL_Renderer *renderer, SDL_Texture *texture, const SDL_Rect *rect, const void *pixels, int pitch)
int(* SetRenderTarget)(SDL_Renderer *renderer, SDL_Texture *texture)
void(* DestroyRenderer)(SDL_Renderer *renderer)
void(* DestroyTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* GL_BindTexture)(SDL_Renderer *renderer, SDL_Texture *texture, float *texw, float *texh)
int(* GetOutputSize)(SDL_Renderer *renderer, int *w, int *h)
SDL_bool(* SupportsBlendMode)(SDL_Renderer *renderer, SDL_BlendMode blendMode)
void(* RenderPresent)(SDL_Renderer *renderer)
int(* RenderReadPixels)(SDL_Renderer *renderer, const SDL_Rect *rect, Uint32 format, void *pixels, int pitch)
int(* QueueDrawPoints)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FPoint *points, int count)
int(* QueueFillRects)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, const SDL_FRect *rects, int count)
void(* WindowEvent)(SDL_Renderer *renderer, const SDL_WindowEvent *event)
int(* RunCommandQueue)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, void *vertices, size_t vertsize)
int(* QueueCopyEx)(SDL_Renderer *renderer, SDL_RenderCommand *cmd, SDL_Texture *texture, const SDL_Rect *srcquad, const SDL_FRect *dstrect, const double angle, const SDL_FPoint *center, const SDL_RendererFlip flip)
int(* CreateTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* QueueSetViewport)(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
int(* GL_UnbindTexture)(SDL_Renderer *renderer, SDL_Texture *texture)
int(* QueueSetDrawColor)(SDL_Renderer *renderer, SDL_RenderCommand *cmd)
Window state change event data (event.window.*)
The type used to identify a window.
static SDL_Renderer * renderer
static SDL_BlendMode blendMode
static screen_context_t context